// /seed.js const mongoose = require('mongoose'); const config = require('./config/config'); const Role = require('./components/roles/roleModel'); const User = require('./components/users/userModel'); const { ALL_PERMISSIONS, PERMISSIONS } = require('./constants/permissions'); const bcrypt = require('bcryptjs'); const defaultRoles = [ { name: 'SuperAdmin', description: 'مدیر ارشد سیستم با دسترسی کامل به تمام بخش‌ها', permissions: ALL_PERMISSIONS, isSystem: true }, { name: 'Admin', description: 'مدیر سیستم', permissions: ALL_PERMISSIONS.filter(p => !p.startsWith('roles:')), isSystem: true }, { name: 'Secretary', description: 'منشی و مسئول ثبت‌نام، امور دانشجویان و پرداخت‌ها', permissions: [ PERMISSIONS.USERS_CREATE, PERMISSIONS.USERS_READ, PERMISSIONS.USERS_UPDATE, PERMISSIONS.USERS_SEARCH, PERMISSIONS.USERS_ENROLL, PERMISSIONS.CLASSES_READ, PERMISSIONS.CLASSES_SEARCH, PERMISSIONS.CLASSES_REGISTER_USERS, PERMISSIONS.COURSES_READ, PERMISSIONS.COURSES_SEARCH, PERMISSIONS.SESSIONS_READ, PERMISSIONS.SESSIONS_SEARCH, PERMISSIONS.SESSIONS_ATTENDANCE, PERMISSIONS.PAYMENTS_CREATE, PERMISSIONS.PAYMENTS_READ, PERMISSIONS.PAYMENTS_UPDATE, PERMISSIONS.PAYMENTS_SEARCH, PERMISSIONS.NOTIFICATIONS_CREATE, PERMISSIONS.NOTIFICATIONS_READ, PERMISSIONS.NOTIFICATIONS_SEARCH, PERMISSIONS.NOTIFICATIONS_RETRY, PERMISSIONS.CERTIFICATES_CREATE, PERMISSIONS.CERTIFICATES_READ, PERMISSIONS.CERTIFICATES_SEARCH, PERMISSIONS.FILES_UPLOAD, PERMISSIONS.FILES_READ, PERMISSIONS.LOGS_READ, PERMISSIONS.LOGS_SEARCH, PERMISSIONS.CONTACT_INQUIRIES_READ, PERMISSIONS.CONTACT_INQUIRIES_UPDATE ], isSystem: true }, { name: 'User', description: 'کاربر معمولی و دانشجو', permissions: [ PERMISSIONS.COURSES_READ, PERMISSIONS.COURSES_SEARCH, PERMISSIONS.CLASSES_READ, PERMISSIONS.CLASSES_SEARCH, PERMISSIONS.SESSIONS_READ, PERMISSIONS.SESSIONS_SEARCH, PERMISSIONS.PAYMENTS_READ, PERMISSIONS.NOTIFICATIONS_READ, PERMISSIONS.CERTIFICATES_READ, PERMISSIONS.FILES_READ ], isSystem: true }, { name: 'Professor', description: 'استاد مدرس دوره', permissions: [ PERMISSIONS.COURSES_READ, PERMISSIONS.COURSES_SEARCH, PERMISSIONS.CLASSES_READ, PERMISSIONS.CLASSES_SEARCH, PERMISSIONS.SESSIONS_READ, PERMISSIONS.SESSIONS_SEARCH, PERMISSIONS.SESSIONS_ATTENDANCE, PERMISSIONS.NOTIFICATIONS_READ, PERMISSIONS.FILES_READ ], isSystem: true } ]; const seedDatabase = async ({ disconnectOnComplete = false } = {}) => { try { if (mongoose.connection.readyState !== 1) { console.log('Connecting to MongoDB...'); await mongoose.connect(config.MONGO_URI); console.log('Connected to MongoDB successfully.'); } let rolesCreatedCount = 0; let rolesUpdatedCount = 0; for (const roleDef of defaultRoles) { const existing = await Role.findOne({ name: roleDef.name }); if (existing) { existing.description = roleDef.description; existing.permissions = roleDef.permissions; existing.isSystem = roleDef.isSystem; await existing.save(); rolesUpdatedCount++; console.log(`Updated existing role: ${roleDef.name}`); } else { await Role.create(roleDef); rolesCreatedCount++; console.log(`Created new role: ${roleDef.name}`); } } let superAdminStatus = 'unchanged'; const superAdminRole = await Role.findOne({ name: 'SuperAdmin' }); const username = config.SUPERADMIN_USERNAME && String(config.SUPERADMIN_USERNAME).trim(); if (!superAdminRole) { superAdminStatus = 'role_missing'; } else if (!config.SUPERADMIN_ENABLED) { if (username) { const adminUser = await User.findOne({ username }); if (adminUser && (adminUser.isActive || adminUser.refreshTokens.length > 0)) { adminUser.isActive = false; adminUser.refreshTokens = []; await adminUser.save(); superAdminStatus = 'disabled'; console.log(`SuperAdmin user disabled (${username}).`); } else { superAdminStatus = adminUser ? 'already_disabled' : 'skipped_disabled'; } } else { superAdminStatus = 'skipped_disabled'; } } else if (!username || !config.SUPERADMIN_PASSWORD) { throw new Error('SUPERADMIN_USERNAME and SUPERADMIN_PASSWORD must be set in env when SUPERADMIN_ENABLED is true'); } else { const adminUser = await User.findOne({ username }); if (!adminUser) { const passwordHash = await bcrypt.hash(config.SUPERADMIN_PASSWORD, 10); await User.create({ name: 'مدیر ارشد', nationalIdCode: config.SUPERADMIN_NATIONAL_ID, phoneNumber: config.SUPERADMIN_PHONE, email: config.SUPERADMIN_EMAIL || undefined, username, passwordHash, role: superAdminRole._id, isActive: true }); superAdminStatus = 'created'; console.log(`SuperAdmin user created (${username}).`); } else { let changed = false; if (!adminUser.isActive) { adminUser.isActive = true; changed = true; } const passwordMatches = await bcrypt.compare(config.SUPERADMIN_PASSWORD, adminUser.passwordHash); if (!passwordMatches) { adminUser.passwordHash = await bcrypt.hash(config.SUPERADMIN_PASSWORD, 10); adminUser.refreshTokens = []; changed = true; } if (config.SUPERADMIN_EMAIL && adminUser.email !== config.SUPERADMIN_EMAIL.toLowerCase()) { adminUser.email = config.SUPERADMIN_EMAIL; changed = true; } if (changed) { await adminUser.save(); superAdminStatus = 'updated'; console.log(`SuperAdmin user updated (${username}).`); } else { superAdminStatus = 'already_exists'; } } } console.log('Database seeding completed successfully.'); return { success: true, rolesCreatedCount, rolesUpdatedCount, superAdminStatus, superAdminUsername: config.SUPERADMIN_USERNAME }; } catch (error) { console.error('Database seeding failed:', error); throw error; } finally { if (disconnectOnComplete) { await mongoose.disconnect(); console.log('Disconnected from MongoDB.'); } } }; if (require.main === module) { seedDatabase({ disconnectOnComplete: true }); } module.exports = seedDatabase;