c8de72e762ad942069bde54941623fca6a6642e2
34 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c8de72e762 |
feat(260911-e2s): Benutzerzaehler im TenantController binden (Fan-out je Mandant)
findAll/findOne/remove zaehlen Benutzer je Mandant jetzt ueber drei
gebundene Aufrufstellen (tenantPrisma.user.count mit where: { tenantId
}, in remove zusaetzlich isActive: true) statt ueber den
Relationszaehler, der nach dem Scharfschalten unbemerkt unter der
Regel von User gelaufen waere (260911-e2s, Aufgabe 1, Pruefungen 5-7).
Fan-out-Muster aus UserService.findAllForPlatformAdmin uebernommen; die
vier tenant-Zugriffe bleiben ungebunden (Tenant ohne Regel). Antwortform,
Meldungen und Statuscodes unveraendert.
tenant.controller.spec.ts legt die Testlage aus dem Nichts an (20
Faelle): Zwei-Klienten-Nachweis ueber __makeBoundClient, Rollen-
Metadaten-Test (Klasse SUPER_ADMIN, kein Handler ueberschreibt), Wachhund
gegen mehrfache Klientenerzeugung. Falsifizierungsnachweis durchgefuehrt:
der probeweise ungebundene Zaehler in findOne macht 2 Faelle rot mit
"Cannot read properties of undefined (reading 'count')" — die dkv-Form
der Falsifizierung, nicht nur eine falsche Zahl —, danach zurueckgenommen.
Klassifikation und Entwicklungsanleitung nachgezogen: 64 Paare (ein
neues, tenant.controller.ts/user), Uebersichtszeile 8/3, Klassen-
Verteilung 32 muss-mandantengebunden, Erkennungsluecke fuer
Relationseinbindungen im Kopf der Bestandsaufnahme benannt, "Zwei
belegte Befunde" und "Was diese Etappe NICHT entscheidet" (erster
Punkt aufgeloest). Beide Dokument-Falsifizierungsnachweise durchgefuehrt
(falsche Klasse macht rls-access-inventory.spec.ts rot, falsche
Uebersichtszahl macht das herleitende Gate rot), zurueckgenommen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
|
||
|
|
652e762ad4 |
feat(260911-e2s): Fehlerrichtung fuer Bereich tenant messen — Relationszaehler laeuft unter User
runTenantAreaChecks (9 neue Pruefungen, 6 davon ueber den generierten Client) belegt: auf "Tenant" ist nichts zu binden (keine Regel in allen 34 Migrationen einschliesslich 20260910120000), aber der Relationszaehler in findAll/findOne/remove liefert nach dem Scharfschalten userCount=0 fuer jeden Mandanten und laesst den Loeschriegel T-02-09 vakuum werden — der Fremdschluessel faengt das nur laut (500) statt mit der verstaendlichen 400-Meldung ab. docs/mandantentrennung-etappe2-fehlerrichtung.md bekommt den Abschnitt "## Bereich tenant" (n1-n5) mit der tatsaechlich beobachteten Werkzeugausgabe, der Signaltabelle je Pfad, den Frontend-Stellen, die die falsche Zahl unkommentiert durchlassen, und der Entscheidung zur Anfrageobjekt-Eigenschaft (Vorbereitung fuer Aufgabe 2). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
e0e163ec63 |
docs(quick-260911-cwh): Bereich calendar Etappe 2 abgeschlossen — restliche Dokumentstellen nachgezogen (Aufgabe 3)
- docs/mandantentrennung-zugriffsklassifikation.md: Uebersichtszeile calendar auf 0/12 gezogen (war 12/0, kein ungebundener Rest — erster Bereich in Folge ohne begruendeten Rest), Summenzeile auf 83/159 fortgeschrieben, Klassen-Verteilung unveraendert mit ausdruecklichem Stand-260911-cwh-Vermerk, Hintergrunddienst-Abschnitt um den Sonderfall refreshCacheInBackground (abgekoppelte Fortsetzung, kein sechster Fall) ergaenzt, Abschnitt "Was diese Etappe NICHT entscheidet" um calendar ergaenzt - .planning/WINDOWS.md: neuer offener Eintrag (#26) zur lautlosen Auspraegung der umgekehrten Fehlerrichtung im Bereich calendar, ueber gsd-tools windows append angelegt - Beide Falsifizierungsnachweise durchgefuehrt (falscher Stand macht rls-access-inventory.spec.ts rot; falsche Uebersichtszahl macht das herleitende Gate rot), zurueckgenommen - Etappe 2, neunter Bereich (calendar) abgeschlossen: alle zwoelf Zugriffe gebunden, Baseline gehalten (883 Tests, 57 Dateien, 101 Werkzeugpruefungen, Typpruefung sauber) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
77cb124f59 |
feat(quick-260911-cwh): Bereich calendar binden — alle 12 Zugriffe ueber forTenant() (Aufgabe 2)
- calendar.service.spec.ts: NEU, Zwei-Klienten-Nachweis ueber __makeBoundClient
(Muster dkv.service.spec.ts), Attrappen fuer CryptoService und die drei
Provider, 23 Testfaelle: getSources/addSource, updateSource inkl. drei
Erhaltungsfaelle, alle drei Besitzpruefungen je Ausnahmeart, testConnection
Erfolgs-/Fehlerpfad, aggregateEvents/fetchAndCacheEvents inkl. beider
Synchronstatus-Rueckschreibungen, Cache-Verhalten inkl. Nutzer-Trennung,
testConnectionFromConfig ohne DB-Zugriff, Wachhund fuer genau einen
gebundenen Klienten je Aufruf
- calendar.service.ts: alle 12 Zugriffe auf forTenant() umgestellt, ein
tenantPrisma-Klient je Methode (getSources, addSource, updateSource,
deleteSource, testConnection, fetchAndCacheEvents); Cache-Schluessel-Urteil
und die kein-sechster-Hintergrunddienst-Begruendung als Kommentare
festgehalten
- calendar.controller.ts: alle sechs kontextnutzenden Handler reichen
Benutzer- UND Mandantenkennung aus extractContext durch, keine neue
Vertrauensquelle
- Falsifizierungsnachweis durchgefuehrt: eine Rueckschreibung testweise
entbunden, benannter Test ging rot ("aggregateEvents, Erfolgspfad"), Fund
bestaetigt, zurueckgenommen
- docs/mandantentrennung-zugriffsklassifikation.md: Bestandsaufnahme-Zeile
calendar.service.ts/calendarSource auf gebunden gezogen
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
|
||
|
|
bf5fc4d4c7 |
feat(quick-260911-cwh): Fehlerrichtung Bereich calendar messen (Aufgabe 1)
- rls-scratch-check.mjs: elfter Abschnitt runCalendarAreaChecks mit 13 namentlich benannten Pruefungen gegen die aus 20260909140000_rls_remaining_tenant_tables geschnittene Regel, davon 4 ueber den generierten Client an einer schemagleichen Wegwerf-Tabelle (17 Spalten, gegen schema.prisma laufzeitgeprueft); Laufzeitpruefung, dass 20260910120000 keine eigene CalendarSource-Regel traegt (Messfalle 260910-jab) - Alle 101 Pruefungen bestehen (88 bisherige + 13 neue) - docs/mandantentrennung-etappe2-fehlerrichtung.md: Abschnitt "## Bereich calendar" mit (k1)-(k5) — Messung, Signaltabelle je Pfad, Leere-als-Abwesenheit in Backend UND Frontend samt Fehlerverschluckung, bewusst nicht geloest (Cache-Schluessel-Urteil, Zugangsdaten-Erhaltung, fehlende Benutzerdimension, 403/404), bewusst nicht angefasst - Wettlauf-Fehlerklasse gemessen: PrismaClientKnownRequestError (P2025), NICHT PrismaClientUnknownRequestError wie im Bereich dashboard — Aufgabe 2 braucht deshalb keine neue Fehleruebersetzung fuer die Besitzpruefungen Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
67b50240d6 |
feat(quick-260910-krx): Suchmaschinen gebunden, Katalog begruendet offen, Klassifikation nachgezogen
Aufgabe 3 — TDD zuerst (7 weitere Faelle in dashboard.service.spec.ts, 20 vorher/27 nach dieser Aufgabe), dann die Umstellung: - getSearchProviders/addSearchProvider/removeSearchProvider laufen ueber forTenant(); removeSearchProvider fuehrt Besitzpruefung UND Schreibzugriff ueber DENSELBEN gebundenen Klienten. Die drei Vorgabe-Suchmaschinen aus der Konstante bleiben unveraendert vorangestellt. - Der eine Katalogzugriff (this.prisma.module in getWidgets) bleibt begruendet ungebunden: Messung und Bedingung getrennt (Tabelle traegt heute keinen Zeilenschutz, wirkungslos statt katastrophal — katastrophal erst, wenn Etappe 3 eine Regel gibt), unter Berufung auf die bestehende Werkzeugpruefung module-tabelle-traegt-keinen-zeilenschutz statt einer neuen Behauptung. Ein Wachhund-Testfall haelt den Katalogzugriff aus dem Bindungsprotokoll heraus (und beweist zuerst, dass der Katalogpfad tatsaechlich durchlaufen wird, nicht nur theoretisch geprueft ist). - docs/mandantentrennung-zugriffsklassifikation.md an allen fuenf handgepflegten Stellen nachgezogen: vier Bestandsaufnahme-Zeilen (inkl. eigenstaendiger Nachpruefung der widerlegten SearchProvider-Praemisse), Uebersichtszeile (13/0 -> 1/12), Summenzeile (95/147), Klassen-Verteilung (unveraendert 63 Paare, ausdruecklich vermerkt), Hintergrunddienst- Abschnitt (dashboard hat keinen sechsten Fall, mit Messanweisung), "Was diese Etappe NICHT entscheidet" (dienst-interner forTenant()-Weg wie alle sieben Bereiche vor ihm). - .planning/WINDOWS.md traegt Eintrag #25 (offen, Tabelle + JSON): die beweisvernichtende Schleife (leeres Dashboard -> Neuaufbau -> automatisches Zurueckschreiben -> ueberschriebene Anordnung, Widget- Dubletten) samt der Vorabpruefung fuer Etappe 4 und dem Verweis auf #22 fuer die verwandte Eindeutigkeitsfrage. Zwei weitere Falsifizierungsnachweise durchgefuehrt: (1) den Katalogzugriff probeweise gebunden (tenantPrisma.module.findMany) — acht Tests werden rot mit "TypeError: Cannot read properties of undefined (reading 'findMany')", weil `module` bewusst nicht in der Testdouble-Bindungsliste steht; Rueckbau zurueckgenommen, 27/27 wieder gruen. (2) den Stand von dashboardLayout in der Klassifikationsdatei probeweise auf "ungebunden" gesetzt — rls-access-inventory.spec.ts wird rot mit "Abweichender Stand (Dokument vs. Quelltext): ... dokumentiert=ungebunden, gemessen=gebunden"; Ruecknahme, Testlauf wieder gruen (10/10). Baseline gehalten: 858 Tests / 56 Dateien gruen, Typpruefung sauber, Wegwerf-Werkzeug 87/87. Schalter bleibt aus. |
||
|
|
e0ce594c5a |
feat(quick-260910-krx): Anordnung und Widgets an forTenant() gebunden
Aufgabe 2 — TDD zuerst (20 Faelle in dashboard.service.spec.ts, 8 vorher/12 neu, Zwei-Klienten-Nachweis ueber __makeBoundClient nach dem Muster von module-access.service.spec.ts), dann die Umstellung: - getLayout/saveLayout laufen GEMEINSAM gebunden (ein Testfall nagelt das fest); saveLayout uebersetzt eine gebundene Konflikt-Schreibung (PrismaClientUnknownRequestError, gemessen in Aufgabe 1 — NICHT P2002) in eine deutsche ConflictException. - getWidgets/addWidget/updateWidgetConfig/removeWidget laufen gebunden; die drei Besitzpruefungen ueber die Benutzerkennung bleiben unveraendert bestehen (die Regeln dieses Bereichs kennen keine Benutzerdimension). updateWidgetConfig/removeWidget fuehren Besitzpruefung UND Schreibzugriff ueber DENSELBEN gebundenen Klienten. - dashboard.controller.ts reicht den bereits aufgeloesten Mandanten bei getLayout/updateWidgetConfig/removeWidget durch (keine neue Vertrauensquelle, weiterhin aus extractContext/Sitzungsnachweis). - Der Modulkatalog und die vier Suchmaschinenzugriffe bleiben in dieser Aufgabe unveraendert (Aufgabe 3). - Falsifizierungsnachweis durchgefuehrt: tenantPrisma.widgetInstance.delete probeweise auf this.prisma zurueckgebaut — Test "Widget entfernen: ebenso, beide Abfragen ueber denselben Klienten" wird rot mit "erwarteter gebundener Aufruf widgetInstance.delete(tenant=tenant-1) fehlt im Protokoll"; Rueckbau zurueckgenommen, Testlauf wieder gruen (20/20). Zwei dokumentierte Abweichungen (Rule 3): (1) Befund A hatte fuer widgetInstance sieben Treffer vorhergesagt, gemessen sind sechs (macht zusammen mit dashboardLayout acht statt neun) — der Verify-Schwellwert wird entsprechend auf >=8 gelesen. (2) Die Stand-Spalte fuer dashboardLayout/widgetInstance in der Klassifikationsdatei wird bereits hier minimal nachgezogen (nicht erst in Aufgabe 3), weil rls-access-inventory.spec.ts sonst am Ende dieser Aufgabe rot waere — derselbe Praezedenzfall wie 260910-exd, Aufgabe 2. Baseline gehalten: 851 Tests / 56 Dateien gruen (839 + 12 neue), Typpruefung sauber, Wegwerf-Werkzeug 87/87. |
||
|
|
6744918a01 |
feat(quick-260910-krx): Fehlerrichtung fuer Bereich dashboard gemessen
Aufgabe 1 — misst die umgekehrte Fehlerrichtung des Bereichs dashboard an den Regeln nach Migration 20260910120000, VOR der Umstellung: - rls-scratch-check.mjs bekommt einen neunten Abschnitt (runDashboardAreaChecks) mit 13 neuen, namentlich benannten Pruefungen gegen die aus der ausgelieferten Migration geschnittenen Regeln fuer DashboardLayout, WidgetInstance und SearchProvider. Alle 87 Pruefungen bestehen (74 bisherige + 13 neue). - Die Konfliktmessung (Befund K) ist gemessen, nicht angenommen: ein gebundenes INSERT ... ON CONFLICT auf eine unter dem Mandanten unsichtbare Zeile scheitert laut mit SQLSTATE 42501. Zusaetzlich am echten generierten Prisma Client gemessen: prisma.dashboardLayout.upsert() wirft PrismaClientUnknownRequestError (nicht P2002) — das tenders-Muster laesst sich deshalb nicht woertlich uebernehmen. - Die widerlegte Praemisse zu SearchProvider (WINDOWS #19) ist in diesem Durchlauf eigenstaendig nachgeprueft, mit benannter Suchreichweite. - docs/mandantentrennung-etappe2-fehlerrichtung.md bekommt den Abschnitt "## Bereich dashboard" (w1)-(w5) samt der beweisvernichtenden Schleife (leeres Dashboard -> Neuaufbau -> automatisches Zurueckschreiben -> ueberschriebene Anordnung) und einen Nachtrag im Abschnitt "## Bereich module-registry" zur geerbten Bindungsentlastung. Baseline gehalten: 839 Tests / 56 Dateien gruen, Typpruefung sauber. Schalter bleibt aus. |
||
|
|
03fb3bf9c7 |
docs(quick-260910-jab): Aktenstand kohaerent machen — Ledger, Klassifikation, Kritikschrift, Betriebsanleitung
- WINDOWS.md: #19 auf fixed gesetzt (Tabelle + JSON-Block), mit Beleg (Migrationsname + benannte Pruefungen) und ausdruecklicher Feststellung, dass die SearchProvider-Haelfte als widerlegte Praemisse schliesst, nicht als geloestes Problem. #18/#20/#21/#22/#23 bleiben unveraendert offen. Ein neuer Eintrag #24 haelt den fehlenden Verwaltungsweg fuer plattformweite Zeilen unter der Anwendungsrolle offen (verschwindet nicht mit #19). Die vier Kopfzahlen sind aus dem JSON-Block abgeleitet (6 offen, 17 behoben, 1 zurueckgestellt, 24 gesamt). - Klassifikation: #19-Block von offener Frage zu beantwortet, die Uebersichtszeile tenders (35/27) und Summenzeile (107/135) aus dem Quelltext neu abgeleitet, vier Bestandsaufnahme-Zeilen nachgezogen (searchProvider, groups.service.ts/user, module-grants.service.ts/ moduleGrant, tender-rss-feed.service.ts/tenderRssFeedSource), der Punkt in "Was diese Etappe NICHT entscheidet" aufgeloest. - Kritikschrift: neuer Abschnitt "Regelschluss T-JTS-02, T-JTS-03 und WINDOWS #19" mit tatsaechlich beobachteter Ausgabe, Regelliste der lebenden Datenbank, Signaltabelle mit beiden Fehlerrichtungen je Regel, der neuen Stelle aus Befund F, der selbst ausgefuehrten Messung zur fehlenden Benutzerdimension (keine zweite Sitzungsvariable gefunden) und dem, was dieser Durchlauf nicht loest/nicht anfasst. Fuenf ueberholte Bestandsstellen mit Nachtraegen versehen (g4, t4, die Signaltabellenzeile zu den RSS-Pfaden, drei aufgezeichnete Werkzeugausgaben, m4), die alten Messprotokolle bleiben woertlich stehen. - Betriebsanleitung: die eine Stelle, die #19 als offen fuehrte, nennt jetzt den Aufloesungsstand und WINDOWS #24. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
9c0eefee90 |
feat(quick-260910-exd): ModuleRegistryService binden, Klassifikation abschliessen
- module-registry.service.ts: findActiveForTenant, activateForTenant, isModuleActive binden je einen Aktivierungszugriff, deactivateForTenant bindet beide (Lesen+Schreiben) ueber EINEN Klienten unter tenantPrisma; alle sechs Katalogzugriffe (findAll/findBySlug/beide Existenzpruefungen/isModuleActive-Katalogsuche/seedModule) bleiben bewusst ungebunden, mit Kommentar der Messung von Bedingung trennt - isModuleActive-Kopfkommentar richtiggestellt: der Waechter ruft sie nicht auf (0 Aufrufer, TEIL 3 von Aufgabe 1) — Waechter nimmt findBySlug + ModuleAccessService.getAccessibleModuleIds - module-registry.service.spec.ts: NEU, Zwei-Klienten-Nachweis, deckt die bislang ungetestete Datei mit elf der siebzehn Zugriffe des Bereichs ab, inkl. der lauten (deactivate ohne Aktivierung) und stillen (isModuleActive ohne Aktivierung) Richtung und dem Katalog-Wachhund - tender-scheduler.service.spec.ts: forTenant() auf Identitaet gemockt (dieselbe Konvention wie ldap.service.spec.ts) — cross-area Bruch durch die Umstellung von activateForTenant behoben (Rule 1/3) - docs/mandantentrennung-zugriffsklassifikation.md: alle fuenf handgepflegten Stellen nachgezogen (Bestandsaufnahme, Uebersichtszeile 7/10, Summenzeile 108/134, Klassen-Verteilung unveraendert bei 63 Paaren, Hintergrunddienst-Abschnitt haelt die Abwesenheit eines sechsten Falls fest) — alle gemessen, nicht abgeschrieben, Befund K haelt exakt - docs/mandantentrennung-etappe2-fehlerrichtung.md: Nachtrag mit tatsaechlich umgesetzten Pfaden, beiden Falsifizierungsnachweisen (Testname+Meldung), und der Feststellung zum unveraenderten Controller-Kommentar - .planning/WINDOWS.md: neuer offener Eintrag #23 (deviation) — kein Signal unterscheidet "keine Freigabe" von "Abfrage fand nichts", mit Vorabpruefung fuer Etappe 4 und begruendeter Verwerfung einer Laufzeitwarnung - 833 Tests gruen (56 Dateien), Typpruefung sauber, Wegwerf-Werkzeug 66/66 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
3df72687c1 |
feat(quick-260910-exd): ModuleAccessService an forTenant() binden
- module-access.service.ts: getAccessibleModuleIds (Kurzschlusszweig,
Direktweg, Gruppenweg, Schnittmenge) und getCatalogFlags' eigener
Aktivierungs-Lesezugriff laufen ueber forTenant(), EIN Klient je Methode
unter dem Namen tenantPrisma; der Katalogzugriff in findAccessibleModules
bleibt bewusst ungebunden (Modulkatalog traegt keine Regel), mit Kommentar
der Messung und Bedingung trennt
- Bestehende where-Filter mit tenantId bleiben als zweites Netz stehen
- module-access.service.spec.ts: Zwei-Klienten-Nachweis ueber
__makeBoundClient (Muster aus module-grants.service.spec.ts), alle 15
bestehenden Faelle erhalten, neue Faelle fuer jede in <behavior> genannte
Bindungseigenschaft inkl. Wachhund gegen eine kuenftige Katalogbindung
- module.guard.spec.ts: ein Fall, der die Abwesenheit eines
unterscheidenden Signals fuer "keine Freigabe" vs. "Abfrage fand nichts"
festnagelt
- Falsifizierungsnachweis durchgefuehrt: Gruppenweg-Bindung probeweise
zurueckgebaut, Test "USER-Zweig bindet BEIDE Freigabe-Lesezugriffe..."
wurde rot ("expected 1 to be 2"), Ruecknahme bestaetigt wieder gruen
- mandantentrennung-zugriffsklassifikation.md: Stand fuer
module-access.service.ts/moduleGrant und /tenantModuleActivation auf
gebunden nachgezogen (Rule 3 — sonst waere rls-access-inventory.spec.ts
rot geblieben); die uebrigen vier Bestandsaufnahme-Stellen bleiben
Aufgabe 3 vorbehalten
- 817 Tests gruen (55 Dateien), Typpruefung sauber, Wegwerf-Werkzeug 66/66
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
|
||
|
|
7d45e2fffd |
test(quick-260910-exd): Fehlerrichtung fuer module-registry messen, kein Produktivcode
- rls-scratch-check.mjs: achter Abschnitt runModuleRegistryAreaChecks mit 13
benannten Pruefungen gegen die echten, aus den ausgelieferten Migrationen
geschnittenen Regeln (Group/GroupMembership/ModuleGrant/TenantModuleActivation),
neu angelegt nur: Modulkatalog-Tabelle ohne Zeilenschutz, Eindeutigkeitsindex
auf TenantModuleActivation, zwei Direkt-Freigaben, eine fremde Mitgliedschaft
- Alle 66 Pruefungen bestanden (53 bisherige + 13 neue), 810 Tests gruen,
Typpruefung sauber
- docs/mandantentrennung-etappe2-fehlerrichtung.md: neuer Abschnitt
"Bereich module-registry" mit den fuenf Unterabschnitten (m1-m5), inklusive
Praezisierung aus Befund E (Katalogbindung ist HEUTE wirkungslos, nicht
katastrophal — die Bedingung wird als Bedingung notiert) und der
unbeschoenigten Antwort auf die Signalfrage ("keines")
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
|
||
|
|
3a9391d9c8 |
feat(quick-260910-das): Steuerungsschicht binden, Selbstloesch-Riegel schliessen
- user.controller.ts: alle sieben Zugriffe binden. ADMIN-Zweig der Benutzerliste laeuft ueber forTenant() mit weiterhin bestehender Mandantenbedingung im where; SUPER_ADMIN-Zweig ueber die neue UserService.findAllForPlatformAdmin(). Die drei Wege ueber die Kennung loesen den Zielbenutzer rollenabhaengig ueber resolveTargetUser() auf (ADMIN gebunden an eigenen Mandanten, SUPER_ADMIN uebergreifend); der Schreibzugriff bei update/delete bindet an den Mandanten des Zielbenutzers, nicht des Aufrufers, damit die uebergreifende Verwaltung durch die oberste Rolle erhalten bleibt - Selbstloesch-Riegel (Befund H) repariert: verglich bisher gegen currentUser.sub, ein Feld, das der Sitzungsnachweis nicht traegt -- der Riegel griff nie. Jetzt gegen currentUser.id. Verhaltensaenderung: ein Administrator kann sein eigenes Konto nun nicht mehr loeschen - Alle fuenf Selbstbedienungszugriffe (Bild hochladen/loeschen/ ausliefern, Akzentfarbe) binden an die Mandantenkennung aus dem Sitzungsnachweis - user.controller.spec.ts (neu): Zwei-Klienten-Nachweis fuer die vorher testlose Steuerungsschicht, 8 Testfaelle, Falsifizierungsnachweis fuer eine gebundene Stelle sowie Rot-vor-Reparatur-Nachweis fuer den Selbstloesch-Riegel (siehe SUMMARY) - docs/mandantentrennung-zugriffsklassifikation.md: alle vier handgepflegten Stellen nachgezogen (Uebersichtszeile 8/14, Summenzeile 118/124, Klassen-Verteilung 63 Paare, Hintergrunddienst-Abschnitt auf fuenf Faelle inkl. admin-seed.service.ts als erster beidseitig korrekter Fall) sowie zwei Klassenkorrekturen (user.service.ts/user und admin-seed.service.ts/user je auf "beides") - docs/mandantentrennung-etappe2-fehlerrichtung.md: Nachtrag zum user-Abschnitt mit den tatsaechlich umgesetzten Pfaden, der geschlossenen Luecke und den Falsifizierungsnachweisen - 810 Tests gruen (8 neue in user.controller.spec.ts), Typpruefung sauber, Wegwerf-Werkzeug meldet weiterhin alle 53 Pruefungen bestanden Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
888f66003c |
feat(quick-260910-das): user-Dienst binden, Linie ziehen, Startsperre entschaerfen
- user.service.ts: findById/update/deactivate/delete bekommen einen Pflicht-Mandanten und laufen ueber forTenant(); create/update uebersetzen die plattformweite Eindeutigkeitsverletzung (P2002) in eine deutsche Konfliktmeldung ohne Halter/Mandant zu nennen; zwei neue Methoden (findAllForPlatformAdmin, findByIdForPlatformAdmin) bilden die Plattform-Administratorsicht als Schleife ueber alle Mandanten mit je einem gebundenen Lesezugriff nach; findByUsername bleibt bewusst ungebunden, Kopfkommentar richtiggestellt (Anmeldeweg laeuft seit Etappe 1 ueber SECURITY-DEFINER-Funktionen, kein Aufrufer mehr) - admin-seed.service.ts: Erstanlage-Pruefung bleibt ungebunden (mit Begruendung), Erstanlage des Administrators bindet an den unmittelbar zuvor angelegten Mandanten (Befund J-Korrektur); P2002 bei der Anlage wird wie "Administrator existiert bereits" behandelt statt den Start abzubrechen -- jeder andere Fehler bricht weiterhin ab - user.controller.ts: die vier Aufrufstellen der geaenderten Signaturen auf currentUser.tenantId umgestellt (Signatur-Minimalanpassung; die Rollenlogik inkl. Plattform-Administratorsicht folgt in Aufgabe 3) - Zwei-Klienten-Nachweis in beiden Testdateien (Muster groups.service.spec.ts), Falsifizierungsnachweis fuer beide Bereiche durchgefuehrt und zurueckgenommen (siehe SUMMARY) - docs/mandantentrennung-zugriffsklassifikation.md: Zwischenstand fuer (user.service.ts, user) und (admin-seed.service.ts, user) auf gemischt korrigiert, neue Zeile (user.service.ts, tenant) ergaenzt -- volle Klassenkorrektur mit Begruendung sowie die vier handgepflegten Uebersichtstabellen folgen in Aufgabe 3 - .planning/WINDOWS.md: offener Eintrag fuer die plattformweite Eindeutigkeit von username/email (Produktentscheidung fuer Etappe 3) - 802 Tests gruen (13 neue in user.service.spec.ts, 4 neue in admin-seed.service.spec.ts), Typpruefung sauber, Wegwerf-Werkzeug meldet weiterhin alle 53 Pruefungen bestanden Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
b848ba6baa |
feat(quick-260910-das): messen die Kette user unsichtbar->frei->Eindeutigkeitsfehler
- runUserAreaChecks in rls-scratch-check.mjs: 12 neue Pruefungen gegen die
ausgelieferte User-Policy (baut auf der vom Anmeldeweg-Abschnitt
angelegten Tabelle auf, legt zusaetzlich Tenant ohne Zeilenschutz an)
- Belegt: ungebundene Suche nach vorhandenem Benutzernamen liefert 0
Zeilen, gebundene Suche nach fremdem Benutzernamen ebenso ("frei"), und
das anschliessende gebundene INSERT scheitert hart an SQLSTATE 23505
(Eindeutigkeitsverletzung), nicht an 42501 (Zeilenschutz)
- SQLSTATE wird aus err.meta.code gelesen, nicht err.code (das bei
$executeRaw-Fehlern immer den generischen Prisma-Code P2010 traegt,
empirisch gegen tessera-ctl-db-1 geprueft)
- docs/mandantentrennung-etappe2-fehlerrichtung.md: neuer Abschnitt
"Bereich user" (u1-u5) mit der tatsaechlich beobachteten Ausgabe,
Signaltabelle, der vollstaendigen Kette (Befund L) und den Grenzen zu
auth.service.ts/ldap.service.ts
- Teil 2/3 gemessen: keine Transaktion in apps/api/src/user (Befund B
haelt), findByUsername hat genau einen Treffer, die eigene Definition
(Befund D haelt)
- 789 Tests weiterhin gruen, Typpruefung sauber, Wegwerf-Werkzeug meldet
alle 53 Pruefungen bestanden (41 bisherige + 12 neue)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
|
||
|
|
ccb5996428 | docs(quick-260909-mir): Etappe 2 Bereich dkv abgeschlossen, zwei Doku-Luecken behoben | ||
|
|
5e8237d313 | feat(quick-260909-mir): dkv-Historie und Fahrzeugstammdaten binden, Download-Besitzriegel schliessen | ||
|
|
222f453747 |
feat(quick-260909-mir): dkv-Testlage herstellen, Konfigurationspfade binden, Planer-Pfad benennen
- apps/api/src/dkv/dkv.service.spec.ts (neu): Zwei-Klienten-Nachweis nach dem Muster aus groups.service.spec.ts/tender-triage.service.spec.ts — dieser Bereich hatte vorher KEINE Testdatei (Befund J). 7 Testfaelle decken getConfigForApi, saveConfig (Zugangsdaten-Erhaltung), testConnection, die Verarbeitungsstrecke und den bewusst ungebundenen Planer-Startpfad ab - dkv.service.ts: loadConfig(tenantId?) in zwei Methoden geteilt — loadConfig(tenantId) [Pflicht-Mandant, gebunden] und die neue, eigene Methode loadAnyActiveConfigForScheduler() [bewusst UNGEBUNDEN, eigener Kopfkommentar mit beiden Zustaenden]. getConfigForApi/saveConfig/ testConnection/_runPipeline binden je EINEN Klienten pro Methode vollstaendig ueber forTenant() - dkv-scheduler.service.ts: Kopfkommentar fortgeschrieben (beide Zustaende, Praezedenzfall, Unsymmetrie), Aufruf auf loadAnyActiveConfigForScheduler() umgestellt — an der Ablauflogik des Planers nichts geaendert - .planning/WINDOWS.md: Eintrag #21 (deviation) fuer die benannte Altlast des Planer-Startpfads angelegt - docs/mandantentrennung-zugriffsklassifikation.md: dkvModuleConfig-Zeile auf den jetzt gemessenen Stand "gemischt" nachgezogen (Rule 3 — noetig, damit rls-access-inventory.spec.ts nach der Aufteilung von loadConfig() gruen bleibt; die uebrigen zwei dkv-Zeilen und die Uebersichtstabelle bleiben Aufgabe 3 vorbehalten) - Falsifizierungsnachweis erbracht: getConfigForApi's erster gebundener Client probeweise durch this.prisma ersetzt, genau Test 1 wurde rot (6 andere blieben gruen), Rueckbau zurueckgenommen, Dateien identisch zum Ausgangsstand bestaetigt Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
761e5e2c36 |
feat(quick-260909-mir): dkv-Fehlerform messen und Kritikschrift erweitern
- rls-scratch-check.mjs: runDkvAreaChecks() misst die drei ausgelieferten Policies (DkvInvoiceHistory/DkvModuleConfig/DkvVehicleMaster) wortgleich aus der Migration, plus die Nebenlaeufigkeitsform von getHistory() (Promise.all ueber zwei gebundene Einzelabfragen); alle 9 neuen plus 32 bestehende Pruefungen bestehen (41 gesamt) - Belegt Befund H (kein P2002-Fall, Mandant ist Teil des zusammengesetzten Schluessels) und Befund I (gebundenes INSERT mit fremder tenantId wird ohne eigene WITH-CHECK-Klausel trotzdem abgewiesen) an der echten Datenbank statt am Policy-Text - docs/mandantentrennung-etappe2-fehlerrichtung.md: neuer Abschnitt "Bereich dkv" mit der dritten Fehlerform der Etappe (ein Einzelobjekt wird null, wo null bereits "nicht eingerichtet" bedeutet), der Signaltabelle je umzustellendem Pfad, den sieben Stellen aus Befund K (zerstoerend/lautlos/irrefuehrend) und der ausgeschriebenen Planer-Entscheidung (Form c, mit Unsymmetrie zum ldap-Praezedenzfall) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
df5c5b728b |
feat(laa-03): binde die Je-Treffer-Haelften der Hintergrunddienste und schliesse die Dokumente
tender-digest.scheduler.ts: die uebergreifende Kandidatenabfrage (tenderMatch.findMany mit distinct:['userId']) bleibt bewusst ungebunden und waehlt zusaetzlich das denormalisierte tenantId der Treffer-Zeile mit aus; innerhalb der Schleife binden tenderNotificationPref.findUnique, tenderMatch.findMany/updateMany und user.findUnique an den Mandanten DIESER Kandidatenzeile. tender-matching.service.ts: die Profilabfrage (tenderSavedSearch.findMany) und der Lesezugriff auf den plattformweiten Tender-Katalog (D-03) bleiben ungebunden; innerhalb der Profilschleife bindet die Treffer-Anlage (tenderMatch.upsert), im nachgelagerten Instant-Dispatch binden tenderMatch.findMany/updateMany und user.findUnique — je EIN gebundener Client pro Profil, nicht neu je Treffer. Beide Dateien tragen Codekommentare, die die uebergreifenden Abfragen ausdruecklich als Etappe-3-Uebergabe benennen — die Trennlinie zwischen Etappe 2 und Etappe 3 wird hier gezogen, nicht verwischt. Alle drei betroffenen Testdateien (inkl. der gemeinsamen Integrationsdatei) bekommen den Zwei-Client-Nachweis, Tests fuer Zwei-Mandanten-Laeufe und die lautlose Fehlerform (kein Versand, notifiedAt bleibt NULL). Falsifiziert: ein probeweiser Rueckbau der user.findUnique-Bindung im Instant-Dispatch von tender-matching.service.ts machte genau den erwarteten Test rot, danach zurueckgenommen. rls-access-inventory.spec.ts gemessen und docs/mandantentrennung-zugriffsklassifikation.md nachgezogen: Stand der fuenf betroffenen Paare (tender-digest.scheduler.ts/ tenderMatch,tenderNotificationPref,user; tender-matching.service.ts/ tenderMatch,user) auf gemischt bzw. gebunden; Bereichsuebersicht und Klassen-Verteilung neu gemessen (tenders jetzt 36 ungebunden/26 gebunden); "Der Hintergrunddienst als Falle" um den Abschluss beider Dateien ergaenzt. docs/mandantentrennung-etappe2-fehlerrichtung.md: (t4) um den Nachtrag ergaenzt, dass die Je-Treffer-Haelften geschlossen sind und die uebergreifenden Haelften an Etappe 3 uebergeben bleiben. 770 Tests gruen, Typpruefung sauber, Wegwerf-Werkzeug 32/32, kein Schema-/Migrations-/Compose-/Umgebungsdatei-Diff. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
3336a6e419 |
feat(laa-02): binde die fuenf Nutzer-CRUD-Dienste des Bereichs tenders an forTenant()
tender-saved-search.service.ts, tender-triage.service.ts, tender-notification-pref.service.ts und tender-email-config.service.ts laufen jetzt vollstaendig ueber forTenant() — vier neue Parameter (list, update, remove, listForUser, favoriteIds, getForUser, getConfigForApi, testConnection bekommen tenantId), die anwendungsseitige userId-Filterung bleibt unveraendert (Befund E: die Policies haben keine Benutzerdimension). tender-rss-feed.service.ts bindet nur createForUser (Zaehler + Anlage, beide ausschliesslich auf persoenlichen Zeilen); listForUser, createPlatform und remove bleiben mit Codekommentar bewusst ungebunden (WINDOWS #19 — eine gebundene plattformweite Zeile waere unter jedem Mandanten unsichtbar, ein gebundenes Einfuegen ohne Mandant wuerde abgewiesen). tender-notification-pref.service.ts und tender-email-config.service.ts uebersetzen eine P2002-Verletzung auf dem tenantlosen upsert-Schluessel (Befund F) in eine verstaendliche deutsche Meldung statt eines rohen Fehlers. tenders.controller.ts reicht tenantId an den acht betroffenen Aufrufstellen durch extractTriageContext() durch (kein neuer Aufloesungsweg); die drei RSS-Aufrufstellen bleiben unveraendert, da ihre Dienstmethoden nicht binden. Alle sieben angefassten Testdateien bekommen den Zwei-Client-Nachweis (__makeBoundClient ueber demselben Speicher) und Bindungstests je umgestellter Methode; tender-rss-feed.service.spec.ts zusaetzlich den Gegentest, dass die drei unveraendert bleibenden Pfade forTenant() NICHT aufrufen. Falsifiziert: ein probeweiser Rueckbau der list()-Bindung in tender-saved-search.service.ts machte genau den erwarteten Bindungstest rot, danach zurueckgenommen. docs/mandantentrennung-zugriffsklassifikation.md: Stand der fuenf Paare auf gebunden bzw. gemischt nachgezogen; tenderRssFeedSource von muss-mandantengebunden auf beides umklassifiziert (derselbe Praezedenzfall wie ldapConfig in 260909-ipc). 761 Tests gruen (743 + 18 neue Bindungsnachweise), Typpruefung sauber, Wegwerf-Werkzeug 32/32, kein Schema-/Migrations-/Compose-/ Umgebungsdatei-Diff. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
349814747e |
feat(laa-01): messe die drei Sonderfaelle des Bereichs tenders und schreibe die Fehlerrichtung
rls-scratch-check.mjs bekommt einen fuenften Abschnitt (runTendersAreaChecks) mit den fuenf Policies von TenderEmailConfig/TenderNotificationPref/ TenderRssFeedSource/TenderSavedSearch/TenderTriage, wortgleich aus der ausgelieferten Migration extrahiert. Neun neue Pruefungen belegen: die Policies haben keine Benutzerdimension (Befund E), eine plattformweite RSS-Zeile ist unter jedem Mandantenkontext unsichtbar und ein gebundenes Einfuegen ohne Mandant wird abgewiesen (WINDOWS #19), und ein gebundenes upsert auf eine unsichtbare Zeile verletzt die Eindeutigkeitsbedingung, nicht die Policy (Befund F). Alle 32 Pruefungen (23 bisherige + 9 neue) bestehen. Nachmessung bestaetigt Befund A: genau eine $transaction in diesem Bereich, Array-Form auf der plattformweiten Tabelle Tender, ausserhalb jeder Mandantenbindung — withTenantTransaction() wird hier nicht gebraucht. docs/mandantentrennung-etappe2-fehlerrichtung.md bekommt einen `## Bereich tenders`-Abschnitt mit der beobachteten Messausgabe, einer Signaltabelle je umzustellendem Pfad und einem eigenen Unterabschnitt zur lautlosen Fehlerform der beiden Hintergrunddienste (fuenf benannte Stellen, keine protokolliert etwas). 743 Tests gruen, Typpruefung sauber, kein Schema-/Migrations-/Compose-/ Umgebungsdatei-Diff. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
604428a91d | fix(quick-260909-jts): Lastprobe nachreichen statt sie zu behaupten | ||
|
|
abb6c8bea3 |
feat(jts-03): module-grants.service.ts binden, beide Dokumente schliessen
Alle fuenf Methoden von ModuleGrantsService (assertTargetBelongsToTenant,
grant, revoke, getMatrix, getUserAccess) laufen jetzt ueber forTenant(); bei
den beiden Datenlieferungen teilen sich alle parallel abgesetzten
Teilabfragen denselben gebundenen Client. Die Mandanten-Gegenpruefung vor
jedem Erteilen bleibt ausdruecklich bestehen und bekommt einen Verweis auf
Befund F/T-JTS-03: die Regel auf ModuleGrant prueft nur die
Mandantenkennung der Zeile, nicht die referenzierte Gruppe. Der veraltete
Kommentar ueber der Mitgliedschaftsabfrage im Benutzer-Detail ("kein
forTenant hier") ist durch den neuen Stand ersetzt.
module-grants.service.spec.ts bekommt denselben Bindungsnachweis-Mock wie
groups.service.spec.ts (zwei unterscheidbare Clients ueber demselben
Speicher) und sechs neue Bindungsnachweise; alle 28 Bestandstests bleiben
gruen.
Beide Dokumente geschlossen: die Bereichsuebersicht fuer groups ist neu
gemessen (0 ungebunden, 31 gebunden — ein dokumentierter methodischer
Bodensatz, da die einfache Rohtrefferzaehlung die neun ueber `tx` gebundenen
Zugriffe innerhalb der drei Transaktionen nicht sieht), die
Klassen-Verteilung auf 62 Paare aktualisiert, und der als offen gefuehrte
Befund D aus dem ldap-Abschnitt der Fehlerrichtung ist mit Verweis auf
diesen Durchlauf als erledigt vermerkt (Nachtrag, nicht Neuschrieb). 743
Tests und die Typpruefung gruen; Schema, Migrationen und alle vier
Compose-Dateien unveraendert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR
|
||
|
|
7f08b27eea |
feat(jts-02): groups.service.ts binden, Transaktionen tragfaehig machen, Absicherung sehend machen
prisma-tenant.extension.ts bekommt withTenantTransaction(prisma, tenantId, fn) — die interaktive Transaktion auf dem UNgebundenen Client mit set_config als erster Anweisung direkt auf tx, die in Aufgabe 1 als einzige der drei gemessenen Formen sowohl die Einzelmessung als auch eine Lastprobe unter echter Nebenlaeufigkeit bestand (die Array-Form auf dem gebundenen Client verteilt jede Operation auf eine eigene Teiltransaktion; die interaktive Form auf dem gebundenen Client brach unter 40 parallelen Aufrufen mit P2028 ab). rls-access-inventory.spec.ts bekommt eine dritte Erkennung fuer Modellzugriffe ueber den Rueckgabeparameter einer interaktiven Transaktion (zwei Formen: direkter Empfaenger.$transaction(async...) und das neue Hilfsmittel withTenantTransaction(...)) — macht das Paar (groups.service.ts, tenantModuleActivation) erstmals sichtbar, das bislang keine Pruefung dieses Projekts je gesehen hat. groups.service.ts: alle zwoelf Methoden inklusive der drei Transaktionen (update() isDefault:true, reassignDefaultBeforeDelete(), ensureDefaultGroup()) laufen jetzt ueber den Mandantenkontext. Zaehler und Transaktion in ensureDefaultGroup() sind gemeinsam gebunden (T-JTS-05). addUserToDefaultGroup() prueft neu, dass der Zielbenutzer zum Mandanten gehoert (Befund E, T-JTS-02) — die Regel auf GroupMembership prueft nachweislich nur die Gruppenseite. groups.service.spec.ts bekommt zwei unterscheidbare Clients ueber demselben Speicher-Fake (Muster aus 260909-ipc, auf die interaktive Form uebertragen) und 13 neue Bindungsnachweise; alle 42 Bestandstests bleiben gruen. Klassifikationsdokument nachgezogen. 737 Tests und die Typpruefung gruen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
fd0b9f7d21 |
feat(jts-01): messen statt annehmen — groups-Policies und Transaktionsform vor jedem Dienstcode
rls-scratch-check.mjs bekommt einen vierten Abschnitt (Group/GroupMembership/ ModuleGrant/TenantModuleActivation, Policies woertlich aus den ausgelieferten Migrationen) sowie eine eigene Messung, welche der drei Transaktionsformen (Array auf gebundenem Client, interaktiv auf gebundenem Client, interaktiv auf ungebundenem Client mit set_config auf tx) den Mandantenkontext tatsaechlich auf derselben Verbindung traegt. Ergebnis: Form (i) versagt nachweisbar (unterschiedliche pg_backend_pid() je Teilschritt); Form (ii) und (iii) bestehen die Einzelmessung, aber eine zusaetzliche Lastprobe mit 40 parallelen Aufrufen zeigt, dass Form (ii) unter echter Nebenlaeufigkeit mit P2028 (Transaction API error) abbricht, waehrend Form (iii) 0 Verletzungen zeigt. Die Kritikschrift bekommt einen eigenen groups-Abschnitt mit den tatsaechlich beobachteten Werten, der Signaltabelle je Pfad und der Liste der Stellen, die Leere als Abwesenheit deuten (inkl. der einen Stelle, an der zu wenig Lesen zu viel Schreiben ausloest). Kein Dienstcode angefasst; 719 Tests und die Typpruefung bleiben gruen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
e1586a41dd |
feat(quick-260909-ipc): ldap.service.ts an forTenant() binden, Adress-Kollisionspruefung bewusst uebergreifend belassen
Aufgabe 3 der Etappe 2: elf Abfragen in sechs Methoden (listGroups, upsertMappedUser, searchUsers, importUsersByDn, importGroupsByDn, syncUsersForTenant) laufen jetzt ueber forTenant(), teils mit einem neu erzeugten, teils mit dem in derselben Methode bereits vorhandenen gebundenen Client. resolveEmailForWrite bleibt ausdruecklich ungebunden (Befund A, T-IPC-04): email/username sind plattformweit eindeutig, eine Bindung wuerde einen fremden Halter uebersehen und eine saubere Kollisionsmeldung in einen P2002-Abbruch verwandeln. Ein neuer Testblock biegt forTenant() auf ein zweites, unterscheidbares Client-Objekt um (der bisherige Identitaets-Mock haette die Umstellung nicht bemerkt, Befund F) und belegt damit, dass die Adressabfrage weiterhin am ungebundenen und der Rest am gebundenen Client landet. Alle 67 Bestandstests bleiben unveraendert gruen. docs/mandantentrennung-zugriffsklassifikation.md ist fuer den Bereich ldap geschlossen: gemessener Stand je Fundstelle, neu gerechnete Bereichsuebersicht (gebunden getrennt von ungebunden gezaehlt) und die Uebergabe des Standardgruppen-Punkts an den Bereich groups vor Etappe 4 dokumentiert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
9a57fa79f5 |
feat(quick-260909-ipc): ldap-config.service.ts an forTenant() binden, Loesch-Fremdzugriff schliessen
Aufgabe 2 der Etappe 2: getConfig/createConfig/updateConfig sowie addFieldMapping/removeFieldMapping laufen jetzt ueber forTenant(), gebunden an den aus der Anfrage bekannten Mandanten. removeFieldMapping nimmt den Mandanten neu als Pflichtparameter entgegen und der Controller holt ihn aus dem Sitzungsnachweis statt nur die URL-Kennung weiterzureichen (T-IPC-01) -- ein Administrator konnte bisher die Feldzuordnung eines fremden Mandanten loeschen, wenn er ihre Kennung kannte. getAllActiveConfigs() und die Start-Nachverschluesselung bleiben bewusst uebergreifend, mit ausgeschriebener Begruendung im Code (Befund B). rls-access-inventory.spec.ts erkennt jetzt neben `this.prisma.<Modell>` auch gebundene `<Name>.<Modell>`-Zugriffe (Befund F/G) und prueft eine neue Stand-Spalte (gebunden/ungebunden/gemischt) im Klassifikationsdokument gegen den Quelltext. Das macht zwei bisher unsichtbare, weil schon laenger gebundene Fundstellen sichtbar (auth.service.ts/passwordResetToken, ldap.service.ts/groupMembership) und deckt auf, dass (ldap-config.service.ts, ldapConfig) tatsaechlich "beides" ist, nicht "muss-mandantengebunden" (Befund B). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
a0c9ef070f |
feat(quick-260909-ipc): Fehlerrichtung des Bereichs ldap messen und schriftlich festhalten
Aufgabe 1 der Etappe 2: erweitert das Wegwerf-Werkzeug rls-scratch-check.mjs um fuenf Messungen des forTenant()-Musters gegen die echte, aus der ausgelieferten Migration geschnittene LdapConfig/LdapFieldMapping-Policy unter einer Rolle ohne BYPASSRLS. Belegt insbesondere, dass ein ungebundener Zugriff nach dem Scharfschalten 0 Zeilen liefert, nicht alle -- die Fehlerrichtung dreht sich um. Die neue Kritikschrift docs/mandantentrennung-etappe2-fehlerrichtung.md haelt das schriftlich fest, mit Signaltabelle je Pfad und den vier Stellen, die Leere als Abwesenheit deuten. Kein Dienstcode angefasst. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMASaSxv5QMY7RncqZriRR |
||
|
|
5f3a39c2c3 |
docs(quick-260909-eor): alle 227 Datenbankzugriffe klassifiziert und maschinell abgesichert
WINDOWS #18/#20, Aufgabe 3: docs/mandantentrennung-zugriffsklassifikation.md haelt fuer jede der 227 this.prisma.*-Fundstellen (32 Dateien, zusammengefasst zu 59 Datei-Modell-Paaren) eine Klasse fest — muss-mandantengebunden (31), keine-mandantengebundene-tabelle (16), bewusst-uebergreifend (3, mit ausgeschriebenem Grund) oder beides (9, der Hintergrunddienst-Sonderfall: uebergreifend lesen, je Zeile mandantengebunden schreiben — betrifft ldap.service.ts, tender-digest.scheduler.ts, tender-matching.service.ts). rls-access-inventory.spec.ts ermittelt die Fundstellen bei jedem Testlauf neu aus dem Quelltext und vergleicht sie gegen die Tabelle im Dokument — Datei und Modellname als Schluessel, keine Zeilennummer. Scheitert nachweislich, sobald eine Fundstelle fehlt oder ein Eintrag verwaist (per Testlauf geprueft, danach zurueckgesetzt). Zwei belegte Befunde im Dokument festgehalten: req.tenantPrisma wird gesetzt, aber nirgends gelesen; WINDOWS #19 (nullbares tenantId bei SearchProvider/ TenderRssFeedSource) bleibt benannter Blocker fuer Etappe 3. docs/mandantentrennung-datenbankrolle.md verweist jetzt auf das neue Dokument und korrigiert die ueberholte Zahl 182 auf den nachgemessenen Stand (227/59). WINDOWS.md #18/#19 um Nachtrag auf diesen Plan ergaenzt; #20 (der in Aufgabe 1 gemessene und behobene forTenant()-Verbindungsdefekt) als "fixed" markiert. Deviation (Rule 3, blockierend fuer die Bestandsaufnahme-Pruefung): auth.service.ts-Kommentar umformuliert, der zuvor woertlich "this.prisma.user.findUnique" als erklaerenden Text enthielt und dadurch einen Eigentreffer der grep-basierten Inventur-Pruefung erzeugte. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYZcd3SSmo14QTqWx2KKzU |
||
|
|
44a90e5bfd |
feat(quick-260909-dgj): Pruefwerkzeug fuer den Nachweis plus Betriebsanleitung (Task 3/4)
- apps/api/scripts/rls-preflight.mjs misst fuenf benannte Eigenschaften (rollenrechte, kontext-setzbar, ohne-kontext-leer, mit-kontext-sichtbar, schreibrechte) jeweils in einer eigenen Transaktion gegen eine per TESSERA_PREFLIGHT_DATABASE_URL angegebene Verbindung; --print-plan verbindet nicht, das Werkzeug schreibt in keiner Betriebsart - 5 Tests in rls-preflight.spec.ts (rot vor dem Werkzeug, jetzt gruen) - docs/mandantentrennung-datenbankrolle.md: Befund, Sperrgrund (182 unskalierte Zugriffe, Anmeldeweg), Handgriffe des Betreibers samt Kennwortsetzung, Freigabebedingung und Rueckweg; docs/README.md verweist darauf Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYZcd3SSmo14QTqWx2KKzU |
||
|
|
dab72eb1f9 |
fix(compose): user-files dauerhaft speichern und Betriebshandbuch nachziehen
- docker-compose.yml und docker-compose.prod.yml mounten /app/user-files im Dienst api auf ein neues benanntes Volume user-files (Eigentuemerschaft uid 1001 folgt aus dem Image, kein Bind-Mount) - docker-compose.dev.yml bleibt unveraendert (Compose fuehrt Mount-Listen ueber das Ziel zusammen) - Betriebshandbuch Kapitel 6: Speicher als dauerhaft beschrieben, Mount-Zeile woertlich zum Kopieren, Hinweis dass /opt/tessera/docker-compose.yml auf dem Server separat gepflegt werden muss (Deploy erreicht sie nicht) - Betriebshandbuch Kapitel 7: Fehlerzeile zu verschwundenen Avataren/Exporten an den reparierten Repository-Stand angepasst WINDOWS #17 bleibt offen, bis die Serverdatei manuell ergaenzt ist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYZcd3SSmo14QTqWx2KKzU |
||
|
|
3501eb4dd1 |
docs: Anleitungen fuer Kollegen — Anwender, Administration, Betrieb, Entwicklung
Bisher gab es fuer Kollegen keine Dokumentation: im Projekt lagen nur das CI/CD-Runbook und die Arbeitsanweisungen fuer die Entwicklung. Diese Luecke schliessen vier Anleitungen plus eine Einstiegsseite unter docs/. Alle vier wurden gegen den Quelltext geschrieben, nicht aus der Planung abgeleitet, und anschliessend unabhaengig gegengeprueft: jede zitierte Beschriftung ist woertlich aus de.json belegt, jede beschriebene Funktion im Code nachgewiesen, alle Befehle und Pfade gegen die echten Compose-Dateien, Dockerfiles und package.json-Skripte verifiziert. Die Gegenpruefung fand keine falsche Aussage. Die Einstiegsseite hebt die drei Punkte hervor, die in der Praxis am meisten Zeit gekostet haben: Anmeldung ueber den Benutzernamen statt der E-Mail, der Unterschied zwischen aktiviert und freigegeben, und dass ein blosses 'up -d' die laufenden Container nicht ersetzt. Nebenbefund beim Schreiben des Betriebshandbuchs, als #17 im Ledger erfasst: user-files/ ist in keiner Compose-Datei als Volume eingebunden — hochgeladene Profilbilder und DKV-Exporte ueberleben kein --force-recreate. Noch ohne Schaden, da bisher kein Nutzer ein Profilbild hinterlegt hat. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYZcd3SSmo14QTqWx2KKzU |
||
|
|
c0e32939e7 |
feat(06-03): add act_runner compose definition and CI/CD setup runbook
- docker-compose.ci.yml with act_runner service (ephemeral mode, Docker socket mount) - docs/ci-cd-setup.md runbook covering Gitea remote, runner setup, secrets, security - Registration token referenced from environment, never hardcoded (T-06-08) |