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
2026-09-06 13:25:44 +02:00
2026-09-06 13:25:44 +02:00
2026-09-06 13:25:44 +02:00
2026-09-06 13:25:44 +02:00
2026-09-06 13:25:44 +02:00
2026-09-06 13:25:44 +02:00
2026-09-06 13:25:44 +02:00

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

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.

Lokal entwickeln

Zwei Fenster:

php -S 127.0.0.1:8080 -t backend/public
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

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.

S
Description
No description provided
Readme
2.2 MiB
Languages
TypeScript 63.1%
PHP 35.2%
CSS 1.5%
HTML 0.2%