docs(quick-260910-das): Plan-Revision — alle vier handgepflegten Dokumentstellen maschinell gegatet
Der Plan benannte vier handgepflegte Stellen als die, die im dkv-Durchlauf uebersehen wurden, gatete aber nur zwei davon. Ein Ausfuehrender haette Aufgabe 3 abschliessen, jede Pruefung bestehen und Uebersichtszeile, Summenzeile und Klassen-Verteilung stehen lassen koennen — derselbe Fehler, gegen den der Plan schuetzen sollte, im Gate des Plans selbst. Die beiden fehlenden Pruefungen leiten ihre Erwartung ab, statt sie zu raten: die Uebersichtszeile gegen die am Quelltext neu ermittelten Rohtrefferzahlen (mit den beiden Befehlen, die das Dokument selbst nennt), die Summenzeile gegen die Addition der zwoelf Bereichszeilen, die Klassen-Verteilung gegen die ueber die Bestandsaufnahme nachgezaehlten Klassen samt Summe und Ueberschrift. Falsifiziert statt behauptet: gruen gegen das heutige, in sich stimmige Dokument; rot gegen den heutigen unumgestellten Baum; und rot in vier getrennten Mutationen, je eine stehen gelassene Handstelle — Uebersichtszeile, Summenzeile, Klassenzahl, Ueberschrift. Gruen erst, wenn Code umgestellt UND alle vier nachgezogen sind. Zusatzauflage, die daraus folgt: der gebundene Klient heisst in jeder Methode tenantPrisma (Konvention aus ldap/groups/dkv/auth) — ein anderer Name liesse die Gebunden-Zaehlung untertreiben und die Zeile ihrer Aussage berauben. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
This commit is contained in:
+28
-6
@@ -35,7 +35,7 @@ must_haves:
|
|||||||
- "Die uebergreifende Sicht des Plattform-Administrators bleibt erhalten, ohne ungebunden zu sein: sie laeuft als Schleife ueber alle Mandanten mit je EINEM gebundenen Lesezugriff im Rumpf — dieselbe Form, die die Standardgruppen-Reparatur beim Start bereits benutzt. Dass der Schleifentreiber selbst ungebunden lesen darf, haengt daran, dass die Mandantentabelle keinen Zeilenschutz traegt, und das ist gemessen."
|
- "Die uebergreifende Sicht des Plattform-Administrators bleibt erhalten, ohne ungebunden zu sein: sie laeuft als Schleife ueber alle Mandanten mit je EINEM gebundenen Lesezugriff im Rumpf — dieselbe Form, die die Standardgruppen-Reparatur beim Start bereits benutzt. Dass der Schleifentreiber selbst ungebunden lesen darf, haengt daran, dass die Mandantentabelle keinen Zeilenschutz traegt, und das ist gemessen."
|
||||||
- "Eine bereits bestehende, heute wirksame Luecke ist geschlossen: der Riegel gegen das Loeschen des eigenen Kontos vergleicht gegen ein Feld, das der Sitzungsnachweis gar nicht traegt, und greift deshalb nie. Ein Administrator kann sich heute selbst loeschen und einen Mandanten ohne Verwaltung zuruecklassen."
|
- "Eine bereits bestehende, heute wirksame Luecke ist geschlossen: der Riegel gegen das Loeschen des eigenen Kontos vergleicht gegen ein Feld, das der Sitzungsnachweis gar nicht traegt, und greift deshalb nie. Ein Administrator kann sich heute selbst loeschen und einen Mandanten ohne Verwaltung zuruecklassen."
|
||||||
- "Die Testlage dieses Bereichs ist repariert und die Form der Luecke ist benannt: zwei vorhandene Testdateien haben KEINE Attrappe fuer das Bindungshilfsmittel und waeren nach der Umstellung aus dem falschen Grund rot geworden, die Steuerungsschicht hat gar keine Testdatei. Nach diesem Durchlauf existiert je Datei ein Zwei-Klienten-Nachweis, dessen Rotwerden durch probeweisen Rueckbau belegt ist."
|
- "Die Testlage dieses Bereichs ist repariert und die Form der Luecke ist benannt: zwei vorhandene Testdateien haben KEINE Attrappe fuer das Bindungshilfsmittel und waeren nach der Umstellung aus dem falschen Grund rot geworden, die Steuerungsschicht hat gar keine Testdatei. Nach diesem Durchlauf existiert je Datei ein Zwei-Klienten-Nachweis, dessen Rotwerden durch probeweisen Rueckbau belegt ist."
|
||||||
- "Klassifikationsdokument und `rls-access-inventory.spec.ts` zeigen fuer alle Paare dieses Bereichs denselben, maschinell gemessenen Stand — einschliesslich des NEUEN Paares, das die Schleife ueber alle Mandanten in `user.service.ts` erzeugt. Uebersichtszeile, Summenzeile, Klassen-Verteilungstabelle samt ihrer Summe und der Abschnitt zur Hintergrunddienst-Falle sind von Hand nachgezogen; genau diese vier Stellen wurden im `dkv`-Durchlauf uebersehen."
|
- "Klassifikationsdokument und `rls-access-inventory.spec.ts` zeigen fuer alle Paare dieses Bereichs denselben, maschinell gemessenen Stand — einschliesslich des NEUEN Paares, das die Schleife ueber alle Mandanten in `user.service.ts` erzeugt. Uebersichtszeile, Summenzeile, Klassen-Verteilungstabelle samt ihrer Summe und der Abschnitt zur Hintergrunddienst-Falle sind von Hand nachgezogen — und jede der vier haengt an einer eigenen maschinellen Pruefung, die die Zahlen aus Quelltext beziehungsweise Bestandsaufnahme neu ableitet, statt nur das Vorhandensein einer Zeile zu bestaetigen. Genau diese vier Stellen wurden im `dkv`-Durchlauf uebersehen; eine Pruefung, die eine stehen gebliebene Fassung bestehen liesse, waere schlimmer als keine, weil sie Sicherheit vortaeuscht."
|
||||||
- "789 Tests und die Typpruefung sind gruen, das Wegwerf-Werkzeug meldet alle Pruefungen bestanden; Schema, Migrationen, alle vier Compose-Dateien und beide Beispiel-Umgebungsdateien sind unveraendert; `DATABASE_URL` zeigt weiterhin auf die Rolle `tessera`, der Schalter bleibt AUS."
|
- "789 Tests und die Typpruefung sind gruen, das Wegwerf-Werkzeug meldet alle Pruefungen bestanden; Schema, Migrationen, alle vier Compose-Dateien und beide Beispiel-Umgebungsdateien sind unveraendert; `DATABASE_URL` zeigt weiterhin auf die Rolle `tessera`, der Schalter bleibt AUS."
|
||||||
artifacts:
|
artifacts:
|
||||||
- apps/api/scripts/rls-scratch-check.mjs
|
- apps/api/scripts/rls-scratch-check.mjs
|
||||||
@@ -893,8 +893,22 @@ Stellen, die im `dkv`-Durchlauf uebersehen wurden, und sie sind alle handgepfleg
|
|||||||
|
|
||||||
- Die Bereichszeile `user` der Uebersichtstabelle mit den bei der Ausfuehrung NEU
|
- Die Bereichszeile `user` der Uebersichtstabelle mit den bei der Ausfuehrung NEU
|
||||||
gemessenen Zahlen fortschreiben, im Stil der bereits fortgeschriebenen Zeilen
|
gemessenen Zahlen fortschreiben, im Stil der bereits fortgeschriebenen Zeilen
|
||||||
(`war X/0` plus eine Begruendung, welche Zugriffe umgestellt wurden und welche
|
(`war 17/0` plus eine Begruendung, welche Zugriffe umgestellt wurden und welche
|
||||||
bewusst nicht). Die Summenzeile mitziehen.
|
bewusst nicht). Die Zahlen werden mit den beiden Befehlen ermittelt, die das
|
||||||
|
Dokument selbst ueber dieser Tabelle nennt — der eine zaehlt die ungebundenen
|
||||||
|
Rohtreffer, der andere die ueber den Namen `tenantPrisma` gebundenen. Die
|
||||||
|
Pruefung dieser Aufgabe ermittelt sie erneut und vergleicht sie gegen die Zeile:
|
||||||
|
das Dokument wird also an den Code angeglichen, nicht umgekehrt. Zur
|
||||||
|
Planungszeit an vier bereits umgestellten Bereichen gegengeprueft, dass diese
|
||||||
|
beiden Befehle deren Tabellenzeilen exakt reproduzieren. Daraus folgt eine
|
||||||
|
Auflage fuer Aufgabe 2 und 3, die sonst still unterlaufen wuerde: der gebundene
|
||||||
|
Klient heisst in jeder Methode `tenantPrisma`, wie in `ldap`, `groups`, `dkv` und
|
||||||
|
`auth` — ein anderer Name wuerde die zweite Zaehlung untertreiben lassen und die
|
||||||
|
Zeile ihrer Aussage berauben.
|
||||||
|
- Die Summenzeile mitziehen. Die Pruefung dieser Aufgabe addiert die zwoelf
|
||||||
|
Bereichszeilen und haelt das Ergebnis gegen die Summenzeile — eine
|
||||||
|
fortgeschriebene Bereichszeile ueber einer stehen gebliebenen Summe faellt damit
|
||||||
|
durch, genau der Fehler, der im `dkv`-Durchlauf durchrutschte.
|
||||||
- Die vier vorhandenen Bestandsaufnahme-Zeilen des Bereichs auf den maschinell
|
- Die vier vorhandenen Bestandsaufnahme-Zeilen des Bereichs auf den maschinell
|
||||||
gemessenen Stand setzen und dabei ZWEI Klassenkorrekturen vornehmen, jede mit
|
gemessenen Stand setzen und dabei ZWEI Klassenkorrekturen vornehmen, jede mit
|
||||||
Begruendung: `user.service.ts`/`user` wechselt wegen der einen bewusst
|
Begruendung: `user.service.ts`/`user` wechselt wegen der einen bewusst
|
||||||
@@ -911,7 +925,15 @@ Stellen, die im `dkv`-Durchlauf uebersehen wurden, und sie sind alle handgepfleg
|
|||||||
wird `rls-access-inventory.spec.ts` rot (Befund N).
|
wird `rls-access-inventory.spec.ts` rot (Befund N).
|
||||||
- Die Klassen-Verteilungstabelle samt ihrer Summe und der Ueberschrift, die die
|
- Die Klassen-Verteilungstabelle samt ihrer Summe und der Ueberschrift, die die
|
||||||
Paarzahl nennt, auf die neuen Zahlen ziehen. Die Zahlen kommen aus der Ausgabe der
|
Paarzahl nennt, auf die neuen Zahlen ziehen. Die Zahlen kommen aus der Ausgabe der
|
||||||
Inventarpruefung, nicht aus einer Rechnung im Kopf.
|
Inventarpruefung, nicht aus einer Rechnung im Kopf. Die Pruefung dieser Aufgabe
|
||||||
|
zaehlt die Klassen ueber die Bestandsaufnahme-Zeilen selbst nach und haelt vier
|
||||||
|
Dinge gegeneinander: jede einzelne Klassenzahl, die Summe der Klassenzeilen, die
|
||||||
|
ausgewiesene Summenzeile und die Paarzahl in der Ueberschrift. Weil dieser
|
||||||
|
Durchlauf mit dem Schleifentreiber ein zusaetzliches Paar erzeugt, wandern alle
|
||||||
|
vier gemeinsam — eine stehen gebliebene faellt durch. Zur Planungszeit gegen das
|
||||||
|
heutige, in sich stimmige Dokument getestet (es besteht) und gegen eine
|
||||||
|
mutierte Fassung, in der genau dieser Fehler nachgestellt wurde (sie faellt
|
||||||
|
durch, mit der Meldung, welche Zahl klemmt).
|
||||||
- Den Abschnitt zum Hintergrunddienst als Falle um den fuenften Fall erweitern und
|
- Den Abschnitt zum Hintergrunddienst als Falle um den fuenften Fall erweitern und
|
||||||
seine Ueberschrift, die heute vier Faelle nennt, mitziehen. Der fuenfte Fall ist die
|
seine Ueberschrift, die heute vier Faelle nennt, mitziehen. Der fuenfte Fall ist die
|
||||||
Standardgruppen-Reparatur beim Start (Befund K) und ist ausdruecklich als der
|
Standardgruppen-Reparatur beim Start (Befund K) und ist ausdruecklich als der
|
||||||
@@ -934,9 +956,9 @@ urspruengliche Text NICHT umgeschrieben — er beschreibt korrekt den Zustand zu
|
|||||||
Zeitpunkt der Umstellung; der Nachtrag steht daneben.
|
Zeitpunkt der Umstellung; der Nachtrag steht daneben.
|
||||||
</action>
|
</action>
|
||||||
<verify>
|
<verify>
|
||||||
<automated>DB_IP=$(docker inspect tessera-ctl-db-1 --format '{{range $k,$v := .NetworkSettings.Networks}}{{$v.IPAddress}}{{end}}') && TESSERA_SCRATCH_ADMIN_URL="postgresql://tessera:tessera_dev@${DB_IP}:5432/postgres" node apps/api/scripts/rls-scratch-check.mjs && npm --prefix apps/api run test && npm --prefix apps/api run type-check && npm --prefix apps/api run test -- src/prisma/rls-access-inventory.spec.ts && test -f apps/api/src/user/user.controller.spec.ts && grep -q '__makeBoundClient' apps/api/src/user/user.controller.spec.ts && grep -qE '^\| apps/api/src/user/user\.controller\.ts \| user \| muss-mandantengebunden \| gebunden \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/user\.service\.ts \| user \| beides \| gemischt \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/user\.service\.ts \| tenant \| keine-mandantengebundene-tabelle \| ungebunden \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/admin-seed\.service\.ts \| user \| beides \| gemischt \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/admin-seed\.service\.ts \| tenant \| keine-mandantengebundene-tabelle \| ungebunden \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^## Der Hintergrunddienst als Falle — fünf Fälle$' docs/mandantentrennung-zugriffsklassifikation.md && test -z "$(git diff --name-only HEAD -- apps/api/prisma apps/api/src/auth apps/api/src/ldap docker-compose.yml docker-compose.dev.yml docker-compose.prod.yml docker-compose.ci.yml .env.example .env.prod.example)"</automated>
|
<automated>DB_IP=$(docker inspect tessera-ctl-db-1 --format '{{range $k,$v := .NetworkSettings.Networks}}{{$v.IPAddress}}{{end}}') && TESSERA_SCRATCH_ADMIN_URL="postgresql://tessera:tessera_dev@${DB_IP}:5432/postgres" node apps/api/scripts/rls-scratch-check.mjs && npm --prefix apps/api run test && npm --prefix apps/api run type-check && npm --prefix apps/api run test -- src/prisma/rls-access-inventory.spec.ts && test -f apps/api/src/user/user.controller.spec.ts && grep -q '__makeBoundClient' apps/api/src/user/user.controller.spec.ts && grep -qE '^\| apps/api/src/user/user\.controller\.ts \| user \| muss-mandantengebunden \| gebunden \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/user\.service\.ts \| user \| beides \| gemischt \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/user\.service\.ts \| tenant \| keine-mandantengebundene-tabelle \| ungebunden \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/admin-seed\.service\.ts \| user \| beides \| gemischt \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^\| apps/api/src/user/admin-seed\.service\.ts \| tenant \| keine-mandantengebundene-tabelle \| ungebunden \|' docs/mandantentrennung-zugriffsklassifikation.md && grep -qE '^## Der Hintergrunddienst als Falle — fünf Fälle$' docs/mandantentrennung-zugriffsklassifikation.md && U=$(grep -ro "this\.prisma\.[a-zA-Z]*" apps/api/src/user | grep -v spec | wc -l | tr -d ' ') && B=$(grep -ro "tenantPrisma\.[a-zA-Z]*\." apps/api/src/user | grep -v spec | wc -l | tr -d ' ') && { test "$U" -lt 17 || { echo "UEBERSICHTSZEILE: ungebundene Rohtreffer in apps/api/src/user sind $U, also nicht gesunken — es wurde nichts umgestellt"; exit 1; }; } && { test "$B" -gt 0 || { echo "UEBERSICHTSZEILE: gebundene Rohtreffer in apps/api/src/user sind $B"; exit 1; }; } && { grep -qE "^\| user \| ${U} \| ${B} \| \*\*war 17/0\*\*" docs/mandantentrennung-zugriffsklassifikation.md || { echo "UEBERSICHTSZEILE user nennt nicht die neu gemessenen Zahlen ${U}/${B} im etablierten Stil"; exit 1; }; } && awk -F'|' '$2 ~ /^ *[a-z][a-z-]* *$/ && $3 ~ /^ *[0-9]+ *$/ && $4 ~ /^ *[0-9]+ *$/ { su+=$3; sb+=$4; n++ } $2 ~ /^ *\*\*Summe\*\* *$/ && $4 !~ /^ *$/ { g3=$3; g4=$4; gsub(/[^0-9]/,"",g3); gsub(/[^0-9]/,"",g4); ru=g3+0; rb=g4+0; seen=1 } END { if (!seen || n+0 != 12) { print "UEBERSICHTSTABELLE nicht erkannt, Bereichszeilen: " n; exit 1 } if (su+0 != ru || sb+0 != rb) { print "SUMMENZEILE stimmt nicht: Bereichszeilen ergeben " su "/" sb ", Summenzeile nennt " ru "/" rb; exit 1 } }' docs/mandantentrennung-zugriffsklassifikation.md && awk -F'|' '$2 ~ /^ *apps\/api\/src\// { k=$4; gsub(/^ +| +$/,"",k); cls[k]++; pairs++ } $2 ~ /^ *(muss-mandantengebunden|keine-mandantengebundene-tabelle|beides|bewusst-uebergreifend) *$/ && $3 ~ /^ *[0-9]+ *$/ && $4 ~ /^ *$/ { k=$2; gsub(/^ +| +$/,"",k); v=$3; gsub(/[^0-9]/,"",v); tab[k]=v+0; tn++ } $2 ~ /^ *\*\*Summe\*\* *$/ && $4 ~ /^ *$/ { v=$3; gsub(/[^0-9]/,"",v); tsum=v+0; tseen=1 } /^## Klassen-Verteilung/ { h=$0; gsub(/[^0-9]/,"",h); hp=h+0; hseen=1 } END { if (tn+0 != 4 || !tseen || !hseen) { print "KLASSEN-VERTEILUNG nicht erkannt: Klassenzeilen " tn ", Summenzeile " tseen ", Ueberschrift " hseen; exit 1 } if (tsum != pairs+0) { print "KLASSEN-SUMME stimmt nicht: Bestandsaufnahme hat " pairs " Paare, Tabellensumme nennt " tsum; exit 1 } if (hp != pairs+0) { print "UEBERSCHRIFT der Klassen-Verteilung nennt " hp " Paare, Bestandsaufnahme hat " pairs; exit 1 } s=0; for (k in tab) { if (tab[k] != cls[k]+0) { print "KLASSE " k ": Tabelle nennt " tab[k] ", Bestandsaufnahme zaehlt " cls[k]+0; exit 1 } s+=tab[k] } if (s != pairs+0) { print "KLASSENZEILEN ergeben " s ", Bestandsaufnahme hat " pairs; exit 1 } }' docs/mandantentrennung-zugriffsklassifikation.md && test -z "$(git diff --name-only HEAD -- apps/api/prisma apps/api/src/auth apps/api/src/ldap docker-compose.yml docker-compose.dev.yml docker-compose.prod.yml docker-compose.ci.yml .env.example .env.prod.example)"</automated>
|
||||||
</verify>
|
</verify>
|
||||||
<done>Alle sieben Zugriffe der Steuerungsschicht laufen ueber `forTenant()` beziehungsweise ueber die uebergreifenden Methoden des Dienstes, deren Rumpf je Mandant gebunden ist; die Rollenverzweigung zwischen mandantengebundener und uebergreifender Sicht ist erhalten und durch Tests belegt; der Riegel gegen das Loeschen des eigenen Kontos greift, und sein Rotwerden vor der Reparatur ist im SUMMARY festgehalten; `apps/api/src/user/user.controller.spec.ts` existiert, nutzt den Zwei-Klienten-Nachweis und deckt die acht in `<behavior>` genannten Faelle ab; der Testlauf ist gruen mit mehr als 789 Tests und die Typpruefung sauber; `rls-access-inventory.spec.ts` laeuft gruen und stimmt mit den fuenf Bestandsaufnahme-Zeilen des Bereichs ueberein, einschliesslich der neu ergaenzten Zeile fuer den Schleifentreiber; die beiden Klassenkorrekturen sind mit Begruendung vollzogen; Uebersichtszeile, Summenzeile, Klassen-Verteilungstabelle samt Summe und Ueberschrift sowie der Abschnitt zur Hintergrunddienst-Falle samt seiner Ueberschrift sind von Hand nachgezogen; die Kritikschrift traegt den Nachtrag mit den tatsaechlich umgesetzten Pfaden; das Wegwerf-Werkzeug meldet alle Pruefungen bestanden; `auth.service.ts`, `ldap.service.ts`, Schema, Migrationen, Compose- und Beispiel-Umgebungsdateien sind unveraendert und `DATABASE_URL` zeigt weiterhin auf die Rolle `tessera`.</done>
|
<done>Alle sieben Zugriffe der Steuerungsschicht laufen ueber `forTenant()` beziehungsweise ueber die uebergreifenden Methoden des Dienstes, deren Rumpf je Mandant gebunden ist; die Rollenverzweigung zwischen mandantengebundener und uebergreifender Sicht ist erhalten und durch Tests belegt; der Riegel gegen das Loeschen des eigenen Kontos greift, und sein Rotwerden vor der Reparatur ist im SUMMARY festgehalten; `apps/api/src/user/user.controller.spec.ts` existiert, nutzt den Zwei-Klienten-Nachweis und deckt die acht in `<behavior>` genannten Faelle ab; der Testlauf ist gruen mit mehr als 789 Tests und die Typpruefung sauber; `rls-access-inventory.spec.ts` laeuft gruen und stimmt mit den fuenf Bestandsaufnahme-Zeilen des Bereichs ueberein, einschliesslich der neu ergaenzten Zeile fuer den Schleifentreiber; die beiden Klassenkorrekturen sind mit Begruendung vollzogen; alle VIER handgepflegten Stellen sind nachgezogen UND einzeln maschinell gegatet — die Uebersichtszeile gegen die am Code neu ermittelten Rohtrefferzahlen, die Summenzeile gegen die Addition der zwoelf Bereichszeilen, die Klassen-Verteilung gegen die ueber die Bestandsaufnahme nachgezaehlten Klassen samt Summe und Ueberschrift, und der Abschnitt zur Hintergrunddienst-Falle gegen seine byte-genaue Ueberschrift; keine dieser vier Pruefungen kann von einer stehen gebliebenen Fassung bestanden werden; die Kritikschrift traegt den Nachtrag mit den tatsaechlich umgesetzten Pfaden; das Wegwerf-Werkzeug meldet alle Pruefungen bestanden; `auth.service.ts`, `ldap.service.ts`, Schema, Migrationen, Compose- und Beispiel-Umgebungsdateien sind unveraendert und `DATABASE_URL` zeigt weiterhin auf die Rolle `tessera`.</done>
|
||||||
</task>
|
</task>
|
||||||
|
|
||||||
</tasks>
|
</tasks>
|
||||||
|
|||||||
Reference in New Issue
Block a user