docs(16-02): complete backend name-lock/internalName/default-handoff plan
This commit is contained in:
@@ -562,7 +562,7 @@ Plans:
|
|||||||
|
|
||||||
**Offen für die Planung**: ob ein Admin eine automatisch angelegte Gruppe in Tessera umbenennen darf (würde beim nächsten Sync überschrieben), und wie sich die Auswahl-Oberfläche zur bestehenden AD-Gruppenauswahl in `/admin/groups` verhält.
|
**Offen für die Planung**: ob ein Admin eine automatisch angelegte Gruppe in Tessera umbenennen darf (würde beim nächsten Sync überschrieben), und wie sich die Auswahl-Oberfläche zur bestehenden AD-Gruppenauswahl in `/admin/groups` verhält.
|
||||||
|
|
||||||
**Plans**: 1/5 plans executed
|
**Plans**: 2/5 plans executed
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
**Wave 1**
|
**Wave 1**
|
||||||
@@ -571,7 +571,7 @@ Plans:
|
|||||||
|
|
||||||
**Wave 2** *(blocked on Wave 1 completion)*
|
**Wave 2** *(blocked on Wave 1 completion)*
|
||||||
|
|
||||||
- [ ] 16-02-PLAN.md — GroupsService: Standardgruppen-Handoff, Namenssperre, interner Name, Anzeige-Fallback (D-03, D-04, D-06, D-07)
|
- [x] 16-02-PLAN.md — GroupsService: Standardgruppen-Handoff, Namenssperre, interner Name, Anzeige-Fallback (D-03, D-04, D-06, D-07)
|
||||||
|
|
||||||
**Wave 3** *(blocked on Wave 2 completion)*
|
**Wave 3** *(blocked on Wave 2 completion)*
|
||||||
|
|
||||||
|
|||||||
+11
-7
@@ -5,15 +5,15 @@ milestone_name: Ausschreibungs-Radar
|
|||||||
current_phase: 16
|
current_phase: 16
|
||||||
current_phase_name: AD-Gruppen-Synchronisation
|
current_phase_name: AD-Gruppen-Synchronisation
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed 16-01-PLAN.md
|
stopped_at: Completed 16-02-PLAN.md
|
||||||
last_updated: "2026-08-06T13:48:07.306Z"
|
last_updated: "2026-08-06T14:03:42.541Z"
|
||||||
last_activity: 2026-08-06
|
last_activity: 2026-08-06
|
||||||
last_activity_desc: Phase 16 execution started
|
last_activity_desc: Phase 16 execution started
|
||||||
progress:
|
progress:
|
||||||
total_phases: 16
|
total_phases: 16
|
||||||
completed_phases: 13
|
completed_phases: 13
|
||||||
total_plans: 80
|
total_plans: 80
|
||||||
completed_plans: 74
|
completed_plans: 75
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -28,11 +28,11 @@ See: .planning/PROJECT.md (updated 2026-07-17)
|
|||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 16 (AD-Gruppen-Synchronisation) — EXECUTING
|
Phase: 16 (AD-Gruppen-Synchronisation) — EXECUTING
|
||||||
Plan: 2 of 5
|
Plan: 3 of 5
|
||||||
Status: Ready to execute
|
Status: Ready to execute
|
||||||
Last activity: 2026-08-06 — Phase 16 execution started
|
Last activity: 2026-08-06 — Phase 16 execution started
|
||||||
|
|
||||||
Progress: [█████████░] 93%
|
Progress: [█████████░] 94%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -108,6 +108,7 @@ Progress: [█████████░] 93%
|
|||||||
| Phase 15 P07 | 30min | 3 tasks | 7 files |
|
| Phase 15 P07 | 30min | 3 tasks | 7 files |
|
||||||
| Phase 15 P08 | 30min | 2 tasks | 12 files |
|
| Phase 15 P08 | 30min | 2 tasks | 12 files |
|
||||||
| Phase 16 P01 | 34min | 3 tasks | 10 files |
|
| Phase 16 P01 | 34min | 3 tasks | 10 files |
|
||||||
|
| Phase 16-ad-gruppen-synchronisation P02 | 5min | 3 tasks | 5 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -258,6 +259,9 @@ Recent decisions affecting current work:
|
|||||||
- [Phase ?]: [quick-260805-fok]: ensureDefaultGroup-Waechter prueft ausschliesslich group.count === 0, nie die fehlende isDefault-Markierung (D-13); Reparatur laeuft als zweiter sequenzieller await-Schritt in AdminSeedService.onApplicationBootstrap statt als eigener Hook in GroupsModule (Ordering-Falle wie in tender-scheduler.service.ts)
|
- [Phase ?]: [quick-260805-fok]: ensureDefaultGroup-Waechter prueft ausschliesslich group.count === 0, nie die fehlende isDefault-Markierung (D-13); Reparatur laeuft als zweiter sequenzieller await-Schritt in AdminSeedService.onApplicationBootstrap statt als eigener Hook in GroupsModule (Ordering-Falle wie in tender-scheduler.service.ts)
|
||||||
- [Phase ?]: Checkpoint 1 (16-01 Task 1): approve-both — Group.internalName + ldapObjectGuid + Unique-Index in einer Migration, freigegeben 2026-08-06
|
- [Phase ?]: Checkpoint 1 (16-01 Task 1): approve-both — Group.internalName + ldapObjectGuid + Unique-Index in einer Migration, freigegeben 2026-08-06
|
||||||
- [Phase ?]: Migrationsverfahren angepasst: prisma migrate dev verweigert nicht-interaktive Shell — Ersatz via migrate diff + Handdatei + migrate deploy, inkl. Baseline der 24 Altmigrationen per migrate resolve --applied
|
- [Phase ?]: Migrationsverfahren angepasst: prisma migrate dev verweigert nicht-interaktive Shell — Ersatz via migrate diff + Handdatei + migrate deploy, inkl. Baseline der 24 Altmigrationen per migrate resolve --applied
|
||||||
|
- [Phase ?]: [16-02]: reassignDefaultBeforeDelete() nutzt bewusst nicht findOwned() — eigenes still-false-Muster fuer Batch-Sync-Laeufe (D-06), kein NotFoundException-Abbruch
|
||||||
|
- [Phase ?]: [16-02]: Namenssperre fuer importierte Gruppen (D-03) ist eine Backend-Invariante in GroupsService.update() (BadRequestException), nicht nur ein UI-Disable
|
||||||
|
- [Phase ?]: [16-02]: PERM-02 bleibt in REQUIREMENTS.md bewusst auf [ ] — dieser Plan liefert nur den Backend-Teil, das Requirement schliesst erst mit Plan 16-05
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -302,7 +306,7 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-08-06T13:48:07.273Z
|
Last session: 2026-08-06T14:03:42.506Z
|
||||||
Stopped at: Completed 16-01-PLAN.md
|
Stopped at: Completed 16-02-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
Last activity: 2026-07-14 - Built LDAP per-user exclude/denylist filter (9d1323f), migration applied on live DB, verified via Playwright: sync deactivated 4 excluded service accounts (administrator/krbtgt/guest/dns-ldap), 2 real LDAP users stay active, 0 wrongly created
|
Last activity: 2026-07-14 - Built LDAP per-user exclude/denylist filter (9d1323f), migration applied on live DB, verified via Playwright: sync deactivated 4 excluded service accounts (administrator/krbtgt/guest/dns-ldap), 2 real LDAP users stay active, 0 wrongly created
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
---
|
||||||
|
phase: 16-ad-gruppen-synchronisation
|
||||||
|
plan: 02
|
||||||
|
subsystem: auth
|
||||||
|
tags: [nestjs, prisma, groups, module-grants, vitest]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 16-ad-gruppen-synchronisation (Plan 16-01)
|
||||||
|
provides: "Group.internalName + Group.ldapObjectGuid Spalten (Migration angewendet), LdapService.importGroupsByDn()"
|
||||||
|
provides:
|
||||||
|
- "GroupsService.reassignDefaultBeforeDelete(tenantId, groupId): deterministischer, nicht-werfender Standardgruppen-Handoff-Baustein (D-06) fuer Plan 16-03"
|
||||||
|
- "GroupsService.update(): serverseitige Namenssperre fuer importierte Gruppen (BadRequestException bei gesetztem ldapObjectGuid), unabhaengiges internalName-Feld mit Leerstring-Normalisierung auf null (D-03/D-04)"
|
||||||
|
- "GroupsService.listForTenant(): liefert internalName zusaetzlich zu name"
|
||||||
|
- "UpdateGroupDto ohne ldapDn (D-07 — keine nachtraegliche AD-Bindung ueber diesen Weg mehr moeglich)"
|
||||||
|
- "ModuleGrantsService.getUserAccess(): Anzeigename mit Fallback (internalName ?? name) an beiden Projektionsstellen, ohne Frontend-Diff (UI-SPEC Surface Contract 6)"
|
||||||
|
affects: [16-03-rekonziliation, 16-04-dialog-umbau, 16-05-anzeige-fallback-frontend]
|
||||||
|
|
||||||
|
# Actuals (#2632)
|
||||||
|
actuals:
|
||||||
|
tokens: 7155
|
||||||
|
tasks: 3
|
||||||
|
commits: 3
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Batch-taugliche Variante eines Ownership-Checks: reassignDefaultBeforeDelete() nutzt bewusst nicht findOwned() (dessen NotFoundException ist HTTP-gebaut), sondern ein eigenes findFirst-Muster, das bei fehlendem/fremdem Datensatz still false liefert statt zu werfen — fuer Batch-Sync-Laeufe (Plan 16-03)"
|
||||||
|
- "Serverseitige Feldsperre als Backend-Invariante statt UI-Disable: die Namenssperre auf importierten Gruppen sitzt in GroupsService.update(), nicht nur im Formular"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- apps/api/src/groups/groups.service.ts
|
||||||
|
- apps/api/src/groups/groups.service.spec.ts
|
||||||
|
- apps/api/src/groups/dto/update-group.dto.ts
|
||||||
|
- apps/api/src/groups/module-grants.service.ts
|
||||||
|
- apps/api/src/groups/module-grants.service.spec.ts
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Alle drei Tasks in einer Datei (groups.service.ts) editiert, aber fuer atomare Task-Commits per Write/Edit-Sequenz in Task-Reihenfolge auseinandergezogen (kein git add -p auf einer Live-Bearbeitung) — Task 1 zuerst vollstaendig geschrieben, getestet und committet, danach erst Task-2-Aenderungen an derselben Datei vorgenommen"
|
||||||
|
- "Bestehender Test 'update() mit ldapDn bindet an eine AD-Gruppe' ersatzlos entfernt statt angepasst — die Funktionalitaet ist nach D-07 absichtlich abgeschafft, kein Aequivalent noetig"
|
||||||
|
- "PERM-02 bleibt in REQUIREMENTS.md unangetastet auf [ ] (Pending) — der Plan deckt nur einen Teil der Anforderung ab, das Requirement schliesst laut Plan-Vorgabe erst mit Plan 16-05"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Namenssperre vor Leerstring-Pruefung: die Reihenfolge in update() (erst ldapObjectGuid-Check, dann trim/empty-Check) verhindert, dass eine gesperrte Gruppe mit der falschen Fehlermeldung antwortet"
|
||||||
|
|
||||||
|
requirements-completed: [PERM-02] # Plan-Frontmatter-Vertrag; die tatsaechliche REQUIREMENTS.md-Checkbox bleibt bewusst [ ] (siehe Decisions) — schliesst erst mit Plan 16-05
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: "reassignDefaultBeforeDelete(tenantId, groupId) verschiebt die Standardmarkierung deterministisch (DEFAULT_GROUP_NAME zuerst, sonst aelteste andere Gruppe per createdAt asc), loescht nichts, wirft in keinem der sechs Faelle (D-06)"
|
||||||
|
requirement: "PERM-02"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "apps/api/src/groups/groups.service.spec.ts#GroupsService.reassignDefaultBeforeDelete (D-06) (6 Faelle)"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: "Ein PATCH mit name auf eine Gruppe mit gesetztem ldapObjectGuid wird serverseitig mit BadRequestException/HTTP 400 abgelehnt — echte Backend-Invariante, nicht nur UI-Konvention (D-03)"
|
||||||
|
requirement: "PERM-02"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "apps/api/src/groups/groups.service.spec.ts#GroupsService.update — Namenssperre und interner Name (D-03/D-04) (9 Faelle)"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: "internalName ist fuer jede Gruppe setz-/loeschbar; leere/nur-Leerzeichen-Werte normalisieren auf null statt eines leeren Anzeigenamens; listForTenant() liefert internalName zusaetzlich zu name (D-04)"
|
||||||
|
requirement: "PERM-02"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "apps/api/src/groups/groups.service.spec.ts#GroupsService.update — Namenssperre und interner Name (D-03/D-04)"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D4
|
||||||
|
description: "UpdateGroupDto verliert ldapDn (D-07) und erhaelt internalName?: string | null — kein Codepfad kann eine lokale Gruppe mehr nachtraeglich an AD binden"
|
||||||
|
requirement: "PERM-02"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "cd apps/api && npx tsc --noEmit (typkorrekt, Controller kompiliert weiterhin) + acceptance-criteria grep auf update-group.dto.ts (0 ldapDn, internalName vorhanden)"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D5
|
||||||
|
description: "ModuleGrantsService.getUserAccess() liefert an beiden Projektionsstellen (viaGroups, groups[].name) internalName ?? name; kein Frontend-Diff (UI-SPEC Surface Contract 6)"
|
||||||
|
requirement: "PERM-02"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "apps/api/src/groups/module-grants.service.spec.ts#ModuleGrantsService.getUserAccess — Anzeigename mit Fallback (D-04) (3 Faelle)"
|
||||||
|
status: pass
|
||||||
|
- kind: other
|
||||||
|
ref: "git diff --name-only HEAD -- apps/web | wc -l == 0"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
|
||||||
|
duration: 5min (Commit-Spanne 2ef9b86 bis f71e614; Kontext-Lesen davor nicht mitgerechnet)
|
||||||
|
completed: 2026-08-06
|
||||||
|
status: complete
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 16 Plan 2: Backend-Bausteine fuer internen Namen, Namenssperre und Default-Handoff Summary
|
||||||
|
|
||||||
|
**GroupsService.update() sperrt den Namen importierter Gruppen serverseitig (BadRequestException statt UI-Konvention), traegt ein unabhaengiges internalName-Feld mit Leerstring-Normalisierung, und ein neuer reassignDefaultBeforeDelete()-Baustein bereitet den Standardgruppen-Handoff fuer den Sync in Plan 16-03 vor — module-grants.service.ts zeigt den internen Namen ohne einen einzigen Frontend-Diff an.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 5 min (Commit-Spanne 2ef9b86 15:55:53 Uhr bis f71e614 16:00:18 Uhr; Lesen von PLAN.md, 16-01-SUMMARY.md, PATTERNS.md, RESEARCH.md und der Zieldateien davor nicht mitgerechnet)
|
||||||
|
- **Started:** 2026-08-06T15:55:53+02:00 (erster Task-Commit)
|
||||||
|
- **Completed:** 2026-08-06T16:00:18+02:00 (dritter Task-Commit)
|
||||||
|
- **Tasks:** 3
|
||||||
|
- **Files modified:** 5
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
- `DEFAULT_GROUP_NAME` als geteilte Konstante extrahiert (aus `ensureDefaultGroup()`), neue Methode `reassignDefaultBeforeDelete(tenantId, groupId)` verschiebt die Standardmarkierung deterministisch, loescht nichts, wirft in keinem der sechs getesteten Faelle (kein Treffer, nicht markiert, kein anderes Ziel, fremder Mandant, P2002-Rennen) — Baustein fuer Plan 16-03
|
||||||
|
- `GroupsService.update()` lehnt `name` fuer eine Gruppe mit gesetztem `ldapObjectGuid` mit `BadRequestException` ab — echte Backend-Invariante vor der bestehenden Leerstring-Pruefung, nicht nur ein deaktiviertes Formularfeld
|
||||||
|
- `internalName` ist unabhaengig von der Namenssperre setz- und loeschbar; leere/nur-Leerzeichen-Werte normalisieren auf `null`, nie auf einen leeren Anzeigenamen; `listForTenant()` liefert das Feld zusaetzlich zu `name`
|
||||||
|
- `UpdateGroupDto` verliert `ldapDn` (D-07) und erhaelt `internalName?: string | null` — kein Codepfad kann ueber diese Route mehr eine lokale Gruppe nachtraeglich an AD binden
|
||||||
|
- `ModuleGrantsService.getUserAccess()` liefert an beiden Projektionsstellen (`viaGroups`-Namen, Mitgliedschafts-Chips) `internalName ?? name`; die Sortierung der Chips laeuft dadurch automatisch ueber den angezeigten statt den rohen Namen — bewusster Unterschied zu `listForTenant()`. Kein einziger `apps/web/`-Diff.
|
||||||
|
- Vollstaendige API-Testsuite gruen: 40 Testdateien, 543 Tests (davon 18 neue Faelle aus diesem Plan)
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Standardgruppen-Handoff als eigener Baustein (D-06)** - `2ef9b86` (feat, tdd)
|
||||||
|
2. **Task 2: Namenssperre fuer importierte Gruppen und internalName im GroupsService (D-03, D-04, D-07)** - `253da91` (feat, tdd)
|
||||||
|
3. **Task 3: Anzeigename mit Fallback im Benutzer-Detail (D-04, UI-SPEC Surface Contract 6)** - `f71e614` (feat, tdd)
|
||||||
|
|
||||||
|
**Plan metadata:** wird mit diesem Summary committet
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
- `apps/api/src/groups/groups.service.ts` - `DEFAULT_GROUP_NAME`, `reassignDefaultBeforeDelete()`, Namenssperre + `internalName`-Normalisierung in `update()`, `internalName` in `listForTenant()`
|
||||||
|
- `apps/api/src/groups/groups.service.spec.ts` - zwei neue `describe`-Bloecke: `GroupsService.reassignDefaultBeforeDelete (D-06)` (6 Faelle), `GroupsService.update — Namenssperre und interner Name (D-03/D-04)` (9 Faelle); veralteter `ldapDn`-Update-Test entfernt
|
||||||
|
- `apps/api/src/groups/dto/update-group.dto.ts` - `ldapDn` entfernt, `internalName?: string | null` ergaenzt
|
||||||
|
- `apps/api/src/groups/module-grants.service.ts` - `internalName: true` in der Mitgliedschafts-Query-Projektion, `internalName ?? name` an beiden Anzeigestellen in `getUserAccess()`
|
||||||
|
- `apps/api/src/groups/module-grants.service.spec.ts` - neuer `describe`-Block `ModuleGrantsService.getUserAccess — Anzeigename mit Fallback (D-04)` (3 Faelle), `__seedGroup`/`groupMembership.findMany`-Fake um `internalName` erweitert
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- Alle drei Tasks aendern `groups.service.ts`; um trotzdem pro Task atomar zu committen, wurde die Datei zunaechst vollstaendig auf den Task-1-Endzustand geschrieben (Write-Tool), getestet und committet — erst danach wurden die Task-2-Aenderungen an derselben Datei vorgenommen. Kein `git add -p` auf einer gemischten Arbeitskopie noetig.
|
||||||
|
- Der bestehende Test "update() mit ldapDn bindet an eine AD-Gruppe; ldapDn:null loest die Bindung" wurde ersatzlos entfernt statt angepasst — nach D-07 ist die Funktionalitaet absichtlich abgeschafft, ein Aequivalent widerspraeche dem Plan.
|
||||||
|
- PERM-02 bleibt in `REQUIREMENTS.md` unveraendert auf `[ ]` (Pending) — dieser Plan liefert nur den Backend-Teil der Anforderung; das Requirement schliesst laut Plan-Vorgabe erst mit dem letzten Plan der Phase (16-05).
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - plan executed exactly as written. Zwei kleinere, in-scope Korrekturen an bestehenden Kommentaren waren fuer die Erfuellung der eigenen Acceptance-Kriterien noetig (kein neuer Code, kein Scope Creep):
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] Bestehender Docstring-Kommentar enthielt ein zweites Vorkommen des Literals `'Alle Benutzer'`**
|
||||||
|
- **Found during:** Task 1 (Acceptance-Kriterium `grep -c "'Alle Benutzer'"` sollte 1 ergeben, lieferte 2)
|
||||||
|
- **Issue:** Der Docblock von `ensureDefaultGroup()` (aus Plan 15-02, unveraendert seither) beschrieb das Verhalten mit dem woertlichen String `'Alle Benutzer'` statt mit dem neuen Konstantennamen — ein reiner Kommentartext, kein Code, aber das Acceptance-Kriterium zaehlt jedes Vorkommen.
|
||||||
|
- **Fix:** Kommentarzeile auf `DEFAULT_GROUP_NAME` umgestellt, Bedeutung unveraendert.
|
||||||
|
- **Files modified:** apps/api/src/groups/groups.service.ts
|
||||||
|
- **Verification:** `grep -c "'Alle Benutzer'" apps/api/src/groups/groups.service.ts` = 1
|
||||||
|
- **Committed in:** 2ef9b86
|
||||||
|
|
||||||
|
**2. [Rule 1 - Bug] DTO-Docblock enthielt das Wort "ldapDn" trotz entfernten Feldes**
|
||||||
|
- **Found during:** Task 2 (Acceptance-Kriterium `grep -c 'ldapDn'` sollte 0 ergeben, lieferte 1)
|
||||||
|
- **Issue:** Der neue Docblock-Kommentar erklaerte die Entfernung des Feldes mit dem woertlichen Feldnamen "ldapDn-Feld" — dadurch schlug das eigene Grep-Kriterium fehl.
|
||||||
|
- **Fix:** Formulierung auf "AD-Bindungsfeld" umgestellt, Bedeutung unveraendert.
|
||||||
|
- **Files modified:** apps/api/src/groups/dto/update-group.dto.ts
|
||||||
|
- **Verification:** `grep -c 'ldapDn' apps/api/src/groups/dto/update-group.dto.ts` = 0
|
||||||
|
- **Committed in:** 253da91
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 2 auto-fixed (beide Rule 1, reine Kommentartext-Korrekturen fuer die eigenen Acceptance-Kriterien)
|
||||||
|
**Impact on plan:** Kein Einfluss auf Funktionalitaet oder Scope — beide Korrekturen betrafen ausschliesslich Kommentartext.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
None.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- `reassignDefaultBeforeDelete()` steht bereit fuer Plan 16-03, das es vor jedem sync-getriebenen `group.delete()` aufrufen muss — fehlt der Aufruf, bleibt ein Mandant ohne Standardgruppe
|
||||||
|
- Die serverseitige Namenssperre (D-03) ist die Grundlage, auf die sich das gesperrte Namensfeld im Frontend-Dialog von Plan 16-04 verlaesst
|
||||||
|
- `internalName ?? name` ist jetzt an drei von vier geplanten Stellen implementiert (`listForTenant()`, beide `getUserAccess()`-Projektionen); die verbleibenden Frontend-Anzeigestellen (`admin/groups/page.tsx`, `admin/modules/grants/page.tsx`) sind Gegenstand von Plan 16-05
|
||||||
|
- Die drei aus Plan 16-01 zurueckgestellten kosmetischen Beobachtungen (this.prisma statt tenantPrisma in LdapService, ungenutztes `escapeLdapFilterBuffer()`, `alreadyImported:false` bei Legacy-`ldapDn`-Gruppen ohne GUID) bleiben unveraendert offen — keine davon lag im Feilenbereich dieses Plans
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 16-ad-gruppen-synchronisation*
|
||||||
|
*Completed: 2026-08-06*
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
Alle 5 in diesem Plan genannten Quelldateien sowie dieses Summary existieren auf der Festplatte; alle 3 Task-Commit-Hashes (2ef9b86, 253da91, f71e614) sind im lokalen Git-Log auffindbar.
|
||||||
Reference in New Issue
Block a user