/*********************************************************************************************************************************************************************** * File Name : notification.controller.js * Type : Controller (Client) * Description : Per-user notification management. * GET /client/notifications — paginated list for the auth user * GET /client/notifications/unseen — unseen count * PATCH /client/notifications/:id/seen — mark one as seen * PATCH /client/notifications/seen-all — mark all as seen * DELETE /client/notifications/clear-all — delete all notifications * * Author: Kenneth Obsequio (@lash0000) * Date Created: Jun. 19, 2026 ***********************************************************************************************************************************************************************/ const UserNotification = require('../../models/notifications/user_notification.mdl'); const R = require('../../utils/response.util'); // ─── GET /client/notifications ──────────────────────────────────────────────── async function list(req, res) { try { const userId = req.user.user_id; const page = Math.max(1, parseInt(req.query.page) || 1); const limit = Math.min(50, parseInt(req.query.limit) || 20); const offset = (page - 1) * limit; const { count, rows } = await UserNotification.findAndCountAll({ where: { user_id: userId }, order: [['createdAt', 'DESC']], limit, offset, }); return R.success(res, 'Notifications fetched.', { notifications: rows, pagination: { page, limit, total: count, pages: Math.ceil(count / limit) }, }); } catch (err) { console.error('[CLIENT NOTIFICATION] list error:', err); return R.error(res, 'Failed to fetch notifications.'); } } // ─── GET /client/notifications/unseen ──────────────────────────────────────── async function unseenCount(req, res) { if (!req.user) return R.success(res, 'Unseen count fetched.', { count: null }); try { const count = await UserNotification.count({ where: { user_id: req.user.user_id, seen: false }, }); return R.success(res, 'Unseen count fetched.', { count }); } catch (err) { console.error('[CLIENT NOTIFICATION] unseenCount error:', err); return R.error(res, 'Failed to fetch unseen count.'); } } // ─── PATCH /client/notifications/:id/seen ──────────────────────────────────── async function markSeen(req, res) { try { const notification = await UserNotification.findOne({ where: { notification_id: req.params.id, user_id: req.user.user_id }, }); if (!notification) return R.error(res, 'Notification not found.', 404); await notification.update({ seen: true, seen_at: new Date() }); return R.success(res, 'Notification marked as seen.', notification); } catch (err) { console.error('[CLIENT NOTIFICATION] markSeen error:', err); return R.error(res, 'Failed to mark notification as seen.'); } } // ─── PATCH /client/notifications/seen-all ──────────────────────────────────── async function markAllSeen(req, res) { try { const now = new Date(); const [count] = await UserNotification.update( { seen: true, seen_at: now }, { where: { user_id: req.user.user_id, seen: false } } ); return R.success(res, `${count} notification(s) marked as seen.`, { count }); } catch (err) { console.error('[CLIENT NOTIFICATION] markAllSeen error:', err); return R.error(res, 'Failed to mark all notifications as seen.'); } } // ─── DELETE /client/notifications/clear-all ────────────────────────────────── async function clearAll(req, res) { try { const count = await UserNotification.destroy({ where: { user_id: req.user.user_id }, }); return R.success(res, `${count} notification(s) cleared.`, { count }); } catch (err) { console.error('[CLIENT NOTIFICATION] clearAll error:', err); return R.error(res, 'Failed to clear notifications.'); } } module.exports = { list, unseenCount, markSeen, markAllSeen, clearAll };