update
This commit is contained in:
305
scripts/generate-models.js
Normal file
305
scripts/generate-models.js
Normal 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(', '));
|
||||
Reference in New Issue
Block a user