Olympus/ARCHITECTURE.md
2026-07-02 23:05:59 +02:00

9.6 KiB

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 <jwt>.

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.

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:

Browser -> Athena /api/... -> Hermes -> PostgreSQL

Beispiel Benutzerliste:

Browser
  GET /api/users

Athena
  GET {HERMES_INTERNAL_URL}/users
  Authorization: Bearer <jwt aus HttpOnly Cookie>

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

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:

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.