ValuationOS
ValuationOS β€” initial commit (Phases 1–5)
d31acaa
import type {
AgentRunRow,
BondDetail,
BondInvestigationResponse,
BondSummary,
DashboardSummary,
HistoryResponse,
InvestigationRow,
IssuerDetail,
ManagerDashboard,
} from "@/types/api";
const BASE = "/api";
async function req<T>(path: string, init?: RequestInit): Promise<T> {
const r = await fetch(`${BASE}${path}`, {
headers: { "content-type": "application/json" },
...init,
});
if (!r.ok) throw new Error(`${r.status} ${r.statusText} β€” ${path}`);
return r.json() as Promise<T>;
}
export const api = {
health: () => req<{ status: string; version: string }>("/health"),
dashboardSummary: () => req<DashboardSummary>("/dashboard/summary"),
listBonds: (params: Record<string, string | number> = {}) => {
const q = new URLSearchParams(
Object.entries(params).map(([k, v]) => [k, String(v)]),
).toString();
return req<BondSummary[]>(`/bonds${q ? `?${q}` : ""}`);
},
bondDetail: (id: string) => req<BondDetail>(`/bonds/${encodeURIComponent(id)}`),
bondHistory: (id: string, windowDays = 60) =>
req<HistoryResponse>(`/bonds/${encodeURIComponent(id)}/history?window_days=${windowDays}`),
listInvestigations: (status?: string) =>
req<InvestigationRow[]>(`/investigations${status ? `?status=${status}` : ""}`),
caseAgentRuns: (caseId: number) =>
req<AgentRunRow[]>(`/investigations/${caseId}/agent-runs`),
issuerDetail: (id: string) => req<IssuerDetail>(`/issuers/${encodeURIComponent(id)}`),
methodology: () => req<Record<string, unknown>>(`/methodology`),
bondInvestigation: (id: string) =>
req<BondInvestigationResponse>(`/bonds/${encodeURIComponent(id)}/investigation`),
runInvestigation: (id: string) =>
req<{ case_id: number; status: string; recommended_action: string | null }>(
`/bonds/${encodeURIComponent(id)}/investigate`,
{ method: "POST" },
),
managerKpis: () => req<ManagerDashboard>("/manager/kpis"),
};