Support public class lookup, user provisioning, installment pricing, and admin approval before final enrollment.
219 lines
7.0 KiB
JavaScript
219 lines
7.0 KiB
JavaScript
// /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.DOCUMENTS_CREATE,
|
|
PERMISSIONS.DOCUMENTS_READ,
|
|
PERMISSIONS.DOCUMENTS_SEARCH,
|
|
PERMISSIONS.FILES_UPLOAD,
|
|
PERMISSIONS.FILES_READ,
|
|
PERMISSIONS.LOGS_READ,
|
|
PERMISSIONS.LOGS_SEARCH,
|
|
PERMISSIONS.CONTACT_INQUIRIES_READ,
|
|
PERMISSIONS.CONTACT_INQUIRIES_UPDATE,
|
|
PERMISSIONS.PENDING_STUDENTS_READ,
|
|
PERMISSIONS.PENDING_STUDENTS_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.DOCUMENTS_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;
|