shinkan-jinkendo/.claude/docs/technical/MEMBERSHIP_RBAC_DECISIONS_2026-06.md
Lars a2f60d3f46
Some checks failed
Deploy Development / deploy (push) Successful in 49s
Test Suite / pytest-backend (push) Failing after 0s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 15s
Test Suite / playwright-tests (push) Has been cancelled
Test Suite / k6 /health Baseline (push) Has been cancelled
Update Capability Catalog and Club Membership Documentation
- Revised the status in the Capability Catalog to reflect partial implementation (M3).
- Added a new reference to `MEMBERSHIP_RBAC_DECISIONS_2026-06.md` in both the Capability Catalog and Club Membership documentation.
- Enhanced the Club Membership documentation with details on product decisions and onboarding phases.
- Implemented middleware in the backend to restrict access for unverified users and those pending club membership.
- Updated versioning in `version.py` to reflect changes in account lifecycle management.
2026-06-07 05:57:13 +02:00

8.6 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: 20260606079 (backend/version.py)
Deploy-Referenz: Dev mit M2-Logging verifiziert (club-feature-usage.log).

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
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)
Custom Roles / Co-Trainer bewusst v2
Legacy-Helfer entfernt bewusst parallel

Bewusst zurückgestellt (Roadmap)

ID Inhalt
M0 CI-Isolation / Test-DB
M5 Hard-Block Kontingente
M6 Superadmin Admin-UI (Pläne, Capability-Matrix)
M7 Vereinsgründung beantragen
M8 Stripe

Hinweis: M4 im Repo (über M3 hinaus)

Falls bereits deployed: GET /api/me/entitlements, EntitlementsContext, FeatureUsageBadge — gehört zur Anzeige-Phase 3, nicht zum M3-Kern. Siehe entitlements Modul v1.0.0.


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 Superadmin-UI Pläne + Capability-Matrix ohne SQL
E Systemrolle co_trainer + Entitlements im Frontend Entscheidung 1.2 risikoarm
F 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

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.