feat(ui): add resource and usage dashboard (/usage route)

adds a new /usage page that lets board operators see how much each ai
provider is consuming across any date window, with per-model breakdowns,
rolling 5h/24h/7d burn windows, weekly budget bars, and a deficit notch
when projected spend is on track to exceed the monthly budget.

- new GET /companies/:id/costs/by-provider endpoint aggregates cost events
  by provider + model with pro-rated billing type splits from heartbeat runs
- new GET /companies/:id/costs/window-spend endpoint returns rolling window
  spend (5h, 24h, 7d) per provider with no schema changes
- QuotaBar: reusable boxed-border progress bar with green/yellow/red
  threshold fill colors and optional deficit notch
- ProviderQuotaCard: per-provider card showing budget allocation bars,
  rolling windows, subscription usage, and model breakdown with token/cost
  share overlays
- Usage page: date preset toggles (mtd, 7d, 30d, ytd, all, custom),
  provider tabs, 30s polling plus ws invalidation on cost_event
- custom date range blocks queries until both dates are selected and
  treats boundaries as local-time (not utc midnight) so full days are
  included regardless of timezone
- query key to timestamp is floored to the nearest minute to prevent
  cache churn on every 30s refetch tick
This commit is contained in:
Sai Shankar
2026-03-08 03:18:37 +05:30
committed by Dotta
parent 3dc3347a58
commit 94018e0239
15 changed files with 803 additions and 4 deletions

View File

@@ -132,6 +132,8 @@ export type {
CostEvent,
CostSummary,
CostByAgent,
CostByProviderModel,
CostWindowSpendRow,
HeartbeatRun,
HeartbeatRunEvent,
AgentRuntimeState,

View File

@@ -34,3 +34,27 @@ export interface CostByAgent {
subscriptionInputTokens: number;
subscriptionOutputTokens: number;
}
export interface CostByProviderModel {
provider: string;
model: string;
costCents: number;
inputTokens: number;
outputTokens: number;
apiRunCount: number;
subscriptionRunCount: number;
subscriptionInputTokens: number;
subscriptionOutputTokens: number;
}
/** spend per provider for a fixed rolling time window */
export interface CostWindowSpendRow {
provider: string;
/** duration label, e.g. "5h", "24h", "7d" */
window: string;
/** rolling window duration in hours */
windowHours: number;
costCents: number;
inputTokens: number;
outputTokens: number;
}

View File

@@ -46,7 +46,7 @@ export type {
CompanySecret,
SecretProviderDescriptor,
} from "./secrets.js";
export type { CostEvent, CostSummary, CostByAgent } from "./cost.js";
export type { CostEvent, CostSummary, CostByAgent, CostByProviderModel, CostWindowSpendRow } from "./cost.js";
export type {
HeartbeatRun,
HeartbeatRunEvent,