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:
@@ -80,6 +80,37 @@ Schritte**. Damit der Schritt dorthin keine Migration braucht:
|
||||
- kein Codepfad nimmt an, dass ein Schritt nur von einem Menschen erledigt wird
|
||||
- das Krypto-Modul für das LDAP-Bind-Passwort ist schon der Platz für Connector-Geheimnisse
|
||||
|
||||
## 5a. Was in der Datenbank steht und warum
|
||||
|
||||
Die Service-Schicht ist der richtige Ort für Regeln mit verständlichen Meldungen. Sie ist aber
|
||||
nicht der einzige Weg, auf dem Daten entstehen: Migrationen, `psql`, Skripte und ab Phase 4 die
|
||||
Connectoren schreiben an ihr vorbei. Was stillschweigend falsch werden könnte, steht deshalb
|
||||
zusätzlich in der Datenbank:
|
||||
|
||||
| Regel | Form |
|
||||
|---|---|
|
||||
| Höchstens eine eigene Organisation | partieller Eindeutigkeitsindex |
|
||||
| Höchstens ein Entwurf je Vorlage | partieller Eindeutigkeitsindex |
|
||||
| Kundenkürzel, `tagCode`-Form, verschlüsseltes Bind-Passwort | CHECK auf die Form |
|
||||
| Registriertes Gerät braucht Hostname oder Bezeichnung | CHECK, greift erst ab `registriertAm` |
|
||||
| Mitarbeiter aus dem Verzeichnis **oder** Freitextname | CHECK |
|
||||
| Status und Zeitstempel laufen nicht auseinander | vier CHECKs |
|
||||
| `NICHT_ZUTREFFEND` und `FEHLGESCHLAGEN` brauchen eine Notiz | CHECK |
|
||||
| Einstellung ist eine einzelne Zeile | CHECK auf die feste Kennung |
|
||||
| **Mandantengrenze** | vier zusammengesetzte Fremdschlüssel |
|
||||
|
||||
Die Mandantengrenze verdient die Erklärung: `Lauf` verweist mit `("geraetId", "kundeId")` auf
|
||||
`Geraet("id", "kundeId")`, analog für Person und Abteilung, und `Geraet` ebenso auf den Besitzer.
|
||||
Damit ist ein Lauf, der ein Gerät eines fremden Kunden zieht, nicht mehr bloß ein Fehler im
|
||||
Service, sondern strukturell unmöglich. `MATCH SIMPLE` sorgt dafür, dass ein Lauf ohne Gerät
|
||||
weiterhin erlaubt ist.
|
||||
|
||||
Zwei Dinge sind bewusst **nicht** kaskadierend: ein `Lauf` nimmt seine Schrittergebnisse und
|
||||
Kommentare nicht mit, und ein `Protokoll`-Eintrag verliert seinen Urheber nicht. Beides stünde
|
||||
gegen den Zweck eines Archivs. Der `tagCode` ist zusätzlich in `TagCodeVergabe` festgehalten,
|
||||
aus dem nie gelöscht wird — sonst würde ein Code nach dem Löschen eines Geräts wieder frei und
|
||||
ein alter Aufkleber zeigte auf ein fremdes Objekt.
|
||||
|
||||
## 6. Betrieb: zwei Wege, eine Regel
|
||||
|
||||
Die Datenbank ist auf beiden Wegen von außen nicht erreichbar:
|
||||
|
||||
Reference in New Issue
Block a user