shinkan-jinkendo/.claude/docs/technical/MEMBERSHIP_RBAC_DECISIONS_2026-06.md
Lars 9d52aeab67
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Test Suite / pytest-backend (push) Successful in 43s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 14s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m13s
Update Membership RBAC Decisions and Enhance Admin Rights Management
- 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.
2026-06-07 15:27:37 +02:00

9.8 KiB
Raw Blame History

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.pyclub-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/meaccount_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)

  1. Fairness Modell A/B/C für Trainer-Budget (Tendenz: A).
  2. Ob admin (Portal) langfristig neben superadmin bleibt.
  3. 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 M1M3; Roadmap AF.
  • 2026-06-06: Phase A — account_onboarding_gate.py, Frontend /onboarding, reduzierte Navigation.
  • 2026-06-07: M4M6 Ist-Stand, Roadmap-Verweis, Superadmin-FAQ; Admin-Matrix UX + Enforcement-Audit.