Files
schalli 149b5aa810
Tessera CI/CD / Lint & Type Check (push) Successful in 47s
Tessera CI/CD / Tests (push) Successful in 49s
Tessera CI/CD / Build & Publish Images (push) Successful in 7s
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>
2026-08-11 14:04:53 +02:00

2.8 KiB

phase, plan, status, executed, documented, requirements, commits
phase plan status executed documented requirements commits
15-modul-berechtigungen-gruppen-user-grants 04 complete 2026-08-04 2026-08-11
PERM-02
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.