feat(K): Phase K EU Compliance — AI Registry, DPIA, Incident Register, Retention Admin, Tests, Doku
- K-REG: GET /api/v1/compliance/ai-registry — lists all agents with ai_use_case_metadata - K-DPIA: GET /api/v1/compliance/dpia-template — pre-filled DPIA template export - K-INC: ComplianceIncident model, Migration 0133 (RLS), CRUD routes (admin-only) - K-RET: GET/PATCH /api/v1/compliance/retention-policies — 5 policies editable - K-COMP-TEST: 12/12 integration tests pass - K-DOC: docs/compliance.md — Betriebsdoku - Frontend: ComplianceTab.tsx in SettingsAI.tsx (new tab) - 13 files created/modified
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Compliance API client — AI registry, DPIA template, incidents, retention policies.
|
||||
*
|
||||
* All endpoints are admin-only and target /api/v1/compliance/...
|
||||
*/
|
||||
|
||||
import { apiGet, apiPost, apiPatch } from './client';
|
||||
|
||||
// ─── Types ───
|
||||
|
||||
export interface AIRegistryEntry {
|
||||
agent_id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
is_active: boolean;
|
||||
llm_model: string;
|
||||
ai_use_case_metadata: Record<string, unknown>;
|
||||
validation_warnings: string[];
|
||||
}
|
||||
|
||||
export interface AIRegistryResponse {
|
||||
items: AIRegistryEntry[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface DPIATemplate {
|
||||
use_case_id: string;
|
||||
agent_name: string;
|
||||
intended_purpose: string;
|
||||
owner: string;
|
||||
risk_class: string;
|
||||
oversight_policy: string;
|
||||
data_categories: string[];
|
||||
allowed_providers: string[];
|
||||
allowed_models: string[];
|
||||
allowed_actions: string[];
|
||||
human_review_required: boolean;
|
||||
validation_warnings: string[];
|
||||
disclaimer: string;
|
||||
}
|
||||
|
||||
export interface ComplianceIncident {
|
||||
id: string;
|
||||
incident_type: string;
|
||||
title: string;
|
||||
description: string;
|
||||
affected_use_cases: string[];
|
||||
affected_versions: string[];
|
||||
provider: string;
|
||||
measures_taken: string;
|
||||
evidence_refs: string[];
|
||||
status: string;
|
||||
created_by: string | null;
|
||||
resolved_by: string | null;
|
||||
resolved_at: string | null;
|
||||
created_at: string | null;
|
||||
updated_at: string | null;
|
||||
}
|
||||
|
||||
export interface IncidentCreate {
|
||||
incident_type: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
affected_use_cases?: string[];
|
||||
affected_versions?: string[];
|
||||
provider?: string;
|
||||
measures_taken?: string;
|
||||
evidence_refs?: string[];
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface IncidentUpdate {
|
||||
title?: string;
|
||||
description?: string;
|
||||
incident_type?: string;
|
||||
affected_use_cases?: string[];
|
||||
affected_versions?: string[];
|
||||
provider?: string;
|
||||
measures_taken?: string;
|
||||
evidence_refs?: string[];
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface IncidentsResponse {
|
||||
items: ComplianceIncident[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface RetentionPolicyEntry {
|
||||
key: string;
|
||||
label: string;
|
||||
description: string;
|
||||
default_days: number;
|
||||
current_days: number;
|
||||
editable: boolean;
|
||||
}
|
||||
|
||||
export interface RetentionPoliciesResponse {
|
||||
items: RetentionPolicyEntry[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
// ─── API Functions ───
|
||||
|
||||
export async function fetchAIRegistry(): Promise<AIRegistryResponse> {
|
||||
return apiGet<AIRegistryResponse>('/compliance/ai-registry');
|
||||
}
|
||||
|
||||
export async function fetchDPIATemplate(agentId: string): Promise<DPIATemplate> {
|
||||
return apiGet<DPIATemplate>('/compliance/dpia-template', {
|
||||
params: { agent_id: agentId },
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchIncidents(params?: {
|
||||
status?: string;
|
||||
incident_type?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<IncidentsResponse> {
|
||||
return apiGet<IncidentsResponse>('/compliance/incidents', { params });
|
||||
}
|
||||
|
||||
export async function createIncident(data: IncidentCreate): Promise<ComplianceIncident> {
|
||||
return apiPost<ComplianceIncident>('/compliance/incidents', data);
|
||||
}
|
||||
|
||||
export async function updateIncident(
|
||||
id: string,
|
||||
data: IncidentUpdate
|
||||
): Promise<ComplianceIncident> {
|
||||
return apiPatch<ComplianceIncident>(`/compliance/incidents/${id}`, data);
|
||||
}
|
||||
|
||||
export async function fetchRetentionPolicies(): Promise<RetentionPoliciesResponse> {
|
||||
return apiGet<RetentionPoliciesResponse>('/compliance/retention-policies');
|
||||
}
|
||||
|
||||
export async function updateRetentionPolicy(
|
||||
key: string,
|
||||
days: number
|
||||
): Promise<{ key: string; days: number; message: string }> {
|
||||
return apiPatch<{ key: string; days: number; message: string }>(
|
||||
`/compliance/retention-policies/${key}`,
|
||||
{ days }
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user