Files
FEDEO/backend/src/routes/notifications.ts

93 lines
3.3 KiB
TypeScript

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 })
}
})
}