import { authMiddleware } from '../middleware/auth'; import { Elysia, t } from 'elysia'; import { db } from '../db'; import { notifications, clients } from '../db/schema'; import { eq, and, desc, sql } from 'drizzle-orm'; import type { User } from '../lib/auth'; export const notificationRoutes = new Elysia({ prefix: '/notifications' }) .use(authMiddleware) // List notifications .get('/', async ({ query, user }: { query: { limit?: string; unreadOnly?: string }; user: User }) => { const limit = query.limit ? parseInt(query.limit) : 50; const unreadOnly = query.unreadOnly === 'true'; let conditions = [eq(notifications.userId, user.id)]; if (unreadOnly) { conditions.push(eq(notifications.read, false)); } const items = await db.select({ notification: notifications, client: { id: clients.id, firstName: clients.firstName, lastName: clients.lastName, }, }) .from(notifications) .leftJoin(clients, eq(notifications.clientId, clients.id)) .where(and(...conditions)) .orderBy(desc(notifications.createdAt)) .limit(limit); // Unread count const [unreadResult] = await db.select({ count: sql`count(*)::int`, }) .from(notifications) .where(and(eq(notifications.userId, user.id), eq(notifications.read, false))); return { notifications: items.map(({ notification, client }) => ({ ...notification, client: client?.id ? client : null, })), unreadCount: unreadResult?.count || 0, }; }, { query: t.Object({ limit: t.Optional(t.String()), unreadOnly: t.Optional(t.String()), }), }) // Mark notification as read .put('/:id/read', async ({ params, user }: { params: { id: string }; user: User }) => { const [updated] = await db.update(notifications) .set({ read: true }) .where(and(eq(notifications.id, params.id), eq(notifications.userId, user.id))) .returning(); if (!updated) throw new Error('Notification not found'); return updated; }, { params: t.Object({ id: t.String({ format: 'uuid' }) }), }) // Mark all as read .post('/mark-all-read', async ({ user }: { user: User }) => { await db.update(notifications) .set({ read: true }) .where(and(eq(notifications.userId, user.id), eq(notifications.read, false))); return { success: true }; }) // Delete notification .delete('/:id', async ({ params, user }: { params: { id: string }; user: User }) => { const [deleted] = await db.delete(notifications) .where(and(eq(notifications.id, params.id), eq(notifications.userId, user.id))) .returning({ id: notifications.id }); if (!deleted) throw new Error('Notification not found'); return { success: true }; }, { params: t.Object({ id: t.String({ format: 'uuid' }) }), });