diff --git a/docker-compose.docs.yml b/docker-compose.docs.yml
index 00f2f40..157ee44 100644
--- a/docker-compose.docs.yml
+++ b/docker-compose.docs.yml
@@ -6,4 +6,4 @@ services:
container_name: fedeo-docs
restart: unless-stopped
ports:
- - "3205:80"
+ - "3205:3000"
diff --git a/docker-compose.yml b/docker-compose.yml
index c1f8388..7263a44 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -31,7 +31,7 @@ services:
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik"
- - "traefik.port=80"
+ - "traefik.port=3000"
# Middlewares
- "traefik.http.middlewares.fedeo-docs-redirect-web-secure.redirectscheme.scheme=https"
- "traefik.http.middlewares.fedeo-docs-strip.stripprefix.prefixes=/docs"
diff --git a/docs-site/.dockerignore b/docs-site/.dockerignore
index 0e9db65..d86f467 100644
--- a/docs-site/.dockerignore
+++ b/docs-site/.dockerignore
@@ -1,4 +1,3 @@
node_modules
-build
-.docusaurus
-.git
+.nuxt
+.output
diff --git a/docs-site/Dockerfile b/docs-site/Dockerfile
index 5aa1582..348371c 100644
--- a/docs-site/Dockerfile
+++ b/docs-site/Dockerfile
@@ -1,7 +1,7 @@
FROM node:20-alpine AS builder
WORKDIR /app/docs-site
-COPY docs-site/package.json docs-site/package-lock.json* ./
+COPY docs-site/package.json ./
RUN npm install
COPY docs-site ./
@@ -9,9 +9,11 @@ COPY docs /app/docs
RUN npm run build
-FROM nginx:1.27-alpine AS runner
-COPY docs-site/nginx.conf /etc/nginx/conf.d/default.conf
-COPY --from=builder /app/docs-site/build /usr/share/nginx/html
+FROM node:20-alpine AS runner
+WORKDIR /app/docs-site
+ENV NODE_ENV=production
-EXPOSE 80
-CMD ["nginx", "-g", "daemon off;"]
+COPY --from=builder /app/docs-site/.output ./.output
+
+EXPOSE 3000
+CMD ["node", ".output/server/index.mjs"]
diff --git a/docs-site/README.md b/docs-site/README.md
index 77bd9b5..6699645 100644
--- a/docs-site/README.md
+++ b/docs-site/README.md
@@ -1,12 +1,6 @@
-# FEDEO Docs Site (Docusaurus)
+# FEDEO Docs Site (Nuxt Content)
-Diese Docusaurus-App rendert die versionierte FEDEO-Dokumentation aus dem Ordner `../docs`.
-
-## Zielpfad in Produktion
-
-Die Seite ist für den Betrieb hinter Traefik unter folgendem Pfad konfiguriert:
-
-- `https://app.fedeo.de/docs`
+Diese Docs-App basiert auf Nuxt Content und rendert die Inhalte aus dem Repository-Ordner `docs/`.
## Lokale Entwicklung
@@ -14,46 +8,27 @@ Im Ordner `docs-site` ausführen:
```bash
npm install
-npm run start
+npm run dev
```
-Danach ist die Seite unter `http://localhost:3005` erreichbar.
+Die App ist danach unter `http://localhost:3005` erreichbar.
-## Statischer Build
+## Build
```bash
npm run build
-npm run serve
```
-## Deploy über Haupt-Compose
+## Production-Deploy
-Die Docs sind in der zentralen `docker-compose.yml` als eigener Service `docs` eingebunden.
+Das Docker-Image startet einen Node-Server auf Port `3000`.
+In der Haupt-`docker-compose.yml` wird die App hinter Traefik unter `/docs` veröffentlicht.
-Deploy aus dem Projekt-Root:
+## Content-Quelle
-```bash
-docker compose pull docs
-docker compose up -d docs
-```
+Vor `dev` und `build` wird automatisch synchronisiert:
-Für ein komplettes Update des gesamten Stacks:
+- Quelle: `../docs/**/*.md`
+- Ziel: `docs-site/content`
-```bash
-docker compose pull
-docker compose up -d
-```
-
-## Workflow bei Funktionsänderungen
-
-Vor jedem Docs-Deploy:
-
-1. Technische Kataloge aktualisieren
-
-```bash
-node docs/scripts/sync-funktionsdoku.mjs
-```
-
-2. Änderungen committen
-3. CI baut und pusht das `docs`-Image
-4. Server zieht neues Image und startet den Service neu
+Dabei wird `docs/README.md` zu `content/index.md` gemappt.
diff --git a/docs-site/app.vue b/docs-site/app.vue
new file mode 100644
index 0000000..8f62b8b
--- /dev/null
+++ b/docs-site/app.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs-site/assets/css/main.css b/docs-site/assets/css/main.css
new file mode 100644
index 0000000..c2073d3
--- /dev/null
+++ b/docs-site/assets/css/main.css
@@ -0,0 +1,106 @@
+:root {
+ --bg: #f6f8f7;
+ --panel: #ffffff;
+ --text: #1f2937;
+ --muted: #5f6b7a;
+ --accent: #0b6e4f;
+ --line: #d8e0dc;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
+ color: var(--text);
+ background: radial-gradient(circle at 10% 10%, #e7f2ed, transparent 35%), var(--bg);
+}
+
+.docs-layout {
+ display: grid;
+ grid-template-columns: 280px minmax(0, 1fr);
+ min-height: 100vh;
+}
+
+.docs-aside {
+ border-right: 1px solid var(--line);
+ background: var(--panel);
+ padding: 1rem;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ overflow: auto;
+}
+
+.docs-brand {
+ display: block;
+ font-weight: 700;
+ color: var(--accent);
+ text-decoration: none;
+ margin-bottom: 1rem;
+}
+
+.docs-sidebar ul {
+ list-style: none;
+ margin: 0;
+ padding: 0 0 0 0.8rem;
+}
+
+.docs-sidebar > ul {
+ padding-left: 0;
+}
+
+.docs-sidebar li {
+ margin: 0.3rem 0;
+}
+
+.docs-sidebar a {
+ color: var(--text);
+ text-decoration: none;
+}
+
+.docs-sidebar a.router-link-active {
+ color: var(--accent);
+ font-weight: 600;
+}
+
+.docs-main {
+ padding: 2rem;
+}
+
+.docs-article {
+ max-width: 900px;
+ background: var(--panel);
+ border: 1px solid var(--line);
+ border-radius: 14px;
+ padding: 2rem;
+}
+
+.docs-article h1,
+.docs-article h2,
+.docs-article h3 {
+ margin-top: 1.5rem;
+}
+
+@media (max-width: 900px) {
+ .docs-layout {
+ grid-template-columns: 1fr;
+ }
+
+ .docs-aside {
+ position: static;
+ height: auto;
+ border-right: none;
+ border-bottom: 1px solid var(--line);
+ }
+
+ .docs-main {
+ padding: 1rem;
+ }
+
+ .docs-article {
+ padding: 1rem;
+ }
+}
diff --git a/docs-site/components/DocsSidebar.vue b/docs-site/components/DocsSidebar.vue
new file mode 100644
index 0000000..ef6f20d
--- /dev/null
+++ b/docs-site/components/DocsSidebar.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/docs-site/content/funktionen/backend-api.md b/docs-site/content/funktionen/backend-api.md
new file mode 100644
index 0000000..a07486b
--- /dev/null
+++ b/docs-site/content/funktionen/backend-api.md
@@ -0,0 +1,238 @@
+# Backend API Funktionskatalog
+
+Automatisch generiert (deterministisch, ohne Zeitstempel).
+
+Hinweis: Diese Datei wird durch `docs/scripts/sync-funktionsdoku.mjs` erzeugt.
+
+## backend/src/routes/admin.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/admin/add-user-to-tenant` |
+| POST | `/admin/customers/:customerId/invite-portal-user` |
+| GET | `/admin/overview` |
+| POST | `/admin/tenants` |
+| PUT | `/admin/tenants/:tenant_id` |
+| GET | `/admin/user-tenants/:user_id` |
+| POST | `/admin/users` |
+| PUT | `/admin/users/:user_id` |
+| PUT | `/admin/users/:user_id/access` |
+
+## backend/src/routes/auth/auth-authenticated.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/auth/password/change` |
+| POST | `/auth/refresh` |
+
+## backend/src/routes/auth/auth.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/auth/login` |
+| POST | `/auth/logout` |
+| POST | `/auth/password/reset` |
+| POST | `/auth/register` |
+
+## backend/src/routes/auth/me.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/me` |
+
+## backend/src/routes/auth/user.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/user/:id` |
+| PUT | `/user/:id/profile` |
+
+## backend/src/routes/banking.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/banking/iban/:iban` |
+| GET | `/banking/institutions/:bic` |
+| GET | `/banking/link/:institutionid` |
+| GET | `/banking/requisitions/:reqId` |
+| POST | `/banking/statements` |
+| DELETE | `/banking/statements/:id` |
+| GET | `/banking/statements/:id/suggestions` |
+
+## backend/src/routes/devices/rfid.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/rfid/createevent/:terminal_id` |
+
+## backend/src/routes/emailAsUser.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/email/accounts/:id?` |
+| POST | `/email/accounts/:id?` |
+| POST | `/email/send` |
+
+## backend/src/routes/exports.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/exports` |
+| POST | `/exports/datev` |
+| POST | `/exports/sepa` |
+
+## backend/src/routes/files.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/files/:id?` |
+| POST | `/files/download/:id?` |
+| POST | `/files/presigned/:id?` |
+| POST | `/files/upload` |
+
+## backend/src/routes/functions.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/functions/changelog` |
+| GET | `/functions/check-zip/:zip` |
+| POST | `/functions/pdf/:type` |
+| POST | `/functions/serial/finish/:execution_id` |
+| POST | `/functions/serial/start` |
+| POST | `/functions/services/backfillfiletext` |
+| POST | `/functions/services/bankstatementsync` |
+| POST | `/functions/services/prepareincominginvoices` |
+| POST | `/functions/services/syncdokubox` |
+| GET | `/functions/timeevaluation/:user_id` |
+| GET | `/functions/usenextnumber/:numberrange` |
+| POST | `/print/label` |
+
+## backend/src/routes/health.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/ping` |
+
+## backend/src/routes/helpdesk.inbound.email.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/helpdesk/inbound-email` |
+
+## backend/src/routes/helpdesk.inbound.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/helpdesk/inbound/:public_token` |
+
+## backend/src/routes/helpdesk.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/helpdesk/channels` |
+| POST | `/helpdesk/contacts` |
+| GET | `/helpdesk/conversations` |
+| POST | `/helpdesk/conversations` |
+| GET | `/helpdesk/conversations/:id` |
+| GET | `/helpdesk/conversations/:id/messages` |
+| POST | `/helpdesk/conversations/:id/messages` |
+| POST | `/helpdesk/conversations/:id/reply` |
+| PATCH | `/helpdesk/conversations/:id/status` |
+
+## backend/src/routes/history.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/history` |
+
+## backend/src/routes/internal/auth.m2m.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/auth/m2m/token` |
+
+## backend/src/routes/internal/tenant.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/tenant/:id` |
+| GET | `/tenant/:id/profiles` |
+| GET | `/tenant/users` |
+
+## backend/src/routes/internal/time.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/staff/time/event` |
+| GET | `/staff/time/spans` |
+
+## backend/src/routes/notifications.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/notifications/trigger` |
+
+## backend/src/routes/profiles.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/profiles/:id` |
+| PUT | `/profiles/:id` |
+
+## backend/src/routes/publiclinks/publiclinks-authenticated.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/publiclinks` |
+
+## backend/src/routes/publiclinks/publiclinks-non-authenticated.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/workflows/context/:token` |
+| POST | `/workflows/submit/:token` |
+
+## backend/src/routes/resources/main.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/resource/:resource` |
+| POST | `/resource/:resource` |
+| PUT | `/resource/:resource/:id` |
+| GET | `/resource/:resource/:id/:no_relations?` |
+| GET | `/resource/:resource/paginated` |
+
+## backend/src/routes/resourcesSpecial.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/resource-special/:resource` |
+
+## backend/src/routes/staff/time.ts
+
+| Methode | Pfad |
+|---|---|
+| POST | `/staff/time/approve` |
+| POST | `/staff/time/edit` |
+| GET | `/staff/time/evaluation` |
+| POST | `/staff/time/event` |
+| POST | `/staff/time/reject` |
+| GET | `/staff/time/spans` |
+| POST | `/staff/time/submit` |
+
+## backend/src/routes/tenant.ts
+
+| Methode | Pfad |
+|---|---|
+| GET | `/tenant` |
+| GET | `/tenant/api-keys` |
+| POST | `/tenant/api-keys` |
+| DELETE | `/tenant/api-keys/:id` |
+| PATCH | `/tenant/api-keys/:id` |
+| PUT | `/tenant/numberrange/:numberrange` |
+| PUT | `/tenant/other/:id` |
+| GET | `/tenant/profiles` |
+| POST | `/tenant/switch` |
+| GET | `/tenant/users` |
+
+Gesamtzahl erkannter Endpunkte: **93**
diff --git a/docs-site/content/funktionen/frontend-web.md b/docs-site/content/funktionen/frontend-web.md
new file mode 100644
index 0000000..ea50a55
--- /dev/null
+++ b/docs-site/content/funktionen/frontend-web.md
@@ -0,0 +1,70 @@
+# Frontend Web Funktionskatalog
+
+Automatisch generiert (deterministisch, ohne Zeitstempel).
+
+Hinweis: Diese Datei wird durch `docs/scripts/sync-funktionsdoku.mjs` erzeugt.
+
+| Route (Nuxt) | Datei |
+|---|---|
+| `/` | `frontend/pages/index.client.vue` |
+| `/accounting/bwa` | `frontend/pages/accounting/bwa.vue` |
+| `/accounting/depreciation` | `frontend/pages/accounting/depreciation.vue` |
+| `/accounting/tax` | `frontend/pages/accounting/tax.vue` |
+| `/accounts` | `frontend/pages/accounts/index.vue` |
+| `/accounts/show/:id` | `frontend/pages/accounts/show/[id].vue` |
+| `/administration/tenants` | `frontend/pages/administration/tenants/index.vue` |
+| `/administration/tenants/:id` | `frontend/pages/administration/tenants/[id].vue` |
+| `/administration/users` | `frontend/pages/administration/users/index.vue` |
+| `/administration/users/:id` | `frontend/pages/administration/users/[id].vue` |
+| `/banking` | `frontend/pages/banking/index.vue` |
+| `/banking/statements/:mode/:id?` | `frontend/pages/banking/statements/[mode]/[[id]].vue` |
+| `/calendar/:mode` | `frontend/pages/calendar/[mode].vue` |
+| `/createdletters/:mode/:id?` | `frontend/pages/createdletters/[mode]/[[id]].vue` |
+| `/createDocument` | `frontend/pages/createDocument/index.vue` |
+| `/createDocument/edit/:id?` | `frontend/pages/createDocument/edit/[[id]].vue` |
+| `/createDocument/serialInvoice` | `frontend/pages/createDocument/serialInvoice.vue` |
+| `/createDocument/show/:id` | `frontend/pages/createDocument/show/[id].vue` |
+| `/customer-portal` | `frontend/pages/customer-portal.vue` |
+| `/email/new` | `frontend/pages/email/new.vue` |
+| `/export` | `frontend/pages/export/index.vue` |
+| `/export/create/sepa` | `frontend/pages/export/create/sepa.vue` |
+| `/files` | `frontend/pages/files/index.vue` |
+| `/forms` | `frontend/pages/forms.vue` |
+| `/helpdesk/:id?` | `frontend/pages/helpdesk/[[id]].vue` |
+| `/historyitems` | `frontend/pages/historyitems/index.vue` |
+| `/incomingInvoices` | `frontend/pages/incomingInvoices/index.vue` |
+| `/incomingInvoices/:mode/:id` | `frontend/pages/incomingInvoices/[mode]/[id].vue` |
+| `/login` | `frontend/pages/login.vue` |
+| `/organisation/plantafel` | `frontend/pages/organisation/plantafel.vue` |
+| `/password-change` | `frontend/pages/password-change.vue` |
+| `/password-reset` | `frontend/pages/password-reset.vue` |
+| `/projecttypes` | `frontend/pages/projecttypes/index.vue` |
+| `/projecttypes/:mode/:id?` | `frontend/pages/projecttypes/[mode]/[[id]].vue` |
+| `/roles` | `frontend/pages/roles/index.vue` |
+| `/roles/:mode/:id?` | `frontend/pages/roles/[mode]/[[id]].vue` |
+| `/settings` | `frontend/pages/settings/index.vue` |
+| `/settings/admin` | `frontend/pages/settings/admin.vue` |
+| `/settings/banking` | `frontend/pages/settings/banking/index.vue` |
+| `/settings/emailaccounts` | `frontend/pages/settings/emailaccounts/index.vue` |
+| `/settings/emailaccounts/:mode/:id?` | `frontend/pages/settings/emailaccounts/[mode]/[[id]].vue` |
+| `/settings/externalDevices` | `frontend/pages/settings/externalDevices.vue` |
+| `/settings/numberRanges` | `frontend/pages/settings/numberRanges.vue` |
+| `/settings/ownfields` | `frontend/pages/settings/ownfields.vue` |
+| `/settings/tenant` | `frontend/pages/settings/tenant.vue` |
+| `/settings/texttemplates` | `frontend/pages/settings/texttemplates.vue` |
+| `/staff/profiles` | `frontend/pages/staff/profiles/index.vue` |
+| `/staff/profiles/:id` | `frontend/pages/staff/profiles/[id].vue` |
+| `/staff/time` | `frontend/pages/staff/time/index.vue` |
+| `/staff/time/:id/evaluate` | `frontend/pages/staff/time/[id]/evaluate.vue` |
+| `/standardEntity/:type` | `frontend/pages/standardEntity/[type]/index.vue` |
+| `/standardEntity/:type/:mode/:id?` | `frontend/pages/standardEntity/[type]/[mode]/[[id]].vue` |
+| `/support` | `frontend/pages/support/index.vue` |
+| `/support/:id` | `frontend/pages/support/[id].vue` |
+| `/support/create` | `frontend/pages/support/create.vue` |
+| `/tasks` | `frontend/pages/tasks/index.vue` |
+| `/tasks/:mode/:id?` | `frontend/pages/tasks/[mode]/[[id]].vue` |
+| `/test` | `frontend/pages/test.vue` |
+| `/wiki/:id?` | `frontend/pages/wiki/[[id]].vue` |
+| `/workflows/:token` | `frontend/pages/workflows/[token].vue` |
+
+Gesamtzahl erkannter Web-Routen: **60**
diff --git a/docs-site/content/funktionen/index.md b/docs-site/content/funktionen/index.md
new file mode 100644
index 0000000..25796a5
--- /dev/null
+++ b/docs-site/content/funktionen/index.md
@@ -0,0 +1,23 @@
+# Funktionen
+
+Diese Sektion dokumentiert alle Funktionen der FEDEO-Software in drei Ebenen:
+
+- Fachliche Übersicht: `uebersicht.md`
+- Technischer API-Katalog: `backend-api.md`
+- Technischer Web-Katalog: `frontend-web.md`
+- Technischer Mobile-Katalog: `mobile-app.md`
+
+## Empfohlene Lesereihenfolge
+
+1. `uebersicht.md`
+2. `backend-api.md`
+3. `frontend-web.md`
+4. `mobile-app.md`
+
+## Aktualisierung
+
+Die technischen Kataloge werden mit folgendem Befehl aktualisiert:
+
+```bash
+node docs/scripts/sync-funktionsdoku.mjs
+```
diff --git a/docs-site/content/funktionen/mobile-app.md b/docs-site/content/funktionen/mobile-app.md
new file mode 100644
index 0000000..300d838
--- /dev/null
+++ b/docs-site/content/funktionen/mobile-app.md
@@ -0,0 +1,29 @@
+# Mobile App Funktionskatalog
+
+Automatisch generiert (deterministisch, ohne Zeitstempel).
+
+Hinweis: Diese Datei wird durch `docs/scripts/sync-funktionsdoku.mjs` erzeugt.
+
+| Route (Expo Router) | Datei |
+|---|---|
+| `/` | `mobile/app/index.tsx` |
+| `/(tabs)` | `mobile/app/(tabs)/index.tsx` |
+| `/(tabs)/explore` | `mobile/app/(tabs)/explore.tsx` |
+| `/(tabs)/projects` | `mobile/app/(tabs)/projects.tsx` |
+| `/(tabs)/tasks` | `mobile/app/(tabs)/tasks.tsx` |
+| `/(tabs)/time` | `mobile/app/(tabs)/time.tsx` |
+| `/login` | `mobile/app/login.tsx` |
+| `/modal` | `mobile/app/modal.tsx` |
+| `/more/account` | `mobile/app/more/account.tsx` |
+| `/more/customer/:id` | `mobile/app/more/customer/[id].tsx` |
+| `/more/customers` | `mobile/app/more/customers.tsx` |
+| `/more/inventory` | `mobile/app/more/inventory.tsx` |
+| `/more/nimbot` | `mobile/app/more/nimbot.tsx` |
+| `/more/plant/:id` | `mobile/app/more/plant/[id].tsx` |
+| `/more/plants` | `mobile/app/more/plants.tsx` |
+| `/more/settings` | `mobile/app/more/settings.tsx` |
+| `/more/wiki` | `mobile/app/more/wiki.tsx` |
+| `/project/:id` | `mobile/app/project/[id].tsx` |
+| `/tenant-select` | `mobile/app/tenant-select.tsx` |
+
+Gesamtzahl erkannter Mobile-Screens: **19**
diff --git a/docs-site/content/funktionen/uebersicht.md b/docs-site/content/funktionen/uebersicht.md
new file mode 100644
index 0000000..971aaf3
--- /dev/null
+++ b/docs-site/content/funktionen/uebersicht.md
@@ -0,0 +1,70 @@
+# Funktionsübersicht
+
+## Zielbild
+
+FEDEO besteht funktional aus drei zentralen Schichten:
+
+- Backend-API (Geschäftslogik, Daten, Integrationen)
+- Web-Frontend (administrative und operative Arbeitsoberfläche)
+- Mobile-App (mobile Nutzung für operative Prozesse)
+
+Die technische Detailauflistung wird automatisiert erzeugt:
+
+- [Backend-API](./backend-api.md)
+- [Frontend Web](./frontend-web.md)
+- [Mobile-App](./mobile-app.md)
+
+## Funktionsbereiche
+
+### 1) Authentifizierung und Mandantenfähigkeit
+
+- Login, Session, Nutzerkontext
+- Rollen, Rechte, Profile
+- Mandantenbezogene Datenabgrenzung
+
+### 2) Stammdaten und Ressourcen
+
+- Kunden, Kontakte, Projekte, Teams
+- Materialien, Leistungen, Fahrzeuge, Standorte
+- Erweiterbare Standard-Entitäten
+
+### 3) Operative Prozesse
+
+- Aufgabenmanagement
+- Zeiterfassung und Zeitauswertung
+- Dokumentenerstellung und Ablage
+- Verlauf/Historie
+
+### 4) Finanz- und Abrechnungsfunktionen
+
+- Buchhaltungssichten
+- Bankdaten und Zuordnungen
+- Exporte (z. B. DATEV/SEPA)
+- Rechnungskontexte
+
+### 5) Kommunikation und Service
+
+- Helpdesk und Nachrichten
+- Benachrichtigungen
+- E-Mail-bezogene Prozesse
+
+### 6) Wissensmanagement
+
+- Wiki-Seiten
+- Strukturierte Inhalte für internes Wissen
+
+### 7) Geräteschnittstellen und Integrationen
+
+- RFID-/Geräteendpunkte
+- S3-Dateispeicher
+- Mail- und externe API-Integrationen
+
+## Dokumentationsprinzip
+
+- Fachliche Beschreibung in dieser Datei
+- Technische Vollständigkeit in den automatisch erzeugten Katalogen
+- Änderungsnachweis über die Doku-Versionierung
+
+## Pflegehinweis
+
+Wenn Funktionen hinzugefügt, umbenannt oder entfernt werden, ist die technische Dokumentation immer per Skript zu aktualisieren und zu committen.
diff --git a/docs-site/content/index.md b/docs-site/content/index.md
new file mode 100644
index 0000000..e3a802b
--- /dev/null
+++ b/docs-site/content/index.md
@@ -0,0 +1,46 @@
+# FEDEO Funktionsdokumentation
+
+Diese Dokumentation bildet alle Funktionen der Software zentral ab und ist für die Nutzung in der Nuxt-Content-Docs-Homepage vorbereitet.
+
+## Ziel
+
+- Vollständige Übersicht über Funktionen in Backend, Web-Frontend und Mobile-App
+- Nachvollziehbare Versionierung der Doku
+- Einfache Aktualisierung bei Funktionsänderungen
+
+## Struktur
+
+- `docs/funktionen/uebersicht.md`: Fachliche Gesamtübersicht der Bereiche
+- `docs/funktionen/backend-api.md`: Automatisch erzeugte API-Funktionsliste
+- `docs/funktionen/frontend-web.md`: Automatisch erzeugte Seiten-/Funktionsliste des Web-Frontends
+- `docs/funktionen/mobile-app.md`: Automatisch erzeugte Screens-/Funktionsliste der Mobile-App
+- `docs/versionen/docs-versionen.md`: Versionierung der Dokumentation
+- `docs/wartung/dokumentationsprozess.md`: Prozess, damit die Doku dauerhaft aktuell bleibt
+- `docs/scripts/sync-funktionsdoku.mjs`: Skript zur automatischen Aktualisierung
+
+## Aktualisierung bei Funktionsänderungen
+
+Bei jeder Funktionsänderung bitte ausführen:
+
+```bash
+node docs/scripts/sync-funktionsdoku.mjs
+```
+
+Danach:
+
+1. Änderungen in `docs/funktionen/*.md` prüfen
+2. Falls nötig fachliche Texte in `docs/funktionen/uebersicht.md` ergänzen
+3. Eintrag in `docs/versionen/docs-versionen.md` ergänzen
+4. Alles gemeinsam committen
+
+## Verwendung mit Nuxt Content
+
+Empfohlene Vorgehensweise:
+
+1. `docs/` in das Content-Verzeichnis übernehmen (oder per Sync einbinden)
+2. Navigation anhand der Ordner `funktionen`, `wartung`, `versionen` aufbauen
+3. `backend-api.md`, `frontend-web.md`, `mobile-app.md` als referenzierende Funktionskataloge einbinden
+
+## Hinweis
+
+Die Dateien `backend-api.md`, `frontend-web.md` und `mobile-app.md` werden automatisch generiert. Manuelle Änderungen in diesen Dateien werden bei der nächsten Synchronisation überschrieben.
diff --git a/docs-site/content/versionen/docs-versionen.md b/docs-site/content/versionen/docs-versionen.md
new file mode 100644
index 0000000..354b5cf
--- /dev/null
+++ b/docs-site/content/versionen/docs-versionen.md
@@ -0,0 +1,25 @@
+# Doku-Versionen
+
+## Version 0.1.0 (2026-04-21)
+
+- Grundstruktur der vollständigen Funktionsdokumentation erstellt
+- Automatische Erzeugung für Backend-API, Frontend-Web und Mobile-App eingeführt
+- Wartungsprozess für laufende Aktualisierung definiert
+
+## Versionsschema
+
+Empfohlenes Schema: `MAJOR.MINOR.PATCH`
+
+- `MAJOR`: Grundlegende Umstrukturierung der Doku
+- `MINOR`: Neue Funktionsbereiche oder größere Ergänzungen
+- `PATCH`: Korrekturen, Präzisierungen, kleinere Ergänzungen
+
+## Eintragsvorlage
+
+```md
+## Version X.Y.Z (YYYY-MM-DD)
+
+- Änderung 1
+- Änderung 2
+- Änderung 3
+```
diff --git a/docs-site/content/wartung/dokumentationsprozess.md b/docs-site/content/wartung/dokumentationsprozess.md
new file mode 100644
index 0000000..3f804b5
--- /dev/null
+++ b/docs-site/content/wartung/dokumentationsprozess.md
@@ -0,0 +1,35 @@
+# Dokumentationsprozess
+
+## Zweck
+
+Dieser Prozess stellt sicher, dass die Funktionsdokumentation bei jeder Änderung aktuell bleibt.
+
+## Verbindlicher Ablauf bei Funktionsänderungen
+
+1. Funktion implementieren oder ändern
+2. Technische Doku synchronisieren:
+
+```bash
+node docs/scripts/sync-funktionsdoku.mjs
+```
+
+3. Fachliche Beschreibung in `docs/funktionen/uebersicht.md` ergänzen, falls ein neuer Bereich entsteht
+4. Neue Doku-Version in `docs/versionen/docs-versionen.md` eintragen
+5. Code und Doku gemeinsam committen
+
+## Was als Funktionsänderung gilt
+
+- Neue API-Route oder geänderte API-Route
+- Neue Web-Seite oder geänderte Seitenstruktur
+- Neuer Mobile-Screen oder geänderte Navigationsstruktur
+- Größere fachliche Änderung in bestehenden Modulen
+
+## Qualitätsregeln
+
+- Automatisch erzeugte Dateien nicht manuell pflegen
+- Fachliche Begriffe konsistent halten
+- Jede Doku-Version erhält Datum, Änderungszusammenfassung und Bezug zu Commits
+
+## CI-Empfehlung
+
+Optional kann in CI geprüft werden, ob die generierten Doku-Dateien aktuell sind (z. B. per Diff nach Skriptlauf), damit keine Funktionsänderung ohne Doku-Update gemerged wird.
diff --git a/docs-site/docusaurus.config.ts b/docs-site/docusaurus.config.ts
deleted file mode 100644
index 91deea4..0000000
--- a/docs-site/docusaurus.config.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import type { Config } from '@docusaurus/types';
-import { themes as prismThemes } from 'prism-react-renderer';
-
-const config: Config = {
- title: 'FEDEO Docs',
- tagline: 'Versionierte Funktionsdokumentation für FEDEO',
-
- url: 'https://app.fedeo.de',
- baseUrl: '/docs/',
-
- onBrokenLinks: 'throw',
- markdown: {
- hooks: {
- onBrokenMarkdownLinks: 'warn',
- },
- },
-
- i18n: {
- defaultLocale: 'de',
- locales: ['de'],
- },
-
- presets: [
- [
- 'classic',
- {
- docs: {
- path: '../docs',
- routeBasePath: '/',
- sidebarPath: './sidebars.ts',
- editUrl: 'https://github.com/DEIN-ORG/DEIN-REPO/tree/main/',
- },
- blog: false,
- theme: {
- customCss: './src/css/custom.css',
- },
- },
- ],
- ],
-
- themeConfig: {
- navbar: {
- title: 'FEDEO Docs',
- items: [
- {
- type: 'docSidebar',
- sidebarId: 'docsSidebar',
- position: 'left',
- label: 'Dokumentation',
- },
- {
- href: 'https://github.com/DEIN-ORG/DEIN-REPO',
- label: 'GitHub',
- position: 'right',
- },
- ],
- },
- footer: {
- style: 'dark',
- links: [
- {
- title: 'Dokumentation',
- items: [
- {
- label: 'Funktionsübersicht',
- to: '/funktionen/uebersicht',
- },
- ],
- },
- {
- title: 'Projekt',
- items: [
- {
- label: 'Repository',
- href: 'https://github.com/DEIN-ORG/DEIN-REPO',
- },
- ],
- },
- ],
- copyright: `Copyright © ${new Date().getFullYear()} FEDEO`,
- },
- prism: {
- theme: prismThemes.github,
- darkTheme: prismThemes.dracula,
- },
- },
-};
-
-export default config;
diff --git a/docs-site/nginx.conf b/docs-site/nginx.conf
deleted file mode 100644
index 61cb853..0000000
--- a/docs-site/nginx.conf
+++ /dev/null
@@ -1,16 +0,0 @@
-server {
- listen 80;
- server_name _;
-
- root /usr/share/nginx/html;
- index index.html;
-
- location / {
- try_files $uri $uri/ /index.html;
- }
-
- location ~* \.(?:css|js|map|jpg|jpeg|gif|png|svg|ico|webp|woff2?)$ {
- expires 30d;
- add_header Cache-Control "public, immutable";
- }
-}
diff --git a/docs-site/nuxt.config.ts b/docs-site/nuxt.config.ts
new file mode 100644
index 0000000..1c25006
--- /dev/null
+++ b/docs-site/nuxt.config.ts
@@ -0,0 +1,22 @@
+export default defineNuxtConfig({
+ modules: ['@nuxt/content'],
+ css: ['~/assets/css/main.css'],
+ app: {
+ head: {
+ title: 'FEDEO Docs',
+ meta: [
+ { name: 'description', content: 'Versionierte FEDEO-Dokumentation auf Nuxt Content.' }
+ ]
+ }
+ },
+ content: {
+ documentDriven: false,
+ highlight: {
+ theme: 'github-light'
+ }
+ },
+ nitro: {
+ preset: 'node-server'
+ },
+ compatibilityDate: '2025-01-01'
+})
diff --git a/docs-site/package.json b/docs-site/package.json
index c2707e3..52a3c47 100644
--- a/docs-site/package.json
+++ b/docs-site/package.json
@@ -1,32 +1,15 @@
{
"name": "fedeo-docs-site",
- "version": "1.0.0",
+ "version": "2.0.0",
"private": true,
"scripts": {
- "start": "docusaurus start --host 0.0.0.0 --port 3005",
- "build": "docusaurus build",
- "serve": "docusaurus serve --host 0.0.0.0 --port 3005",
- "clear": "docusaurus clear",
- "swizzle": "docusaurus swizzle",
- "deploy": "docusaurus deploy"
+ "dev": "node ./scripts/sync-content.mjs && nuxi dev --host 0.0.0.0 --port 3005",
+ "build": "node ./scripts/sync-content.mjs && nuxi build",
+ "preview": "nuxi preview --host 0.0.0.0 --port 3005"
},
"dependencies": {
- "@docusaurus/core": "3.9.2",
- "@docusaurus/preset-classic": "3.9.2",
- "clsx": "^2.1.1",
- "prism-react-renderer": "^2.4.1",
- "react": "^19.1.1",
- "react-dom": "^19.1.1"
- },
- "devDependencies": {
- "typescript": "^5.8.3",
- "@docusaurus/module-type-aliases": "3.9.2",
- "@types/react": "^19.1.12",
- "@types/react-dom": "^19.1.9"
- },
- "overrides": {
- "webpack": "5.95.0",
- "webpackbar": "6.0.1"
+ "nuxt": "^3.17.7",
+ "@nuxt/content": "^2.13.4"
},
"engines": {
"node": ">=20.0"
diff --git a/docs-site/pages/[...slug].vue b/docs-site/pages/[...slug].vue
new file mode 100644
index 0000000..28434c9
--- /dev/null
+++ b/docs-site/pages/[...slug].vue
@@ -0,0 +1,30 @@
+
+
+
+
+
diff --git a/docs-site/pages/index.vue b/docs-site/pages/index.vue
new file mode 100644
index 0000000..5ee5f90
--- /dev/null
+++ b/docs-site/pages/index.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/docs-site/scripts/sync-content.mjs b/docs-site/scripts/sync-content.mjs
new file mode 100755
index 0000000..e8383c4
--- /dev/null
+++ b/docs-site/scripts/sync-content.mjs
@@ -0,0 +1,62 @@
+#!/usr/bin/env node
+
+import { promises as fs } from 'node:fs'
+import path from 'node:path'
+
+const ROOT = process.cwd()
+const DOCS_SOURCE = path.resolve(ROOT, '../docs')
+const CONTENT_TARGET = path.resolve(ROOT, 'content')
+
+async function ensureDir(dirPath) {
+ await fs.mkdir(dirPath, { recursive: true })
+}
+
+async function clearDir(dirPath) {
+ await fs.rm(dirPath, { recursive: true, force: true })
+ await ensureDir(dirPath)
+}
+
+async function walk(dir) {
+ const entries = await fs.readdir(dir, { withFileTypes: true })
+ const out = []
+ for (const entry of entries) {
+ const full = path.join(dir, entry.name)
+ if (entry.isDirectory()) {
+ out.push(...(await walk(full)))
+ } else if (entry.isFile() && entry.name.endsWith('.md')) {
+ out.push(full)
+ }
+ }
+ return out
+}
+
+function toPosix(p) {
+ return p.split(path.sep).join('/')
+}
+
+async function main() {
+ await clearDir(CONTENT_TARGET)
+ const files = await walk(DOCS_SOURCE)
+
+ for (const file of files) {
+ const rel = toPosix(path.relative(DOCS_SOURCE, file))
+ let targetRel = rel
+
+ if (rel === 'README.md') {
+ targetRel = 'index.md'
+ } else if (rel.endsWith('/README.md')) {
+ targetRel = `${rel.slice(0, -'/README.md'.length)}/index.md`
+ }
+
+ const target = path.join(CONTENT_TARGET, targetRel)
+ await ensureDir(path.dirname(target))
+ await fs.copyFile(file, target)
+ }
+
+ console.log(`Nuxt-Content Synchronisierung abgeschlossen: ${files.length} Dateien`)
+}
+
+main().catch((err) => {
+ console.error('Fehler bei der Content-Synchronisierung', err)
+ process.exit(1)
+})
diff --git a/docs-site/sidebars.ts b/docs-site/sidebars.ts
deleted file mode 100644
index 50299c2..0000000
--- a/docs-site/sidebars.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
-
-const sidebars: SidebarsConfig = {
- docsSidebar: [{ type: 'autogenerated', dirName: '.' }],
-};
-
-export default sidebars;
diff --git a/docs-site/src/css/custom.css b/docs-site/src/css/custom.css
deleted file mode 100644
index c20ba78..0000000
--- a/docs-site/src/css/custom.css
+++ /dev/null
@@ -1,36 +0,0 @@
-:root {
- --ifm-color-primary: #0b6e4f;
- --ifm-color-primary-dark: #0a6348;
- --ifm-color-primary-darker: #095d44;
- --ifm-color-primary-darkest: #074c37;
- --ifm-color-primary-light: #0c7956;
- --ifm-color-primary-lighter: #0d7f5a;
- --ifm-color-primary-lightest: #0f8f66;
- --ifm-background-color: #f6f8f7;
- --ifm-font-family-base: 'Atkinson Hyperlegible', 'Source Sans 3', system-ui, sans-serif;
- --ifm-heading-font-family: 'IBM Plex Sans', 'Source Sans 3', system-ui, sans-serif;
-}
-
-.heroSection {
- min-height: calc(100vh - 60px);
- display: grid;
- place-items: center;
- background:
- radial-gradient(circle at 80% 20%, rgba(11, 110, 79, 0.2), transparent 40%),
- radial-gradient(circle at 20% 80%, rgba(25, 130, 196, 0.2), transparent 35%),
- linear-gradient(160deg, #eef6f3 0%, #f8faf9 100%);
-}
-
-.heroSection h1 {
- font-size: clamp(2rem, 6vw, 3.6rem);
- margin-bottom: 0.75rem;
-}
-
-.heroSection p {
- font-size: clamp(1.05rem, 2.2vw, 1.35rem);
- max-width: 680px;
-}
-
-.heroButtons {
- margin-top: 1.4rem;
-}
diff --git a/docs-site/static/img/.gitkeep b/docs-site/static/img/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/docs-site/tsconfig.json b/docs-site/tsconfig.json
index ccaa2d6..0819810 100644
--- a/docs-site/tsconfig.json
+++ b/docs-site/tsconfig.json
@@ -1,7 +1,5 @@
{
- "extends": "@docusaurus/tsconfig",
"compilerOptions": {
- "baseUrl": "."
- },
- "exclude": ["build", "node_modules"]
+ "types": ["@types/node"]
+ }
}
diff --git a/docs/README.md b/docs/README.md
index 2bab4c0..e3a802b 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,6 +1,6 @@
# FEDEO Funktionsdokumentation
-Diese Dokumentation bildet alle Funktionen der Software zentral ab und ist für die spätere Nutzung auf einer eigenen Docs-Homepage vorbereitet, z. B. mit Nuxt Content oder Docusaurus.
+Diese Dokumentation bildet alle Funktionen der Software zentral ab und ist für die Nutzung in der Nuxt-Content-Docs-Homepage vorbereitet.
## Ziel
@@ -41,14 +41,6 @@ Empfohlene Vorgehensweise:
2. Navigation anhand der Ordner `funktionen`, `wartung`, `versionen` aufbauen
3. `backend-api.md`, `frontend-web.md`, `mobile-app.md` als referenzierende Funktionskataloge einbinden
-## Verwendung mit Docusaurus
-
-Empfohlene Vorgehensweise:
-
-1. Inhalte aus `docs/` in den Docusaurus-`docs`-Ordner übernehmen
-2. Sidebar nach den Bereichen `Funktionen`, `Wartung`, `Versionen` strukturieren
-3. Die automatisch erzeugten Dateien als technische Referenzseiten markieren
-
## Hinweis
Die Dateien `backend-api.md`, `frontend-web.md` und `mobile-app.md` werden automatisch generiert. Manuelle Änderungen in diesen Dateien werden bei der nächsten Synchronisation überschrieben.