import { FastifyInstance } from "fastify" import { eq } from "drizzle-orm" import { authUsers } from "../../db/schema" import { NotificationService, UserDirectory } from "../modules/notification.service" const getUserDirectory: UserDirectory = async (server: FastifyInstance, userId) => { const rows = await server.db .select({ email: authUsers.email }) .from(authUsers) .where(eq(authUsers.id, userId)) .limit(1) const data = rows[0] if (!data) return null return { email: data.email } } const requireTenant = (tenantId: number | null) => { if (!tenantId) throw new Error("Kein aktiver Mandant") return tenantId } export default async function notificationsRoutes(server: FastifyInstance) { const svc = new NotificationService(server, getUserDirectory) server.get("/notifications", async (req) => { const limit = Number((req.query as { limit?: string })?.limit || 50) return await svc.listForUser(requireTenant(req.user.tenant_id), req.user.user_id, limit) }) server.post("/notifications/:id/read", async (req, reply) => { const params = req.params as { id: string } const item = await svc.markRead(requireTenant(req.user.tenant_id), req.user.user_id, params.id) if (!item) return reply.code(404).send({ error: "Benachrichtigung nicht gefunden" }) return item }) server.get("/notifications/push/config", async () => { return svc.getPublicPushConfig() }) server.post("/notifications/push/subscribe", async (req) => { const tenantId = requireTenant(req.user.tenant_id) const userAgent = req.headers["user-agent"] const subscription = await svc.registerPushSubscription( tenantId, req.user.user_id, req.body as any, Array.isArray(userAgent) ? userAgent.join(" ") : userAgent ) return { success: true, id: subscription?.id, } }) server.delete("/notifications/push/subscribe", async (req) => { const body = (req.body || {}) as { endpoint?: string } if (!body.endpoint) throw new Error("endpoint fehlt") return await svc.disablePushSubscription(requireTenant(req.user.tenant_id), req.user.user_id, body.endpoint) }) server.post("/notifications/test-push", async (req) => { return await svc.trigger({ tenantId: requireTenant(req.user.tenant_id), userId: req.user.user_id, eventType: "system.test_push", title: "FEDEO Desktop Push ist aktiv", message: "Diese Testbenachrichtigung wurde von FEDEO selbst zugestellt.", payload: { link: "/", icon: "/favicon.ico", }, channels: ["inapp", "push"], }) }) server.post("/notifications/trigger", async (req, reply) => { try { const body = req.body as any const tenantId = body.tenantId || req.user.tenant_id const res = await svc.trigger({ ...body, tenantId: requireTenant(tenantId), }) reply.send(res) } catch (err: any) { server.log.error(err) reply.code(500).send({ error: err.message }) } }) }