const { StudentDetail, UserProfile, UsersAuth, Class } = require('../models'); const { cacheUtils } = require('../config/redis'); const { addDatabaseWriteJob } = require('../config/bullmq'); /** * Student Controller - Quản lý học sinh */ class StudentController { /** * Get all students with pagination and caching */ async getAllStudents(req, res, next) { try { const { page = 1, limit = 20, status, class_id } = req.query; const offset = (page - 1) * limit; const cacheKey = `students:list:${page}:${limit}:${status || 'all'}:${class_id || 'all'}`; const cached = await cacheUtils.get(cacheKey); if (cached) { return res.json({ success: true, data: cached, cached: true, }); } const where = {}; if (status) where.status = status; if (class_id) where.current_class_id = class_id; const { count, rows } = await StudentDetail.findAndCountAll({ where, limit: parseInt(limit), offset: parseInt(offset), include: [ { model: UserProfile, as: 'profile', attributes: ['full_name', 'phone', 'date_of_birth', 'gender'], }, { model: Class, as: 'currentClass', attributes: ['class_code', 'class_name', 'grade_level'], }, ], order: [['created_at', 'DESC']], }); const result = { students: rows, pagination: { total: count, page: parseInt(page), limit: parseInt(limit), totalPages: Math.ceil(count / limit), }, }; await cacheUtils.set(cacheKey, result, 1800); res.json({ success: true, data: result, cached: false, }); } catch (error) { next(error); } } /** * Get student by ID */ async getStudentById(req, res, next) { try { const { id } = req.params; const cacheKey = `student:${id}`; const cached = await cacheUtils.get(cacheKey); if (cached) { return res.json({ success: true, data: cached, cached: true, }); } const student = await StudentDetail.findByPk(id, { include: [ { model: UserProfile, as: 'profile', }, { model: Class, as: 'currentClass', }, ], }); if (!student) { return res.status(404).json({ success: false, message: 'Student not found', }); } await cacheUtils.set(cacheKey, student, 3600); res.json({ success: true, data: student, cached: false, }); } catch (error) { next(error); } } /** * Create new student (async via BullMQ) */ async createStudent(req, res, next) { try { const studentData = req.body; const job = await addDatabaseWriteJob('create', 'StudentDetail', studentData); await cacheUtils.deletePattern('students:list:*'); res.status(202).json({ success: true, message: 'Student creation job queued', jobId: job.id, data: studentData, }); } catch (error) { next(error); } } /** * Update student (async via BullMQ) */ async updateStudent(req, res, next) { try { const { id } = req.params; const updates = req.body; const job = await addDatabaseWriteJob('update', 'StudentDetail', { id, updates, }); await cacheUtils.delete(`student:${id}`); await cacheUtils.deletePattern('students:list:*'); res.status(202).json({ success: true, message: 'Student update job queued', jobId: job.id, }); } catch (error) { next(error); } } /** * Delete student (update status to dropped) */ async deleteStudent(req, res, next) { try { const { id } = req.params; const job = await addDatabaseWriteJob('update', 'StudentDetail', { id, updates: { status: 'dropped' }, }); await cacheUtils.delete(`student:${id}`); await cacheUtils.deletePattern('students:list:*'); res.status(202).json({ success: true, message: 'Student deletion job queued', jobId: job.id, }); } catch (error) { next(error); } } /** * Get student datatypes */ async getStudentDatatypes(req, res, next) { try { const datatypes = StudentDetail.rawAttributes; res.json({ success: true, data: datatypes, }); } catch (error) { next(error); } } } module.exports = new StudentController();