export const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8000/api/v1"; export type Entity = { id: string; created_at: string; updated_at: string; }; export type Customer = Entity & { customer_type: "practice" | "clinic"; name: string; city?: string | null; phone?: string | null; email?: string | null; hygiene_officer?: string | null; quality_manager?: string | null; notes?: string | null; }; export type Location = Entity & { customer_id: string; name: string; street?: string | null; postal_code?: string | null; city?: string | null; room?: string | null; }; export type Contact = Entity & { customer_id: string; full_name: string; function?: string | null; email?: string | null; phone?: string | null; }; export type Device = Entity & { customer_id: string; location_id?: string | null; manufacturer: string; model: string; serial_number: string; device_type?: string | null; year_built?: number | null; commissioned_on?: string | null; chamber_volume_liters?: number | null; steam_generation?: string | null; water_treatment?: string | null; documentation?: string | null; supplier?: string | null; }; export type Equipment = Entity & { kind: string; manufacturer?: string | null; model?: string | null; serial_number: string; calibrated_on?: string | null; calibration_due_on?: string | null; certificate_document_id?: string | null; status: "green" | "yellow" | "red"; }; export type ValidationItem = Entity & { report_number: string; customer_id: string; location_id?: string | null; contact_id?: string | null; device_id?: string | null; validation_type: string; project?: string | null; test_location?: string | null; examiner_name?: string | null; participants?: string | null; operator_name?: string | null; status: string; result?: string | null; scheduled_on?: string | null; performed_on?: string | null; next_validation_on?: string | null; equipment_ids: string[]; environment_conditions: Record; documentation_checklist: Record[]; performance_checklist: Record[]; programs: Record[]; loading_patterns: Record[]; measurement_data: Record[]; drying: Record; recommendations: Record[]; attachments: Record[]; }; export type Paginated = { items: T[]; total: number; page: number; page_size: number; }; export async function login(email: string, password: string) { const response = await fetch(`${API_BASE}/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }) }); if (!response.ok) { throw new Error("Anmeldung fehlgeschlagen"); } return response.json() as Promise<{ access_token: string; token_type: string }>; } export async function apiGet(path: string, token: string): Promise { const response = await fetch(`${API_BASE}${path}`, { headers: { Authorization: `Bearer ${token}` }, cache: "no-store" }); if (!response.ok) { throw new Error(`API request failed: ${response.status}`); } return response.json() as Promise; } export async function apiSend(path: string, token: string, method: "POST" | "PUT", body: unknown): Promise { const response = await fetch(`${API_BASE}${path}`, { method, headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }, body: JSON.stringify(body) }); if (!response.ok) { const detail = await response.text(); throw new Error(detail || `API request failed: ${response.status}`); } return response.json() as Promise; } export async function apiDelete(path: string, token: string): Promise { const response = await fetch(`${API_BASE}${path}`, { method: "DELETE", headers: { Authorization: `Bearer ${token}` } }); if (!response.ok) { throw new Error(`API request failed: ${response.status}`); } }