Files
breakpilot-compliance/admin-compliance/lib/sdk/reporting/api.ts
Benjamin Boenisch 16e3c251cc
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 36s
CI / test-python-backend-compliance (push) Successful in 28s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 18s
fix(admin): tune chat params, add Training sidebar link, fix reporting API keys
- Reduce chat history from 10 to 6 messages to fit context window
- Lower num_predict from 8192 to 2048 for faster responses
- Add Training module link to SDK sidebar navigation
- Add snake_case to camelCase key transformation for reporting API
  (Go backend returns snake_case, TypeScript expects camelCase)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 23:46:19 +01:00

90 lines
2.3 KiB
TypeScript

/**
* Reporting API Client
*
* Client functions for the Executive Reporting module.
* Communicates with the Go backend via Next.js API proxy at /api/sdk/v1/reporting/*
*/
import type {
ExecutiveReport,
ComplianceScoreResponse,
Deadline,
RiskOverview,
} from './types'
const BASE_URL = '/api/sdk/v1/reporting'
/**
* Rekursive snake_case -> camelCase Konvertierung fuer API-Responses.
* Das Go-Backend liefert snake_case JSON, der TypeScript-Client erwartet camelCase.
*/
function snakeToCamel(str: string): string {
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())
}
function transformKeys(obj: unknown): unknown {
if (Array.isArray(obj)) {
return obj.map(transformKeys)
}
if (obj !== null && typeof obj === 'object') {
return Object.fromEntries(
Object.entries(obj as Record<string, unknown>).map(([key, value]) => [
snakeToCamel(key),
transformKeys(value),
])
)
}
return obj
}
async function apiFetch<T>(path: string): Promise<T> {
const res = await fetch(`${BASE_URL}${path}`, {
headers: {
'Content-Type': 'application/json',
'X-Tenant-ID': typeof window !== 'undefined'
? (localStorage.getItem('bp-tenant-id') || 'default')
: 'default',
},
})
if (!res.ok) {
const error = await res.json().catch(() => ({ error: res.statusText }))
throw new Error(error.error || `API Error: ${res.status}`)
}
const data = await res.json()
return transformKeys(data) as T
}
/**
* Vollstaendigen Executive Report abrufen
* GET /sdk/v1/reporting/executive
*/
export async function getExecutiveReport(): Promise<ExecutiveReport> {
return apiFetch<ExecutiveReport>('/executive')
}
/**
* Nur den Compliance-Score abrufen (leichtgewichtig)
* GET /sdk/v1/reporting/score
*/
export async function getComplianceScore(): Promise<ComplianceScoreResponse> {
return apiFetch<ComplianceScoreResponse>('/score')
}
/**
* Bevorstehende Fristen abrufen
* GET /sdk/v1/reporting/deadlines
*/
export async function getUpcomingDeadlines(): Promise<{ deadlines: Deadline[]; total: number }> {
return apiFetch<{ deadlines: Deadline[]; total: number }>('/deadlines')
}
/**
* Risikouebersicht abrufen
* GET /sdk/v1/reporting/risks
*/
export async function getRiskOverview(): Promise<RiskOverview> {
return apiFetch<RiskOverview>('/risks')
}