diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..2bab4c0 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,54 @@ +# 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. + +## 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 + +## 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. diff --git a/docs/funktionen/backend-api.md b/docs/funktionen/backend-api.md new file mode 100644 index 0000000..3424bb0 --- /dev/null +++ b/docs/funktionen/backend-api.md @@ -0,0 +1,238 @@ +# Backend API Funktionskatalog + +Automatisch generiert am: 2026-04-21T17:33:18.397Z + +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/funktionen/frontend-web.md b/docs/funktionen/frontend-web.md new file mode 100644 index 0000000..deea323 --- /dev/null +++ b/docs/funktionen/frontend-web.md @@ -0,0 +1,70 @@ +# Frontend Web Funktionskatalog + +Automatisch generiert am: 2026-04-21T17:33:18.423Z + +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/funktionen/index.md b/docs/funktionen/index.md new file mode 100644 index 0000000..25796a5 --- /dev/null +++ b/docs/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/funktionen/mobile-app.md b/docs/funktionen/mobile-app.md new file mode 100644 index 0000000..3097c4b --- /dev/null +++ b/docs/funktionen/mobile-app.md @@ -0,0 +1,29 @@ +# Mobile App Funktionskatalog + +Automatisch generiert am: 2026-04-21T17:33:18.425Z + +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/funktionen/uebersicht.md b/docs/funktionen/uebersicht.md new file mode 100644 index 0000000..971aaf3 --- /dev/null +++ b/docs/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/scripts/sync-funktionsdoku.mjs b/docs/scripts/sync-funktionsdoku.mjs new file mode 100755 index 0000000..491b925 --- /dev/null +++ b/docs/scripts/sync-funktionsdoku.mjs @@ -0,0 +1,234 @@ +#!/usr/bin/env node + +import { promises as fs } from "node:fs"; +import path from "node:path"; + +const ROOT = process.cwd(); +const DOCS_DIR = path.join(ROOT, "docs"); + +const BACKEND_ROUTES_DIR = path.join(ROOT, "backend", "src", "routes"); +const FRONTEND_PAGES_DIR = path.join(ROOT, "frontend", "pages"); +const MOBILE_APP_DIR = path.join(ROOT, "mobile", "app"); + +const OUT_BACKEND = path.join(DOCS_DIR, "funktionen", "backend-api.md"); +const OUT_FRONTEND = path.join(DOCS_DIR, "funktionen", "frontend-web.md"); +const OUT_MOBILE = path.join(DOCS_DIR, "funktionen", "mobile-app.md"); + +const HTTP_METHODS = ["get", "post", "put", "patch", "delete", "options", "head"]; + +async function walkFiles(dir, extension) { + const result = []; + + async function walk(current) { + const entries = await fs.readdir(current, { withFileTypes: true }); + + for (const entry of entries) { + const full = path.join(current, entry.name); + if (entry.isDirectory()) { + await walk(full); + } else if (entry.isFile() && full.endsWith(extension)) { + result.push(full); + } + } + } + + await walk(dir); + return result.sort(); +} + +function normalizePosix(p) { + return p.split(path.sep).join("/"); +} + +function toRelative(filePath) { + return normalizePosix(path.relative(ROOT, filePath)); +} + +function extractBackendEndpoints(sourceText) { + const endpoints = []; + const regex = /\b(?:server|subApp|m2mApp|devicesApp)\.(get|post|put|patch|delete|options|head)\(\s*["'`](.+?)["'`]/g; + + let match; + while ((match = regex.exec(sourceText)) !== null) { + const method = String(match[1] || "").toUpperCase(); + const routePath = String(match[2] || ""); + if (!HTTP_METHODS.includes(method.toLowerCase())) { + continue; + } + endpoints.push({ method, path: routePath }); + } + + return endpoints.sort((a, b) => { + if (a.path === b.path) { + return a.method.localeCompare(b.method); + } + return a.path.localeCompare(b.path); + }); +} + +function sortAndUnique(items) { + return [...new Set(items)].sort((a, b) => a.localeCompare(b)); +} + +function filePathToNuxtRoute(filePath, baseDir) { + const relative = normalizePosix(path.relative(baseDir, filePath)); + let route = relative.replace(/\.vue$/, ""); + route = route.replace(/\.client$/, "").replace(/\.server$/, ""); + + route = route + .replace(/\[\[\.\.\.(.+?)\]\]/g, ":$1*?") + .replace(/\[\.\.\.(.+?)\]/g, ":$1*") + .replace(/\[\[(.+?)\]\]/g, ":$1?") + .replace(/\[(.+?)\]/g, ":$1"); + + route = route.replace(/\/index$/g, ""); + if (route === "index") { + route = ""; + } + + if (!route.startsWith("/")) { + route = `/${route}`; + } + + if (route === "") { + return "/"; + } + + return route || "/"; +} + +function filePathToExpoRoute(filePath, baseDir) { + const relative = normalizePosix(path.relative(baseDir, filePath)); + const baseName = path.basename(relative); + + if (baseName.startsWith("_")) { + return null; + } + + let route = relative.replace(/\.tsx$/, ""); + + route = route + .replace(/\[\[(.+?)\]\]/g, ":$1?") + .replace(/\[(.+?)\]/g, ":$1"); + + route = route.replace(/\/index$/g, ""); + if (route === "index") { + route = ""; + } + + if (!route.startsWith("/")) { + route = `/${route}`; + } + + if (route === "") { + return "/"; + } + + return route; +} + +async function generateBackendDoc() { + const files = await walkFiles(BACKEND_ROUTES_DIR, ".ts"); + const generatedAt = new Date().toISOString(); + + let output = "# Backend API Funktionskatalog\n\n"; + output += `Automatisch generiert am: ${generatedAt}\n\n`; + output += "Hinweis: Diese Datei wird durch `docs/scripts/sync-funktionsdoku.mjs` erzeugt.\n\n"; + + const allEndpoints = []; + + for (const file of files) { + const source = await fs.readFile(file, "utf-8"); + const endpoints = extractBackendEndpoints(source); + const relativeFile = toRelative(file); + + if (endpoints.length === 0) { + continue; + } + + output += `## ${relativeFile}\n\n`; + output += "| Methode | Pfad |\n"; + output += "|---|---|\n"; + + for (const endpoint of endpoints) { + output += `| ${endpoint.method} | \`${endpoint.path}\` |\n`; + allEndpoints.push(`${endpoint.method} ${endpoint.path}`); + } + + output += "\n"; + } + + const uniqueCount = sortAndUnique(allEndpoints).length; + output += `Gesamtzahl erkannter Endpunkte: **${uniqueCount}**\n`; + + await fs.writeFile(OUT_BACKEND, output, "utf-8"); +} + +async function generateFrontendDoc() { + const files = await walkFiles(FRONTEND_PAGES_DIR, ".vue"); + const generatedAt = new Date().toISOString(); + + const rows = files.map((file) => { + const route = filePathToNuxtRoute(file, FRONTEND_PAGES_DIR); + return { route, file: toRelative(file) }; + }); + + rows.sort((a, b) => a.route.localeCompare(b.route)); + + let output = "# Frontend Web Funktionskatalog\n\n"; + output += `Automatisch generiert am: ${generatedAt}\n\n`; + output += "Hinweis: Diese Datei wird durch `docs/scripts/sync-funktionsdoku.mjs` erzeugt.\n\n"; + output += "| Route (Nuxt) | Datei |\n"; + output += "|---|---|\n"; + + for (const row of rows) { + output += `| \`${row.route}\` | \`${row.file}\` |\n`; + } + + output += `\nGesamtzahl erkannter Web-Routen: **${rows.length}**\n`; + + await fs.writeFile(OUT_FRONTEND, output, "utf-8"); +} + +async function generateMobileDoc() { + const files = await walkFiles(MOBILE_APP_DIR, ".tsx"); + const generatedAt = new Date().toISOString(); + + const rows = files + .map((file) => { + const route = filePathToExpoRoute(file, MOBILE_APP_DIR); + if (!route) { + return null; + } + return { route, file: toRelative(file) }; + }) + .filter(Boolean); + + rows.sort((a, b) => a.route.localeCompare(b.route)); + + let output = "# Mobile App Funktionskatalog\n\n"; + output += `Automatisch generiert am: ${generatedAt}\n\n`; + output += "Hinweis: Diese Datei wird durch `docs/scripts/sync-funktionsdoku.mjs` erzeugt.\n\n"; + output += "| Route (Expo Router) | Datei |\n"; + output += "|---|---|\n"; + + for (const row of rows) { + output += `| \`${row.route}\` | \`${row.file}\` |\n`; + } + + output += `\nGesamtzahl erkannter Mobile-Screens: **${rows.length}**\n`; + + await fs.writeFile(OUT_MOBILE, output, "utf-8"); +} + +async function main() { + await generateBackendDoc(); + await generateFrontendDoc(); + await generateMobileDoc(); + console.log("Funktionsdokumentation erfolgreich synchronisiert."); +} + +main().catch((error) => { + console.error("Fehler bei der Doku-Synchronisierung:", error); + process.exit(1); +}); diff --git a/docs/versionen/docs-versionen.md b/docs/versionen/docs-versionen.md new file mode 100644 index 0000000..354b5cf --- /dev/null +++ b/docs/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/wartung/dokumentationsprozess.md b/docs/wartung/dokumentationsprozess.md new file mode 100644 index 0000000..3f804b5 --- /dev/null +++ b/docs/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.