import { FastifyInstance } from "fastify"; import { requireAnyPermission } from "../../middleware/auth"; import { success, error } from "../../utils/response"; import { aresLookupByIco, aresSearchByName } from "../../services/ares.service"; // Czech messages for the service's token errors. const ARES_ERRORS: Record = { invalid_ico: { message: "IČO musí být 8 číslic", status: 400 }, not_found: { message: "Subjekt s tímto IČO nebyl v ARES nalezen", status: 404, }, ares_unavailable: { message: "Registr ARES je momentálně nedostupný, zkuste to později", status: 502, }, }; /** * ARES proxy — the browser cannot call ares.gov.cz directly (CORS + CSP), so * the customer/supplier modals go through these endpoints. Guarded by the * permissions of the two modals that use the prefill (customer editing and * warehouse supplier management); ARES data itself is public. */ export default async function aresRoutes(fastify: FastifyInstance) { const guard = requireAnyPermission( "customers.create", "customers.edit", "warehouse.manage", ); // GET /ico/:ico — single subject by IČO fastify.get<{ Params: { ico: string } }>( "/ico/:ico", { preHandler: guard }, async (request, reply) => { const result = await aresLookupByIco(request.params.ico); if ("error" in result) { const e = ARES_ERRORS[result.error]; return error(reply, e.message, e.status); } return success(reply, result); }, ); // GET /search?q=… — subjects by (part of) business name, max 10 fastify.get<{ Querystring: { q?: string } }>( "/search", { preHandler: guard }, async (request, reply) => { const q = String(request.query.q ?? "").trim(); if (q.length < 2) { return error(reply, "Zadejte alespoň 2 znaky názvu", 400); } const result = await aresSearchByName(q); if ("error" in result && !Array.isArray(result)) { const e = ARES_ERRORS[result.error]; return error(reply, e.message, e.status); } return success(reply, result); }, ); }