From 2f354cd59c4e8b8e81610ac9ffbbb3670a77264d Mon Sep 17 00:00:00 2001 From: Schalli Date: Tue, 4 Aug 2026 13:39:00 +0200 Subject: [PATCH] docs(15): UI design contract --- .../15-UI-SPEC.md | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 .planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-UI-SPEC.md diff --git a/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-UI-SPEC.md b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-UI-SPEC.md new file mode 100644 index 0000000..2df9975 --- /dev/null +++ b/.planning/phases/15-modul-berechtigungen-gruppen-user-grants/15-UI-SPEC.md @@ -0,0 +1,225 @@ +--- +phase: 15 +slug: modul-berechtigungen-gruppen-user-grants +status: draft +shadcn_initialized: false +preset: none +created: 2026-08-04 +--- + +# Phase 15 — UI Design Contract + +> Visual and interaction contract for frontend phases. Generated by gsd-ui-researcher, verified by gsd-ui-checker. + +--- + +## Design System + +| Property | Value | +|----------|-------| +| Tool | none — kein `components.json`, keine shadcn-CLI im Repo (verifiziert: `find` liefert keinen Treffer) | +| Preset | not applicable | +| Component library | none — keine Radix-/Base-UI-Abhängigkeit im Projekt (`grep radix\|lucide\|cva\|clsx` in `apps/web/package.json` liefert nichts). Alle fünf bestehenden Admin-Seiten (`ldap`, `users`, `modules`, `tenants`, `smtp`) sind handgebaute Tailwind-Komponenten mit einem konsistenten, projekteigenen Vokabular (Tabellen, Modal-Dialoge, Toggle-Switches, Badge-Chips) | +| Icon library | none — Icons sind handgeschriebene Inline-`` im Lucide-Stil (`viewBox="0 0 24 24"`, `stroke="currentColor"`, `strokeWidth="2"`, `strokeLinecap="round"`, `strokeLinejoin="round"`, kein `fill`), siehe `apps/web/src/components/admin/admin-sidebar.tsx` | +| Font | Inter via `--font-sans` (`apps/web/src/app/globals.css:33`), system-ui-Fallback | + +**Shadcn-Gate-Entscheidung:** Kein `components.json` gefunden, Stack ist Next.js — der Gate würde normalerweise fragen, ob shadcn initialisiert werden soll. Diese Frage ist hier bereits beantwortet: der ``-Auftrag verlangt explizit "Reuse existing components and tokens; do not introduce a new component library or a second styling approach", und 14 vorherige Phasen haben ein durchgängiges, funktionierendes handgebautes System etabliert (5 Admin-Seiten, Marketplace, Modul-Shells). shadcn jetzt einzuführen würde einen zweiten, inkonsistenten Styling-Ansatz neben den bestehenden ~40 Seiten schaffen. **Tool bleibt `none`, Registry-Safety-Gate ist damit nicht anwendbar.** + +--- + +## Spacing Scale + +Declared values (must be multiples of 4), identisch mit dem bereits im Projekt etablierten Raster (verifiziert in allen fünf Admin-Seiten): + +| Token | Value | Usage | +|-------|-------|-------| +| xs | 4px | Icon-Text-Abstand in Badges/Chips (`gap-1`), Checkbox-zu-Label-Feinabstand | +| sm | 8px | Kompakte Element-Abstände (`gap-2`), Badge-Innenpolsterung (`px-2 py-0.5`) | +| md | 16px | Standard-Formularabstand (`space-y-4`), Tabellenzellen-Polsterung (`px-4 py-3`) | +| lg | 24px | Card-/Section-Innenpolsterung (`p-6`), Abstand zwischen Seitenabschnitten (`space-y-6`/`space-y-8`) | +| xl | 32px | reserviert, in dieser Phase nicht benötigt | +| 2xl | 48px | reserviert, in dieser Phase nicht benötigt | +| 3xl | 64px | reserviert, in dieser Phase nicht benötigt | + +**Exceptions:** +- Icon-only Aktionsbuttons in Tabellenzeilen (Standardgruppen-Stern-Toggle, Mitglied-Entfernen-Button) übernehmen das bestehende Projektmaß `px-2 py-1` (kein 44px-Touch-Target) — Admin-Oberflächen sind Desktop-Maus-Bedienung, identisch zu den bereits ausgelieferten "Bearbeiten"/"Löschen"-Buttons in `admin/users/page.tsx`. Kein neuer Präzedenzfall, reine Fortführung. +- Matrix-Checkboxen (Permission-Matrix-Seite) nutzen die native ``-Rahmen ohne jeden Hinweis erscheint | +| loading | Matrix-Zellen-Toggle, Gruppen-Modal-Speichern | ✅ covered | Identisches Inline-Spinner-Muster wie bestehender `isToggling`-Zustand in `AdminModulesPage` — kein neues Ladeverhalten | +| error | Grant-Speicherfehler | ✅ covered | Dokumentierte Fehlermeldung im bestehenden `error`-Div-Muster | +| error | Gruppe löschen schlägt fehl (z. B. Netzwerkfehler) | 🧪 backstop | Kein bestehendes Netzwerkfehler-Muster für Lösch-Dialoge im Projekt (aktuelle Lösch-Dialoge scheitern "silently" laut Code-Kommentar) — Planner muss entscheiden, ob dieser Präzedenzfall (stiller Fail) hier ebenfalls gilt oder eine sichtbare Fehlermeldung nötig ist, da PERM-01 konkrete Zahlen verspricht, die bei Fehlschlag nicht veralten dürfen | +| populated | Matrix mit vielen Modulen/Gruppen | ✅ covered | Sticky Header + sticky erste Spalte + Kategorie-Gruppierung + Suchfeld, siehe Surface Contract 2 | +| overflow | Lange Gruppennamen in der Matrix-Kopfzeile | 🧪 backstop | Kein expliziter Truncate-/Tooltip-Mechanismus dokumentiert — Planner sollte `truncate` + `title`-Attribut auf den Spaltenkopf anwenden, analog zum bestehenden `truncate`-Einsatz in `MarketplaceCard.tsx` (`h3.truncate`) | +| zero-one-many | AD-Bindung: Gruppe ohne/mit gebundener AD-Gruppe | ✅ covered | Zwei explizite Zustände dokumentiert (ungebunden zeigt Auswahl-UI, gebunden zeigt Chip + Entfernen-Link) | +| zero-one-many | Standardgruppe: keine/eine markierte Gruppe pro Mandant | ✅ covered | D-13 erzwingt DB-seitig genau 0 oder 1 — UI zeigt Stern-Toggle je Zeile, "Sofort freigeben" wird `disabled`, wenn keine Standardgruppe existiert (Surface Contract 6) | +| long-text | Modulnamen in der Matrix-ersten-Spalte | ✅ covered | `sticky left-0`-Spalte erhält feste Mindestbreite + `truncate` mit `title`-Attribut, identisch zur Overflow-Behandlung in Zeile darüber | + +--- + +## Registry Safety + +| Registry | Blocks Used | Safety Gate | +|----------|-------------|--------------| +| shadcn official | keine — Tool ist `none` | not required | +| Drittanbieter | keine | not required | + +Kein Registry-Zugriff in dieser Phase — alle Komponenten sind handgebaut nach den in "Surface Contracts" referenzierten, bereits im Repo vorhandenen Mustern. + +--- + +## Checker Sign-Off + +- [ ] Dimension 1 Copywriting: PASS +- [ ] Dimension 2 Visuals: PASS +- [ ] Dimension 3 Color: PASS +- [ ] Dimension 4 Typography: PASS +- [ ] Dimension 5 Spacing: PASS +- [ ] Dimension 6 Registry Safety: PASS + +**Approval:** pending