/** * Bounded, side-effect-free dashboard read projection. * * This module deliberately knows only the persisted accounting read model. It * neither owns the store nor reaches into live provider/circuit-breaker state: * quota and cooldown facts are injected as one already-captured snapshot. */ import type { AccountingReader } from "./accounting-store.js"; import { type AttributionPolicy, type CostBy, type CostReportV1, type WindowId } from "./dashboard-contract.js"; import type { DashboardReadPort } from "./dashboard-routes.js"; /** What the cost roll-up accepts: the window, whether repair joins, and the grouping axis. */ export interface CostReportQuery { readonly window: WindowId; /** Fold role:"repair" attempts into the report as their own labelled share (C1). */ readonly includeRepair: boolean; readonly by?: CostBy; } /** * The cost roll-up surface beside {@link DashboardReadPort}. Declared here rather than in * `dashboard-routes.ts` because only producers and the CLI consume it; the dashboard API * routes deliberately stay unaware of it (Gap 7: no HTTP endpoint for cost). */ export interface CostReportingPort { readCostReport(query: CostReportQuery): Promise; } /** A point-in-time, already-read availability view. No provider probe belongs here. */ export interface DashboardAvailabilitySnapshot { readonly quotas?: readonly unknown[]; readonly cooldowns?: readonly unknown[]; } /** Narrow read-only availability dependency for the snapshot path. */ export interface DashboardAvailabilityPort { snapshot(): DashboardAvailabilitySnapshot; } export interface DashboardSnapshotReadOptions { /** The only persistence dependency used by the projector. */ readonly accounting: AccountingReader; readonly relayVersion: string; /** Inject for deterministic tests; defaults to Date.now. */ readonly now?: () => number | Date | string; /** Already-captured facts, or a narrow synchronous snapshot reader. */ readonly availability?: DashboardAvailabilitySnapshot | DashboardAvailabilityPort | (() => DashboardAvailabilitySnapshot); /** The caller-owned policy label; unknown is the only safe default. */ readonly attributionPolicy?: AttributionPolicy; } export type DashboardSnapshotOptions = DashboardSnapshotReadOptions; /** * Create the read port consumed by dashboard routes. The returned object has * no mutable aliases into the accounting reader or availability snapshot. */ export declare function createDashboardSnapshotReadPort(options: DashboardSnapshotReadOptions): DashboardReadPort & CostReportingPort;