import { AccessScopeType, PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); const PERMISSIONS = [ // Campaigns { code: 'campaigns:read', module: 'campaigns', name: 'مشاهده کمپین‌ها', description: 'مشاهده لیست و جزئیات کمپین‌ها' }, { code: 'campaigns:create', module: 'campaigns', name: 'ایجاد کمپین', description: 'ثبت کمپین جدید' }, { code: 'campaigns:update', module: 'campaigns', name: 'ویرایش کمپین', description: 'تغییر تنظیمات و وضعیت کمپین' }, { code: 'campaigns:delete', module: 'campaigns', name: 'حذف کمپین', description: 'حذف کمپین از سامانه' }, // Prizes { code: 'prizes:read', module: 'prizes', name: 'مشاهده جوایز', description: 'مشاهده لیست جوایز کمپین‌ها' }, { code: 'prizes:manage', module: 'prizes', name: 'مدیریت جوایز', description: 'افزودن، ویرایش و تنظیم ظرفیت جوایز' }, // Users & Chances { code: 'users:read', module: 'users', name: 'مشاهده کاربران', description: 'مشاهده لیست کاربران شرکت‌کننده و پروفایل' }, { code: 'users:block', module: 'users', name: 'مسدودسازی کاربران', description: 'بلاک یا آن‌بلاک کردن کاربران' }, { code: 'chances:adjust', module: 'chances', name: 'تنظیم دستی شانس', description: 'افزایش یا کاهش شانس با ثبت لاگ' }, // Winners & Spins { code: 'spins:read', module: 'spins', name: 'مشاهده لاگ چرخش‌ها', description: 'بررسی تاریخچه اسپین‌های کاربران' }, { code: 'winners:read', module: 'winners', name: 'مشاهده برندگان', description: 'مشاهده لیست برندگان و کدهای هدیه' }, { code: 'winners:manage', module: 'winners', name: 'مدیریت وضعیت جوایز', description: 'تغییر وضعیت کدهای جایزه به تحویل‌شده و...' }, // SMS & Logs { code: 'sms:read', module: 'sms', name: 'مشاهده لاگ پیامک', description: 'مشاهده پیامک‌های ارسالی OTP و برندگان' }, { code: 'sms:resend', module: 'sms', name: 'ارسال مجدد پیامک', description: 'ارسال دوباره پیامک‌های ناموفق' }, { code: 'audit:read', module: 'audit', name: 'مشاهده لاگ بازرسی', description: 'مشاهده ردپای عملیات و تغییرات مدیران' }, // Reports { code: 'reports:read', module: 'reports', name: 'مشاهده گزارش‌ها و آمار', description: 'مشاهده نمودارها، آمار زنده و داشبورد' }, { code: 'reports:export', module: 'reports', name: 'خروجی داده‌ها', description: 'دریافت خروجی اکسل و CSV گزارش‌ها' }, // Access Control & Admins { code: 'admins:read', module: 'admins', name: 'مشاهده مدیران', description: 'مشاهده لیست مدیران و همکاران' }, { code: 'admins:manage', module: 'admins', name: 'مدیریت مدیران', description: 'ایجاد، ویرایش، تغییر رمز و غیرفعال‌سازی مدیران' }, { code: 'roles:manage', module: 'roles', name: 'مدیریت نقش‌ها و مجوزها', description: 'تعریف نقش جدید و تخصیص مجوزها' }, { code: 'workspaces:manage', module: 'workspaces', name: 'مدیریت فضاهای کاری', description: 'تعریف و مدیریت فضاهای کاری سازمانی' }, ]; async function main() { console.log('Seeding RBAC and Workspaces...'); // 1. Ensure Default Workspace exists let defaultWorkspace = await prisma.workspace.findUnique({ where: { slug: 'default-workspace' }, }); if (!defaultWorkspace) { defaultWorkspace = await prisma.workspace.create({ data: { name: 'فضای کاری اصلی', slug: 'default-workspace', description: 'فضای کاری پیش‌فرض و سراسری سیستم گردونه شانس', status: 'ACTIVE', }, }); console.log('Created default workspace:', defaultWorkspace.id); } // Link any unassigned campaigns to default workspace await prisma.campaign.updateMany({ where: { workspaceId: null }, data: { workspaceId: defaultWorkspace.id }, }); // 2. Seed Permissions const permissionMap = new Map(); for (const perm of PERMISSIONS) { const p = await prisma.permission.upsert({ where: { code: perm.code }, update: { module: perm.module, name: perm.name, description: perm.description, }, create: { code: perm.code, module: perm.module, name: perm.name, description: perm.description, }, }); permissionMap.set(p.code, p.id); } console.log(`Seeded ${permissionMap.size} permissions.`); // 3. Seed Roles // SUPER_ADMIN (All permissions) const superAdminRole = await prisma.role.upsert({ where: { code: 'SUPER_ADMIN' }, update: { name: 'مدیر ارشد سامانه', description: 'دسترسی کامل و بدون محدودیت به تمامی بخش‌ها و تنظیمات سامانه', isSystem: true, }, create: { code: 'SUPER_ADMIN', name: 'مدیر ارشد سامانه', description: 'دسترسی کامل و بدون محدودیت به تمامی بخش‌ها و تنظیمات سامانه', isSystem: true, }, }); // OPERATOR (Operational permissions) const operatorRole = await prisma.role.upsert({ where: { code: 'OPERATOR' }, update: { name: 'اپراتور سامانه', description: 'مدیریت کمپین‌ها، جوایز، شانس‌ها، برندگان و کاربران بدون دسترسی به مدیریت ادمین‌ها', isSystem: true, }, create: { code: 'OPERATOR', name: 'اپراتور سامانه', description: 'مدیریت کمپین‌ها، جوایز، شانس‌ها، برندگان و کاربران بدون دسترسی به مدیریت ادمین‌ها', isSystem: true, }, }); // SUPPORT (Read-only + winner management) const supportRole = await prisma.role.upsert({ where: { code: 'SUPPORT' }, update: { name: 'کارشناس پشتیبانی', description: 'مشاهده کاربران، برندگان، پیامک‌ها و تغییر وضعیت تحویل جوایز', isSystem: true, }, create: { code: 'SUPPORT', name: 'کارشناس پشتیبانی', description: 'مشاهده کاربران، برندگان، پیامک‌ها و تغییر وضعیت تحویل جوایز', isSystem: true, }, }); // 4. Assign permissions to roles // SUPER_ADMIN gets all permissions for (const permId of permissionMap.values()) { await prisma.rolePermission.upsert({ where: { roleId_permissionId: { roleId: superAdminRole.id, permissionId: permId, }, }, update: {}, create: { roleId: superAdminRole.id, permissionId: permId, }, }); } // OPERATOR permissions const operatorPermCodes = [ 'campaigns:read', 'campaigns:create', 'campaigns:update', 'campaigns:delete', 'prizes:read', 'prizes:manage', 'users:read', 'users:block', 'chances:adjust', 'spins:read', 'winners:read', 'winners:manage', 'sms:read', 'sms:resend', 'reports:read', 'reports:export', 'audit:read', ]; for (const code of operatorPermCodes) { const permId = permissionMap.get(code); if (permId) { await prisma.rolePermission.upsert({ where: { roleId_permissionId: { roleId: operatorRole.id, permissionId: permId, }, }, update: {}, create: { roleId: operatorRole.id, permissionId: permId, }, }); } } // SUPPORT permissions const supportPermCodes = [ 'campaigns:read', 'prizes:read', 'users:read', 'spins:read', 'winners:read', 'winners:manage', 'sms:read', ]; for (const code of supportPermCodes) { const permId = permissionMap.get(code); if (permId) { await prisma.rolePermission.upsert({ where: { roleId_permissionId: { roleId: supportRole.id, permissionId: permId, }, }, update: {}, create: { roleId: supportRole.id, permissionId: permId, }, }); } } // 5. Backfill existing admins const admins = await prisma.admin.findMany(); for (const admin of admins) { const isSuper = admin.role === 'SUPER_ADMIN'; await prisma.admin.update({ where: { id: admin.id }, data: { isSuperAdmin: isSuper, }, }); const targetRoleId = isSuper ? superAdminRole.id : admin.role === 'OPERATOR' ? operatorRole.id : supportRole.id; await prisma.adminRoleAssignment.upsert({ where: { adminId_roleId: { adminId: admin.id, roleId: targetRoleId, }, }, update: {}, create: { adminId: admin.id, roleId: targetRoleId, }, }); await prisma.adminWorkspaceAssignment.upsert({ where: { adminId_workspaceId: { adminId: admin.id, workspaceId: defaultWorkspace.id, }, }, update: {}, create: { adminId: admin.id, workspaceId: defaultWorkspace.id, scopeType: AccessScopeType.ALL, }, }); } console.log(`Backfilled ${admins.length} existing admins with roles and workspace assignments.`); console.log('RBAC seed completed successfully.'); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });