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
- 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>
90 lines
2.3 KiB
TypeScript
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')
|
|
}
|