Label- and page-scope grants UI including deny #55

Closed
opened 2026-07-04 14:52:27 +02:00 by fable-5 · 1 comment
Collaborator

Context

The vision's fine-grained cases ('all pages except label X', 'only label Y') need an admin surface that regular humans can operate.

Scope

Pond settings 'Access rules': per member (and the pseudo-subjects 'all signed-in users', 'public') show the effective base role and a rule list; add scoped rules — pick scope (label from tree / specific page), role, allow/deny — with plain-language sentence rendering ('Anna may not edit pages labeled confidential'); page-level shortcut: a 'permissions' section in page settings showing rules affecting this page with add-rule.

Acceptance criteria

  • both vision patterns are configurable through the UI and verified by e2e (deny label X; only label Y)
  • rules render as readable sentences in de/en, not as raw tuples
  • conflicting-rule warning when a new rule is shadowed by a more specific existing one (client-side hint using the shared algorithm)
  • public scope changes show a confirmation warning ('visible to everyone on the internet')

Technical notes

  • permissions.md (semantics are fixed — the UI must not invent new ones), ADR 0012 (sentence templates with ICU).

Dependencies

Depends on #52, #54.

Size: ~2 days


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context The vision's fine-grained cases ('all pages except label X', 'only label Y') need an admin surface that regular humans can operate. ## Scope Pond settings 'Access rules': per member (and the pseudo-subjects 'all signed-in users', 'public') show the effective base role and a rule list; add scoped rules — pick scope (label from tree / specific page), role, allow/deny — with plain-language sentence rendering ('Anna may not edit pages labeled *confidential*'); page-level shortcut: a 'permissions' section in page settings showing rules affecting this page with add-rule. ## Acceptance criteria - [ ] both vision patterns are configurable through the UI and verified by e2e (deny label X; only label Y) - [ ] rules render as readable sentences in de/en, not as raw tuples - [ ] conflicting-rule warning when a new rule is shadowed by a more specific existing one (client-side hint using the shared algorithm) - [ ] public scope changes show a confirmation warning ('visible to everyone on the internet') ## Technical notes - permissions.md (semantics are fixed — the UI must not invent new ones), ADR 0012 (sentence templates with ICU). ## Dependencies Depends on #52, #54. **Size**: ~2 days --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M5 — Permissions & quotas milestone 2026-07-04 14:52:27 +02:00
fable-5 added the
frontend
auth
labels 2026-07-04 14:52:27 +02:00
Collaborator

Umgesetzt in 406886c (Claude Opus 4.8). Pipeline nach einem Runner-Infra-Ausfall (volle Runner-VPS-Platte → korrupter Docker-/Action-Cache; behoben durch Aufräumen + Neustart) auf e62fdcd (identischer Baum) komplett grün (CI Lint/typecheck/test + alle e2e-Packs, CD Deploy Test/Smoke/Int-Promotion). Live auf Test und Int verifiziert.

Was #55 liefert

  • Zugriffsregeln-UI (apps/web/src/access/AccessRulesManager) in den Teich-Einstellungen: pro Subjekt (Mitglied + Pseudo-Subjekte „Angemeldete"/„Öffentlich") die Regeln als lesbare de/en-Sätze („Anna darf Seiten mit dem Label „Vertraulich" nicht bearbeiten."), Add-Formular (Scope = Label aus dem Baum oder Seite, Recht, Erlauben/Verbieten).
  • Shadow-Warnung client-seitig über den geteilten Algorithmus (isRuleShadowed), wenn eine neue Regel von einer spezifischeren bestehenden überschrieben würde; Public-Bestätigung vor dem Öffnen für alle.
  • api GET /ponds/:id/grants/access-rules (pond_admin): Grants angereichert um Subjekt-/Scope-Namen (batched). Grant-Semantik bleibt der geteilte Resolver (permissions.md) — die UI erfindet nichts.

Acceptance criteria

  • Beide Vision-Muster über die UI konfigurierbar + per e2e verifiziert: „deny label X" (Editor verliert die gelabelte Seite) und „only label Y" (angemeldeter Nicht-Mitglied fixture-viewer liest nur die gelabelten Seiten).
  • Regeln rendern als lesbare Sätze in de/en, nicht als rohe Tupel.
  • Konflikt-/Shadow-Warnung, wenn eine neue Regel von einer spezifischeren überschattet wird (Client-Hinweis via geteiltem Algorithmus).
  • Public-Scope-Änderungen zeigen eine Bestätigungswarnung („für alle im Internet sichtbar").

Live-Checks: GET /grants/access-rules liefert angereicherte Regeln (Int: „Anna Test"/pond_admin + „Ben Test"/editor; Test: fixture-user).

Tests: shared conflicts.test.ts; api-DB-Fall für den angereicherten Endpoint (api-DB 162 grün); neuer Browser-Pack access-rules (beide Muster + Effekt, Shadow-Hinweis, Public-Bestätigung) mit eigenem CI-Step; neuer Fixture-User fixture-viewer.

Hinweis: Der optionale In-Page-„permissions"-Shortcut aus dem Scope ist nicht Teil dieses Commits; page-scope-Regeln sind über die pond-weite UI voll konfigurierbar. Kann als kleines Folge-Issue nachgezogen werden.

Umgesetzt in `406886c` (Claude Opus 4.8). Pipeline nach einem Runner-Infra-Ausfall (volle Runner-VPS-Platte → korrupter Docker-/Action-Cache; behoben durch Aufräumen + Neustart) auf `e62fdcd` (identischer Baum) **komplett grün** (CI Lint/typecheck/test + alle e2e-Packs, CD Deploy Test/Smoke/Int-Promotion). Live auf Test **und** Int verifiziert. **Was #55 liefert** - **Zugriffsregeln-UI** (`apps/web/src/access/AccessRulesManager`) in den Teich-Einstellungen: pro Subjekt (Mitglied + Pseudo-Subjekte „Angemeldete"/„Öffentlich") die Regeln als **lesbare de/en-Sätze** („Anna darf Seiten mit dem Label „Vertraulich" nicht bearbeiten."), Add-Formular (Scope = Label aus dem Baum oder Seite, Recht, Erlauben/Verbieten). - **Shadow-Warnung** client-seitig über den geteilten Algorithmus (`isRuleShadowed`), wenn eine neue Regel von einer spezifischeren bestehenden überschrieben würde; **Public-Bestätigung** vor dem Öffnen für alle. - **api** `GET /ponds/:id/grants/access-rules` (pond_admin): Grants angereichert um Subjekt-/Scope-Namen (batched). Grant-Semantik bleibt der geteilte Resolver (permissions.md) — die UI erfindet nichts. **Acceptance criteria** - [x] Beide Vision-Muster über die UI konfigurierbar + per e2e verifiziert: „deny label X" (Editor verliert die gelabelte Seite) und „only label Y" (angemeldeter Nicht-Mitglied `fixture-viewer` liest nur die gelabelten Seiten). - [x] Regeln rendern als lesbare Sätze in de/en, nicht als rohe Tupel. - [x] Konflikt-/Shadow-Warnung, wenn eine neue Regel von einer spezifischeren überschattet wird (Client-Hinweis via geteiltem Algorithmus). - [x] Public-Scope-Änderungen zeigen eine Bestätigungswarnung („für alle im Internet sichtbar"). **Live-Checks:** `GET /grants/access-rules` liefert angereicherte Regeln (Int: „Anna Test"/pond_admin + „Ben Test"/editor; Test: fixture-user). **Tests:** shared `conflicts.test.ts`; api-DB-Fall für den angereicherten Endpoint (api-DB 162 grün); neuer Browser-Pack `access-rules` (beide Muster + Effekt, Shadow-Hinweis, Public-Bestätigung) mit eigenem CI-Step; neuer Fixture-User `fixture-viewer`. _Hinweis: Der optionale In-Page-„permissions"-Shortcut aus dem Scope ist nicht Teil dieses Commits; page-scope-Regeln sind über die pond-weite UI voll konfigurierbar. Kann als kleines Folge-Issue nachgezogen werden._
Sign in to join this conversation.
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#55
No description provided.