import type { Context, Hono } from "hono"; import type { AuthUser } from "./auth.ts"; import { tenantScope } from "./auth.ts"; import { requireCoreAuth } from "./scope.ts"; import type { Db } from "./db.ts"; import { callCoreFn } from "./rpc.ts"; import { respondRpc, routeLabel } from "./http_errors.ts"; import { requireAnyPermission, requirePermission } from "./permissions.ts"; type App = Hono<{ Variables: { user: AuthUser; db: Db } }>; function tid(c: { get: (k: "user") => AuthUser }): number { return tenantScope(c.get("user")) ?? 0; } function actor(c: Context): { id: number; name: string } { const u = c.get("user"); return { id: u.id, name: u.display_name }; } export function registerWarehouseRoutes(app: App) { app.get("/v1/warehouses", ...requireCoreAuth, requireAnyPermission("view_warehouse", "manage_warehouse"), async (c) => { const db = c.get("db"); const env = await callCoreFn(db, "core.fn_warehouse_list", { tenant_id: tid(c), include_closed: c.req.query("include_closed") === "true", }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.post("/v1/warehouses/central/ensure", ...requireCoreAuth, requirePermission("manage_warehouse"), async (c) => { const db = c.get("db"); const env = await callCoreFn(db, "core.fn_warehouse_ensure_central", { tenant_id: tid(c) }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.post("/v1/projects/:id/warehouse/open", ...requireCoreAuth, requirePermission("manage_warehouse"), async (c) => { const db = c.get("db"); const env = await callCoreFn(db, "core.fn_warehouse_open_project", { tenant_id: tid(c), project_id: Number(c.req.param("id")), }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.post("/v1/projects/:id/warehouse/close", ...requireCoreAuth, requirePermission("close_warehouse"), async (c) => { const body = await c.req.json<{ force?: boolean; close_notes?: string }>().catch(() => ({} as { force?: boolean; close_notes?: string })); const db = c.get("db"); const a = actor(c); const env = await callCoreFn(db, "core.fn_warehouse_close_project", { project_id: Number(c.req.param("id")), force: body.force, closed_by_name: a.name, close_notes: body.close_notes, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.get("/v1/warehouses/:id/stock", ...requireCoreAuth, requireAnyPermission("view_warehouse", "manage_warehouse"), async (c) => { const db = c.get("db"); const env = await callCoreFn(db, "core.fn_warehouse_stock_list", { tenant_id: tid(c), warehouse_id: Number(c.req.param("id")), global: false, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.get("/v1/warehouses/stock/global", ...requireCoreAuth, requireAnyPermission("view_warehouse", "manage_warehouse"), async (c) => { const db = c.get("db"); const env = await callCoreFn(db, "core.fn_warehouse_stock_list", { tenant_id: tid(c), global: true, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.get("/v1/warehouses/:id/movements", ...requireCoreAuth, requireAnyPermission("view_warehouse", "manage_warehouse"), async (c) => { const db = c.get("db"); const env = await callCoreFn(db, "core.fn_warehouse_movement_list", { warehouse_id: Number(c.req.param("id")), material_id: c.req.query("material_id"), }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.post("/v1/warehouse-materials", ...requireCoreAuth, requirePermission("manage_warehouse"), async (c) => { const body = await c.req.json>(); const db = c.get("db"); const env = await callCoreFn(db, "core.fn_warehouse_material_upsert", { ...body, tenant_id: tid(c) }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.post("/v1/warehouses/:id/entries", ...requireCoreAuth, requirePermission("manage_warehouse"), async (c) => { const body = await c.req.json>(); const db = c.get("db"); const a = actor(c); const env = await callCoreFn(db, "core.fn_warehouse_entry_create", { ...body, tenant_id: tid(c), warehouse_id: Number(c.req.param("id")), created_by_id: a.id, created_by_name: a.name, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.post("/v1/warehouses/:id/exits", ...requireCoreAuth, requirePermission("manage_warehouse"), async (c) => { const body = await c.req.json>(); const db = c.get("db"); const a = actor(c); const env = await callCoreFn(db, "core.fn_warehouse_exit_create", { ...body, tenant_id: tid(c), warehouse_id: Number(c.req.param("id")), created_by_id: a.id, created_by_name: a.name, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.post("/v1/warehouse-transfers", ...requireCoreAuth, requirePermission("manage_warehouse"), async (c) => { const body = await c.req.json>(); const db = c.get("db"); const a = actor(c); const env = await callCoreFn(db, "core.fn_warehouse_transfer_create", { ...body, tenant_id: tid(c), created_by_name: a.name, }, { route: routeLabel(c) }); return respondRpc(c, env); }); }