/** * Notification Controller * Handles notification-related HTTP requests */ import { Response } from 'express'; import { AuthenticatedRequest } from '../../../core/guards/auth.guard'; import { notificationService } from '../services/notification.service'; import { logger } from '../../../shared/utils/logger'; /** * GET /api/v1/notifications * Get user's notifications */ export async function getNotifications( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const { limit, offset, unreadOnly } = req.query; const notifications = await notificationService.getUserNotifications(userId, { limit: limit ? parseInt(limit as string, 10) : 50, offset: offset ? parseInt(offset as string, 10) : 0, unreadOnly: unreadOnly === 'true', }); res.json({ success: true, data: notifications, }); } catch (error) { logger.error('[NotificationController] Failed to get notifications:', error); res.status(500).json({ success: false, error: 'Failed to get notifications', }); } } /** * GET /api/v1/notifications/unread-count * Get unread notification count */ export async function getUnreadCount( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const count = await notificationService.getUnreadCount(userId); res.json({ success: true, data: { count }, }); } catch (error) { logger.error('[NotificationController] Failed to get unread count:', error); res.status(500).json({ success: false, error: 'Failed to get unread count', }); } } /** * PATCH /api/v1/notifications/:notificationId/read * Mark notification as read */ export async function markAsRead( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const { notificationId } = req.params; const success = await notificationService.markAsRead(notificationId, userId); if (!success) { res.status(404).json({ success: false, error: 'Notification not found', }); return; } res.json({ success: true, message: 'Notification marked as read', }); } catch (error) { logger.error('[NotificationController] Failed to mark as read:', error); res.status(500).json({ success: false, error: 'Failed to mark notification as read', }); } } /** * POST /api/v1/notifications/read-all * Mark all notifications as read */ export async function markAllAsRead( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const count = await notificationService.markAllAsRead(userId); res.json({ success: true, data: { markedCount: count }, }); } catch (error) { logger.error('[NotificationController] Failed to mark all as read:', error); res.status(500).json({ success: false, error: 'Failed to mark notifications as read', }); } } /** * DELETE /api/v1/notifications/:notificationId * Delete a notification */ export async function deleteNotification( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const { notificationId } = req.params; const success = await notificationService.deleteNotification(notificationId, userId); if (!success) { res.status(404).json({ success: false, error: 'Notification not found', }); return; } res.json({ success: true, message: 'Notification deleted', }); } catch (error) { logger.error('[NotificationController] Failed to delete notification:', error); res.status(500).json({ success: false, error: 'Failed to delete notification', }); } } /** * GET /api/v1/notifications/preferences * Get notification preferences */ export async function getPreferences( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const preferences = await notificationService.getUserPreferences(userId); res.json({ success: true, data: preferences, }); } catch (error) { logger.error('[NotificationController] Failed to get preferences:', error); res.status(500).json({ success: false, error: 'Failed to get notification preferences', }); } } /** * PATCH /api/v1/notifications/preferences * Update notification preferences */ export async function updatePreferences( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const updates = req.body; await notificationService.updateUserPreferences(userId, updates); const preferences = await notificationService.getUserPreferences(userId); res.json({ success: true, data: preferences, }); } catch (error) { logger.error('[NotificationController] Failed to update preferences:', error); res.status(500).json({ success: false, error: 'Failed to update notification preferences', }); } } /** * POST /api/v1/notifications/push-token * Register a push notification token */ export async function registerPushToken( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const { token, platform, deviceInfo } = req.body; if (!token || !platform) { res.status(400).json({ success: false, error: 'Token and platform are required', }); return; } if (!['web', 'ios', 'android'].includes(platform)) { res.status(400).json({ success: false, error: 'Invalid platform. Must be web, ios, or android', }); return; } await notificationService.registerPushToken(userId, token, platform, deviceInfo); res.json({ success: true, message: 'Push token registered successfully', }); } catch (error) { logger.error('[NotificationController] Failed to register push token:', error); res.status(500).json({ success: false, error: 'Failed to register push token', }); } } /** * DELETE /api/v1/notifications/push-token * Remove a push notification token */ export async function removePushToken( req: AuthenticatedRequest, res: Response ): Promise { try { const userId = req.user!.id; const { token } = req.body; if (!token) { res.status(400).json({ success: false, error: 'Token is required', }); return; } await notificationService.removePushToken(userId, token); res.json({ success: true, message: 'Push token removed successfully', }); } catch (error) { logger.error('[NotificationController] Failed to remove push token:', error); res.status(500).json({ success: false, error: 'Failed to remove push token', }); } }