syncova-policies/lib/api.ts
Weapie 328f042307 Syncova Policies: Portal für DSGVO-Datenschutzerklärungen
Next.js 15 App Router mit öffentlicher Übersicht und geschütztem
Admin-Bereich zur Pflege von Datenschutzerklärungen nach Art. 12ff. DSGVO.

- Oberfläche auf Basis von shadcn/ui, Inter lokal eingebunden
- Prisma/SQLite, Auth.js mit Credentials-Provider und Rollen
- Massenimport der Merkblätter des Amtes Leezen aus PDF
- Docker-Image (standalone) und Gitea-Workflow zur Veröffentlichung

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 16:23:51 +02:00

67 lines
1.8 KiB
TypeScript

import { PrivacyPolicy } from '@/types/privacy-policy'
const API_BASE_URL = '/api'
/** Fehler einer API-Antwort inkl. der Feld-Validierungsmeldungen des Servers. */
export class ApiError extends Error {
details: string[]
constructor(message: string, details: string[] = []) {
super(message)
this.name = 'ApiError'
this.details = details
}
}
export class ApiClient {
private async request(endpoint: string, options?: RequestInit) {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
...options,
})
if (!response.ok) {
const error = await response.json().catch(() => ({ error: 'Netzwerkfehler' }))
throw new ApiError(
error.error || 'Die Anfrage ist fehlgeschlagen',
Array.isArray(error.details) ? error.details : []
)
}
return response.json()
}
async getAllPolicies(admin = false): Promise<PrivacyPolicy[]> {
const query = admin ? '?admin=true' : ''
return this.request(`/privacy-policies${query}`)
}
async getPolicy(id: number): Promise<PrivacyPolicy> {
return this.request(`/privacy-policies/${id}`)
}
async createPolicy(data: Omit<PrivacyPolicy, 'id' | 'createdAt' | 'updatedAt'>): Promise<PrivacyPolicy> {
return this.request('/privacy-policies', {
method: 'POST',
body: JSON.stringify(data),
})
}
async updatePolicy(id: number, data: Omit<PrivacyPolicy, 'id' | 'createdAt' | 'updatedAt'>): Promise<PrivacyPolicy> {
return this.request(`/privacy-policies/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
})
}
async deletePolicy(id: number): Promise<{ message: string }> {
return this.request(`/privacy-policies/${id}`, {
method: 'DELETE',
})
}
}
export const apiClient = new ApiClient()