306 lines
12 KiB
JavaScript
306 lines
12 KiB
JavaScript
/**
|
|
* Tạo nhanh các models còn lại
|
|
* Chạy script này để generate các file model
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const models = [
|
|
{
|
|
name: 'Permission',
|
|
tableName: 'permissions',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
permission_code: { type: DataTypes.STRING(50), unique: true, allowNull: false },
|
|
permission_name: { type: DataTypes.STRING(100), allowNull: false },
|
|
permission_description: { type: DataTypes.TEXT },
|
|
resource: { type: DataTypes.STRING(50), comment: 'Tài nguyên (students, grades, etc.)' },
|
|
action: { type: DataTypes.STRING(50), comment: 'Hành động (view, create, edit, delete)' },
|
|
is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
|
|
`,
|
|
},
|
|
{
|
|
name: 'RolePermission',
|
|
tableName: 'role_permissions',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
role_id: { type: DataTypes.INTEGER, allowNull: false, references: { model: 'roles', key: 'id' } },
|
|
permission_id: { type: DataTypes.INTEGER, allowNull: false, references: { model: 'permissions', key: 'id' } },
|
|
`,
|
|
},
|
|
{
|
|
name: 'UserAssignment',
|
|
tableName: 'user_assignments',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
user_id: { type: DataTypes.INTEGER, allowNull: false, references: { model: 'users_auth', key: 'id' } },
|
|
role_id: { type: DataTypes.INTEGER, allowNull: false, references: { model: 'roles', key: 'id' } },
|
|
school_id: { type: DataTypes.INTEGER, references: { model: 'schools', key: 'id' } },
|
|
class_id: { type: DataTypes.INTEGER, references: { model: 'classes', key: 'id' } },
|
|
is_primary: { type: DataTypes.BOOLEAN, defaultValue: false, comment: 'Vai trò chính' },
|
|
valid_from: { type: DataTypes.DATE },
|
|
valid_until: { type: DataTypes.DATE },
|
|
is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
|
|
`,
|
|
},
|
|
{
|
|
name: 'StudentDetail',
|
|
tableName: 'student_details',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
user_id: { type: DataTypes.INTEGER, unique: true, allowNull: false, references: { model: 'user_profiles', key: 'user_id' } },
|
|
student_code: { type: DataTypes.STRING(20), unique: true, allowNull: false },
|
|
enrollment_date: { type: DataTypes.DATE },
|
|
current_class_id: { type: DataTypes.INTEGER, references: { model: 'classes', key: 'id' } },
|
|
status: { type: DataTypes.ENUM('active', 'on_leave', 'graduated', 'dropped'), defaultValue: 'active' },
|
|
`,
|
|
},
|
|
{
|
|
name: 'TeacherDetail',
|
|
tableName: 'teacher_details',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
user_id: { type: DataTypes.INTEGER, unique: true, allowNull: false, references: { model: 'user_profiles', key: 'user_id' } },
|
|
teacher_code: { type: DataTypes.STRING(20), unique: true, allowNull: false },
|
|
teacher_type: { type: DataTypes.ENUM('foreign', 'assistant', 'homeroom', 'specialist'), allowNull: false },
|
|
qualification: { type: DataTypes.STRING(200) },
|
|
specialization: { type: DataTypes.STRING(200) },
|
|
hire_date: { type: DataTypes.DATE },
|
|
status: { type: DataTypes.ENUM('active', 'on_leave', 'resigned'), defaultValue: 'active' },
|
|
`,
|
|
},
|
|
{
|
|
name: 'ParentStudentMap',
|
|
tableName: 'parent_student_map',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
parent_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
student_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
relationship: { type: DataTypes.ENUM('father', 'mother', 'guardian', 'other'), allowNull: false },
|
|
is_primary_contact: { type: DataTypes.BOOLEAN, defaultValue: false },
|
|
`,
|
|
},
|
|
{
|
|
name: 'StaffContract',
|
|
tableName: 'staff_contracts',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
teacher_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
school_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
contract_type: { type: DataTypes.ENUM('full_time', 'part_time', 'contract'), allowNull: false },
|
|
start_date: { type: DataTypes.DATE, allowNull: false },
|
|
end_date: { type: DataTypes.DATE },
|
|
salary: { type: DataTypes.DECIMAL(12, 2) },
|
|
status: { type: DataTypes.ENUM('active', 'expired', 'terminated'), defaultValue: 'active' },
|
|
`,
|
|
},
|
|
{
|
|
name: 'AcademicYear',
|
|
tableName: 'academic_years',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
year_name: { type: DataTypes.STRING(50), allowNull: false },
|
|
start_date: { type: DataTypes.DATE, allowNull: false },
|
|
end_date: { type: DataTypes.DATE, allowNull: false },
|
|
semester_count: { type: DataTypes.INTEGER, defaultValue: 2 },
|
|
is_current: { type: DataTypes.BOOLEAN, defaultValue: false },
|
|
`,
|
|
},
|
|
{
|
|
name: 'Subject',
|
|
tableName: 'subjects',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
subject_code: { type: DataTypes.STRING(20), unique: true, allowNull: false },
|
|
subject_name: { type: DataTypes.STRING(100), allowNull: false },
|
|
subject_name_en: { type: DataTypes.STRING(100) },
|
|
description: { type: DataTypes.TEXT },
|
|
is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
|
|
`,
|
|
},
|
|
{
|
|
name: 'Class',
|
|
tableName: 'classes',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
class_code: { type: DataTypes.STRING(20), unique: true, allowNull: false },
|
|
class_name: { type: DataTypes.STRING(100), allowNull: false },
|
|
school_id: { type: DataTypes.INTEGER, allowNull: false, references: { model: 'schools', key: 'id' } },
|
|
academic_year_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
grade_level: { type: DataTypes.INTEGER },
|
|
homeroom_teacher_id: { type: DataTypes.INTEGER },
|
|
max_students: { type: DataTypes.INTEGER, defaultValue: 30 },
|
|
current_students: { type: DataTypes.INTEGER, defaultValue: 0 },
|
|
`,
|
|
},
|
|
{
|
|
name: 'ClassSchedule',
|
|
tableName: 'class_schedules',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
class_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
subject_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
teacher_id: { type: DataTypes.INTEGER },
|
|
room_id: { type: DataTypes.INTEGER },
|
|
day_of_week: { type: DataTypes.INTEGER, comment: '1=Monday, 7=Sunday' },
|
|
period: { type: DataTypes.INTEGER, comment: 'Tiết học' },
|
|
start_time: { type: DataTypes.TIME },
|
|
end_time: { type: DataTypes.TIME },
|
|
`,
|
|
},
|
|
{
|
|
name: 'Room',
|
|
tableName: 'rooms',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
room_code: { type: DataTypes.STRING(20), allowNull: false },
|
|
room_name: { type: DataTypes.STRING(100), allowNull: false },
|
|
school_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
room_type: { type: DataTypes.ENUM('classroom', 'lab', 'library', 'gym', 'other') },
|
|
capacity: { type: DataTypes.INTEGER },
|
|
floor: { type: DataTypes.INTEGER },
|
|
`,
|
|
},
|
|
{
|
|
name: 'AttendanceDaily',
|
|
tableName: 'attendance_daily',
|
|
fields: `
|
|
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
|
|
user_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
school_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
class_id: { type: DataTypes.INTEGER },
|
|
attendance_date: { type: DataTypes.DATE, allowNull: false },
|
|
status: { type: DataTypes.ENUM('present', 'absent', 'late', 'excused'), allowNull: false },
|
|
check_in_time: { type: DataTypes.TIME },
|
|
check_out_time: { type: DataTypes.TIME },
|
|
notes: { type: DataTypes.TEXT },
|
|
`,
|
|
},
|
|
{
|
|
name: 'LeaveRequest',
|
|
tableName: 'leave_requests',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
student_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
requested_by: { type: DataTypes.INTEGER, allowNull: false, comment: 'Parent user_id' },
|
|
leave_from: { type: DataTypes.DATE, allowNull: false },
|
|
leave_to: { type: DataTypes.DATE, allowNull: false },
|
|
reason: { type: DataTypes.TEXT, allowNull: false },
|
|
status: { type: DataTypes.ENUM('pending', 'approved', 'rejected'), defaultValue: 'pending' },
|
|
approved_by: { type: DataTypes.INTEGER },
|
|
approved_at: { type: DataTypes.DATE },
|
|
`,
|
|
},
|
|
{
|
|
name: 'GradeCategory',
|
|
tableName: 'grade_categories',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
category_code: { type: DataTypes.STRING(20), allowNull: false },
|
|
category_name: { type: DataTypes.STRING(100), allowNull: false },
|
|
subject_id: { type: DataTypes.INTEGER },
|
|
weight: { type: DataTypes.DECIMAL(5, 2), comment: 'Trọng số %' },
|
|
description: { type: DataTypes.TEXT },
|
|
`,
|
|
},
|
|
{
|
|
name: 'GradeItem',
|
|
tableName: 'grade_items',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
item_name: { type: DataTypes.STRING(200), allowNull: false },
|
|
category_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
class_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
max_score: { type: DataTypes.DECIMAL(5, 2), defaultValue: 100 },
|
|
exam_date: { type: DataTypes.DATE },
|
|
description: { type: DataTypes.TEXT },
|
|
`,
|
|
},
|
|
{
|
|
name: 'GradeSummary',
|
|
tableName: 'grade_summaries',
|
|
fields: `
|
|
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
|
|
student_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
subject_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
academic_year_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
semester: { type: DataTypes.INTEGER },
|
|
average_score: { type: DataTypes.DECIMAL(5, 2) },
|
|
final_grade: { type: DataTypes.STRING(5) },
|
|
`,
|
|
},
|
|
{
|
|
name: 'GradeHistory',
|
|
tableName: 'grade_history',
|
|
fields: `
|
|
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
|
|
grade_id: { type: DataTypes.BIGINT, allowNull: false },
|
|
changed_by: { type: DataTypes.INTEGER, allowNull: false },
|
|
old_score: { type: DataTypes.DECIMAL(5, 2) },
|
|
new_score: { type: DataTypes.DECIMAL(5, 2) },
|
|
change_reason: { type: DataTypes.TEXT },
|
|
changed_at: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
`,
|
|
},
|
|
{
|
|
name: 'Notification',
|
|
tableName: 'notifications',
|
|
fields: `
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
title: { type: DataTypes.STRING(200), allowNull: false },
|
|
content: { type: DataTypes.TEXT, allowNull: false },
|
|
notification_type: { type: DataTypes.ENUM('system', 'school', 'class', 'personal'), allowNull: false },
|
|
priority: { type: DataTypes.ENUM('low', 'medium', 'high', 'urgent'), defaultValue: 'medium' },
|
|
target_audience: { type: DataTypes.JSONB, comment: 'Schools, classes, roles to send' },
|
|
scheduled_at: { type: DataTypes.DATE },
|
|
expires_at: { type: DataTypes.DATE },
|
|
`,
|
|
},
|
|
{
|
|
name: 'NotificationLog',
|
|
tableName: 'notification_logs',
|
|
fields: `
|
|
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
|
|
notification_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
user_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
sent_at: { type: DataTypes.DATE },
|
|
read_at: { type: DataTypes.DATE },
|
|
status: { type: DataTypes.ENUM('pending', 'sent', 'failed', 'read'), defaultValue: 'pending' },
|
|
`,
|
|
},
|
|
{
|
|
name: 'Message',
|
|
tableName: 'messages',
|
|
fields: `
|
|
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
|
|
sender_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
recipient_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
subject: { type: DataTypes.STRING(200) },
|
|
content: { type: DataTypes.TEXT, allowNull: false },
|
|
is_read: { type: DataTypes.BOOLEAN, defaultValue: false },
|
|
read_at: { type: DataTypes.DATE },
|
|
parent_message_id: { type: DataTypes.BIGINT, comment: 'For thread replies' },
|
|
`,
|
|
},
|
|
{
|
|
name: 'AuditLog',
|
|
tableName: 'audit_logs_system',
|
|
fields: `
|
|
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
|
|
user_id: { type: DataTypes.INTEGER, allowNull: false },
|
|
action: { type: DataTypes.STRING(100), allowNull: false },
|
|
resource_type: { type: DataTypes.STRING(50) },
|
|
resource_id: { type: DataTypes.INTEGER },
|
|
old_values: { type: DataTypes.JSONB },
|
|
new_values: { type: DataTypes.JSONB },
|
|
ip_address: { type: DataTypes.INET },
|
|
user_agent: { type: DataTypes.TEXT },
|
|
performed_at: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
`,
|
|
},
|
|
];
|
|
|
|
console.log(`Tạo ${models.length} file models...`);
|
|
console.log('Các models cần tạo:', models.map(m => m.name).join(', '));
|