- Updated the Membership RBAC Decisions document to reflect the latest implementation status and roadmap, including new features and enhancements. - Incremented application version to 0.8.200 and updated database schema version to 20260606083. - Added a new API endpoint to clear capability grants for club roles, improving admin rights management. - Enhanced the Admin Rights page in the frontend to display enforcement status and feature consumption details for capabilities. - Improved the user interface for better clarity on rights and capabilities management.
9.8 KiB
Membership, RBAC & Kontingente — Produktentscheidungen
Status: Verbindlich (Zielbild & Roadmap-Priorisierung)
Stand: 2026-06-06
Bezüge: CAPABILITY_CATALOG.v1.md, CLUB_MEMBERSHIP_AND_FEATURES.v1.md, ACCESS_LAYER_AND_GOVERNANCE_PLAN.md
Dieses Dokument hält getroffene Produktentscheidungen fest (Session 2026-06-06) und ergänzt die v1-Konzept-Specs um Umsetzungsrichtung. Technischer Implementierungsstand: Abschnitt 2.
1. Getroffene Entscheidungen
1.1 Onboarding: verified_pending_club
Nutzer ohne aktive Vereinsmitgliedschaft (E-Mail verifiziert) dürfen nur:
| Erlaubt | Nicht erlaubt (Zielbild) |
|---|---|
| Konto / Einstellungen | Übungen, Planung, KI, Medien |
| Vereinsverzeichnis lesen | Vereinsinterne Inhalte (club), private Fremdinhalte |
| Beitrittsantrag an bestehenden Verein | Vollzugriff auf Bibliothek / offizielle Inhalte (Lesen) — bewusst gesperrt bis Mitgliedschaft |
| Vereinsgründung beantragen (Prozess M7, Superadmin-Freigabe) |
Kein „Bibliothek durchstöbern“ für Bewerber — reduziert Datenexposition und vereinfacht UX („erst Verein, dann Arbeit“).
Technischer Zustand: account_state = verified_pending_club (siehe CAPABILITY_CATALOG.v1.md §3).
1.2 Rollenmodell: Risikoarm statt Big-Bang
Zielbild (langfristig):
- Fest: nur
superadmin(Plattform) als nicht konfigurierbare Systemrolle. - Dynamisch konfigurierbar: alle Vereinsrollen und deren Capability-Bundles (später
club_custom_roles). - Optional:
admin(Plattform) als abgeschwächter Portal-Admin bleibt vorerst bestehen (Ist-Code).
Entscheidung v1 (risikoarm):
| Maßnahme | Jetzt | Später |
|---|---|---|
Alte Helfer (can_plan_in_club, if (club_admin) in JSX) |
Behalten — weiter produktiv | Schrittweise durch entitlements ersetzen |
| Neue Endpoints / Features | Nur über Capability-IDs + Audit | — |
| Neue Vereinsrollen | Als Systemrollen ergänzen (z. B. co_trainer) |
Custom Roles UI |
club_custom_roles |
Nicht in v1 | v2 Epic |
Begründung: Backend und Frontend haben hunderte Verdrahtungen auf trainer / club_admin / Plattform-Rollen. Parallelbetrieb Capability-System + Legacy-Helfer ist sicherer als einmaliges Aufbrechen.
Co-Trainer (geplant als Systemrolle): weniger Capabilities als trainer (z. B. kein planning.*, kein exercises.create) — Umsetzung nach Onboarding-Gates + Entitlements-Rollout, nicht vorher.
1.3 Vereins-Kontingente (Membership-Pakete)
Jetzt: Schema und Anzeige vorbereiten; keine detaillierte Paket-Logik (z. B. „3 Trainer + 10 Co-Trainer“) implementieren.
| Vorbereitet (DB/Module) | Bewusst zurückgestellt |
|---|---|
features, club_plans, club_subscriptions |
Eigene Feature-IDs trainer_seats / co_trainer_seats |
Bestands-Limits (exercises, training_groups, ai_calls, …) |
Zählregel „nur planungsberechtigte Mitglieder“ vs. alle Mitglieder |
GET /me/entitlements Feature-Teil |
Stripe / Rechnung (M8) |
Prinzip: Neue Kontingent-Typen = neue features-Zeile + Plan-Limits + optional Capability-linked_feature_id — ohne Schema-Bruch.
1.4 Trainer-Budget innerhalb Vereins-Kontingent (v2)
Anforderung: Vereins-KI-Kontingent liegt beim Verein; Vereinsadmin kann pro Trainer ein Sub-Budget vergeben (Fairness, „Kontingent-Fresser“).
Entscheidung:
- v1: nur Vereins-Ebene (
club_plan_limits,club_feature_usage). - v2: neue Tabellen (Skizze):
-- Skizze — noch nicht migriert
club_member_feature_budgets (club_id, profile_id, feature_id, limit_value, …)
club_member_feature_usage (club_id, profile_id, feature_id, usage_count, reset_at, …)
Prüf-Kette v2: Capability → Mitglieds-Budget (falls gesetzt) → Vereins-Kontingent.
Fairness-Modell (offen, Tendenz): harte Sub-Budgets (Modell A) — Trainer darf sein Budget nicht überschreiten, auch wenn Verein noch Rest hat.
1.5 Enforcement-Phasen (unverändert, bestätigt)
| Phase | Verhalten | Nutzer sichtbar |
|---|---|---|
| 2 (M2/M3) | JSON-Log, kein Block | Nein (außer Logs) |
| 3 (M4) | GET /me/entitlements + Badge |
Kontingent-Anzeige |
| 4 (M5+) | HTTP 403 + increment |
Hard-Block |
Env-Schalter: ACCOUNT_GATE_ENFORCE (Default 1, Endpoint-Helfer), ACCOUNT_GATE_API_ENFORCE (Default 1, API-Middleware Phase A), CAPABILITY_ENFORCE / CLUB_FEATURE_ENFORCE (Default 0).
2. Implementierungsstand (Ist, Codebase)
DB-Schema: 20260606083 · App 0.8.199 (backend/version.py)
Roadmap (detailliert): docs/working/RBAC_ENFORCEMENT_ROADMAP.md
M1 — Feature-Schema v9c ✅
| Deliverable | Status |
|---|---|
Migration 078_club_features_and_plans.sql |
✅ |
Legacy 001 archiviert |
✅ |
club_plans, club_subscriptions, Usage-Tabellen |
✅ |
Seed Features + Pläne (free, …) |
✅ |
club_features.py: check_club_feature_access, get_effective_club_plan |
✅ |
Backfill Vereine → Plan free |
✅ |
M2 — Feature-Probe (Log only) ✅
| Deliverable | Status |
|---|---|
club_feature_logger.py → club-feature-usage.log |
✅ |
probe_club_feature_access() |
✅ |
Hooks: KI-Endpoints, POST /exercises, Medien-Upload, Planungs-KI |
✅ |
Consume-Standard + feature_usage in Response (ai_calls) |
✅ |
CLUB_FEATURE_ENFORCE=0 (Default) |
✅ |
M3 — Account-Lifecycle + Capability-Grants ⚠️ teilweise
| Deliverable | Status | Lücke |
|---|---|---|
Migration 079_capabilities.sql + Seed |
✅ | — |
account_lifecycle.py, resolve_account_state |
✅ | — |
capabilities.py, check_capability, probe_capability |
✅ | — |
TenantContext.account_state |
✅ | — |
GET /profiles/me → account_state, club_roles |
✅ | — |
| Account-Gates auf Schreib-/KI-Endpoints | ✅ | Lesepfade für Bewerber noch offen |
CAPABILITY_ENFORCE=0 (nur Log) |
✅ | — |
| Onboarding UX: nur Bewerbung/Gründung | ✅ | Phase A: API-Middleware + /onboarding + reduzierte Nav |
club_creation_requests (M7) |
✅ Basis | Capabilities + Admin-Freigabe |
| Quota-Bypass via Capability-Grants (083) | ✅ | kein paralleles Exemption-Schema |
| Custom Roles / Co-Trainer | ❌ | bewusst v2 |
| Legacy-Helfer entfernt | ❌ | bewusst parallel |
M4 — Anzeige ✅ teilweise
| Deliverable | Status |
|---|---|
GET /api/me/entitlements |
✅ |
EntitlementsContext, hasCapability() |
✅ (UI nutzt noch kaum) |
FeatureUsageBadge |
✅ nur KI im Übungsformular |
featureUsageSync in request() |
✅ |
M5 — Hard-Block + vollständiger Verbrauch ⚠️
| Deliverable | Status |
|---|---|
consume_club_feature_with_usage Standard |
✅ ai_calls |
CLUB_FEATURE_ENFORCE=1 produktiv |
❌ Default 0 |
Consume exercises, exercise_media, … |
❌ |
M6 — Admin UI Rollen & Rechte ⚠️
| Deliverable | Status |
|---|---|
/admin/rights Capability-Matrix (Portal + Verein) |
✅ |
| Klartext zuerst, Enforcement-Badge | ✅ 2026-06-07 |
| Kontingent-Bypass + Vereinspläne (Seed) | ✅ |
| Neue Pläne / Rollen anlegen (CRUD) | ❌ |
Bewusst zurückgestellt
| ID | Inhalt |
|---|---|
| M0 | CI-Isolation / Test-DB |
| M8 | Stripe |
| v2 | Trainer-Budgets, Custom Roles |
3. Architektur-Zielbild (kompakt)
Request
→ require_auth
→ account_state (Gate)
→ TenantContext
→ assert_capability (Rolle / Funktion)
→ check_club_feature_access (Vereins-Kontingent)
→ [v2] member_feature_budget (Trainer-Budget)
→ Governance (Objekt)
Drei Achsen: Account-Lifecycle · Capabilities · Features (Kontingente). Governance bleibt vierte Prüfung.
4. Empfohlene Roadmap (nach Entscheidungen)
| Phase | Paket | Warum zuerst |
|---|---|---|
| A | Onboarding-Gates vollständig | ✅ umgesetzt (API + Frontend /onboarding) |
| B | M7 Vereinsgründung beantragen | Als Nächstes — zweiter Pfad für verified_pending_club |
| C | M5 Hard-Block ai_calls |
Free-Plan 0 wird real; Badge (M4) liefert Erklärung |
| D | M6 voll | Pläne-CRUD, Rollen-CRUD |
| E | Entitlements im Frontend (hasCapability) |
Entscheidung 1.2 risikoarm |
| F | co_trainer + Member-Budgets (v2) |
Entscheidung 1.4 |
M0 parallel, nicht blockierend.
5. Offene Punkte (vor M6 / v2)
- Fairness Modell A/B/C für Trainer-Budget (Tendenz: A).
- Ob
admin(Portal) langfristig nebensuperadminbleibt. - Ob offizielle Inhalte für Bewerber nie lesbar bleiben (aktuell: ja).
6. Referenzen
| Pfad | Inhalt |
|---|---|
CAPABILITY_CATALOG.v1.md |
Capability-IDs, Account-States |
CLUB_MEMBERSHIP_AND_FEATURES.v1.md |
Feature-Registry, Kontingente |
backend/club_features.py |
Vereins-Features |
backend/capabilities.py |
Capability-Auflösung |
backend/account_lifecycle.py |
Account-Gates |
7. Superadmin im Verein (FAQ)
Siehe docs/working/RBAC_ENFORCEMENT_ROADMAP.md §4: Plattform-Admin (admin, superadmin) erhält Capability-Bypass für Vereins-Funktionen ohne club_admin-Mitgliedschaft. Mandant über aktiven Verein wählen; Kontingente via Bypass. Einzelne Legacy-Pfade (z. B. Löschen visibility=club) sind noch nicht vereinheitlicht — Ziel Phase 3.
Changelog
- 2026-06-06: Initial — Entscheidungen Onboarding, Rollen-Risiko, Kontingente, Trainer-Budget v2; Ist-Stand M1–M3; Roadmap A–F.
- 2026-06-06: Phase A —
account_onboarding_gate.py, Frontend/onboarding, reduzierte Navigation. - 2026-06-07: M4–M6 Ist-Stand, Roadmap-Verweis, Superadmin-FAQ; Admin-Matrix UX + Enforcement-Audit.