Push the rest

This commit is contained in:
2026-05-11 10:58:46 +02:00
parent adb5c1a439
commit 0031caf16c
94 changed files with 11777 additions and 3474 deletions

70
frontend/src/api/aw.ts Normal file
View File

@@ -0,0 +1,70 @@
import { SpanStatusCode, trace } from "@opentelemetry/api";
import { currentAccessToken } from "../auth/oidc";
import type {
AWKpi,
AWHistoryPoint,
AWForecastPoint,
AWRepScore,
AWProductDemand,
AWAnomalyPoint,
} from "./types";
const API_BASE = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8000";
const tracer = trace.getTracer("aw-frontend-api");
async function get<T>(path: string, spanName: string): Promise<T> {
return tracer.startActiveSpan(spanName, async (span) => {
try {
const token = currentAccessToken();
const resp = await fetch(`${API_BASE}${path}`, {
headers: {
Accept: "application/json",
...(token ? { Authorization: `Bearer ${token}` } : {}),
},
});
if (!resp.ok) {
const body = await resp.text();
throw new Error(`HTTP ${resp.status}: ${body}`);
}
span.setAttribute("http.status_code", resp.status);
span.setStatus({ code: SpanStatusCode.OK });
return (await resp.json()) as T;
} catch (err) {
span.recordException(err as Error);
span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) });
throw err;
} finally {
span.end();
}
});
}
export const getAWKpis = () =>
get<AWKpi>("/api/aw/sales/kpis", "frontend.aw.sales_kpis");
export const getAWSalesHistory = (daysBack = 365) =>
get<AWHistoryPoint[]>(
`/api/aw/sales/history?days_back=${daysBack}`,
"frontend.aw.sales_history",
);
export const getAWSalesForecast = (horizonDays = 30) =>
get<AWForecastPoint[]>(
`/api/aw/sales/forecast?horizon_days=${horizonDays}`,
"frontend.aw.sales_forecast",
);
export const getAWRepScores = (topN = 10) =>
get<AWRepScore[]>(
`/api/aw/reps/scores?top_n=${topN}`,
"frontend.aw.rep_scores",
);
export const getAWProductDemand = (topN = 20) =>
get<AWProductDemand[]>(
`/api/aw/products/demand?top_n=${topN}`,
"frontend.aw.product_demand",
);
export const getAWAnomalies = () =>
get<AWAnomalyPoint[]>("/api/aw/anomalies", "frontend.aw.anomalies");