Compare commits
3 Commits
0b7d20d946
...
b27b00f59c
| Author | SHA1 | Date | |
|---|---|---|---|
| b27b00f59c | |||
| 1637d4bd91 | |||
| 8114a8c645 |
@@ -1,5 +1,5 @@
|
||||
name: Build and Push Docker Images
|
||||
run-name: Build Backend & Frontend by @${{ github.actor }}
|
||||
run-name: Build Backend, Frontend & Docs by @${{ github.actor }}
|
||||
|
||||
on: [push]
|
||||
|
||||
@@ -13,7 +13,32 @@ env:
|
||||
ACTOR: flfeders
|
||||
|
||||
jobs:
|
||||
verify-docs-sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Prüfe Node-Version
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Synchronisiere Funktionsdokumentation
|
||||
run: node docs/scripts/sync-funktionsdoku.mjs
|
||||
|
||||
- name: Breche ab, wenn Doku nicht aktuell committed ist
|
||||
run: |
|
||||
if [ -n "$(git status --porcelain docs/)" ]; then
|
||||
echo "Die generierte Dokumentation ist nicht aktuell."
|
||||
echo "Bitte lokal ausführen: node docs/scripts/sync-funktionsdoku.mjs"
|
||||
echo "Danach die Änderungen committen."
|
||||
git status --short docs/
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build-backend:
|
||||
needs: verify-docs-sync
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
@@ -46,6 +71,7 @@ jobs:
|
||||
labels: ${{ steps.meta-backend.outputs.labels }}
|
||||
|
||||
build-frontend:
|
||||
needs: verify-docs-sync
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
@@ -75,3 +101,36 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta-frontend.outputs.tags }}
|
||||
labels: ${{ steps.meta-frontend.outputs.labels }}
|
||||
|
||||
build-docs:
|
||||
needs: verify-docs-sync
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Log in to Docker Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.REGISTRY_HOST }}
|
||||
username: ${{ env.ACTOR }}
|
||||
password: ${{ vars.CI_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docs
|
||||
id: meta-docs
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: ${{ env.REGISTRY_HOST }}/${{ env.IMAGE_NAME }}/docs
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
|
||||
- name: Build and push Docs
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: ./docs-site/Dockerfile
|
||||
push: true
|
||||
tags: ${{ steps.meta-docs.outputs.tags }}
|
||||
labels: ${{ steps.meta-docs.outputs.labels }}
|
||||
|
||||
9
docker-compose.docs.yml
Normal file
9
docker-compose.docs.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
docs:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docs-site/Dockerfile
|
||||
container_name: fedeo-docs
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3205:80"
|
||||
4
docs-site/.dockerignore
Normal file
4
docs-site/.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
build
|
||||
.docusaurus
|
||||
.git
|
||||
17
docs-site/Dockerfile
Normal file
17
docs-site/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app/docs-site
|
||||
|
||||
COPY docs-site/package.json docs-site/package-lock.json* ./
|
||||
RUN npm install
|
||||
|
||||
COPY docs-site ./
|
||||
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
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
51
docs-site/README.md
Normal file
51
docs-site/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# FEDEO Docs Site (Docusaurus)
|
||||
|
||||
Diese Docusaurus-App rendert die versionierte FEDEO-Dokumentation aus dem Ordner `../docs`.
|
||||
|
||||
## Lokale Entwicklung
|
||||
|
||||
Im Ordner `docs-site` ausführen:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run start
|
||||
```
|
||||
|
||||
Danach ist die Seite unter `http://localhost:3005` erreichbar.
|
||||
|
||||
## Statischer Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npm run serve
|
||||
```
|
||||
|
||||
## Deploy mit Docker Compose
|
||||
|
||||
Aus dem Projekt-Root:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.docs.yml up -d --build
|
||||
```
|
||||
|
||||
Standard-Port ist `3205`.
|
||||
|
||||
## Workflow bei Funktionsänderungen
|
||||
|
||||
Vor jedem Docs-Deploy:
|
||||
|
||||
1. Technische Kataloge aktualisieren
|
||||
|
||||
```bash
|
||||
node docs/scripts/sync-funktionsdoku.mjs
|
||||
```
|
||||
|
||||
2. Änderungen committen
|
||||
3. Docs-Container neu bauen und starten
|
||||
|
||||
## Wichtige Platzhalter
|
||||
|
||||
Bitte in `docs-site/docusaurus.config.ts` anpassen:
|
||||
|
||||
- `url` auf die echte Docs-Domain
|
||||
- GitHub-Links (`editUrl`, `Repository`)
|
||||
85
docs-site/docusaurus.config.ts
Normal file
85
docs-site/docusaurus.config.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
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://docs.example.com',
|
||||
baseUrl: '/',
|
||||
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
|
||||
i18n: {
|
||||
defaultLocale: 'de',
|
||||
locales: ['de'],
|
||||
},
|
||||
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
{
|
||||
docs: {
|
||||
path: '../docs',
|
||||
routeBasePath: 'docs',
|
||||
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: '/docs/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;
|
||||
16
docs-site/nginx.conf
Normal file
16
docs-site/nginx.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
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";
|
||||
}
|
||||
}
|
||||
30
docs-site/package.json
Normal file
30
docs-site/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "fedeo-docs-site",
|
||||
"version": "1.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"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0"
|
||||
}
|
||||
}
|
||||
7
docs-site/sidebars.ts
Normal file
7
docs-site/sidebars.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
||||
|
||||
const sidebars: SidebarsConfig = {
|
||||
docsSidebar: [{ type: 'autogenerated', dirName: '.' }],
|
||||
};
|
||||
|
||||
export default sidebars;
|
||||
36
docs-site/src/css/custom.css
Normal file
36
docs-site/src/css/custom.css
Normal file
@@ -0,0 +1,36 @@
|
||||
: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;
|
||||
}
|
||||
20
docs-site/src/pages/index.tsx
Normal file
20
docs-site/src/pages/index.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import Link from '@docusaurus/Link';
|
||||
import Layout from '@theme/Layout';
|
||||
|
||||
export default function Home(): JSX.Element {
|
||||
return (
|
||||
<Layout title="FEDEO Docs" description="Versionierte Funktionsdokumentation für FEDEO">
|
||||
<main className="heroSection">
|
||||
<div className="container">
|
||||
<h1>FEDEO Dokumentation</h1>
|
||||
<p>Versionierte Anleitung aller Funktionen für Backend, Web und Mobile.</p>
|
||||
<div className="heroButtons">
|
||||
<Link className="button button--primary button--lg" to="/docs/funktionen">
|
||||
Zur Dokumentation
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
0
docs-site/static/img/.gitkeep
Normal file
0
docs-site/static/img/.gitkeep
Normal file
7
docs-site/tsconfig.json
Normal file
7
docs-site/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "@docusaurus/tsconfig",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "."
|
||||
},
|
||||
"exclude": ["build", "node_modules"]
|
||||
}
|
||||
54
docs/README.md
Normal file
54
docs/README.md
Normal file
@@ -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.
|
||||
238
docs/funktionen/backend-api.md
Normal file
238
docs/funktionen/backend-api.md
Normal file
@@ -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**
|
||||
70
docs/funktionen/frontend-web.md
Normal file
70
docs/funktionen/frontend-web.md
Normal file
@@ -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**
|
||||
23
docs/funktionen/index.md
Normal file
23
docs/funktionen/index.md
Normal file
@@ -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
|
||||
```
|
||||
29
docs/funktionen/mobile-app.md
Normal file
29
docs/funktionen/mobile-app.md
Normal file
@@ -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**
|
||||
70
docs/funktionen/uebersicht.md
Normal file
70
docs/funktionen/uebersicht.md
Normal file
@@ -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.
|
||||
234
docs/scripts/sync-funktionsdoku.mjs
Executable file
234
docs/scripts/sync-funktionsdoku.mjs
Executable file
@@ -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);
|
||||
});
|
||||
25
docs/versionen/docs-versionen.md
Normal file
25
docs/versionen/docs-versionen.md
Normal file
@@ -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
|
||||
```
|
||||
35
docs/wartung/dokumentationsprozess.md
Normal file
35
docs/wartung/dokumentationsprozess.md
Normal file
@@ -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.
|
||||
Reference in New Issue
Block a user