# Olympus CRM Architektur ## Projektueberblick Olympus CRM ist als mehrschichtige CRM-Anwendung aufgebaut. Die Architektur trennt klar zwischen Browser, Frontend/BFF, Backend-API und Datenbank. Die zentrale Regel lautet: **Der Browser kommuniziert ausschliesslich mit Athena. Athena kommuniziert serverseitig mit Hermes. Hermes kommuniziert mit PostgreSQL.** Diese Trennung ist verbindlich, besonders fuer Authentifizierung, API-Zugriffe und spaetere Modul-Erweiterungen wie Kunden, Projekte, Lieferanten, Kontakte und Mitarbeiter. ## Systemkomponenten ### Athena: Next.js 16 Frontend Athena liegt unter `frontend/athena` und ist das Frontend sowie die BFF-Schicht des Systems. Aufgaben: - rendert die Benutzeroberflaeche mit Next.js 16 App Router - stellt eigene API-Routes unter `/api/...` bereit - setzt und loescht das HttpOnly-Auth-Cookie - ruft Hermes serverseitig auf - schuetzt Seiten ueber `proxy.ts` Der Browser darf keine Hermes-URLs direkt aufrufen. ### Hermes: FastAPI Backend Hermes liegt unter `backend/hermes` und stellt die interne Backend-API bereit. Aufgaben: - validiert Requests mit Pydantic v2 - verarbeitet Fachlogik und Persistenz - prueft JWT Bearer Tokens - stellt REST-Endpunkte bereit - nutzt SQLAlchemy 2.x fuer Datenbankzugriffe - setzt keine Browser-Cookies Hermes bleibt Cookie-frei. Authentifizierte Hermes-Endpunkte erwarten `Authorization: Bearer `. ### PostgreSQL Datenbank PostgreSQL ist die relationale Datenbank fuer Olympus CRM. Hermes greift ueber SQLAlchemy darauf zu. Schemaaenderungen erfolgen ueber Alembic-Migrationen. Manuelle Datenbankeingriffe sind nur in Notfaellen zulaessig und muessen nachvollziehbar dokumentiert werden. ### Docker Compose Die gemeinsame Docker-Compose-Konfiguration liegt im Projektroot in `docker-compose.yml`. Sie verbindet: - `hermes` - `athena` - das konfigurierte Docker-Netzwerk - die notwendigen Runtime-Umgebungsvariablen ## BFF-Architektur Olympus nutzt eine Backend-for-Frontend-Architektur. Regeln: - Browser spricht ausschliesslich mit Athena. - Athena spricht serverseitig mit Hermes. - Hermes setzt keine Browser-Cookies. - Cross-Origin-Cookies werden nicht verwendet. - Frontend-API-Zugriffe laufen ueber relative Athena-Routen wie `/api/users`. Der Datenfluss bleibt dadurch kontrolliert, sicher und leichter hinter Reverse Proxies betreibbar. ## Authentifizierungsfluss ### Login 1. Der Browser sendet Benutzername und Passwort an Athena: `POST /api/login`. 2. Athena ruft serverseitig Hermes auf: `POST /auth/login`. 3. Hermes validiert die Zugangsdaten. 4. Hermes gibt JWT, Ablaufzeit und Benutzerdaten als JSON zurueck. 5. Athena setzt das JWT in einem HttpOnly-Cookie. 6. Der Browser wird auf eine geschuetzte Seite weitergeleitet. Hermes setzt kein Cookie. ### Logout 1. Der Browser sendet `POST /api/logout` an Athena. 2. Athena loescht das HttpOnly-Cookie. 3. Der Benutzer wird zur Login-Seite gefuehrt. ### HttpOnly Cookie Das Auth-Cookie wird von Athena gesetzt. Eigenschaften: - `HttpOnly` - `SameSite=Lax` - `Path=/` - `Secure` in Produktion - Ablaufzeit orientiert sich an der JWT-Ablaufzeit Tokens duerfen nicht in `localStorage` oder `sessionStorage` gespeichert werden. ### JWT Hermes erzeugt JWT Access Tokens. Wichtige Claims: - `sub`: Benutzername - `exp`: Ablaufzeit - `iat`: Ausstellungszeitpunkt - `iss`: konfigurierter Issuer - `type`: Token-Typ, aktuell `access` ### Issuer Der Issuer wird ueber `JWT_ISSUER` konfiguriert. Hermes prueft den Issuer bei der Token-Validierung. ### Ablaufzeit Die Ablaufzeit wird ueber `ACCESS_TOKEN_EXPIRE_MINUTES` konfiguriert. Athena nutzt die von Hermes gelieferte Ablaufzeit fuer das Cookie. ### `proxy.ts` Athena schuetzt Routen ueber `frontend/athena/proxy.ts`. Aufgaben: - geschuetzte Bereiche ohne Cookie auf `/login` umleiten - eingeloggte Benutzer von `/login` auf `/dashboard` umleiten ## API-Datenfluss Standardfluss: ```text Browser -> Athena /api/... -> Hermes -> PostgreSQL ``` Beispiel Benutzerliste: ```text Browser GET /api/users Athena GET {HERMES_INTERNAL_URL}/users Authorization: Bearer Hermes SQLAlchemy Query gegen PostgreSQL ``` Athena ist die einzige API-Oberflaeche fuer den Browser. ## RBAC: Rollen und Berechtigungen Olympus verwendet ein serverseitiges RBAC-System als Grundlage fuer alle CRM-Module. Konzepte: - Benutzer besitzen genau eine primaere Rolle. - Rollen besitzen mehrere Berechtigungen. - Berechtigungen sind stabile String-Keys wie `users.read`. - Hermes prueft Berechtigungen serverseitig ueber Dependencies. - Athena darf Permissions fuer UI-Sichtbarkeit nutzen, aber niemals als Auth-Quelle. Tabellen: - `roles` - `permissions` - `role_permissions` - `users.role_id` Das alte `users.role`-Feld bleibt vorerst als Legacy-Kompatibilitaet erhalten. Neue Logik verwendet `users.role_id` und die `roles`-Beziehung. ### Standardrollen - `administrator` - `management` - `sales` - `technician` - `support` - `warehouse` - `guest` `administrator` erhaelt alle Berechtigungen. `management` erhaelt mindestens Lesezugriff auf Dashboard, Benutzer, Kunden, Projekte und Tickets. `guest` erhaelt minimal `dashboard.read`. ### Standardberechtigungen Benutzer: - `users.read` - `users.create` - `users.update` - `users.delete` - `users.password.update` Rollen: - `roles.read` - `roles.create` - `roles.update` - `roles.delete` - `roles.assign` Kunden: - `customers.read` - `customers.create` - `customers.update` - `customers.delete` Projekte: - `projects.read` - `projects.create` - `projects.update` - `projects.delete` Tickets: - `tickets.read` - `tickets.create` - `tickets.update` - `tickets.delete` Dashboard und System: - `dashboard.read` - `system.settings.read` - `system.settings.update` ### Berechtigungspruefung Zentrale Hermes-Dependencies: - `get_current_user` - `get_current_active_user` - `require_permission("permission.name")` - `require_any_permission([...])` - `require_all_permissions([...])` Backend-Endpunkte muessen immer selbst pruefen. Frontend-Helfer wie `hasPermission` dienen nur dazu, Buttons oder Navigation auszublenden. ### Rollen-API Hermes: - `GET /roles` - `GET /roles/{id}` - `POST /roles` - `PUT /roles/{id}` - `DELETE /roles/{id}` - `PUT /roles/{id}/permissions` - `GET /permissions` Athena stellt entsprechende BFF-Routen unter `/api/roles`, `/api/permissions` und `/api/me` bereit. ## Benutzerverwaltung Die Benutzerverwaltung ist das erste Enterprise-Modul und dient als Vorlage fuer weitere Module. Funktionen: - Benutzerliste - Detailseite - Erstellen - Bearbeiten - Loeschen - Passwort separat aendern - Suche, Filter, Sortierung und Pagination im Frontend Backend-Endpunkte in Hermes: - `GET /users` - `GET /users/{id}` - `POST /users` - `PUT /users/{id}` - `PUT /users/{id}/password` - `DELETE /users/{id}` Athena stellt die passenden BFF-Routen unter `/api/users` und `/api/users/[id]` bereit. Diese Endpunkte sind per RBAC geschuetzt: - `GET /users` und `GET /users/{id}`: `users.read` - `POST /users`: `users.create` und fuer Rollenzuweisung `roles.assign` - `PUT /users/{id}`: `users.update`; Rollenwechsel benoetigt `roles.assign` - `PUT /users/{id}/password`: `users.password.update` - `DELETE /users/{id}`: `users.delete` ### Passwortaenderung Wenn beim Bearbeiten kein Passwort uebergeben wird, bleibt das bestehende Passwort unveraendert. Wenn ein Passwort gesetzt wird, wird es in Hermes mit `pwdlib` neu gehasht. ### Self-Delete-Schutz Der aktuell angemeldete Benutzer darf sich nicht selbst loeschen. Hermes verhindert dies serverseitig. ### Rollenmodell Benutzer besitzen eine primaere RBAC-Rolle ueber `role_id`. Die Rolle bestimmt die serverseitigen Berechtigungen. ## Verzeichnisstruktur ```text backend/hermes app/ api/ core/ db/ models/ repositories/ schemas/ alembic/ alembic.ini dockerfile pyproject.toml frontend/athena app/ api/ roles/ users/ components/ lib/ types/ proxy.ts Dockerfile package.json docker-compose.yml ``` ## Umgebungsvariablen ### Hermes `DATABASE_URL` : PostgreSQL-Verbindungsstring. `SECRET_KEY` : Signierschluessel fuer JWTs. Muss geheim bleiben. `JWT_ISSUER` : Erwarteter JWT-Issuer, z. B. `hermes`. `ACCESS_TOKEN_EXPIRE_MINUTES` : Ablaufzeit fuer Access Tokens in Minuten. ### Athena `HERMES_INTERNAL_URL` : Serverseitige URL, ueber die Athena Hermes erreicht. `AUTH_COOKIE_SECURE` : Steuert das `Secure`-Flag des Cookies. In Produktion `true`. ## Datenbankmigrationen Olympus verwendet Alembic fuer Datenbankmigrationen. Regeln: - Schemaaenderungen immer ueber Alembic. - Migrationen muessen ins Repository aufgenommen werden. - Vor Deployment `alembic upgrade head` testen. - Keine manuellen DB-Aenderungen ausser in Notfaellen. Typischer Ablauf: ```bash cd backend/hermes alembic upgrade head ``` ## Sicherheitsprinzipien Verbindliche Regeln: - Keine Tokens im `localStorage`. - Keine Tokens im `sessionStorage`. - Keine Browserzugriffe auf Hermes. - Keine Cross-Origin-Cookies. - Hermes bleibt Cookie-frei. - Athena setzt HttpOnly Cookies. - Mutierende Athena-API-Routes pruefen Same-Origin. - Hermes prueft JWTs serverseitig. - Hermes prueft RBAC-Berechtigungen serverseitig. - Secrets gehoeren in Umgebungsvariablen, nicht in den Code. ## Produktionshinweise Fuer Produktion gilt: - HTTPS ist erforderlich. - `AUTH_COOKIE_SECURE=true` setzen. - Reverse Proxy ist moeglich und soll Forwarded Header korrekt setzen. - `HERMES_INTERNAL_URL` muss serverseitig erreichbar sein. - `SECRET_KEY` muss stark, geheim und stabil sein. - Datenbankmigrationen vor App-Rollout ausfuehren. Lokaler HTTP-Betrieb ist nur fuer Entwicklung gedacht. In Produktion duerfen keine unsicheren Cookie-Einstellungen verwendet werden.