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) <noreply@anthropic.com>
This commit is contained in:
@@ -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 | `(&<filter>(memberOf=<dn>))`, `: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<username>`, `: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.
|
||||
Reference in New Issue
Block a user