import type { Application, RequestHandler, Response } from "express"; import { Router } from "express"; import { z } from "zod/v4"; import { SupportToolInputSchema, SupportValuesSchema } from "../../../common/support"; import type { SupportUseCases } from "../../application/support.use-cases"; import { buildSupport, buildSupportTool } from "../../application/support-response.builder"; function fail(response: Response, code: string) { response .status(code === "INVALID_REQUEST" ? 400 : code.endsWith("NOT_FOUND") ? 404 : 409) .json({ code, requestId: response.getHeader("x-request-id") }); } const Params = z.strictObject({ companyId: z.uuid(), assetId: z.uuid() }); const Empty = z.strictObject({}); export function registerSupportRoutes( app: Application, useCases: SupportUseCases, authenticate: RequestHandler ) { const router = Router(); router.get("/tools", (request, response, next) => { if (!Empty.safeParse(request.query).success) { fail(response, "INVALID_REQUEST"); return; } useCases .tools() .then((tools) => response.json({ tools: tools.map(buildSupportTool) })) .catch(next); }); router.get("/:companyId/:assetId", (request, response, next) => { const params = Params.safeParse(request.params); if (!(params.success && Empty.safeParse(request.query).success)) { fail(response, "INVALID_REQUEST"); return; } useCases .get(params.data.companyId, params.data.assetId) .then((result) => { if (!result.isSuccess) { fail(response, result.error.code); return; } response.json({ connections: result.data.connections.map((item) => buildSupport(item, result.data.actorNames) ), tools: result.data.tools.map(buildSupportTool), }); }) .catch(next); }); for (const path of ["/tools", "/tools/:id/update"]) { router.post(path, (request, response, next) => { const params = (path.endsWith("update") ? z.strictObject({ id: z.uuid() }) : Empty).safeParse( request.params ); const body = z.strictObject({ values: SupportToolInputSchema }).safeParse(request.body); if (!(params.success && body.success && Empty.safeParse(request.query).success)) { fail(response, "INVALID_REQUEST"); return; } const id = "id" in params.data && typeof params.data.id === "string" ? params.data.id : undefined; useCases .saveTool(id, body.data.values) .then((result) => { if (!result.isSuccess) { fail(response, result.error.code); return; } response.status(id ? 200 : 201).json({ tool: buildSupportTool(result.data) }); }) .catch(next); }); } for (const path of ["/:companyId/:assetId", "/:companyId/:assetId/:id/update"]) { router.post(path, (request, response, next) => { const params = (path.endsWith("update") ? Params.extend({ id: z.uuid() }) : Params).safeParse( request.params ); const body = z.strictObject({ values: SupportValuesSchema }).safeParse(request.body); const actor = z .object({ userId: z.uuid() }) .safeParse("session" in request ? request.session : undefined); if ( !(params.success && body.success && actor.success && Empty.safeParse(request.query).success) ) { fail(response, "INVALID_REQUEST"); return; } const id = "id" in params.data && typeof params.data.id === "string" ? params.data.id : undefined; useCases .save(params.data.companyId, params.data.assetId, id, body.data.values, actor.data.userId) .then((result) => { if (!result.isSuccess) { fail(response, result.error.code); return; } response .status(id ? 200 : 201) .json({ connection: buildSupport(result.data.connection, result.data.actorNames) }); }) .catch(next); }); } app.use("/api/asset-support", authenticate, router); }