121 lines · 3.8 KB · TypeScript
RawDownload
/** * HTTP route handlers for Notification Operations. * * Routes: * - GET /api/notifications - Get notifications (paginated) * - POST /api/notifications/:id/read - Mark as read * - POST /api/notifications/read-all - Mark all as read * - DELETE /api/notifications/:id - Delete notification * - DELETE /api/notifications - Clear all notifications * - GET /api/notifications/unread-count - Get unread count */ import { getErrorMessage } from '@shared/utils/errorHandling';import { createLogger } from '@shared/utils/logger'; import { coercePageLimit, validateNotificationId } from '../ipc/guards';import { NotificationManager } from '../services'; import type { FastifyInstance } from 'fastify'; const logger = createLogger('HTTP:notifications'); export function registerNotificationRoutes(app: FastifyInstance): void {  // Get notifications  app.get<{ Querystring: { limit?: string; offset?: string } }>(    '/api/notifications',    async (request) => {      try {        const limit = coercePageLimit(          request.query.limit ? Number(request.query.limit) : undefined,          20        );        const rawOffset = request.query.offset ? Number(request.query.offset) : 0;        const offset =          typeof rawOffset === 'number' && Number.isFinite(rawOffset) && rawOffset >= 0            ? Math.floor(rawOffset)            : 0;         const manager = NotificationManager.getInstance();        const result = await manager.getNotifications({ limit, offset });        return result;      } catch (error) {        logger.error('Error in GET /api/notifications:', getErrorMessage(error));        return {          notifications: [],          total: 0,          totalCount: 0,          unreadCount: 0,          hasMore: false,        };      }    }  );   // Mark read  app.post<{ Params: { id: string } }>('/api/notifications/:id/read', async (request) => {    try {      const validated = validateNotificationId(request.params.id);      if (!validated.valid) {        logger.error(`POST notifications/:id/read rejected: ${validated.error ?? 'unknown'}`);        return false;      }       const manager = NotificationManager.getInstance();      return await manager.markRead(validated.value!);    } catch (error) {      logger.error(`Error in POST notifications/${request.params.id}/read:`, error);      return false;    }  });   // Mark all read  app.post('/api/notifications/read-all', async () => {    try {      const manager = NotificationManager.getInstance();      return await manager.markAllRead();    } catch (error) {      logger.error('Error in POST /api/notifications/read-all:', error);      return false;    }  });   // Delete notification  app.delete<{ Params: { id: string } }>('/api/notifications/:id', async (request) => {    try {      const validated = validateNotificationId(request.params.id);      if (!validated.valid) {        logger.error(`DELETE notifications/:id rejected: ${validated.error ?? 'unknown'}`);        return false;      }       const manager = NotificationManager.getInstance();      return manager.deleteNotification(validated.value!);    } catch (error) {      logger.error(`Error in DELETE notifications/${request.params.id}:`, error);      return false;    }  });   // Clear all  app.delete('/api/notifications', async () => {    try {      const manager = NotificationManager.getInstance();      return await manager.clearAll();    } catch (error) {      logger.error('Error in DELETE /api/notifications:', error);      return false;    }  });   // Unread count  app.get('/api/notifications/unread-count', async () => {    try {      const manager = NotificationManager.getInstance();      return await manager.getUnreadCount();    } catch (error) {      logger.error('Error in GET /api/notifications/unread-count:', error);      return 0;    }  });}