const { StudentDetail, UserProfile, UsersAuth, Class } = require('../models'); const { cacheUtils } = require('../config/redis'); /** * 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 createStudent(req, res, next) { try { const studentData = req.body; const newStudent = await StudentDetail.create(studentData); await cacheUtils.deletePattern('students:list:*'); res.status(201).json({ success: true, message: 'Student created successfully', data: newStudent, }); } catch (error) { next(error); } } /** * Update student */ async updateStudent(req, res, next) { try { const { id } = req.params; const updates = req.body; const student = await StudentDetail.findByPk(id); if (!student) { return res.status(404).json({ success: false, message: 'Student not found', }); } await student.update(updates); await cacheUtils.delete(`student:${id}`); await cacheUtils.deletePattern('students:list:*'); res.status(200).json({ success: true, message: 'Student updated successfully', data: student, }); } catch (error) { next(error); } } /** * Delete student (update status to dropped) */ async deleteStudent(req, res, next) { try { const { id } = req.params; const student = await StudentDetail.findByPk(id); if (!student) { return res.status(404).json({ success: false, message: 'Student not found', }); } await student.update({ status: 'dropped' }); await cacheUtils.delete(`student:${id}`); await cacheUtils.deletePattern('students:list:*'); res.status(200).json({ success: true, message: 'Student status updated to dropped', data: student, }); } 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();