const { DataTypes } = require('sequelize'); const { sequelize } = require('../config/database'); /** * AttendanceLogs Model - Dữ liệu thô điểm danh từ QR * Bảng này cần partition theo thời gian do data lớn */ const AttendanceLog = sequelize.define('attendance_logs', { id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, }, user_id: { type: DataTypes.UUID, allowNull: false, references: { model: 'users_auth', key: 'id', }, comment: 'ID người dùng (học sinh/giáo viên)', }, school_id: { type: DataTypes.UUID, allowNull: false, references: { model: 'schools', key: 'id', }, comment: 'ID trường', }, check_time: { type: DataTypes.DATE, allowNull: false, comment: 'Thời gian quét QR', }, check_type: { type: DataTypes.ENUM('IN', 'OUT'), allowNull: false, comment: 'Loại: Vào hoặc Ra', }, device_id: { type: DataTypes.STRING(100), comment: 'ID thiết bị quét', }, location: { type: DataTypes.STRING(200), comment: 'Vị trí quét (cổng, lớp học)', }, qr_version: { type: DataTypes.INTEGER, comment: 'Version QR code', }, ip_address: { type: DataTypes.STRING(45), comment: 'IP address thiết bị (IPv4/IPv6)', }, user_agent: { type: DataTypes.TEXT, comment: 'User agent', }, is_valid: { type: DataTypes.BOOLEAN, defaultValue: true, comment: 'QR code hợp lệ', }, notes: { type: DataTypes.TEXT, comment: 'Ghi chú', }, created_at: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW, }, }, { tableName: 'attendance_logs', timestamps: false, underscored: true, indexes: [ { fields: ['user_id', 'check_time'] }, { fields: ['school_id', 'check_time'] }, { fields: ['check_time'] }, { fields: ['device_id'] }, { fields: ['is_valid'] }, ], comment: 'Bảng log điểm danh thô - Cần partition theo tháng', }); module.exports = AttendanceLog;