refactor: migrate all page.server.ts files to typed API client

All server-side fetch calls now go through createApiClient() from
$lib/api.server.ts, which wraps openapi-fetch with the generated OpenAPI
types. This means backend changes are reflected in the frontend after
running npm run generate:api.

- Add stub src/lib/generated/api.ts (replaced by generate:api output)
- Fix GroupController: missing /api prefix and ResponseStatusException
- Root, conversations, persons, documents pages all use typed client
- Error handling uses apiError.code directly (no parseBackendError needed)
- Edit page load uses typed client; PUT action keeps raw fetch (multipart)
- Login keeps raw fetch (explicit Authorization header, not cookie auth)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-03-15 13:39:15 +01:00
parent 5d356cd694
commit d76248cffd
11 changed files with 220 additions and 259 deletions

View File

@@ -1,18 +1,12 @@
import { redirect } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import { createApiClient } from '$lib/api.server';
export async function load({ url, fetch }) {
const q = url.searchParams.get('q') || '';
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
const api = createApiClient(fetch);
// Query Parameter an Backend durchreichen
const apiUrl = new URL(`${baseUrl}/api/persons`);
if (q) apiUrl.searchParams.set('q', q);
const { data } = await api.GET('/api/persons', {
params: { query: { q: q || undefined } }
});
const res = await fetch(apiUrl.toString());
if (!res.ok) return { persons: [] };
const persons = await res.json();
return { persons, q };
return { persons: data ?? [], q };
}

View File

@@ -1,27 +1,23 @@
import { error, } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import { error } from '@sveltejs/kit';
import { createApiClient } from '$lib/api.server';
import { getErrorMessage } from '$lib/errors';
export async function load({ params, fetch }) {
const { id } = params;
const api = createApiClient(fetch);
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
const [personResult, docsResult] = await Promise.all([
api.GET('/api/persons/{id}', { params: { path: { id } } }),
api.GET('/api/persons/{id}/documents', { params: { path: { id } } })
]);
try {
// Parallel Fetching: Person Infos + Ihre Dokumente
const [personRes, docsRes] = await Promise.all([
fetch(`${baseUrl}/api/persons/${id}`),
fetch(`${baseUrl}/api/persons/${id}/documents`)
]);
if (personRes.status === 404) throw error(404, 'Person nicht gefunden');
return {
person: await personRes.json(),
documents: await docsRes.json()
};
} catch (e) {
if (e.status) throw e;
throw error(500, 'Ladefehler');
if (personResult.error) {
const code = (personResult.error as { code?: string })?.code;
throw error(personResult.response.status, getErrorMessage(code));
}
return {
person: personResult.data,
documents: docsResult.data ?? []
};
}