import { and, eq } from "drizzle-orm" import type { FastifyInstance } from "fastify" import { authProfiles } from "../../db/schema" import { createScannerInboxService, SCANNER_DAV_PATH, SCANNER_UPLOAD_LIMIT, type ScannerInboxService } from "../modules/scanner-inbox.service" export default async function documentInboxRoutes(server: FastifyInstance, options: { service?: ScannerInboxService }) { const service = options.service || createScannerInboxService(server.db) server.addHook("preHandler", async (req, reply) => { if (!req.user?.tenant_id) return reply.code(400).send({ error: "Bitte einen Mandanten auswählen." }) const [profile] = await server.db.select({ portal: authProfiles.customer_for_portal }).from(authProfiles) .where(and(eq(authProfiles.tenant_id, req.user.tenant_id), eq(authProfiles.user_id, req.user.user_id))).limit(1) if (profile?.portal) return reply.code(403).send({ error: "Die Dokumentenablage ist nur intern verfügbar." }) if (req.routeOptions.url?.includes("/scanner") && !req.user.is_admin) { return reply.code(403).send({ error: "Scanner-Zugänge können nur Administratoren verwalten." }) } reply.header("Cache-Control", "no-store") }) server.get("/document-inbox", async (req, reply) => { const query = req.query as { limit?: string; offset?: string; search?: string } const limit = Number(query.limit ?? 50) const offset = Number(query.offset ?? 0) if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100 || !Number.isSafeInteger(offset) || offset < 0 || (query.search?.length || 0) > 200) { return reply.code(400).send({ error: "Ungültige Such- oder Seiteneinstellungen." }) } return service.list(req.user.tenant_id!, limit, offset, query.search?.trim() || "") }) server.get("/document-inbox/filing-options", async req => service.filingOptions(req.user.tenant_id!)) server.post<{ Params: { id: string }; Body: { folder: string | null; type: string } }>("/document-inbox/:id/file", { schema: { params: { type: "object", required: ["id"], properties: { id: { type: "string", format: "uuid" } } }, body: { type: "object", required: ["folder", "type"], additionalProperties: false, properties: { folder: { anyOf: [{ type: "string", format: "uuid" }, { type: "null" }] }, type: { type: "string", format: "uuid" }, } }, }, }, async req => service.fileDocument(req.user.tenant_id!, req.user.user_id, req.params.id, req.body.folder, req.body.type)) server.get("/document-inbox/scanner", async req => ({ connection: await service.connection(req.user.tenant_id!), path: SCANNER_DAV_PATH, maxFileSize: SCANNER_UPLOAD_LIMIT, })) server.post("/document-inbox/scanner/credentials", async req => ({ connection: await service.credentials(req.user.tenant_id!), path: SCANNER_DAV_PATH, })) server.delete("/document-inbox/scanner", async (_req, reply) => { await service.disable(_req.user.tenant_id!) return reply.code(204).send() }) }