feat(datenmodell): Schema, tagCodes und Geheimnisse (#20)
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

Vollständiges Datenmodell in deutscher Benennung: 20 Tabellen, 9 Aufzählungen,
eine Migration, dazu die framework-freien Helfer für tagCodes und Geheimnisse.

Regeln stehen zusätzlich in der Datenbank, nicht nur im Service: 12 CHECKs,
2 partielle Eindeutigkeitsindizes, 4 zusammengesetzte Fremdschlüssel. Die
Mandantengrenze ist damit strukturell erzwungen. Schrittergebnisse, Kommentare
und Protokolleinträge kaskadieren bewusst nicht — das Archiv ist das Gedächtnis
der Anwendung.

106 Tests, davon 42 gegen die echten Datenbankregeln.

Closes #6

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #20.
This commit is contained in:
2026-09-24 23:11:58 +00:00
co-authored by Claude Opus 5
parent 49ce06f206
commit 7a0f875f55
19 changed files with 2820 additions and 40 deletions
+12
View File
@@ -24,8 +24,20 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
- `pnpm docs:screenshots` erzeugt Screenshots reproduzierbar und prüft dabei gleich, dass am
Handy nicht horizontal gescrollt wird (#005)
- Issues, Labels und Meilensteine für alle vier Phasen im Gitea-Tracker (#001–#019)
- Vollständiges Datenmodell in deutscher Benennung: 20 Tabellen, 9 Aufzählungen, erste
Migration, idempotenter Seed für Betriebsmodus, eigene Organisation und Administrator (#006)
- Erzeugung der `tagCode`s für die QR-Aufkleber, mit Vergabebuch, aus dem nie gelöscht wird —
ein Code kommt auch nach dem Löschen eines Geräts nicht zurück (#006)
- Verschlüsselung von Geheimnissen mit AES-256-GCM aus `APP_SECRET`, für das LDAP-Bind-Passwort
und später die Zugangsdaten der Connectoren (#006)
### Sicherheit
- Der Compose-Stand bricht ab, wenn `APP_SECRET`, `POSTGRES_PASSWORD` oder `APP_URL` fehlen,
statt mit Standardwerten zu starten (#005)
- Die Mandantengrenze steht als zusammengesetzter Fremdschlüssel in der Datenbank: ein Lauf kann
strukturell kein Gerät, keine Person und keine Abteilung eines fremden Kunden wählen (#006)
- Ein Bind-Passwort ohne Versionspräfix wird von der Datenbank abgewiesen, ein versehentlich im
Klartext geschriebenes fällt damit sofort auf (#006)
- Ein Lauf nimmt seine Schrittergebnisse und Kommentare beim Löschen nicht mehr mit, und ein
Protokolleintrag kann seinen Urheber nicht mehr verlieren (#006)