Architektur¶
Visueller Überblick
Für ein Diagramm aller Container/Services/Daten und ihrer Interaktionen siehe Big Picture. Diese Seite hier beschreibt Stack und Prinzipien in Textform.
Stack¶
- Backend: FastAPI + SQLAlchemy 2.x + Python 3.13, Migrationen via Alembic
- Frontend: Next.js (App Router) + TypeScript, strict
- Datenbank: PostgreSQL 16
- Cache/State: Redis 7 – ausschliesslich ephemerer State für Live-Kollaboration im Protokoll-Editor (Presence, Feld-/Zellensperren), kein persistentes Volume
- PDF-Export: XeLaTeX/pdflatex per Subprozess
- Reverse Proxy / TLS: Traefik v3, automatische Let's-Encrypt-Zertifikate
- Infra: Docker Compose
Services (Docker Compose)¶
| Service | Zweck |
|---|---|
traefik |
Reverse Proxy, TLS-Terminierung, Routing nach Host/Pfad |
db |
PostgreSQL, nur an 127.0.0.1 gebunden |
redis |
Live-Kollaborations-State |
backend |
FastAPI-Hauptanwendung (/api, /docs, /openapi.json) |
frontend |
Next.js-Hauptanwendung (Kunden-UI + Admin-Panel unter /admin) |
abgabebox-backend / abgabebox-frontend |
Öffentliche Abgabebox, eigene Codebase |
clamav |
Virenscan für Uploads |
docs |
Diese Dokumentation (statischer MkDocs-Build hinter nginx) |
Multi-Tenancy¶
hocX ist Multi-Tenant: fast jede Tabelle trägt eine tenant_id. Ein normaler Benutzer
sieht ausschliesslich Daten der Vereine, in denen er Mitglied ist. Mandantenübergreifende
Verwaltung existiert ausschliesslich im separaten Platform-Admin-Panel.
Snapshot-Prinzip¶
Protokolle sind unveränderliche Kopien ihrer Vorlage zum Erstellungszeitpunkt. Änderungen an einer Vorlage wirken sich nie auf bereits erstellte Protokolle aus. Eine kontrollierte Ausnahme ist das "live bis Status abgeschlossen"-Muster (z. B. bei aus Listen verknüpften Tabellenzeilen oder "Verantwortlich"-Namen): dort wird nur ein ID-Pointer gesnapshottet, Lesen/Schreiben läuft bis zum Abschluss live über die referenzierte Ressource, und beim Abschliessen wird der zuletzt gültige Wert endgültig eingefroren.
Abgabebox¶
Die Abgabebox ist bewusst als eigenständige Anwendung mit eigenem Backend/Frontend/Compose-Service umgesetzt, nicht als Teil der Hauptanwendung:
- Eigene Subdomain, komplett unauthentifiziert erreichbar.
- Datenbankzugriff über eine restricted Postgres-Rolle
(
hocx_abgabebox): REVOKE-ALL-Baseline, danach explizites Allowlisting nur für die wenigen benötigten Insert-Operationen, keinSELECTauf sensible Spalten. - Eigenes Storage-Verzeichnis, getrennt vom regulären Upload-Storage.
- Hochgeladene Dateien werden über ClamAV gescannt.
Diese Trennung ist die eigentliche Sicherheitsgrenze – nicht Applikationslogik –, damit ein Fehler in der öffentlich erreichbaren Abgabebox nicht automatisch Zugriff auf die Hauptdatenbank bedeutet.
Platform-Admin-Panel¶
Siehe eigene Seite: Platform-Admin-Panel.