# RBAC, Kontingente & Enforcement — Roadmap **Stand:** 2026-06-08 · App **0.8.202** · Schema **20260606084** **Bezüge:** `MEMBERSHIP_RBAC_DECISIONS_2026-06.md`, `CAPABILITY_CATALOG.v1.md`, `CLUB_MEMBERSHIP_AND_FEATURES.v1.md` Diese Roadmap bündelt **was fertig ist**, **was als Standard gilt** und **was noch fehlt** — ohne Insellösungen pro Feature. --- ## 1. Architektur-Standard (verbindlich) ### Registry-first (korrigiert 2026-06-07) **Nicht:** vollständiger Capability-Katalog in Migration 079. **Sondern:** Module registrieren Rechte/Kontingente bei Implementierung → `docs/working/RIGHTS_AND_FEATURES_REGISTRY.md`. Admin-Matrix zeigt nur `capabilities.module IS NOT NULL` — keine vorgetäuschte Vollständigkeit. ### Request-Kette (Ziel) ``` Auth → Account-State → TenantContext → probe_capability (Recht) → probe_member_feature_access (Person, v2/M9 — falls Sub-Budget gesetzt) → probe_club_feature_access (Vereins-Kontingent) → Governance (Objekt) → Business-Logik → consume (Verein + Person) + merge_feature_usage_into_response ``` **v1 (aktuell):** nur Vereins-Ebene. **v2 (Phase 5b):** Prüfung und Zählung zusätzlich gegen `profile_id` aus der Session. ### Frontend-Standard - `GET /api/me/entitlements` = einzige Quelle für Rechte + Kontingente in der UI - `request()` synchronisiert `feature_usage` aus API-Responses automatisch (`featureUsageSync.js`) - Keine parallelen `if (club_admin)` für **Sicherheit** (UX-Fallback nur übergangsweise) ### Admin - **Rollen & Rechte** (`/admin/rights`): Matrix mit Klartext zuerst, technische ID darunter - Umsetzungsstand pro Recht: `capability_enforcement_audit.py` → Feld `enforcement` in der Matrix --- ## 2. Ist-Stand nach Meilenstein | Meilenstein | Inhalt | Status | |-------------|--------|--------| | **M1** | Feature-Schema, Pläne, Seeds | ✅ | | **M2** | Feature-Probe + JSON-Log | ✅ | | **M3** | Capabilities, Account-Lifecycle, Tenant | ✅ (Legacy parallel) | | **M4** | `/me/entitlements`, Badge (KI) | ✅ teilweise | | **M5** | Hard-Block + vollständiger Consume | ⚠️ `ai_calls` consume + Enforce auf Dev/Prod (0.8.202); Consume andere Features offen | | **M6** | Admin UI Rollen & Rechte | ⚠️ Matrix + Kontingente; kein Plan-/Rollen-CRUD | | **M7** | Vereinsgründung beantragen | ✅ Basis + Capabilities | | **M8** | Stripe | ❌ | | **Sync** | `feature_usage` + `request()` | ✅ | --- ## 3. Roadmap (empfohlene Reihenfolge) ### Phase 1 — Durchsetzung sichtbar machen (kurz) | # | Paket | Lieferumfang | Aufwand | |---|--------|--------------|---------| | 1.1 | **Admin-Matrix UX** | Alle Rechte, Haken-Matrix, Umsetzungs-Badge | ✅ 2026-06-07 | | 1.2 | **Doku-Sync** | Diese Roadmap, `MEMBERSHIP_RBAC` §2 | ✅ | | 1.3 | **Audit pflegen** | Bei jedem `probe_capability` → `capability_enforcement_audit.py` | laufend | ### Phase 2 — Kontingente vollständig (M5) | # | Paket | Lieferumfang | |---|--------|--------------| | 2.1 | **Consume erweitern** | `exercises`, `exercise_media` nach Standard-Helfer | | 2.2 | **Badges** | `FeatureUsageBadge` an Create/Upload, nicht nur KI | | 2.3 | **Dev: Enforce** | `CLUB_FEATURE_ENFORCE=1` auf Dev, Free `ai_calls=0` testen | ✅ verifiziert | | 2.4 | **Prod-Rollout** | Enforce schrittweise; Kommunikation an Vereine | ✅ Default Compose=1 | ### Phase 3 — Capabilities an alle Endpoints (C3–C4) | # | Paket | Lieferumfang | |---|--------|--------------| | 3.1 | **Endpoint-Audit** | `ACCESS_LAYER_ENDPOINT_AUDIT.md` — jeder Schreib-Pfad | | 3.2 | **probe_capability** | `exercises.update/delete`, `planning.*`, `org.*`, Medien-Bibliothek, … | | 3.3 | **CAPABILITY_ENFORCE=1** | Nach Audit auf Dev, dann Prod | | 3.4 | **Legacy abbauen** | `can_plan_in_club` nur noch als Fallback, dokumentiert | ### Phase 4 — Frontend auf Entitlements (Phase E) | # | Paket | Lieferumfang | |---|--------|--------------| | 4.1 | **Navigation** | Menüpunkte aus `hasCapability()` | | 4.2 | **Buttons** | KI, Anlegen, Löschen, Planung — aus Entitlements | | 4.3 | **Rollen-Labels** | Anzeige `club_roles` statt technischer IDs | ### Phase 5 — Admin & Produkt (M6 voll) | # | Paket | Lieferumfang | |---|--------|--------------| | 5.1 | **Pläne-CRUD** | Neue Vereinspläne anlegen, nicht nur Seed | | 5.2 | **Systemrolle Co-Trainer** | Seed + Matrix | ### Phase 5b — Kontingent-Verteilung durch Vereinsadmins (M9, Priorität KI-Kosten) **Ziel:** Vereins-Kontingent bleibt Plan-Ebene; **Vereinsadmin** verteilt Teilkontingente auf **einzelne Personen** (`profile_id`). Verbrauch und Hard-Block gelten **pro Person** und gegen den Vereins-Pool. | # | Paket | Lieferumfang | |---|--------|--------------| | 5b.1 | **Schema** | `club_member_feature_budgets`, `club_member_feature_usage` (Migration); Events mit `profile_id` (bestehend teilweise) | | 5b.2 | **Prüf-Kette** | `probe_capability` → **Mitglieds-Budget** (`profile_id` aus Session) → Vereins-Kontingent → Governance | | 5b.3 | **Consume** | Zählung auf Verein **und** Person; `consume_club_feature_with_usage` erweitern | | 5b.4 | **Entitlements** | `/me/entitlements`: persönliches Budget + Vereins-Rest (z. B. `ai_calls_personal`, `ai_calls_club`) | | 5b.5 | **Vereinsadmin-UI** | Kontingente auf Mitglieder verteilen (Liste/Formular pro Trainer); nur `club_admin` im eigenen Verein | | 5b.6 | **Auswertung** | Admin/Superadmin: Verbrauch **je Person** einsehbar (Fairness, „Kontingent-Fresser“); Filter `profile_id` | | 5b.7 | **Fairness-Modell** | Harte Sub-Budgets (Modell A, Tendenz): Person darf eigenes Limit nicht überschreiten, auch wenn Verein noch Rest hat | **Erstes Feature:** `ai_calls` (OpenRouter-Kosten). Später gleiches Muster für andere registrierte Kontingente. **Registry:** `register_member_quota_feature()` oder Erweiterung `FeatureRegistration` mit `supports_member_budget: true`. Bezug: `MEMBERSHIP_RBAC_DECISIONS_2026-06.md` §1.4. ### Phase 6 — Abrechnung (M8) Stripe / Rechnung — bewusst nach funktionierendem Enforce. --- ## 4. Superadmin & Vereinsrechte (Entscheidung) **Kurz: Superadmin braucht keine Vereinsrolle `club_admin` für die meiste Arbeit.** | Ebene | Verhalten | |-------|-----------| | **Capabilities (neu)** | `admin` und `superadmin` = `platform_admin_bypass` für **alle Vereins-Capabilities** (`capabilities.py`) — unabhängig von `club_member_roles` | | **Legacy-Helfer** | `can_plan_in_club`, `can_manage_club_org` → `True` für Plattform-Admin ohne Mitgliedschaft | | **Mandant** | Aktiver Verein über `X-Active-Club-Id` / `active_club_id` — **keine** Mitgliedschaft nötig für Plattform-Admin | | **Kontingente** | Superadmin: Quota-Bypass (Capability-Grant); zählt nicht gegen Vereins-Kontingent | | **Ausnahmen Legacy** | Einzelne Pfade prüfen noch **nur** `has_club_role(…, 'club_admin')` ohne Plattform-Bypass — z. B. Löschen von `visibility=club`-Übungen. → Phase 3 bereinigen | **Empfehlung:** Superadmin **nicht** zwingend als `club_admin` in jeden Verein eintragen. Optional Mitgliedschaft nur für realistische Audit-Tests oder Vereinsorga-Simulation. Produktiv: Mandant per Club-Switcher wählen. `admin` (Portal-Admin): gleicher Capability-Bypass für Vereins-Funktionen; Portal-Capabilities nur mit explizitem Grant in der Matrix. --- ## 5. Vereinsrollen-Matrix — Semantik (Admin-UI) | Zustand | Bedeutung | UI | |---------|-----------|-----| | **Keine Grants** in DB | Alle aktiven Mitglieder (wenn `min_account_state` reicht) | Zellen zeigen „alle“ | | **Mindestens ein Grant** | Nur angehakte Rollen | Checkboxen | | **„Alle Mitglieder“** | Löscht alle Grants der Zeile | Zurück zum offenen Zustand | Das ersetzt das frühere Formular „Vereinsrollen-Grant hinzufügen“, das nur bereits eingeschränkte Rechte sichtbar machte. --- ## 6. Offene Lücken (Checkliste) - [ ] `CAPABILITY_ENFORCE=1` in Produktion - [x] `CLUB_FEATURE_ENFORCE=1` auf Dev (Deploy 0.8.202 verifiziert) - [ ] `CLUB_FEATURE_ENFORCE=1` in Produktion (nach Prod-Deploy bestätigen) - [ ] Consume für alle Features mit Verbrauch (nicht nur `ai_calls`) - [ ] `probe_capability` auf >90 % der Schreib-Endpoints - [ ] Frontend ohne Legacy-Rollen-Guards - [ ] Multipart-Uploads an `featureUsageSync` anbinden - [ ] Legacy-Löschpfade mit Plattform-Bypass harmonisieren - [ ] **M9:** Kontingent-Verteilung Vereinsadmin → Person (`profile_id`), Prüfung + UI - [ ] `HANDOVER.md` / `PROJECT_STATUS` Versionsstand aktualisieren --- ## 7. Referenzen | Datei | Zweck | |-------|--------| | `backend/capability_enforcement_audit.py` | Matrix-Badges „angebunden / Legacy“ | | `backend/club_features.py` | Consume-Standard | | `frontend/src/utils/featureUsageSync.js` | Entitlements-Sync | | `frontend/src/pages/AdminRightsPage.jsx` | Konfiguration | **Changelog** - 2026-06-07: Initial nach Session Rollen/Kontingente — Standard, Roadmap Phasen 1–6, Superadmin-Klärung, Matrix-Semantik. - 2026-06-08: Phase 5b / M9 — Kontingent-Verteilung durch Vereinsadmins, personenbezogene Prüfung (`profile_id`); M5 Enforce Dev verifiziert.