package models import "time" const ( ExamStatusDraft = "draft" ExamStatusReady = "ready" ExamStatusEnded = "ended" ExamStatusCancelled = "cancelled" ) // ExamRoom — phòng thi độc lập với lớp học type ExamRoom struct { ID uint `gorm:"primaryKey" json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` Name string `gorm:"column:name;size:255;not null" json:"name"` StartTime time.Time `gorm:"column:start_time;not null;index" json:"startTime"` EndTime time.Time `gorm:"column:end_time;not null;index" json:"endTime"` AllowedApps string `gorm:"column:allowed_apps;type:text" json:"allowedApps"` QuizURL string `gorm:"column:quiz_url;size:1024" json:"quizUrl"` Status string `gorm:"column:status;size:16;not null;default:draft;index" json:"status"` } func (ExamRoom) TableName() string { return "exam_rooms" } // ExamPaper — gói đề (1 PDF chính + tài nguyên kèm theo) type ExamPaper struct { ID uint `gorm:"primaryKey" json:"id"` ExamRoomID uint `gorm:"column:exam_room_id;not null;index" json:"examRoomId"` Title string `gorm:"column:title;size:128;not null" json:"title"` PdfPath string `gorm:"column:pdf_path;size:512;not null" json:"pdfPath"` SortOrder int `gorm:"column:sort_order;default:0" json:"sortOrder"` } func (ExamPaper) TableName() string { return "exam_papers" } // ExamPaperResource — file tài nguyên kèm đề (đuôi bất kỳ) type ExamPaperResource struct { ID uint `gorm:"primaryKey" json:"id"` ExamPaperID uint `gorm:"column:exam_paper_id;not null;index" json:"examPaperId"` FilePath string `gorm:"column:file_path;size:512;not null" json:"filePath"` FileName string `gorm:"column:file_name;size:255;not null" json:"fileName"` } func (ExamPaperResource) TableName() string { return "exam_paper_resources" } // ExamRoomStudent — sinh viên trong phòng thi type ExamRoomStudent struct { ID uint `gorm:"primaryKey" json:"id"` ExamRoomID uint `gorm:"column:exam_room_id;not null;uniqueIndex:idx_exam_room_student,priority:1" json:"examRoomId"` StudentRkID int64 `gorm:"column:student_rk_id;not null;uniqueIndex:idx_exam_room_student,priority:2" json:"studentRkId"` AssignedPaperID *uint `gorm:"column:assigned_paper_id;index" json:"assignedPaperId,omitempty"` PaperSentAt *time.Time `gorm:"column:paper_sent_at" json:"paperSentAt,omitempty"` PaperScheduledAt *time.Time `gorm:"column:paper_scheduled_at;index" json:"paperScheduledAt,omitempty"` } func (ExamRoomStudent) TableName() string { return "exam_room_students" } // ExamSubmission — bài nộp (zip folder) của sinh viên type ExamSubmission struct { ID uint `gorm:"primaryKey" json:"id"` CreatedAt time.Time `json:"createdAt"` ExamRoomID uint `gorm:"column:exam_room_id;not null;index" json:"examRoomId"` StudentRkID int64 `gorm:"column:student_rk_id;not null;index" json:"studentRkId"` FilePath string `gorm:"column:file_path;size:512;not null" json:"filePath"` FileName string `gorm:"column:file_name;size:255;not null" json:"fileName"` } func (ExamSubmission) TableName() string { return "exam_submissions" }