docs(quick-260911-mkj): Abschnitte abgeleitet, WINDOWS #27 geschlossen, Restmenge als eigener Eintrag

- Klassifikationsdokument: Klassen-Verteilung (35/21/14/2, 72 Paare),
  Uebersichtsabsatz (zweite methodische Luecke, geschlossen) und
  Hintergrunddienst-Nachtrag (ldap/getAllActiveConfigs reicht auch in
  LdapFieldMapping hinein) aus Tabelle/Greps abgeleitet, nicht abgeschrieben
- Kritikschrift: Nachtrag (260911-mkj) unter (n4) im Bereich tenant, Vermerk
  im Etappe-2-Abschluss dass #27 geschlossen ist
- WINDOWS.md: #27 fixed (Nachweis: vierte Erkennungsform, Proben,
  Zwischenmessung 7/3/1); neuer Eintrag #33 fuer die Empfaenger ausserhalb
  der vier Erkennungsformen (tenders.seed.ts, backfill-tender-source.ts)
- Spec: WINDOWS #TBD-MKJ-Platzhalter durch #33 ersetzt

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
This commit is contained in:
2026-09-11 16:49:58 +02:00
parent 5ad23d0537
commit 388690fdf0
4 changed files with 104 additions and 14 deletions
@@ -131,6 +131,25 @@ Bodensatz, nicht die vollständige Zahl gebundener Zugriffe in `groups`; die
Bestandsaufnahme unten (Spalte "Stand", je (Datei, Modell)-Paar) ist die
autoritative Quelle.
**Zweite methodische Lücke, seit 260911-mkj geschlossen — aber nur in der
Bestandsaufnahme:** die beiden Rohtreffer-Greps dieser Tabelle
(`this\.prisma\.[a-zA-Z]*` bzw. `tenantPrisma\.[a-zA-Z]*\.`) zählen
Relationsziele (`include:`, `select:`, `_count:`, Relationsfilter in
`where:`/`orderBy:`) strukturell NICHT — ein `include: { module: true }`
auf `tenantPrisma.tenantModuleActivation` erzeugt keinen Rohtreffer auf
`module`, weil `module` in der Datei nie als `tenantPrisma.module` steht.
Die Spalten und die Summenzeile behalten deshalb ihre bisherige Bedeutung
und ihre bisherigen Werte (weiterhin 68 ungebunden / 178 gebunden, NACH-
GERECHNET, nicht abgeschrieben) — sie zählen weiterhin nur direkte
Modellaufrufe. Autoritativ für Relationszugriffe ist allein die
Bestandsaufnahme unten, deren vierte Erkennungsform
(`rls-access-inventory.spec.ts`, `analyzeSource`) die Ziele als eigene
Paare führt: sieben der 72 Paare dort tauchen in KEINER Rohtrefferzahl
dieser Übersicht auf, zum Beispiel
`module-registry/module-access.service.ts`/`group` (nur über den
Relationsfilter `group: { memberships: { some: { userId } } }` sichtbar,
niemals als `tenantPrisma.group` im Quelltext).
| Bereich | Ungebunden | Gebunden | Hinweis |
|---|---|---|---|
| tenders | 35 | 27 | **war 62/0**, dann 36/26 nach 260909-laa — 260910-jab (Aufgabe 2) hat `tender-rss-feed.service.ts`/`listForUser` zusätzlich auf `forTenant()` umgestellt (WINDOWS #19 geschlossen, Befund F: ungebunden hätte die Reparatur den Pfad sonst still auf nur die plattformweiten Zeilen reduziert): ein Rohtreffer wandert von ungebunden nach gebunden (36→35, 26→27). Die 35 verbleibenden ungebundenen Treffer sind die zwölf bewusst nicht angefassten Paare (D-03-Katalog, zwei Fan-out-Adapter) plus die zwei bewusst ungebundenen RSS-Pfade (`createPlatform`/`remove`, WINDOWS #24) plus die übergreifenden Hälften der beiden Hintergrunddienste (Etappe-3-Übergabe) |
@@ -147,7 +166,7 @@ autoritative Quelle.
| settings | 1 | 3 | **war 4/0** — 260911-gwh (Aufgabe 2) hat `getSmtpConfig`, `saveSmtpConfig`, `getDecryptedSmtpConfig` auf `forTenant()` umgestellt (3 gebundene `smtpConfig`-Rohtreffer). Der eine verbleibende ungebundene Rohtreffer ist der umbenannte Planer-Startpfad `loadAnySmtpConfigForStartupTransport()` (Befund D, WINDOWS #30) — bewusst, mit dreifacher Markierung; Befund K (`tenders`/`dkv` hängen an `getDecryptedSmtpConfig`) ist damit erfüllt |
| **Summe** | **68** | **178** | Ungebunden: war 118 nach 260910-das, dann 108 nach 260910-exd (module-registry 17→7), dann 107 nach 260910-jab (`tenders` 36→35, `listForUser` gebunden), dann 95 nach 260910-krx (`dashboard` 13→1), dann 83 nach 260911-cwh (`calendar` 12→0), unverändert nach 260911-e2s (`tenant` bleibt bei 8 ungebundenen Rohtreffern), dann 78 nach 260911-fh9 (`auth` 8→3), jetzt 68 nach 260911-gwh (`favorites` 7→0, `settings` 4→1). Gebunden: war 124, dann 134 nach 260910-exd (zusätzlich 10 in `module-registry`), dann 135 nach 260910-jab (zusätzlich 1 in `tenders`), dann 147 nach 260910-krx (zusätzlich 12 in `dashboard`), dann 159 nach 260911-cwh (zusätzlich 12 in `calendar`), dann 162 nach 260911-e2s (zusätzlich 3 in `tenant`), dann 167 nach 260911-fh9 (zusätzlich 5 in `auth`), jetzt 178 nach 260911-gwh (zusätzlich 8 in `favorites`, 3 in `settings`). Dies ist der ENDSTAND der Etappe 2: jeder verbleibende ungebundene Rohtreffer ist einer der in diesem Dokument benannten, bewusst ungebundenen Fälle. Diese Übersicht ist eine Buchführungshilfe; **autoritativ ist die Fundstellentabelle unten**, die `rls-access-inventory.spec.ts` bei jedem Lauf gegen den Quelltext prüft |
## Klassen-Verteilung (nach (Datei, Modell)-Fundstellen, 65 Paare)
## Klassen-Verteilung (nach (Datei, Modell)-Fundstellen, 72 Paare)
Stand 260909-jts (Aufgabe 3): 61 Paare aus dem vorherigen Durchlauf
(260909-ipc) plus ein bisher vollstaendig unsichtbares Paar
@@ -236,13 +255,36 @@ bestaetigt). Zwei Paare aendern nur ihre `Stand`-Spalte, keine ihrer Klasse:
der ENDSTAND der Etappe 2 — die Zahl ist der Ausgabe von
`rls-access-inventory.spec.ts` entnommen, nicht geschaetzt.
**Stand 260911-mkj (Aufgabe 1/2):** 72 Paare — 65 aus dem Endstand der
Etappe 2 plus SIEBEN neue Paare der vierten Erkennungsform (WINDOWS #27):
`groups/module-grants.service.ts`/`module` (`keine-mandantengebundene-tabelle`,
`gebunden`), `ldap/ldap-config.service.ts`/`tenant`
(`keine-mandantengebundene-tabelle`, `ungebunden`),
`module-registry/module-access.service.ts`/`group` UND `/groupMembership`
(beide `muss-mandantengebunden`, `gebunden`),
`tenders/tender-digest.scheduler.ts`/`tender`
(`keine-mandantengebundene-tabelle`, `gebunden`) UND `/tenderSavedSearch`
(`muss-mandantengebunden`, `gebunden`),
`tenders/tenders.controller.ts`/`tenderSource`
(`keine-mandantengebundene-tabelle`, `ungebunden`). Drei Paare aendern ihren
Stand, eines davon zusaetzlich die Klasse:
`ldap-config.service.ts`/`ldapFieldMapping` wechselt von
`muss-mandantengebunden`/`gebunden` auf `beides`/`gemischt` — der
uebergreifende Planer-Lesepfad `getAllActiveConfigs()` reicht ueber
`include: { fieldMappings: true }` in `LdapFieldMapping` hinein, dieselbe
Unterabfrage-Form, die WINDOWS #27 aufgedeckt hat.
`module-registry.service.ts`/`module` und `tender-matching.service.ts`/
`tender` wechseln je von `ungebunden` auf `gemischt`, ihre Klasse bleibt.
Die Zahl 72 ist der Ausgabe von `rls-access-inventory.spec.ts` entnommen,
nicht geschaetzt.
| Klasse | Anzahl Paare |
|---|---|
| muss-mandantengebunden | 33 |
| keine-mandantengebundene-tabelle | 17 |
| beides | 13 |
| muss-mandantengebunden | 35 |
| keine-mandantengebundene-tabelle | 21 |
| beides | 14 |
| bewusst-uebergreifend | 2 |
| **Summe** | **65** |
| **Summe** | **72** |
## Der Hintergrunddienst als Falle — sechs Fälle
@@ -278,6 +320,19 @@ beim Start — mit einer zusätzlichen Verdeckungsschicht, siehe unten:
Zustand zum Zeitpunkt der ldap-Umstellung korrekt beschreibt und für
spätere Etappen als Beleg dient, siehe auch
`docs/mandantentrennung-etappe2-fehlerrichtung.md`, Abschnitt (e), Befund D.
**Nachtrag (260911-mkj):** WINDOWS #27 geschlossen — derselbe Bereich
`ldap` traegt
einen zweiten, bislang unsichtbaren Planer-Lesezugriff:
`LdapConfigService.getAllActiveConfigs()` (`ldap-config.service.ts`)
reicht ueber `include: { tenant: true, fieldMappings: true }` sowohl in
`Tenant` (schutzlos, harmlos) als auch in `LdapFieldMapping` (geschuetzt
ueber Join auf `LdapConfig`) hinein. Nach dem Scharfschalten verstummt
die Feldzuordnung mit der Elternzeile, nicht getrennt von ihr — der
Etappe-3-Systemkontext muss BEIDE Tabellen sehen. Die Bestandsaufnahme
fuehrt `ldapFieldMapping` deshalb seither als `beides`/`gemischt` statt
`muss-mandantengebunden`/`gebunden` (siehe Bestandsaufnahme unten,
`ldap-config.service.ts`/`ldapFieldMapping`).
- **`tender-digest.scheduler.ts`** (Ausschreibungs-Digest) — **Stand
260909-laa, Aufgabe 3: Je-Treffer-Hälfte geschlossen, übergreifende
Hälfte an Etappe 3 übergeben.** Liest `tenderMatch` (Kandidatenabfrage,