/** * 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; } });}
/**
* 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;
}
});
}