import { Request, Response } from 'express'; import mongoose from 'mongoose'; import { NotificationModel as Notification } from '../models/mongoose/Notification.schema'; import logger from '../utils/logger'; import { notificationMongoService as notificationService } from '../services/notification.service'; export class NotificationController { /** * Get user's notifications with pagination */ async getUserNotifications(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const { page = 1, limit = 20, unreadOnly = false } = req.query; if (!userId) { res.status(401).json({ success: false, message: 'Unauthorized' }); return; } const where: any = { userId }; if (unreadOnly === 'true') { where.isRead = false; } const offset = (Number(page) - 1) * Number(limit); const rows = await Notification.find(where) .sort({ createdAt: -1 }) .limit(Number(limit)) .skip(offset); const count = await Notification.countDocuments(where); res.json({ success: true, data: { notifications: rows, pagination: { page: Number(page), limit: Number(limit), total: count, totalPages: Math.ceil(count / Number(limit)) }, unreadCount: unreadOnly === 'true' ? count : await Notification.countDocuments({ userId, isRead: false }) } }); } catch (error: any) { logger.error('[Notification Controller] Error fetching notifications:', error); res.status(500).json({ success: false, message: error.message }); } } /** * Get unread notification count */ async getUnreadCount(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; if (!userId) { res.status(401).json({ success: false, message: 'Unauthorized' }); return; } const count = await Notification.countDocuments({ userId, isRead: false }); res.json({ success: true, data: { unreadCount: count } }); } catch (error: any) { logger.error('[Notification Controller] Error fetching unread count:', error); res.status(500).json({ success: false, message: error.message }); } } /** * Mark notification as read */ async markAsRead(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const { notificationId } = req.params; if (!userId) { res.status(401).json({ success: false, message: 'Unauthorized' }); return; } if (!mongoose.Types.ObjectId.isValid(notificationId)) { res.status(400).json({ success: false, message: 'Invalid notification ID' }); return; } const notification = await Notification.findOne({ _id: notificationId, userId }); if (!notification) { res.status(404).json({ success: false, message: 'Notification not found' }); return; } notification.isRead = true; notification.metadata = notification.metadata || {}; notification.metadata.readAt = new Date(); await notification.save(); res.json({ success: true, message: 'Notification marked as read', data: { notification } }); } catch (error: any) { logger.error('[Notification Controller] Error marking notification as read:', error); res.status(500).json({ success: false, message: error.message }); } } /** * Mark all notifications as read */ async markAllAsRead(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; if (!userId) { res.status(401).json({ success: false, message: 'Unauthorized' }); return; } await Notification.updateMany( { userId, isRead: false }, { $set: { isRead: true } } ); res.json({ success: true, message: 'All notifications marked as read' }); } catch (error: any) { logger.error('[Notification Controller] Error marking all as read:', error); res.status(500).json({ success: false, message: error.message }); } } /** * Delete notification */ async deleteNotification(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; const { notificationId } = req.params; if (!userId) { res.status(401).json({ success: false, message: 'Unauthorized' }); return; } if (!mongoose.Types.ObjectId.isValid(notificationId)) { res.status(400).json({ success: false, message: 'Invalid notification ID' }); return; } const result = await Notification.deleteOne({ _id: notificationId, userId }); const deleted = result.deletedCount; if (deleted === 0) { res.status(404).json({ success: false, message: 'Notification not found' }); return; } res.json({ success: true, message: 'Notification deleted' }); } catch (error: any) { logger.error('[Notification Controller] Error deleting notification:', error); res.status(500).json({ success: false, message: error.message }); } } /** * Get user's push notification subscriptions */ async getUserSubscriptions(req: Request, res: Response): Promise { try { const userId = (req as any).user?.userId; if (!userId) { res.status(401).json({ success: false, message: 'Unauthorized' }); return; } const subscriptions = await notificationService.getUserSubscriptions(userId); res.json({ success: true, data: { subscriptions, count: subscriptions.length } }); } catch (error: any) { logger.error('[Notification Controller] Error fetching subscriptions:', error); res.status(500).json({ success: false, message: error.message }); } } }