diff --git a/backend/pom.xml b/backend/pom.xml
index e525f1c1..a48c8137 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -136,6 +136,13 @@
org.flywaydb
flyway-database-postgresql
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ 3.0.2
+
diff --git a/backend/src/main/resources/application-dev.yaml b/backend/src/main/resources/application-dev.yaml
index 45827c3e..56c49e96 100644
--- a/backend/src/main/resources/application-dev.yaml
+++ b/backend/src/main/resources/application-dev.yaml
@@ -1,3 +1,10 @@
spring:
jpa:
show-sql: true
+
+springdoc:
+ api-docs:
+ enabled: true
+ swagger-ui:
+ enabled: true
+ path: /swagger-ui.html
diff --git a/backend/src/main/resources/application.yaml b/backend/src/main/resources/application.yaml
index a604c24c..6b89b8cf 100644
--- a/backend/src/main/resources/application.yaml
+++ b/backend/src/main/resources/application.yaml
@@ -21,6 +21,12 @@ spring:
max-file-size: 50MB
max-request-size: 50MB
+springdoc:
+ api-docs:
+ enabled: false
+ swagger-ui:
+ enabled: false
+
app:
s3:
endpoint: ${S3_ENDPOINT}
diff --git a/frontend/.gitignore b/frontend/.gitignore
index 83eb0159..a3537d4e 100644
--- a/frontend/.gitignore
+++ b/frontend/.gitignore
@@ -24,3 +24,6 @@ vite.config.ts.timestamp-*
# Paraglide
src/lib/paraglide
+
+# Generated OpenAPI types — regenerate with: npm run generate:api
+src/lib/generated/api.ts
diff --git a/frontend/package.json b/frontend/package.json
index cd35f0a5..45c8f35a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -13,9 +13,14 @@
"format": "prettier --write .",
"lint": "prettier --check . && eslint .",
"test:unit": "vitest",
- "test": "npm run test:unit -- --run"
+ "test": "npm run test:unit -- --run",
+ "generate:api": "openapi-typescript http://localhost:8080/v3/api-docs -o ./src/lib/generated/api.ts"
+ },
+ "dependencies": {
+ "openapi-fetch": "^0.13.5"
},
"devDependencies": {
+ "openapi-typescript": "^7.8.0",
"@eslint/compat": "^1.4.0",
"@eslint/js": "^9.39.1",
"@inlang/paraglide-js": "^2.5.0",
diff --git a/frontend/src/lib/api.server.ts b/frontend/src/lib/api.server.ts
new file mode 100644
index 00000000..927509cc
--- /dev/null
+++ b/frontend/src/lib/api.server.ts
@@ -0,0 +1,25 @@
+/**
+ * Typed API client for the Familienarchiv backend.
+ *
+ * Types are generated from the OpenAPI spec — run `npm run generate:api`
+ * (with the backend running in dev mode) to regenerate src/lib/generated/api.ts.
+ *
+ * Usage in +page.server.ts:
+ *
+ * export async function load({ fetch }) {
+ * const api = createApiClient(fetch);
+ * const { data, error } = await api.GET('/api/documents/{id}', {
+ * params: { path: { id } }
+ * });
+ * }
+ */
+import createClient from 'openapi-fetch';
+import { env } from '$env/dynamic/private';
+import type { paths } from '$lib/generated/api';
+
+export function createApiClient(fetch: typeof globalThis.fetch) {
+ return createClient({
+ baseUrl: env.API_INTERNAL_URL || 'http://localhost:8080',
+ fetch
+ });
+}
diff --git a/frontend/src/lib/generated/.gitkeep b/frontend/src/lib/generated/.gitkeep
new file mode 100644
index 00000000..e69de29b