This commit is contained in:
Ken
2026-01-19 09:33:35 +07:00
parent 374dc12b2d
commit 70838a4bc1
103 changed files with 16929 additions and 2 deletions

305
scripts/generate-models.js Normal file
View File

@@ -0,0 +1,305 @@
/**
* 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(', '));