Files
FEDEO/backend/src/routes/documentInbox.ts
flfeders 052a3a8446
All checks were successful
Build and Release FEDEO / verify (push) Successful in 1m0s
Build and Release FEDEO / build-and-release (push) Successful in 5m56s
feat(documents): file scanner inbox documents with folder and type
2026-09-29 16:48:15 +02:00

48 lines
3.1 KiB
TypeScript

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