import { eq } from "drizzle-orm"; import { Hono } from "hono"; import type { Db } from "../db/client.js"; import { departments } from "../db/schema/index.js"; import type { AppBindings } from "../auth/middleware.js"; import { errorJson } from "../http.js"; import { asString, iso, isUuid, parseJsonBody, requireCan } from "./helpers.js"; function toDepartment(row: typeof departments.$inferSelect) { return { id: row.id, code: row.code, name: row.name, createdAt: iso(row.createdAt), updatedAt: iso(row.updatedAt), }; } export function createDepartmentRoutes(handle: Db) { const routes = new Hono(); routes.get("/departments", async (c) => { const denied = requireCan(c, "read:invoices"); if (denied) return denied; const rows = await handle.db.select().from(departments); return c.json({ items: rows.map(toDepartment) }); }); routes.get("/departments/:id", async (c) => { const denied = requireCan(c, "read:invoices"); if (denied) return denied; const id = c.req.param("id"); if (!isUuid(id)) return errorJson(c, 400, "VALIDATION_ERROR", "Invalid department id."); const row = await handle.db.query.departments.findFirst({ where: eq(departments.id, id) }); if (!row) return errorJson(c, 404, "NOT_FOUND", "Department not found."); return c.json(toDepartment(row)); }); routes.post("/departments", async (c) => { const denied = requireCan(c, "admin:settings"); if (denied) return denied; const body = await parseJsonBody(c); const code = asString(body.code).trim(); const name = asString(body.name).trim(); if (!code || !name) return errorJson(c, 400, "VALIDATION_ERROR", "Code and name are required."); const [row] = await handle.db.insert(departments).values({ code, name }).returning(); return c.json(toDepartment(row), 201); }); routes.patch("/departments/:id", async (c) => { const denied = requireCan(c, "admin:settings"); if (denied) return denied; const id = c.req.param("id"); if (!isUuid(id)) return errorJson(c, 400, "VALIDATION_ERROR", "Invalid department id."); const existing = await handle.db.query.departments.findFirst({ where: eq(departments.id, id), }); if (!existing) return errorJson(c, 404, "NOT_FOUND", "Department not found."); const body = await parseJsonBody(c); const patch: Partial = { updatedAt: new Date() }; if (body.code !== undefined) { const code = asString(body.code).trim(); if (!code) return errorJson(c, 400, "VALIDATION_ERROR", "Code is required."); patch.code = code; } if (body.name !== undefined) { const name = asString(body.name).trim(); if (!name) return errorJson(c, 400, "VALIDATION_ERROR", "Name is required."); patch.name = name; } const [row] = await handle.db .update(departments) .set(patch) .where(eq(departments.id, id)) .returning(); return c.json(toDepartment(row)); }); return routes; }