From 149b5aa8107353669406a3c65850b3384e265dd2 Mon Sep 17 00:00:00 2001 From: Schalli Date: Tue, 11 Aug 2026 14:04:53 +0200 Subject: [PATCH] docs(15): write the missing 15-04 summary, closing Phase 15 The AD group membership sync shipped on 2026-08-04 as 614de28; only its summary was never written, which left Phase 15 sitting at 7/8 as if work were outstanding. Nothing was. Each promise the plan made is checked against today's source rather than against the commit message: bound-only selection, no second sync job, deletion restricted to source LDAP, manual memberships preserved, memberOf reverse query instead of attribute reads, RFC-4515 escaping of the group DN, no nested-group resolution, order independence, per-group error isolation. The 2026-08-11 sync run on alpha additionally exercised this path against a real directory. Co-Authored-By: Claude Opus 5 (1M context) --- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 4 +- .../15-04-SUMMARY.md | 64 +++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-04-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index ad3a7df..f2573d8 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -33,7 +33,7 @@ Decimal phases appear between their surrounding integers in numeric order. - [ ] **Phase 12: Tender Notifications** - Configurable digest and instant email alerts without duplicate sends or backfill floods - [ ] **Phase 13: Scraping Adapters & Cross-Source Deduplication** - AI-AG NetServer + cosinex adapters with fuzzy cross-source dedup and a hard denylist for banned portals - [ ] **Phase 14: RSS, Email-Alert Ingestion & Module Rollout** - RSS + email-alert long tail, admin source/mailbox config, excluded-portal transparency, i18n -- [ ] **Phase 15: Modul-Berechtigungen: Gruppen & User-Grants** - Modulzugriff pro Gruppe und pro Benutzer zusätzlich zur Mandanten-Aktivierung, Gruppen mit optionaler AD-Bindung +- [x] **Phase 15: Modul-Berechtigungen: Gruppen & User-Grants** - Modulzugriff pro Gruppe und pro Benutzer zusätzlich zur Mandanten-Aktivierung, Gruppen mit optionaler AD-Bindung (completed 2026-08-04) - [x] **Phase 16: AD-Gruppen-Synchronisation** - Ausgewählte AD-Gruppen werden als Tessera-Gruppen übernommen und in Name, Bestand und Mitgliedschaft nachgeführt (completed 2026-08-11) ## Phase Details @@ -607,5 +607,5 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 | 12. Tender Notifications | 4/4 | In Progress| | | 13. Scraping Adapters & Cross-Source Deduplication | 6/6 | In Progress| | | 14. RSS, Email-Alert Ingestion & Module Rollout | 5/5 | In Progress| | -| 15. Modul-Berechtigungen: Gruppen & User-Grants | 7/8 | In Progress| 15-04 ohne SUMMARY | +| 15. Modul-Berechtigungen: Gruppen & User-Grants | 8/8 | Complete | 2026-08-04 (Bericht 15-04 am 2026-08-11 nachgezogen) | | 16. AD-Gruppen-Synchronisation | 5/5 | Complete | 2026-08-11 | diff --git a/.planning/STATE.md b/.planning/STATE.md index 1a4f669..70d7c5b 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -8,12 +8,12 @@ status: complete stopped_at: Phase 16 abgeschlossen — UAT durchgefuehrt, kritischer Sweep-Fehler gefunden und behoben (260811-f9i), Rest-Annahme A1 bewusst als offen akzeptiert last_updated: "2026-08-11T09:25:00.000Z" last_activity: 2026-08-11 -last_activity_desc: DOE-Bekanntmachungslinks repariert (260811-j04) +last_activity_desc: Phase 15 geschlossen (Bericht 15-04 nachgezogen) progress: total_phases: 16 completed_phases: 15 total_plans: 80 - completed_plans: 78 + completed_plans: 79 --- # Project State diff --git a/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-04-SUMMARY.md b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-04-SUMMARY.md new file mode 100644 index 0000000..bcfa3d3 --- /dev/null +++ b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-04-SUMMARY.md @@ -0,0 +1,64 @@ +--- +phase: 15-modul-berechtigungen-gruppen-user-grants +plan: 04 +status: complete +executed: 2026-08-04 +documented: 2026-08-11 +requirements: [PERM-02] +commits: + - 614de28 feat(15-04) AD-Gruppenmitgliedschafts-Abgleich im bestehenden LDAP-Sync +--- + +# Summary 15-04: AD-Gruppenmitgliedschafts-Abgleich + +## Nachtrag zur Entstehung dieses Berichts + +Die Arbeit wurde am 2026-08-04 mit Commit `614de28` ausgeliefert, der +Abschlussbericht dazu aber nie geschrieben. Dadurch stand Phase 15 auf 7/8, +obwohl nichts fehlte. Dieser Bericht ist am 2026-08-11 nachgezogen worden, +nachdem jede Zusage des Plans gegen den heutigen Stand des Codes geprüft wurde — +nicht gegen die Commit-Nachricht. + +## Was gebaut wurde + +`LdapService.syncGroupMembershipsForTenant()` (privat, `ldap.service.ts:1058`), +aufgerufen aus `syncUsersForTenant()` (`:927`). Für jede Tessera-Gruppe mit +gesetztem `ldapDn` wird per Reverse-Query ermittelt, wer im AD Mitglied ist, und +die Mitgliedschaften werden abgeglichen. + +## Prüfung der Plan-Zusagen gegen den Code (2026-08-11) + +| Zusage | Beleg | +|---|---| +| Gruppe ohne `ldapDn` wird gar nicht angefasst | `findMany({ where: { ldapDn: { not: null } } })`, `:1069` | +| Kein zweiter Sync-Job, kein zweiter Button (D-21) | Aufruf hängt in `syncUsersForTenant`, `:927` | +| Nur `source: 'LDAP'` wird entfernt (D-19) | `deleteMany` mit `source: 'LDAP'`, `:1134-1141` | +| Manuelle Mitgliedschaften bleiben (D-20) | `createMany`/`skipDuplicates`, hebt MANUAL nie auf LDAP an | +| Reverse-Query statt Attribut-Lesen | `(&(memberOf=))`, `:1083` — kein `member`/`memberOf`-Attributzugriff | +| Gruppen-DN RFC-4515-escaped | `LdapService.escapeLdapFilterValue(group.ldapDn)`, `:1083` | +| Verschachtelte Gruppen bewusst nicht aufgelöst | kein `1.2.840.113556.1.4.1941` im Code (0 Treffer) | +| Reihenfolge der AD-Treffer unerheblich | Zwischenergebnis ist ein `Set`, `:1087` | +| Fehler je Gruppe isoliert | try/catch pro Gruppe, Fehlerzeile in `result.errors`, Schleife läuft weiter | + +Tests: `ldap.service.spec.ts`, Block „AD-bound group membership sync +(D-19/D-20/D-21, PERM-02)" — 62 Tests der Datei grün (Stand 2026-08-11). + +## Live belegt + +Der Sync-Lauf auf alpha am 2026-08-11 um 13:32 hat für die AD-gebundene Gruppe +`CN=Claude_VT` 9 Mitgliedschaften angelegt und keine entfernt — der hier +beschriebene Codepfad also nicht nur gegen Mocks, sondern gegen das echte +Verzeichnis. + +## Abweichung vom Plan + +Keine. Der Plan sah zwei Aufgaben vor (Methode + Testsuite), beide sind +umgesetzt. + +## Nachträgliche Änderungen an derselben Datei + +Phase 16 hat `ldap.service.ts` weiterentwickelt (Gruppen-Rekonziliation als +Schritt 5a vor diesem Mitgliedschafts-Abgleich, `syncBoundGroupsForTenant`). +Der hier beschriebene Abgleich ist davon unberührt geblieben; die +Reihenfolge — erst Bestand und Namen, dann Mitgliedschaften — ist in +16-03 bewusst so gewählt worden.