docs(16-03): complete Gruppen-Rekonziliation plan
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
---
|
||||
phase: 16-ad-gruppen-synchronisation
|
||||
plan: 03
|
||||
subsystem: auth
|
||||
tags: [nestjs, prisma, ldap, ldapts, groups, vitest, rls]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 16-ad-gruppen-synchronisation (Plan 16-01)
|
||||
provides: "Group.ldapObjectGuid (Migration angewendet), LdapService.escapeLdapFilterBuffer() (bislang ungenutzt)"
|
||||
- phase: 16-ad-gruppen-synchronisation (Plan 16-02)
|
||||
provides: "GroupsService.reassignDefaultBeforeDelete(tenantId, groupId), GroupsService.ensureDefaultGroup(tenantId), DEFAULT_GROUP_NAME"
|
||||
provides:
|
||||
- "LdapService.syncBoundGroupsForTenant(client, config, tenantId, result): Rename-Erkennung (SC-3), Verschwinden-Loeschung mit Default-Handoff (SC-4/D-05/D-06), Alt-Bindungs-GUID-Nachtrag (D-07), 32-Hex-Validierung vor jeder Filter-Interpolation (T-16-01)"
|
||||
- "LdapSyncResult erweitert um groupsAdopted, groupsRenamed, groupsDeleted, defaultMarkerMoved"
|
||||
- "syncUsersForTenant() Schritt 5a: syncBoundGroupsForTenant() laeuft nachweislich vor Schritt 5b (syncGroupMembershipsForTenant, D-21) — Kernkorrektheitsbedingung der Phase (RESEARCH.md Pitfall 1)"
|
||||
- "LdapService(prisma, userService, groupsService) — dritter Konstruktor-Parameter; LdapModule importiert GroupsModule"
|
||||
affects: [16-04-dialog-umbau, 16-05-anzeige-fallback-frontend]
|
||||
|
||||
# Actuals (#2632)
|
||||
actuals:
|
||||
tokens: 11091
|
||||
tasks: 2
|
||||
commits: 2
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "Erster tatsaechlicher Aufrufer von escapeLdapFilterBuffer() (aus Plan 16-01) — der binaere Existenz-Sweep-Filter (objectGUID=...)"
|
||||
- "Reihenfolge-Kopplung zweier privater Sync-Schritte durch einen beobachtenden Test (Call-Order-Spy via vi.spyOn mit mockImplementation, das die Originalmethode aufruft) statt nur behaupteter Kommentar-Reihenfolge"
|
||||
- "32-Zeichen-Hex-Validierung als eigener Guard VOR jeder Buffer-Rueckwandlung — ein Wert, der die Regex nicht besteht, erzeugt eine Fehlerzeile statt einer Filter-Interpolation (T-16-01)"
|
||||
|
||||
key-files:
|
||||
created: []
|
||||
modified:
|
||||
- apps/api/src/ldap/ldap.service.ts
|
||||
- apps/api/src/ldap/ldap.module.ts
|
||||
- apps/api/src/ldap/ldap.service.spec.ts
|
||||
|
||||
key-decisions:
|
||||
- "syncBoundGroupsForTenant() wird in Task 1 als eigenstaendige, noch nicht eingehaengte Methode gebaut und per direktem Cast ((service as any).syncBoundGroupsForTenant(...)) getestet — die Verdrahtung in syncUsersForTenant() ist bewusst Task 2 vorbehalten (Plan-Vorgabe), damit die Reihenfolge-Korrektheit als eigener, isoliert testbarer Schritt sichtbar bleibt."
|
||||
- "D-21-Testfixtures (Plan 15/vor Plan 16) hatten nie ein ldapObjectGuid-Feld gesetzt. Nach der Verdrahtung in Task 2 durchlaeuft jede dieser Gruppen jetzt zwingend Schritt 5a (Alt-Bindungs-Nachtrag). Statt jede der ueber zehn Test-Fixtures im D-21-Block einzeln um ein Feld zu erweitern, wurde der gemeinsame mockSearch so erweitert, dass er 5a's zwei Filterformen (Backfill-Probe, Existenz-Sweep) deterministisch als No-Op aufloest (DN-abgeleitete GUID, Identitaets-Treffer) — kleinerer, zentralerer Diff als 11 Einzelaenderungen."
|
||||
- "PERM-02 bleibt in REQUIREMENTS.md bewusst auf [ ] (Pending) stehen — dieser Plan liefert Rekonziliation und Verdrahtung, das Requirement schliesst laut Plan-Vorgabe erst mit Plan 16-05."
|
||||
- "A1/A2-Live-Pruefung gegen ViCoTest nicht durchfuehrbar: kein erreichbares Active Directory in dieser Sandbox (Umgebungsvorgabe fuer diesen Lauf). Als offener Punkt im Broken-Windows-Ledger (WINDOWS.md #4) und unten dokumentiert, statt stillschweigend uebersprungen."
|
||||
|
||||
patterns-established:
|
||||
- "Reihenfolge-Kopplung zwischen zwei privaten Sync-Schritten wird durch einen beobachtenden Call-Order-Test abgesichert, nicht nur durch Kommentartext an der Aufrufstelle"
|
||||
|
||||
requirements-completed: [PERM-02] # Plan-Frontmatter-Vertrag; REQUIREMENTS.md-Checkbox bleibt bewusst [ ] (siehe Decisions) — schliesst erst mit Plan 16-05
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "syncBoundGroupsForTenant() erkennt Rename (cn/dn-Aenderung -> Group.name/ldapDn-Update, internalName bleibt unberuehrt) und Verschwinden (kein Treffer -> Loeschung) korrekt, ohne lokale Gruppen (ldapObjectGuid+ldapDn beide null) jemals abzufragen (SC-3/SC-4/SC-5, D-04)"
|
||||
requirement: "PERM-02"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/api/src/ldap/ldap.service.spec.ts#LdapService.syncBoundGroupsForTenant — Rekonziliation gegen das Verzeichnis (SC-3/SC-4/SC-5, D-05/D-06) (14 it-Faelle)"
|
||||
status: pass
|
||||
- kind: other
|
||||
ref: "grep -c internalName im Methodenkoerper (awk-Range) = 0"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D2
|
||||
description: "Loesch-Zweig ruft reassignDefaultBeforeDelete() nachweislich VOR group.delete(); nach jeder Loeschung laeuft ensureDefaultGroup() einmal — kein Mandant bleibt ohne markierte Standardgruppe (D-06, RESEARCH.md Pitfall 5)"
|
||||
requirement: "PERM-02"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/api/src/ldap/ldap.service.spec.ts — Faelle 'no hit, IS the default group...' und 'no hit, is the ONLY group of the tenant...'"
|
||||
status: pass
|
||||
- kind: other
|
||||
ref: "awk-Range-Grep: reassignDefaultBeforeDelete-Zeile < group.delete-Zeile"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D3
|
||||
description: "Alt-Bindungen (ldapDn gesetzt, ldapObjectGuid null) werden per Base-Scoped-Lookup einmalig nachgetragen (groupsAdopted) und im selben Lauf regulaer weiterverarbeitet; loest der DN nicht mehr auf, wird NICHT geloescht, nur eine Fehlerzeile erzeugt (D-07, T-16-11)"
|
||||
requirement: "PERM-02"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/api/src/ldap/ldap.service.spec.ts — Faelle 'a legacy binding ... whose DN still resolves ...' und '... whose DN no longer resolves ...'"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D4
|
||||
description: "Der gespeicherte Hex-Wert wird vor jeder Filter-Interpolation auf exakt 32 [0-9a-f]-Zeichen validiert; ein ungueltiger Wert erzeugt eine Fehlerzeile statt eines Filters (T-16-01)"
|
||||
requirement: "PERM-02"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/api/src/ldap/ldap.service.spec.ts#'an invalid stored ldapObjectGuid (not 32 [0-9a-f] chars) never reaches a filter'"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D5
|
||||
description: "syncBoundGroupsForTenant() laeuft in syncUsersForTenant() nachweislich VOR syncGroupMembershipsForTenant() (Schritt 5a vor 5b); ein im selben Lauf erkannter Rename fuehrt beobachtbar zu keinem memberOf-Filter mit der alten DN mehr (RESEARCH.md Pitfall 1)"
|
||||
requirement: "PERM-02"
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/api/src/ldap/ldap.service.spec.ts#LdapService.syncUsersForTenant — Schrittreihenfolge Gruppen vor Mitgliedschaften (3 it-Faelle: Call-Order-Spy, No-Op-Waechter, Regressions-Filter-Check)"
|
||||
status: pass
|
||||
- kind: other
|
||||
ref: "grep -n Aufrufzeilen: syncBoundGroupsForTenant-Zeile < syncGroupMembershipsForTenant-Zeile"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D6
|
||||
description: "RESEARCH.md-Annahmen A1 (objectGUID uebersteht AD-Umbenennung) und A2 (byteweise Hex-Filter-Syntax vom Ziel-AD akzeptiert) read-only gegen ViCoTest verifiziert, bevor die Loeschsemantik (D-05) als produktionsreif gilt"
|
||||
requirement: "PERM-02"
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "Kein erreichbares Active Directory in dieser Sandbox (Umgebungsvorgabe) — Live-Pruefung nicht durchgefuehrt"
|
||||
status: fail
|
||||
human_judgment: true
|
||||
rationale: "A1/A2 bleiben unverifizierte Annahmen aus RESEARCH.md. Als WINDOWS.md-Eintrag #4 (unrun-verify) festgehalten. Ein negatives Ergebnis bei A1 ODER A2 ist ein Stopp-Grund fuer die Loeschsemantik aus D-05 — vor produktivem Einsatz gegen ViCoTest (balios.ctl.local) nachzuholen."
|
||||
|
||||
duration: 12min
|
||||
completed: 2026-08-06
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Phase 16 Plan 3: Gruppen-Rekonziliation gegen das Verzeichnis Summary
|
||||
|
||||
**syncBoundGroupsForTenant() unterscheidet AD-Umbenennung von AD-Verschwinden ueber den rename-stabilen ldapObjectGuid, laeuft nachweislich vor dem Mitgliedschafts-Abgleich, uebergibt die Standardmarkierung vor jeder Loeschung und traegt Alt-Bindungen aus Plan 15-06 nach — die A1/A2-Live-Pruefung gegen ein echtes Active Directory bleibt offen (kein AD in dieser Sandbox erreichbar).**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 12 min (Commit-Spanne 16:15:09 Uhr bis 16:21:10 Uhr; Lesen von PLAN.md, 16-01-/16-02-SUMMARY.md, PATTERNS.md, RESEARCH.md und der Zieldateien davor nicht mitgerechnet)
|
||||
- **Started:** 2026-08-06T14:15:09Z (erster Task-Commit)
|
||||
- **Completed:** 2026-08-06T14:21:10Z (zweiter Task-Commit)
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 3
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Neue private Methode `LdapService.syncBoundGroupsForTenant()`: fragt alle Gruppen mit gesetztem `ldapObjectGuid` ODER `ldapDn` ab (der D-07-Anschluss fuer Alt-Bindungen), tut fuer eine rein lokale Gruppe (beide Felder `null`) nichts und loest dafuer keine einzige LDAP-Suche aus
|
||||
- Rename-Erkennung (SC-3): ein AD-Treffer mit geaendertem `cn`/`dn` zieht `Group.name`/`Group.ldapDn` nach, `internalName` bleibt in jedem Codepfad der Methode unberuehrt (D-04); ein `P2002` aus einer Namenskollision wird abgefangen und als Fehlerzeile gemeldet, der Lauf geht weiter
|
||||
- Verschwinden-Loeschung (SC-4/D-05): kein Treffer im binaeren Existenz-Sweep loescht die Gruppe — aber immer erst NACH dem Standardmarkierungs-Handoff (`reassignDefaultBeforeDelete`, Plan 16-02), nachweislich in dieser Zeilenreihenfolge; nach jeder Loeschung laeuft `ensureDefaultGroup()` einmal, damit kein Mandant ohne Standardgruppe dasteht (D-06)
|
||||
- Alt-Bindungs-Nachtrag (D-07): eine Gruppe mit `ldapDn`, aber ohne `ldapObjectGuid`, bekommt den Identitaetsschluessel per Base-Scoped-Lookup einmalig nachgetragen (`groupsAdopted`) und wird im selben Lauf reguelaer weiterverarbeitet; loest der DN nicht mehr auf, wird **nicht** geloescht, nur eine Fehlerzeile erzeugt — ohne stabilen Schluessel waere eine Loeschung eine Vermutung
|
||||
- Der gespeicherte Hex-Wert wird vor jeder Filter-Interpolation auf exakt 32 `[0-9a-f]`-Zeichen validiert (T-16-01); ein ungueltiger Wert erzeugt eine Fehlerzeile statt einer Filter-Interpolation
|
||||
- Schritt 5a (`syncBoundGroupsForTenant`) laeuft in `syncUsersForTenant()` nachweislich VOR Schritt 5b (`syncGroupMembershipsForTenant`, D-21) — abgesichert durch einen beobachtenden Call-Order-Test (nicht nur durch Kommentartext), plus einen Regressionstest, der zeigt, dass ein im selben Lauf erkannter Rename zu keinem `memberOf`-Filter mit der alten DN mehr fuehrt
|
||||
- `LdapService`-Konstruktor nimmt neu `GroupsService` entgegen; `LdapModule` importiert `GroupsModule` (kein Zyklus, da `GroupsModule` weder `LdapModule` noch `UserModule` importiert)
|
||||
- 17 neue Testfaelle (14 fuer die neue Methode isoliert, 3 fuer die Verdrahtungsreihenfolge); vollstaendige API-Testsuite gruen: 40 Testdateien, 560 Tests
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: Gruppen-Rekonziliation gegen das Verzeichnis (SC-3, SC-4, SC-5, D-05, D-06)** — `5222934` (feat, tdd)
|
||||
2. **Task 2: Einhaengen als Schritt 5a vor dem Mitgliedschafts-Abgleich (RESEARCH.md Pitfall 1)** — `68aca81` (feat, tdd)
|
||||
|
||||
**Plan metadata:** wird mit diesem Summary committet
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `apps/api/src/ldap/ldap.service.ts` — `LdapSyncResult` um `groupsAdopted`/`groupsRenamed`/`groupsDeleted`/`defaultMarkerMoved` erweitert; Konstruktor nimmt `GroupsService`; neue private Methode `syncBoundGroupsForTenant()`; Aufruf als Schritt 5a in `syncUsersForTenant()` vor Schritt 5b
|
||||
- `apps/api/src/ldap/ldap.module.ts` — `GroupsModule`-Import ergaenzt
|
||||
- `apps/api/src/ldap/ldap.service.spec.ts` — zwei neue `describe`-Bloecke (`syncBoundGroupsForTenant` mit 14 Faellen, `Schrittreihenfolge Gruppen vor Mitgliedschaften` mit 3 Faellen); alle acht `new LdapService(...)`-Konstruktionen um einen dritten Mock-Parameter ergaenzt; D-21-Block-Fixtures um eine 5a-No-Op-Aufloesung im gemeinsamen `mockSearch` erweitert, ohne jede der ueber zehn Einzel-Fixtures anzufassen
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- `syncBoundGroupsForTenant()` wurde in Task 1 bewusst noch NICHT in `syncUsersForTenant()` eingehaengt (Plan-Vorgabe) — Task 1 testet die Methode per direktem Cast auf die private Methode, Task 2 liefert ausschliesslich die Verdrahtung samt Reihenfolge-Test. Diese Trennung macht die zentrale Korrektheitsbedingung der Phase (Reihenfolge) als eigenen, isoliert nachvollziehbaren Schritt sichtbar.
|
||||
- Statt jede der ueber zehn D-21-Test-Fixtures (aus Plan 15, vor Plan 16 gebaut, nie mit `ldapObjectGuid` versehen) einzeln um ein Feld zu erweitern, wurde der gemeinsame `mockSearch` im D-21-Block um eine deterministische No-Op-Aufloesung fuer beide 5a-Filterformen erweitert (DN-abgeleitete GUID, Identitaets-Treffer bei unveraendertem `cn`/`dn`). Kleinerer, zentralerer Diff; die D-21-Tests bleiben inhaltlich unveraendert auf die Mitgliedschafts-Reconciliation fokussiert.
|
||||
- PERM-02 bleibt in `REQUIREMENTS.md` bewusst auf `[ ]` (Pending) — dieser Plan liefert Rekonziliation und Verdrahtung, das Requirement schliesst laut Plan-Vorgabe erst mit Plan 16-05.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 1 - Bug] Bestehender D-21-Test brach nach der additiven `LdapSyncResult`-Erweiterung (exaktes `toEqual`)**
|
||||
- **Found during:** Task 1
|
||||
- **Issue:** Der Test „creates nobody and deactivates nobody when the base DN is empty" verglich `result` per `toEqual` gegen ein Literal ohne die vier neuen Felder — nach der additiven Interface-Erweiterung schlug der Vergleich fehl, obwohl das Verhalten unveraendert korrekt war.
|
||||
- **Fix:** Die vier neuen Felder (`groupsAdopted: 0, groupsRenamed: 0, groupsDeleted: 0, defaultMarkerMoved: 0`) im erwarteten Literal ergaenzt.
|
||||
- **Files modified:** apps/api/src/ldap/ldap.service.spec.ts
|
||||
- **Verification:** `npx vitest run src/ldap/ldap.service.spec.ts` gruen
|
||||
- **Committed in:** 5222934
|
||||
|
||||
**2. [Rule 1 - Bug] Wiederverwendete GUID-Test-Fixture aus Plan 16-01 war tatsaechlich nur 31 Hex-Zeichen lang**
|
||||
- **Found during:** Task 1
|
||||
- **Issue:** Der bestehende `guidBuffer`-Fixture-String im "AD group import"-Block (`'0123456789abcdef0123456789abcde'`) ist bei genauer Zaehlung 31, nicht 32 Zeichen lang — `Buffer.from(..., 'hex')` schneidet das letzte ungerade Zeichen stumm ab und liefert 15 statt 16 Bytes zurueck. Das fiel dort nie auf, weil `importGroupsByDn()` die Laenge nie validiert; die neue 32-Hex-Validierung in `syncBoundGroupsForTenant()` (T-16-01) schlug mit demselben Wert sofort fehl.
|
||||
- **Fix:** Eigene, lokal im neuen `describe`-Block definierte, garantiert 32 Zeichen lange Fixture (`'0123456789abcdef'.repeat(2)`) statt den bestehenden (fehlerhaften) Fixture-String zu teilen. Der bestehende Fixture-String im 16-01-Block wurde NICHT angefasst (aussarhalb des Scopes dieses Plans, dortige Tests bleiben unveraendert gruen).
|
||||
- **Files modified:** apps/api/src/ldap/ldap.service.spec.ts
|
||||
- **Verification:** `npx vitest run src/ldap/ldap.service.spec.ts` gruen, neuer Kommentar dokumentiert den Unterschied explizit
|
||||
- **Committed in:** 5222934
|
||||
|
||||
**3. [Rule 1 - Bug] Verdrahtung in Task 2 brach vier bestehende D-21-Tests (Schritt 5a lief nun ungewollt gegen deren Fixtures)**
|
||||
- **Found during:** Task 2
|
||||
- **Issue:** Nach dem Einhaengen von Schritt 5a liefen die vorher isoliert getesteten D-21-Membership-Tests real durch `syncUsersForTenant()` — deren Gruppen-Fixtures (nur `ldapDn`, kein `ldapObjectGuid`, vor Plan 16 gebaut) loesten in jedem Lauf den Alt-Bindungs-Nachtragspfad aus und produzierten unerwuenschte Fehlerzeilen bzw. veraenderten `result.errors`.
|
||||
- **Fix:** Der gemeinsame `mockSearch` im D-21-`beforeEach` (und die eine Test-lokale Ueberschreibung im „records a search failure"-Test) um eine deterministische Aufloesung beider 5a-Filterformen erweitert (`resolve5aNoOp`-Helfer auf Describe-Ebene), die pro Fixture-Gruppe einen DN-abgeleiteten, immer gueltigen GUID annimmt und einen Identitaets-Treffer liefert — 5a wird dadurch fuer jede D-21-Fixture ein reiner No-Op, ohne die ueber zehn einzelnen `groups = [...]`-Literale anzufassen.
|
||||
- **Files modified:** apps/api/src/ldap/ldap.service.spec.ts
|
||||
- **Verification:** `npx vitest run src/ldap/ldap.service.spec.ts` — alle 55 Faelle gruen; `npx vitest run` — vollstaendige API-Suite (560 Tests) gruen
|
||||
- **Committed in:** 68aca81
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 3 auto-fixed (alle Rule 1, direkte Folgen der additiven Interface-Erweiterung bzw. der Verdrahtung — kein Scope Creep, kein Architekturwechsel)
|
||||
**Impact on plan:** Keine Auswirkung auf Funktionalitaet oder Scope der neuen Methode selbst — alle drei Korrekturen betrafen ausschliesslich bestehende Testinfrastruktur, die durch additive/verdrahtende Aenderungen aus diesem Plan beruehrt wurde.
|
||||
|
||||
## Outstanding Live Verification (A1/A2)
|
||||
|
||||
**RESEARCH.md fuehrt zwei Annahmen, die dieser Plan gegen ein echtes Active Directory pruefen sollte (Task 2 `<human-check>`), aber in dieser Sandbox nicht pruefen konnte — es ist kein Active-Directory-Server erreichbar (Umgebungsvorgabe fuer diesen Ausfuehrungslauf, siehe `<environment>` im Auftrag):**
|
||||
|
||||
1. **A1 — `objectGUID` uebersteht eine reine CN-Umbenennung unveraendert.** Unverifiziert. Die gesamte Rename-Erkennung (SC-3) haengt an dieser Annahme — ist sie falsch, wuerde jede echte AD-Umbenennung weiterhin wie ein Verschwinden+Neuanlage behandelt.
|
||||
2. **A2 — die byteweise `\XX`-Hex-Escaping-Syntax fuer den binaeren `(objectGUID=...)`-Filter wird vom Ziel-AD korrekt interpretiert.** Unverifiziert. Ist sie falsch, liefert der Existenz-Sweep fuer JEDE gebundene Gruppe null Treffer — SC-4 (Loeschung) wuerde dann faelschlich auf jede weiterhin existierende Gruppe angewendet.
|
||||
|
||||
**Beide Antworten stehen noch aus.** Sie sind als offener Eintrag im projektweiten Broken-Windows-Ledger festgehalten: `.planning/WINDOWS.md` Eintrag #4 (kind: `unrun-verify`, phase: 16). Ein negatives Ergebnis bei A1 ODER A2 ist ein **Stopp-Grund fuer die Loeschsemantik aus D-05** — die Implementierung darf in diesem Fall NICHT einfach "umgebogen" werden (so RESEARCH.md/PLAN.md ausdruecklich), sondern erfordert eine erneute Planungsentscheidung. Vor produktivem Einsatz der Loeschsemantik muss die read-only Pruefung gegen ViCoTest (`balios.ctl.local`) aus `16-VALIDATION.md` nachgeholt werden: (1) eine AD-Gruppe suchen, `objectGUID` notieren, im AD umbenennen, erneut suchen, GUID vergleichen; (2) eine Suche mit dem byteweise escaped `objectGUID`-Filter absetzen und pruefen, ob sie exakt diese Gruppe zurueckliefert.
|
||||
|
||||
Gemaess `workflow.human_verify_mode: end-of-phase` wurde dieser Plan trotz der offenen Pruefung bis zum Ende ausgefuehrt, statt mittendrin anzuhalten — die offene Verifikation ist hier klar dokumentiert und im Ledger sichtbar, nicht stillschweigend uebersprungen.
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
Siehe Deviations oben — alle drei Punkte betrafen ausschliesslich bestehende Testinfrastruktur, die durch die additiven bzw. verdrahtenden Aenderungen dieses Plans beruehrt wurde, nicht die fachliche Logik der neuen Methode selbst.
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None — keine externe Service-Konfiguration erforderlich. Der laufende Docker-Stack (lokal) wurde von diesem Plan nicht angefasst; die Aenderungen liegen im Quellcode und werden erst mit einem `--build`/`--force-recreate` durch den Nutzer wirksam. Kein Deploy auf den Testserver durch diesen Lauf (Projektregel).
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
- `syncBoundGroupsForTenant()` ist vollstaendig implementiert, verdrahtet und getestet — die Kernkorrektheitsbedingung der Phase (Reihenfolge vor dem Mitgliedschafts-Abgleich) ist durch einen beobachtenden Test abgesichert, nicht nur behauptet
|
||||
- Plan 16-04 (Dialog-Umbau) und 16-05 (Anzeige-Fallback Frontend, Requirement-Abschluss PERM-02) koennen auf dieser Grundlage aufsetzen
|
||||
- **Offener Punkt bleibt bestehen (WINDOWS.md #4):** A1/A2-Live-Pruefung gegen ein echtes Active Directory (ViCoTest) muss nachgeholt werden, bevor die Loeschsemantik aus D-05 als produktionsreif gilt — siehe Abschnitt „Outstanding Live Verification" oben
|
||||
|
||||
---
|
||||
*Phase: 16-ad-gruppen-synchronisation*
|
||||
*Completed: 2026-08-06*
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
Alle 3 in diesem Plan genannten Quelldateien sowie dieses Summary existieren auf der Festplatte; beide Task-Commit-Hashes (5222934, 68aca81) sind im lokalen Git-Log auffindbar.
|
||||
Reference in New Issue
Block a user