Your seed files are structurally correct and will work with the database schema. However, there are some improvements recommended for production use.
Current: All set to null
frontendAuth: null, // ❌ This is a unique field in your schema
Recommended: Derive from path or create unique identifiers
// In seed-menu.ts, update the create data:
frontendAuth: (seed.path, // Use path as unique identifier
// OR create a dedicated field in menu-seeds.ts:
{
legacyId: 16,
title: '系统用户',
frontendAuth: '/system/users', // ✅ Add this
// ... rest
});
Why: Your OperationLog decorator uses frontendAuth to link backend operations to frontend menus. Without it, you can't track which menu triggered which operation.
Current: All set to 0 (no permissions)
canView: 0, // ❌ User can't even view
canCreate: 0,
canUpdate: 0,
canDelete: 0,
Recommended: Set defaults based on menu type
// Helper function in seed-menu.ts:
function getDefaultPermissions(type: MenuType) {
switch (type) {
case 'DIRECTORY':
return { canView: 1, canCreate: 0, canUpdate: 0, canDelete: 0 };
case 'MENU':
return { canView: 1, canCreate: 1, canUpdate: 1, canDelete: 1 };
case 'SUBMENU':
return { canView: 1, canCreate: 1, canUpdate: 1, canDelete: 1 };
case 'BUTTON':
return { canView: 0, canCreate: 1, canUpdate: 0, canDelete: 0 };
default:
return { canView: 0, canCreate: 0, canUpdate: 0, canDelete: 0 };
}
}
// Then use it:
const permissions = getDefaultPermissions(seed.type);
const created = await prisma.menu.create({
data: {
// ... other fields
...permissions,
},
});
Action Flag Values:
0 = Not available1 = Available2 = Required (must be checked in frontend)Current: All set to null
component_key: null, // ❌ Frontend might need this for routing
Recommended: Add to menu-seeds.ts and use it
// In menu-seeds.ts:
export interface SeedMenu {
// ... existing fields
componentKey?: string; // Add this
}
// Example data:
{
legacyId: 16,
title: '系统用户',
componentKey: 'SystemUsers', // ✅ For Vue/React component routing
// ... rest
}
// In seed-menu.ts:
component_key: seed.componentKey ?? null,
Current: All set to null
redirect: null, // Might be needed for DIRECTORY types
Recommended: Set for DIRECTORY types to redirect to first child
// Example for directories:
{
legacyId: 1,
type: 'DIRECTORY',
path: '/marketing',
redirect: '/marketing/videos', // ✅ Redirect to first child
// ... rest
}
Update seed-menu.ts to derive frontendAuth from path:
const created = await prisma.menu.create({
data: {
parentId,
title: seed.title,
status: true,
type: seed.type,
order: seed.order,
frontendAuth: seed.path, // ✅ Use path as unique identifier
path: seed.path,
name: seed.name,
icon: seed.icon,
redirect: null,
component_key: null,
meta: seed.meta ?? undefined,
// ✅ Set default permissions based on type
...getDefaultPermissions(seed.type),
},
});
Update menu-seeds.ts interface:
export interface SeedMenu {
legacyId: number;
legacyParentId: number | null;
title: string;
type: MenuType;
name: string;
path: string;
icon: string | null;
order: number;
frontendAuth?: string; // ✅ Add
componentKey?: string; // ✅ Add
redirect?: string; // ✅ Add
permissions?: {
// ✅ Add
canView?: number;
canCreate?: number;
canUpdate?: number;
canDelete?: number;
};
meta?: Prisma.JsonValue;
}
Update seed data with these values:
{
legacyId: 16,
title: '系统用户',
type: 'MENU',
name: 'systemUsers',
path: '/system/users',
frontendAuth: '/system/users', // ✅
componentKey: 'SystemUsers', // ✅
permissions: { // ✅
canView: 1,
canCreate: 1,
canUpdate: 1,
canDelete: 1,
},
// ... rest
}
Update seed-menu.ts to use these values:
const defaultPerms = getDefaultPermissions(seed.type);
const created = await prisma.menu.create({
data: {
parentId,
title: seed.title,
status: true,
type: seed.type,
order: seed.order,
frontendAuth: seed.frontendAuth ?? seed.path,
path: seed.path,
name: seed.name,
icon: seed.icon,
redirect: seed.redirect ?? null,
component_key: seed.componentKey ?? null,
meta: seed.meta ?? undefined,
canView: seed.permissions?.canView ?? defaultPerms.canView,
canCreate: seed.permissions?.canCreate ?? defaultPerms.canCreate,
canUpdate: seed.permissions?.canUpdate ?? defaultPerms.canUpdate,
canDelete: seed.permissions?.canDelete ?? defaultPerms.canDelete,
},
});
frontendAuth values (use path if nothing else)canView: 1 for visible menus)componentKey for frontend routingredirect for DIRECTORY typesmeta fieldYour seed script should pass these checks:
Add this to verify your seed data before running:
// Add to seed-menu.ts before the main seeding loop:
function validateSeeds() {
const paths = new Set<string>();
const legacyIds = new Set<number>();
for (const seed of MENU_SEEDS) {
// Check unique paths
if (paths.has(seed.path)) {
throw new Error(`Duplicate path: ${seed.path}`);
}
paths.add(seed.path);
// Check unique legacy IDs
if (legacyIds.has(seed.legacyId)) {
throw new Error(`Duplicate legacyId: ${seed.legacyId}`);
}
legacyIds.add(seed.legacyId);
// Check parent exists (except for roots)
if (seed.legacyParentId !== null) {
const parentExists = MENU_SEEDS.some(
(s) => s.legacyId === seed.legacyParentId,
);
if (!parentExists) {
throw new Error(
`Invalid parent ${seed.legacyParentId} for menu ${seed.legacyId}`,
);
}
}
}
console.log('✅ Seed data validation passed');
}
// Call before seeding:
validateSeeds();
Current State: Your seed files are functional and will work, but they create menus with minimal permissions and missing RBAC links.
Recommended State: Add the suggested fields to make the system production-ready with proper permissions and frontend integration.
Estimated Time:
Risk Level: Low - All changes are additive, won't break existing structure
pnpm run prisma:seed:mysql (when DB is accessible)Last Updated: November 17, 2025