feat(datenmodell): Schema, tagCodes und Geheimnisse (#20)
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:
+63
-2
@@ -8,11 +8,12 @@ als Unterpunkte mit Aufgabe und Dauer.
|
||||
| Issue | Titel | Tatsächlich |
|
||||
|---|---|---|
|
||||
| #005 | M0 – Gerüst, Prozess, Design-Token | 1 h 25 min |
|
||||
| | **Summe** | **1 h 25 min** |
|
||||
| #006 | M1 – Datenmodell | 1 h 10 min |
|
||||
| | **Summe** | **2 h 35 min** |
|
||||
|
||||
| Meilenstein | Tatsächlich | Status |
|
||||
|---|---|---|
|
||||
| v0.1.0 | 1 h 25 min | in Arbeit |
|
||||
| v0.1.0 | 2 h 35 min | in Arbeit |
|
||||
|
||||
---
|
||||
|
||||
@@ -104,3 +105,63 @@ als Unterpunkte mit Aufgabe und Dauer.
|
||||
|
||||
- #006 Datenmodell: das vollständige Schema in deutscher Benennung, `tagCode`-Generator,
|
||||
Krypto-Helfer, erste Migration, idempotenter Seed-Rumpf.
|
||||
|
||||
---
|
||||
|
||||
## 2026-09-25 · Sitzung 2 · 00:05–01:15
|
||||
|
||||
**Issue:** #006 (M1)
|
||||
**Version:** 0.1.0
|
||||
|
||||
### Erledigt
|
||||
|
||||
- Vollständiges Schema in deutscher Benennung: 20 Tabellen, 9 Aufzählungen, eine Migration
|
||||
- `src/lib/tagcode.ts` und `src/lib/geheimnisse.ts` samt Tests, parallel von einem Sub-Agenten
|
||||
gebaut, während ich das Schema schrieb (Dauer dort: rund 10 min)
|
||||
- Idempotenter Seed für Betriebsmodus, eigene Organisation und Administrator — zweimal
|
||||
hintereinander gefahren, keine Zeile geändert
|
||||
- Unabhängiger Review-Agent gegen die Akzeptanzkriterien; alle Blocker und alle neun „sollte
|
||||
behoben werden"-Punkte abgearbeitet
|
||||
- **106 Tests** grün (vorher 11), davon 42 gegen die echten Datenbankregeln
|
||||
|
||||
### Entscheidungen
|
||||
|
||||
- **Regeln gehören zusätzlich in die Datenbank.** Zwölf CHECK-Bedingungen, zwei partielle
|
||||
Eindeutigkeitsindizes und vier zusammengesetzte Fremdschlüssel. Begründung: die Service-Schicht
|
||||
ist nicht der einzige Weg, auf dem Daten entstehen — Migrationen, `psql`, Skripte und ab
|
||||
Phase 4 die Connectoren schreiben an ihr vorbei.
|
||||
- **Die Mandantengrenze wird strukturell erzwungen.** `Lauf` verweist mit
|
||||
`("geraetId", "kundeId")` auf `Geraet("id", "kundeId")`, analog für Person und Abteilung.
|
||||
`docs/architektur.md` nennt die Grenze eine Sicherheitsgrenze — dann soll sie nicht allein an
|
||||
`kundeErmitteln()` hängen. `MATCH SIMPLE` lässt einen Lauf ohne Gerät weiter zu.
|
||||
- **Kein Cascade dort, wo das Archiv hängt.** Ein `DELETE` auf einen Lauf hätte Schrittergebnisse
|
||||
und Kommentare stillschweigend mitgenommen, ein Protokolleintrag hätte seinen Urheber verlieren
|
||||
können. Beides jetzt `Restrict`.
|
||||
- **`TagCodeVergabe` als Vergabebuch.** Die Eindeutigkeit allein aus `Geraet.tagCode` zu ziehen
|
||||
reicht nicht: verschwindet die Zeile, wäre der Code wieder frei und ein alter Aufkleber im
|
||||
Regal zeigte auf ein fremdes Objekt.
|
||||
- **Widerspruch im Auftrag beim tagCode-Alphabet.** Das wörtliche Alphabet enthält ein `L`,
|
||||
die Klammer daneben verbietet es. Aufgelöst zugunsten des wörtlichen Alphabets: die Klammer
|
||||
benennt Verwechslungsgruppen, keine Ausschlussliste — aus `{1, I, L}` sind `1` und `I` weg,
|
||||
dadurch ist `L` eindeutig. Das Akzeptanzkriterium in #006 ist richtiggestellt worden, statt
|
||||
einen grünen Test darüber zu setzen.
|
||||
- **Ein Systemlauf muss darstellbar sein.** `Lauf.erstelltVonId` ist optional, wie schon
|
||||
`Schrittergebnis.aktualisiertVonId`. Wiederkehrende Läufe und der Start per Webhook (Phase 4)
|
||||
haben keinen Menschen dahinter.
|
||||
|
||||
### Probleme
|
||||
|
||||
- **`prisma migrate reset --force` zeigte den Bestätigungsdialog trotzdem** und ließ einen
|
||||
Schema-Engine-Prozess zurück, der die Advisory-Sperre hielt; der nächste `migrate dev` lief
|
||||
daraufhin in einen Timeout. Verlässlicher: `DROP SCHEMA public CASCADE` per psql, dann
|
||||
`migrate dev --create-only < /dev/null`.
|
||||
- **Port 5433 ist von ProxLedger belegt.** Die Entwicklungsdatenbank liegt jetzt auf 5434,
|
||||
umstellbar über `DEV_DB_PORT`.
|
||||
- **Eine Regex-Ersetzung hat `quelle.length` auch aus der Längenprüfung gerissen** und den
|
||||
Krypto-Helfer unübersetzbar gemacht. Die Testsuite hat es sofort gezeigt — ein Argument mehr
|
||||
dafür, nach jeder Sammeländerung wirklich alle Schranken laufen zu lassen.
|
||||
|
||||
### Nächster Schritt
|
||||
|
||||
- #007 Auth, Rollen, Benutzer: `openid-client` mit Discovery, `jose`-Sitzungscookie, lokaler
|
||||
Login mit argon2, `RECHTE`-Tabelle, Login-Seite mit Rücksprung auf die ursprüngliche URL.
|
||||
|
||||
Reference in New Issue
Block a user