docs(quick-260909-jts): Etappe 2 Bereich groups abgeschlossen und verifiziert
This commit is contained in:
+3
-2
@@ -374,6 +374,7 @@ None yet.
|
||||
| 260909-cx0 | Dateisicherung nachgeruestet und Versionsangaben geradegezogen. **user-files** liegt jetzt in einem benannten Volume (docker-compose.yml und .prod.yml) — vorher lag der Ordner nur in der fluechtigen Container-Schicht, hochgeladene Profilbilder und DKV-Exporte waeren bei jedem --force-recreate weg gewesen. Benanntes Volume statt Bind-Mount, weil das Image /app/user-files an uid 1001 uebereignet; ein frisch angelegtes Host-Verzeichnis gehoert root und haette aus dem Datenverlust einen kaputten Upload gemacht. docker-compose.dev.yml blieb bewusst unveraendert (Compose fuehrt Mount-Listen ueber das Ziel zusammen). **CLAUDE.md** nennt jetzt die installierten Fassungen statt der urspruenglich empfohlenen (Next.js 15.5.19 statt 16, Prisma 6.19.3 statt 7); neu ist ein Abschnitt 'Recommended But Not Adopted', der sechs nie eingebaute Empfehlungen benennt — darunter Keycloak, Redis und shadcn/ui. Der Block ist generiert, deshalb traegt er einen Herkunftsvermerk und die Recherchedatei eine datierte Hinweiszeile; ihre Zahlen blieben unangetastet. Keine Abhaengigkeit angefasst (per git diff gegengeprueft). **WINDOWS #17 am 2026-09-09 geschlossen.** Beim Nachtragen auf dem Server kam heraus, dass dort gar nicht `docker-compose.yml` gilt: die `.env` setzt `COMPOSE_FILE=docker-compose.prod.yml`. Die drei Zeilen wurden in dieser Datei ergaenzt (Sicherung `docker-compose.prod.yml.bak.20260909-0818`). Nach dem Neuerstellen durch den User belegt: Mount `tessera_user-files -> /app/user-files` vorhanden, Ordner gehoert uid 1001 (das benannte Volume hat die Eigentuemerschaft uebernommen), Schreiben als Dienstnutzer funktioniert, und eine Probedatei lag tatsaechlich unter /var/lib/docker/volumes/tessera_user-files/_data auf dem Host — also ausserhalb des Containers | 2026-09-09 | c807049 | [260909-cx0-dateisicherung-nachruesten-und-versionsa](./quick/260909-cx0-dateisicherung-nachruesten-und-versionsa/) |
|
||||
| 260909-dgj | Mandantentrennung auf Datenbankebene vorbereitet (WINDOWS #18). Ausloeser war ein gemessener Befund: die Anwendung verbindet als Rolle mit Superuser- und BYPASSRLS-Recht, daher greifen die sieben vorhandenen Policies gar nicht — ohne gesetzten Mandantenkontext lieferte 'SELECT count(*) FROM Group' zwei statt null Zeilen. Gebaut wurden: Rolle `tessera_app` ohne Umgehungsrecht (wiederholbare Migration, kein Kennwort im SQL), Trennung von Migrations- und Laufzeitverbindung ueber TESSERA_MIGRATE_DATABASE_URL, ein Pruefwerkzeug mit fuenf transaktionssicheren Nachweisen, Policies fuer die 16 fehlenden Tabellen und eine Betriebsanleitung. **Der Schalter bleibt bewusst aus, #18 bleibt offen:** im Code stehen 182 Datenbankzugriffe ohne Mandantenkontext gegen 19 mit — darunter zwingend der Anmeldeweg, der die Benutzerzeile liest, bevor der Mandant bekannt ist (er kommt erst aus dieser Zeile). Ein Umschalten wuerde die Anmeldung fuer alle sperren. Dabei fiel #19 an: SearchProvider und TenderRssFeedSource haben ein nullable tenantId; die einfache Policy wuerde die plattformweiten Zeilen nach dem Scharfschalten fuer jeden Mandanten unsichtbar machen. 673/673 Tests gruen | 2026-09-09 | efaabc9 | [260909-dgj-mandantentrennung-auf-alle-tabellen-mit-](./quick/260909-dgj-mandantentrennung-auf-alle-tabellen-mit-/) |
|
||||
| 260909-ipc | Mandantentrennung Etappe 2, Bereich ldap: alle 21 klassifizierten Zugriffe in `ldap-config.service.ts` (9) und `ldap.service.ts` (12) an `forTenant()` gebunden. **Zuerst gemessen, dann gebaut:** `rls-scratch-check.mjs` um `runLdapAreaChecks` erweitert (13/13 bestanden), Beleg ist die Zeile `ldapconfig-ungebunden-null-zeilen` gegen die echte, ausgelieferte Policy — die Umkehr der Fehlerrichtung ist damit gemessen, nicht behauptet. Die geforderte Kritikschrift liegt in `docs/mandantentrennung-etappe2-fehlerrichtung.md` mit Signaltabelle je Pfad und vier namentlich benannten Stellen, die Leere als Abwesenheit deuten. **Sicherheitsluecke nebenbei geschlossen (T-IPC-01):** `DELETE /ldap/config/mappings/:id` nahm nur die Kennung — ein Administrator von Mandant A konnte die Feldzuordnung von B loeschen; der Mandant kommt jetzt aus der Sitzung. **Drei Stellen bleiben bewusst ungebunden, jede mit Begruendung im Code:** `getAllActiveConfigs` und die Start-Nachverschluesselung lesen zwingend uebergreifend; `resolveEmailForWrite` darf nicht gebunden werden, weil `email`/`username` plattformweit eindeutig sind — gebunden saehe die Kollisionspruefung keinen fremden Halter, meldete 'frei', und aus einer sauber berichteten Kollision wuerde ein P2002-Abbruch (Produktfrage fuer Etappe 3). **Befund, der die Testlage aendert:** `forTenant` war in `ldap.service.spec.ts` als Identitaet gemockt — die Tests haetten den Umbau in keiner Richtung bemerkt; ersetzt durch zwei unterscheidbare Clients. `rls-access-inventory.spec.ts` um eine `Stand`-Spalte und Erkennung gebundener Fundstellen erweitert, dabei zwei bisher unbekannte Paare gefunden (`auth.service.ts`/`passwordResetToken`, `ldap.service.ts`/`groupMembership`), Klassifikationsdokument auf 61 Paare nachgezogen. Schema, Migrationen, Compose und Umgebungsdateien unberuehrt, Schalter weiter aus. **Verifiziert 7/7** (unabhaengig nachgemessen: 719/719 Tests, Typpruefung sauber, 13/13 Live-Pruefungen gegen den echten Container) | 2026-09-09 | a0c9ef0,9a57fa7,e1586a4 | [260909-ipc-mandantentrennung-etappe-2-bereich-ldap-](./quick/260909-ipc-mandantentrennung-etappe-2-bereich-ldap-/) |
|
||||
| 260909-jts | Mandantentrennung Etappe 2, Bereich groups — die Berechtigungsschicht. Alle 34 echten Zugriffe in `groups.service.ts` (21) und `module-grants.service.ts` (13) gebunden, dazu fuenf Zugriffe, die **keine Pruefung dieses Projekts je gesehen hatte**: sie laufen innerhalb einer Transaktion ueber den Callback-Parameter, den der Detektor der Inventarpruefung nicht kannte — einer davon ist der Schreibvorgang, der Modulfreigaben vergibt. Das Paar `(groups.service.ts, tenantModuleActivation)` fehlte im Klassifikationsdokument komplett und ist ergaenzt; der Detektor sieht jetzt auch Transaktionsparameter. **Kernbefund — neues Hilfsmittel `withTenantTransaction()`:** die Frage, welche Transaktionsform den Mandantenkontext auf derselben Verbindung traegt, wurde an der lebenden Datenbank gemessen statt angenommen. Form (i) faellt durch (zwei verschiedene `pg_backend_pid()`), Form (ii) besteht die Einzelmessung, bricht aber unter 40 gleichzeitigen Aufrufen mit P2028 ab, weil jeder Aufruf eine verschachtelte Transaktion aus demselben endlichen Verbindungsvorrat oeffnet; Form (iii) besteht beides. Alle weiteren Bereiche bauen darauf auf. **Die Lastprobe war zunaechst nur Fliesstext** — eine Zahl, die eine Entscheidung trug, ohne nachvollziehbar zu sein; vom Verifizierer beanstandet und als `runConcurrencyProbe` nachgereicht (604428a), laeuft seither bei jedem Werkzeuglauf mit: 24 Verletzungen von 40 fuer Form (ii), 0 von 40 fuer Form (iii). **Zwei Datenbankregeln greifen kuerzer als gedacht** und sind bewusst nur gemessen und festgehalten, nicht repariert: die Regel fuer Gruppenmitgliedschaften prueft nur die Gruppen-, nicht die Benutzerseite (T-JTS-02), die fuer Modulfreigaben nur die Mandantenkennung, nicht die referenzierte Gruppe (T-JTS-03) — dort haengt der Schutz allein an `assertTargetBelongsToTenant`. Umgekehrter Gefahrenfall geschlossen: `ensureDefaultGroup` deutet Leere als 'Mandant hat noch keine Gruppe' und baut alles neu auf, eine halb umgestellte Fassung haette eine zweite Standardgruppe samt Freigaben erzeugt — Zaehler und Transaktion sind deshalb gemeinsam gebunden. Beide Testdateien hatten gar keine Attrappe fuer den Helfer, waeren nach der Umstellung also aus dem falschen Grund rot gewesen; ersetzt durch den Zwei-Client-Nachweis, vom Verifizierer durch Rueckbau falsifiziert. Schema, Migrationen, Compose und Umgebungsdateien unberuehrt, Schalter aus. **Verifiziert 9/9** (743/743 Tests, Typpruefung sauber, 23/23 Live-Pruefungen) | 2026-09-09 | fd0b9f7,7f08b27,abb6c8b,604428a | [260909-jts-mandantentrennung-etappe-2-bereich-group](./quick/260909-jts-mandantentrennung-etappe-2-bereich-group/) |
|
||||
| 260909-eor | Etappe 1 der Mandantentrennung: Anmeldeweg mandantenfaehig gemacht und alle Zugriffe klassifiziert. **Kernfund (#20):** `forTenant()` setzte den Mandantenkontext per set_config auf der Transaktionsverbindung, dispatchte die Abfrage aber ueber den aeusseren Client — empirisch reproduziert (set_config auf Backend-PID 254999, Abfrage auf 255000, Kontext dort NULL). Die Trennung hat damit nie funktioniert, auch nicht an den Stellen, die sie scheinbar nutzten; nach dem Scharfschalten haetten diese Abfragen NULL Zeilen geliefert, was der LDAP-Loeschzweig als 'Gruppe im Verzeichnis verschwunden' gedeutet und geloescht haette. Behoben und live nachgewiesen. Der Anmeldeweg bekam drei SECURITY-DEFINER-Funktionen als schmale Ausnahme (feste Spaltenliste, Gleichheitsbedingung, LIMIT 1) — eine Policy haette nicht gereicht, weil sie zwangslaeufig die ganze Tabelle freigibt. Browser-Gegenprobe lokal bestanden: Anmeldung laedt das Portal, falsches Kennwort verraet weiterhin nicht welches Feld, Kennwort-vergessen laeuft durch (der einzige Protokollfehler war ein lokal fehlender Mailserver, also NACH dem Datenbankzugriff). Klassifikation aller 227 Zugriffe in 59 Einheiten, maschinell gegen Abdriften abgesichert: 31 muessen mandantengebunden werden, 9 teilweise, 16 betreffen keine mandantengebundene Tabelle, 3 bleiben bewusst uebergreifend. 701 Tests gruen | 2026-09-09 | da0ac04 | [260909-eor-anmeldeweg-mandantenfaehig-machen-und-al](./quick/260909-eor-anmeldeweg-mandantenfaehig-machen-und-al/) |
|
||||
|
||||
## Deferred Items
|
||||
@@ -416,6 +417,6 @@ sind. Kein Anlass, sie vorher erneut vorzulegen.
|
||||
|
||||
Last session: 2026-09-09T12:13:05.681Z
|
||||
Resumed: 2026-09-09 — Sitzung ueber /gsd-resume-work fortgesetzt; Einstiegspunkt Etappe 2 (Bereich ldap), Auswahl des Nutzers steht aus.
|
||||
Stopped at: Etappe 2 Bereich ldap abgeschlossen (Quick 260909-ipc). Naechster Bereich laut .continue-here.md: groups (37 Zugriffe).
|
||||
Stopped at: Etappe 2, zwei von elf Bereichen durch (ldap 260909-ipc, groups 260909-jts). Naechster Bereich: tenders (62 Zugriffe), danach dkv, user, module-registry, dashboard, calendar, tenant, favorites, settings. Der User hat am 2026-09-09 gesagt, die restlichen Bereiche sollen ohne Rueckfrage durchlaufen; beim Scharfschalten (Etappe 4) wird ausdruecklich angehalten.
|
||||
Resume file: None
|
||||
Last activity: 2026-09-09 - Completed quick task 260909-ipc: Mandantentrennung Etappe 2, Bereich ldap (verifiziert 7/7)
|
||||
Last activity: 2026-09-09 - Completed quick task 260909-jts: Mandantentrennung Etappe 2, Bereich groups (verifiziert 9/9)
|
||||
|
||||
Reference in New Issue
Block a user