import type { 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 { requirePermission } from "./permissions.ts"; import { denyUnlessProjectScope } from "./scope_enforcement.ts"; type App = Hono<{ Variables: { user: AuthUser; db: Db } }>; function tid(c: { get: (k: "user") => AuthUser }): number { return tenantScope(c.get("user")) ?? 0; } export function registerCostControlRoutes(app: App) { const auth = [...requireCoreAuth, requirePermission("cost_control.view")] as const; app.get("/v1/projects/:id/cost-control/summary", ...auth, async (c) => { const projectId = Number(c.req.param("id")); if (!await denyUnlessProjectScope(c, projectId)) return; const db = c.get("db"); const env = await callCoreFn(db, "core.fn_cost_control_project_summary", { tenant_id: tid(c), project_id: projectId, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.get("/v1/projects/:id/cost-control/items", ...auth, async (c) => { const projectId = Number(c.req.param("id")); if (!await denyUnlessProjectScope(c, projectId)) return; const db = c.get("db"); const env = await callCoreFn(db, "core.fn_cost_control_by_item", { tenant_id: tid(c), project_id: projectId, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.get("/v1/projects/:id/cost-control/chapters", ...auth, async (c) => { const projectId = Number(c.req.param("id")); if (!await denyUnlessProjectScope(c, projectId)) return; const db = c.get("db"); const env = await callCoreFn(db, "core.fn_cost_control_by_chapter", { tenant_id: tid(c), project_id: projectId, }, { route: routeLabel(c) }); return respondRpc(c, env); }); app.get("/v1/projects/:id/cost-control/deviations", ...auth, async (c) => { const projectId = Number(c.req.param("id")); if (!await denyUnlessProjectScope(c, projectId)) return; const db = c.get("db"); const env = await callCoreFn(db, "core.fn_cost_control_top_deviations", { tenant_id: tid(c), project_id: projectId, limit: c.req.query("limit"), }, { route: routeLabel(c) }); return respondRpc(c, env); }); }