// models/notificationModel.js const { getDb } = require('../dbPool'); // 순환 참조를 피하기 위해 함수 내에서 require async function getRecipientIds(notificationType) { const db = await getDb(); const [rows] = await db.query( `SELECT user_id FROM notification_recipients WHERE notification_type = ? AND is_active = 1`, [notificationType] ); return rows.map(r => r.user_id); } const notificationModel = { // 알림 생성 async create(notificationData) { const db = await getDb(); const { user_id, type, title, message, link_url, reference_type, reference_id, created_by } = notificationData; const [result] = await db.query( `INSERT INTO notifications (user_id, type, title, message, link_url, reference_type, reference_id, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [user_id || null, type || 'system', title, message || null, link_url || null, reference_type || null, reference_id || null, created_by || null] ); return result.insertId; }, // 읽지 않은 알림 조회 (특정 사용자 또는 전체) async getUnread(userId = null) { const db = await getDb(); const [rows] = await db.query( `SELECT * FROM notifications WHERE is_read = 0 AND (user_id IS NULL OR user_id = ?) ORDER BY created_at DESC LIMIT 50`, [userId || 0] ); return rows; }, // 전체 알림 조회 (페이징) async getAll(userId = null, page = 1, limit = 20) { const db = await getDb(); const offset = (page - 1) * limit; const [rows] = await db.query( `SELECT * FROM notifications WHERE (user_id IS NULL OR user_id = ?) ORDER BY created_at DESC LIMIT ? OFFSET ?`, [userId || 0, limit, offset] ); const [[{ total }]] = await db.query( `SELECT COUNT(*) as total FROM notifications WHERE (user_id IS NULL OR user_id = ?)`, [userId || 0] ); return { notifications: rows, total, page, limit }; }, // 알림 읽음 처리 async markAsRead(notificationId) { const db = await getDb(); const [result] = await db.query( `UPDATE notifications SET is_read = 1, read_at = NOW() WHERE notification_id = ?`, [notificationId] ); return result.affectedRows > 0; }, // 모든 알림 읽음 처리 async markAllAsRead(userId = null) { const db = await getDb(); const [result] = await db.query( `UPDATE notifications SET is_read = 1, read_at = NOW() WHERE is_read = 0 AND (user_id IS NULL OR user_id = ?)`, [userId || 0] ); return result.affectedRows; }, // 알림 삭제 async delete(notificationId) { const db = await getDb(); const [result] = await db.query( `DELETE FROM notifications WHERE notification_id = ?`, [notificationId] ); return result.affectedRows > 0; }, // 오래된 알림 삭제 (30일 이상) async deleteOld(days = 30) { const db = await getDb(); const [result] = await db.query( `DELETE FROM notifications WHERE created_at < DATE_SUB(NOW(), INTERVAL ? DAY)`, [days] ); return result.affectedRows; }, // 읽지 않은 알림 개수 async getUnreadCount(userId = null) { const db = await getDb(); const [[{ count }]] = await db.query( `SELECT COUNT(*) as count FROM notifications WHERE is_read = 0 AND (user_id IS NULL OR user_id = ?)`, [userId || 0] ); return count; }, // 수리 신청 알림 생성 헬퍼 (지정된 수신자에게 전송) async createRepairNotification(repairData) { const { equipment_id, equipment_name, repair_type, request_id, created_by } = repairData; // 수리 알림 수신자 목록 가져오기 const recipientIds = await getRecipientIds('repair'); if (recipientIds.length === 0) { // 수신자가 지정되지 않은 경우 전체 알림 (user_id = null) return await this.create({ type: 'repair', title: `수리 신청: ${equipment_name || '설비'}`, message: `${repair_type} 수리가 신청되었습니다.`, link_url: `/pages/admin/repair-management.html`, reference_type: 'work_issue_reports', reference_id: request_id, created_by }); } // 지정된 수신자 각각에게 알림 생성 const results = []; for (const userId of recipientIds) { const notificationId = await this.create({ user_id: userId, type: 'repair', title: `수리 신청: ${equipment_name || '설비'}`, message: `${repair_type} 수리가 신청되었습니다.`, link_url: `/pages/admin/repair-management.html`, reference_type: 'work_issue_reports', reference_id: request_id, created_by }); results.push(notificationId); } return results; }, // 일반 알림 생성 (유형별 지정된 수신자에게 전송) async createTypedNotification(notificationData) { const { type, title, message, link_url, reference_type, reference_id, created_by } = notificationData; // 해당 유형의 수신자 목록 가져오기 const recipientIds = await getRecipientIds(type); if (recipientIds.length === 0) { // 수신자가 지정되지 않은 경우 전체 알림 return await this.create({ type, title, message, link_url, reference_type, reference_id, created_by }); } // 지정된 수신자 각각에게 알림 생성 const results = []; for (const userId of recipientIds) { const notificationId = await this.create({ user_id: userId, type, title, message, link_url, reference_type, reference_id, created_by }); results.push(notificationId); } return results; } }; module.exports = notificationModel;