metis-desk/modules/assets/src/api/infrastructure/http/support.routes.ts

113 lines
3.5 KiB
TypeScript

import type { Application, RequestHandler, Response } from "express";
import { Router } from "express";
import { z } from "zod/v4";
import { 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("/: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 ["/: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);
});
}
router.post("/:companyId/:assetId/:id/delete", (request, response, next) => {
const params = Params.extend({ id: z.uuid() }).safeParse(request.params);
if (
!(
params.success &&
Empty.safeParse(request.body).success &&
Empty.safeParse(request.query).success
)
) {
fail(response, "INVALID_REQUEST");
return;
}
useCases
.remove(params.data.companyId, params.data.assetId, params.data.id)
.then((result) => {
if (!result.isSuccess) {
fail(response, result.error.code);
return;
}
response.json({ deleted: true });
})
.catch(next);
});
app.use("/api/asset-support", authenticate, router);
}