Problem
sumAiCostForTenantSince (src/db/repositories.ts ~3678, added via #7176 for "centralized hosted billing") has zero real callers outside its own test file. Its fleet-wide sibling listAiCostByTenantSince is consumed only by src/services/operator-dashboard.ts, gated to the operator role — no ORB or AMS hosted tenant can see their own usage/spend anywhere today.
Area
src/api/routes.ts, src/services/.
Proposal
Unit decided (2026-07-21): normalized compute-units, mirroring packages/loopover-engine/src/tenant-quota.ts's TenantQuota.computeUnits shape — not raw costUsd. Add a tenant-facing usage/spend route calling sumAiCostForTenantSince, converting the raw cost figure into the same compute-unit representation tenant-quota.ts already uses, scoped to the requesting session's own installation the same way /v1/app/maintainer-dashboard (src/api/routes.ts ~1596-1619) already scopes its data.
⚠️ Required pattern. Reuse /v1/app/maintainer-dashboard's exact tenant-scoping call (loadControlPanelRoleSummary or whatever helper it calls — read that route first). A PR that invents a second scoping mechanism instead of reusing that one does not satisfy this issue, and a PR that exposes raw costUsd instead of the normalized compute-unit figure does not satisfy this issue either.
Deliverables
Test Coverage Requirements
src/** — standard 99%+ Codecov patch target.
Resources
src/db/repositories.ts (sumAiCostForTenantSince, listAiCostByTenantSince)
src/api/routes.ts ~1596-1619 (/v1/app/maintainer-dashboard, the required scoping pattern)
packages/loopover-engine/src/tenant-quota.ts (the required unit shape)
Boundaries
Read-only exposure of an already-computed figure, converted to the decided unit — no changes to how cost itself is tracked or computed.
Re-locked to maintainer-only on 2026-07-21 — see the issue comment for why (tenant billing/usage-exposure surface, not purely mechanical). This line is left from before that correction; do not treat it as current guidance.
Problem
sumAiCostForTenantSince(src/db/repositories.ts~3678, added via #7176 for "centralized hosted billing") has zero real callers outside its own test file. Its fleet-wide siblinglistAiCostByTenantSinceis consumed only bysrc/services/operator-dashboard.ts, gated to the operator role — no ORB or AMS hosted tenant can see their own usage/spend anywhere today.Area
src/api/routes.ts,src/services/.Proposal
Unit decided (2026-07-21): normalized compute-units, mirroring
packages/loopover-engine/src/tenant-quota.ts'sTenantQuota.computeUnitsshape — not rawcostUsd. Add a tenant-facing usage/spend route callingsumAiCostForTenantSince, converting the raw cost figure into the same compute-unit representationtenant-quota.tsalready uses, scoped to the requesting session's own installation the same way/v1/app/maintainer-dashboard(src/api/routes.ts~1596-1619) already scopes its data.Deliverables
Test Coverage Requirements
src/**— standard 99%+ Codecov patch target.Resources
src/db/repositories.ts(sumAiCostForTenantSince,listAiCostByTenantSince)src/api/routes.ts~1596-1619 (/v1/app/maintainer-dashboard, the required scoping pattern)packages/loopover-engine/src/tenant-quota.ts(the required unit shape)Boundaries
Read-only exposure of an already-computed figure, converted to the decided unit — no changes to how cost itself is tracked or computed.
Re-locked to maintainer-only on 2026-07-21 — see the issue comment for why (tenant billing/usage-exposure surface, not purely mechanical). This line is left from before that correction; do not treat it as current guidance.