Files
Kyle Müller 7d82e807fc
EK-DOS-WEB bauen und ausrollen / frontend (push) Failing after 22s
EK-DOS-WEB bauen und ausrollen / backend (push) Failing after 27s
EK-DOS-WEB bauen und ausrollen / deploy (push) Skipped
Initial
2026-09-06 13:25:44 +02:00

113 lines
5.1 KiB
Markdown

# EK-DOS-WEB
Büroanwendung der Elektro Krüger GmbH. Tickets, Angebote, Rechnungen, Kundenstamm,
interne Aufgaben, Stundennachweise und Online-Käufe -- die Fachdaten liegen in
n8n, die Benutzer in einer eigenen Datenbank.
```
Browser
│ HTTPS, Sitzungscookie (undurchsichtig)
nginx ────────────────┬──────────────────────────────┐
│ statisch │ /api/ über Unix-Socket │
▼ ▼ │
React-Bündel php8.5-fpm ──► PostgreSQL (Benutzer, Rollen, Protokoll)
(nur Dateien) Slim 4 ──► Redis (Sitzungen, n8n-Cache)
──► n8n (alle Fachdaten)
```
Auf dem Server läuft **kein Node**. Die Oberfläche wird im Gitea-Lauf zu
statischen Dateien kompiliert; ausgeliefert wird sie von nginx.
## Verzeichnisse
| Ordner | Inhalt |
| ------------------- | ----------------------------------------------------------------- |
| `backend/` | PHP 8.5, Slim 4. BFF-Sitzung, Benutzerverwaltung, n8n-Weiterleitung |
| `frontend/` | React 19 + Vite. Baut nach `frontend/dist/` |
| `deploy/nginx/` | nginx-Site |
| `deploy/php-fpm/` | php-fpm-Pool |
| `.gitea/workflows/` | Bau- und Ausrollstrecke |
| `docs/` | Betrieb und n8n-Schnittstelle |
| `legacy-nextjs/` | Die abgelöste Next.js-Fassung. Kann nach dem Umstieg weg |
## Wie es zusammenhängt
**Die Anmeldung** ist ein Backend-For-Frontend: der Browser hält nur eine
zufällige Kennung im Cookie, alles Weitere -- Benutzer, Rolle, Rechte -- liegt in
Redis. Das Cookie wächst dadurch nicht mit den Rechten mit, und eine
Rechteänderung wirkt sofort, weil das Backend die Sitzung wegwerfen kann.
**Die Rechte** ersetzen die früheren Namensabfragen. Statt `user === "Sascha"`
gibt es `Permission::OffersDelete`, und Rollen bündeln diese Rechte:
| Rolle | darf zusätzlich |
| ---------------- | -------------------------------------------------------------------- |
| `admin` | alles, einschließlich Benutzerverwaltung |
| `inhaber` | Angebote/Kunden/Aufgaben löschen, Online-Käufe eintragen und löschen |
| `buero` | Online-Käufe abschließen, Rechnungen bearbeiten und versenden |
`inhaber` entspricht dem, was Sascha vorher durfte, `buero` dem von Svenja.
**Die n8n-Daten** kommen weiter live aus den Webhooks, aber durch einen kurzen
Redis-Cache. Drei Dinge passieren dort: eine frische Antwort wird für 15--300
Sekunden wiederverwendet; läuft sie ab, während mehrere Ansichten gleichzeitig
fragen, holt genau **eine** die Daten (Single-Flight); und ist n8n nicht
erreichbar, wird die letzte bekannte Antwort ausgeliefert statt einer
Fehlerseite. Jeder schreibende Aufruf verwirft seine Gruppe sofort.
## Erste Einrichtung
```bash
cd backend
cp .env.example .env # DB, Redis, n8n-Geheimnisse eintragen
composer install --no-dev --optimize-autoloader
php bin/ekdos migrate
php bin/ekdos user:create # der erste Administrator
php bin/ekdos check # Postgres, Redis und n8n prüfen
```
Details zu nginx, php-fpm und dem Ausrollen: [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md).
## Lokal entwickeln
Zwei Fenster:
```bash
php -S 127.0.0.1:8080 -t backend/public
```
```bash
cd frontend && pnpm install && pnpm dev
```
Der Vite-Entwicklungsserver läuft auf `http://127.0.0.1:5173` und reicht `/api`
an den PHP-Server weiter. Ein anderes Backend lässt sich über `EKDOS_BACKEND`
angeben. Postgres und Redis müssen erreichbar sein; n8n nur, wenn die
Fachansichten Daten zeigen sollen -- Anmeldung und Benutzerverwaltung laufen ohne.
## Wartungs-CLI
```bash
php backend/bin/ekdos migrate # Schema fortschreiben
php backend/bin/ekdos user:create # Benutzer anlegen
php backend/bin/ekdos user:list # Benutzer auflisten
php backend/bin/ekdos user:password <name> # Passwort zurücksetzen
php backend/bin/ekdos cache:flush # n8n-Cache leeren
php backend/bin/ekdos check # Verbindungen prüfen
```
## Was noch offen ist
`frontend/src/views/Dashboard.tsx` ist unverändert die eine große Komponente aus
der Next.js-Fassung (rund 4.700 Zeilen, 22 Ansichten in einer Zustandsmaschine).
Sie wurde bewusst **kopiert statt neu geschrieben**, damit an der Darstellung
nichts unbemerkt verrutscht. Herausgelöst sind bisher Anmeldung, Sitzung und die
neue Benutzeransicht.
Die Aufteilung in eine Ansicht pro Datei ist der nächste sinnvolle Schritt.
Der Weg dorthin ohne Umschreiben der Markup-Blöcke: den Zustand in einen
`AppState`-Kontext heben, und jede Ansichtsdatei oben genau die Namen
destrukturieren, die ihr JSX schon verwendet -- dann bleibt das Markup wörtlich
unverändert.