| 15-modul-berechtigungen-gruppen-user-grants |
06 |
ui |
| nextjs |
| next-intl |
| react |
| admin |
| groups |
| ldap |
|
| phase |
plan |
provides |
| 15-modul-berechtigungen-gruppen-user-grants |
02 |
GroupsService/GroupsController — vollständiges CRUD für Gruppen und Mitgliedschaften, GroupsService.getImpact als Zahlenquelle für den Löschdialog (D-17) |
|
|
| /admin/groups Seite: Tabelle (Name/AD-Bindung/Standardgruppe/Mitglieder/Aktionen), Anlege/Umbenennen-Modal mit AD-Radio-Auswahl aus GET /ldap/groups (D-05, D-18), Mitglieder-Modal mit LDAP-Herkunfts-Sperre (D-19), Löschdialog mit konkreten Zahlen (D-17) |
| Sechster Admin-Navigationseintrag 'Gruppen' mit eigenem Roster-Icon |
| Sämtliche i18n-Schlüssel der gesamten Phase 15 in de.json/en.json — admin.groups.*, admin.users.grants.*, adminModules.grantsLink/grants.*/activationDialog.*, modules.accessDenied.*, marketplace.statusNoAccess/toastNoAccess, header.admin.groups |
|
|
| tokens |
tasks |
commits |
| 14500 |
3 |
3 |
|
| added |
patterns |
|
|
| AD-Bindungs-Auswahl per Radio-Liste (nicht Checkbox) aus derselben GET /ldap/groups-Discovery, die admin/ldap/page.tsx für den Import-Filter nutzt — Markup 1:1 übernommen, nur input type gewechselt |
| Sichtbare Fehlerbehandlung für Lösch- und AD-Discovery-Fehlschläge (border-destructive/50 bg-destructive/10), bewusster Bruch mit dem sonst projektweiten silent-fail-Muster der Admin-Lösch-Dialoge — dokumentiert als Code-Kommentar an DeleteGroupDialog |
| ICU-select-Syntax in next-intl-Werten ({granted, select, true {freigeben} other {entziehen}}) für Checkbox-aria-labels, die je nach Zustand zwei Verbformen brauchen, ohne einen zweiten i18n-Schlüssel anzulegen |
|
|
| created |
modified |
| apps/web/src/app/(portal)/admin/groups/page.tsx |
| apps/web/src/app/(portal)/admin/groups/components/GroupFormModal.tsx |
| apps/web/src/app/(portal)/admin/groups/components/GroupMembersModal.tsx |
| apps/web/src/app/(portal)/admin/groups/components/DeleteGroupDialog.tsx |
| apps/web/src/app/(portal)/admin/groups/groups-page.test.tsx |
|
| apps/web/src/messages/de.json |
| apps/web/src/messages/en.json |
| apps/web/src/components/admin/admin-sidebar.tsx |
|
|
| Task 2/3-Split von page.tsx: Task 2 committet die Seite mit Create/Edit-Modal verdrahtet, aber Mitglieder-/Lösch-State bereits deklariert und an die Aktionsbuttons gehängt, ohne die (noch nicht existierenden) Task-3-Komponenten zu importieren — hält jeden Task-Commit für sich buildbar, statt beide Dateien in einem Commit zu bündeln |
| Erstellen einer Gruppe MIT sofortiger AD-Bindung läuft zweistufig (POST /groups, dann PATCH /groups/:id {ldapDn}), weil CreateGroupDto ausschliesslich name entgegennimmt (15-02) — keine Schema-/DTO-Änderung nötig, nur Client-seitige Sequenzierung |
| matrixCheckboxLabel/directCheckboxLabel (Wave-4-Schlüssel für 15-07/15-08) als next-intl-ICU-select mit zusätzlichem granted-Parameter modelliert, um freigeben/entziehen aus einem einzigen Schlüssel zu bedienen, statt zwei separate Schlüssel anzulegen |
|
|
| id |
description |
requirement |
verification |
human_judgment |
| D1 |
/admin/groups Tabelle mit Name/AD-Bindung/Standardgruppe/Mitglieder/Aktionen, leerer Zustand, optimistischer Standardgruppen-Stern-Toggle mit Rollback bei Fehler |
PERM-01 |
| kind |
ref |
status |
| unit |
apps/web/src/app/(portal)/admin/groups/groups-page.test.tsx (describe 'AdminGroupsPage': empty state, populated table, star-toggle PATCH + rollback — 4 Tests) |
pass |
|
| kind |
ref |
status |
| other |
grep-Nachweise aus Task 2 acceptance_criteria (font-weight-Vokabular, sechs Sidebar-Einträge) + pnpm --filter @tessera/web run build |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
rationale |
| D2 |
GroupFormModal: Anlegen/Umbenennen mit AD-Bindung per Radio-Auswahl aus GET /ldap/groups (D-05/D-18), sichtbarer Fehler-/Leerfall bei der AD-Suche statt stillem Leerbild |
PERM-01 |
| kind |
ref |
status |
| other |
grep-Nachweise aus Task 2 acceptance_criteria: type="radio" vorhanden, type="checkbox" abwesend, ldap/groups referenziert, discoverError/noResults sichtbar ausgeführt |
pass |
|
| kind |
ref |
status |
| other |
pnpm --filter @tessera/web run build (Typecheck inkl. GroupFormModal) + pnpm --filter @tessera/web test (voller Lauf, 162/162 grün) |
pass |
|
|
true |
Kein interaktiver Komponententest öffnet das Modal und klickt einen Radio-Eintrag — die Task-2-acceptance_criteria verlangten explizit nur grep-Nachweise für diese Datei, kein Render-Test. Der volle Klickpfad (Discover -> Radio wählen -> Speichern -> Chip erscheint) und insbesondere das Verhalten gegen ein echtes AD wurden in dieser Session nicht im Browser geprüft (kein Browser-Tool verfügbar). |
|
| id |
description |
requirement |
verification |
human_judgment |
| D3 |
GroupMembersModal: Mitglieder-Chips mit Herkunfts-Badge, LDAP-Mitgliedschaften mit deaktiviertem Entfernen-Button (D-19), manuelles Hinzufügen per Benutzersuche |
PERM-01 |
| kind |
ref |
status |
| unit |
groups-page.test.tsx ('disables the remove button for LDAP-sourced members and keeps it active for MANUAL members') |
pass |
|
| kind |
ref |
status |
| other |
grep-Nachweise: disabled/ldapManaged in GroupMembersModal.tsx |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D4 |
DeleteGroupDialog: laedt GET /groups/:id/impact, zeigt memberCount/grantCount konkret (D-17), bleibt bei fehlgeschlagenem DELETE offen mit sichtbarer Fehlermeldung (T-15-24, bewusste Abweichung vom silent-fail-Präzedenzfall) |
PERM-01 |
| kind |
ref |
status |
| unit |
groups-page.test.tsx ('shows both concrete numbers...', 'stays open and shows a visible error when DELETE fails') |
pass |
|
| kind |
ref |
status |
| other |
grep-Nachweise: impact-Aufruf + border-destructive/50 bg-destructive/10 in DeleteGroupDialog.tsx |
pass |
|
|
false |
|
| id |
description |
verification |
human_judgment |
rationale |
| D5 |
Vollständiges manuelles Durchklicken im Browser aus dem Plan-<verification>-Block: Anlegen, Umbenennen, Standardmarkierung setzen/abschalten, AD-Bindung setzen/lösen, Mitglied hinzufügen/entfernen, Löschdialog mit gefüllter Gruppe, sowie AD-Suche/Löschen bei abgeschalteter API |
|
true |
Diese Session hatte kein Browser-/Playwright-Tool zur Verfügung (nur Read/Write/Edit/Bash/Skill) — der interaktive Durchlauf aus dem Plan-<verification>-Block konnte nicht ausgeführt werden. Abgedeckt ist stattdessen: vollständiger Vitest-Lauf (162/162 grün), fehlerfreier Produktions-Build inkl. Next.js-Typecheck, sowie alle grep-basierten acceptance_criteria aus allen drei Tasks. In WINDOWS.md als unrun-verify vermerkt. |
|
|
ca. 35min |
2026-08-04 |
complete |