shinkan-jinkendo/docs/jinkendo-family/design-principles/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md
Lars 6c7c24e887
All checks were successful
Deploy Development / deploy (push) Successful in 48s
Test Suite / pytest-backend (push) Successful in 45s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 15s
Test Suite / k6 /health Baseline (push) Successful in 34s
Test Suite / playwright-tests (push) Successful in 1m35s
Add Jinkendo family design principles and entitlement model docs.
Document cross-app architecture patterns, Mitai alignment, and family entitlement standards. Documentation only; no runtime changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 09:12:48 +02:00

126 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Capability & Club Features Designprinzipien (Extraktion)
**Status:** Analyse / Arbeitspapier
**Stand:** 2026-07-04
**Geltungsbereich:** Modul „Capabilities & Vereins-Feature-Kontingente“ — nicht Billing/Stripe
**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 2 von 15
**Mitai-Vergleich:** [FEATURE_ENTITLEMENT_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/FEATURE_ENTITLEMENT_DESIGN_PRINCIPLES.md) (#3)
**Kernkomponenten:**
| Bereich | Pfade |
|---------|-------|
| Capabilities | `backend/capabilities.py` |
| Vereins-Features | `backend/club_features.py` |
| Entitlements-API | `backend/entitlements.py`, `backend/routers/me_entitlements.py` |
| Quota-Bypass | `backend/club_quota_bypass.py` |
| Spez | `CAPABILITY_CATALOG.v1.md`, `CLUB_MEMBERSHIP_AND_FEATURES.v1.md` |
---
## Modul
**Capability & Club Feature Entitlements**
Zwei Schichten: **Capabilities** (darf Nutzer X im Verein Y?) und **Club Features** (Kontingente/Limits pro Verein, Subjekt `club_id`). Zusammenführung in `GET /api/me/entitlements`.
---
## Fachliche Verantwortung
1. **Capability-Checks**`check_capability`, `probe_capability`, `require_capability` mit Env `CAPABILITY_ENFORCE`.
2. **Vereins-Kontingente**`probe_club_feature_access`, `consume_club_feature_with_usage` mit Env `CLUB_FEATURE_ENFORCE`.
3. **Entitlements-Snapshot** — Frontend erhält `capabilities` + `features` + Plan für UI-Gating ohne Tier-Logik in Widgets.
4. **Account-Lifecycle**`min_account_state` blockiert Capabilities vor Verifizierung.
### Unterschied zu Mitai
| Aspekt | Mitai | Shinkan |
|--------|-------|---------|
| Limit-Subjekt | Profil / Subscription | **Verein** (`club_id`) |
| Rollen | Tier + Features | Vereinsrollen + Portal-Rolle |
| Legacy | `check_feature_access` (001) | Explizit **nicht** für Shinkan-Limits nutzen |
---
## Designprinzipien
### 1. Eine Entitlements-API für das Frontend
| | |
|---|---|
| **Prinzip** | `GET /api/me/entitlements?club_id=` liefert Capabilities-Map + Feature-Kontingente + Plan. |
| **Begründung** | Keine Tier-Logik in React-Komponenten; ein Roundtrip pro Mandantenwechsel. |
| **Quelle** | `entitlements.py`, `me_entitlements.py` |
| **Tragfähigkeit** | **hoch** |
| **Einschränkung** | Nicht alle UI-Stellen nutzen Entitlements konsequent. |
### 2. 4-Phasen-Rollout (Probe → Enforce)
| | |
|---|---|
| **Prinzip** | Phase 2: JSON-Log ohne Block; Phase 3+: `CAPABILITY_ENFORCE=1` / `CLUB_FEATURE_ENFORCE=1` → HTTP 403. |
| **Begründung** | Sicheres Einführen ohne Produktions-Crash; Audit vor Hard-Block. |
| **Quelle** | `capabilities.py`, `club_features.py`; Mitai-Vorbild in Spec |
| **Tragfähigkeit** | **hoch** |
| **Einschränkung** | Env-Flags müssen pro Umgebung bewusst gesetzt werden. |
### 3. Capabilities verknüpft mit Features
| | |
|---|---|
| **Prinzip** | Capability kann `linked_feature_id` haben — Kontingent-Check vor Ausführung. |
| **Begründung** | Recht und Limit bleiben getrennt modelliert aber gemeinsam enforcebar. |
| **Quelle** | `capabilities`-Tabelle; `check_capability` |
| **Tragfähigkeit** | **hoch** |
| **Einschränkung** | Nicht jede Capability hat linked Feature. |
### 4. Enforcement an der API, nicht in der UI
| | |
|---|---|
| **Prinzip** | Router rufen `require_capability` / `probe_club_feature_access` — UI blendet nur vor. |
| **Begründung** | API ist Source of Truth; UI-Gating allein ist umgehbar. |
| **Quelle** | `exercise_ai.py`, Planungs-KI-Router |
| **Tragfähigkeit** | **hoch** |
| **Einschränkung** | Teilweise noch Probe-only in Prod. |
### 5. Bestands-Features als Live-Zählung
| | |
|---|---|
| **Prinzip** | Inventar-Features (`exercises`, `training_groups`, …) zählen live in DB, nicht nur `club_feature_usage`. |
| **Begründung** | Keine Drift zwischen tatsächlichem Bestand und Usage-Tabelle. |
| **Quelle** | `_INVENTORY_FEATURES` in `club_features.py` |
| **Tragfähigkeit** | **mittel** |
| **Einschränkung** | Performance bei großen Vereinen — ggf. Cache nötig. |
### 6. Quota-Bypass für Plattform-Rollen
| | |
|---|---|
| **Prinzip** | Konfigurierbare Bypass-Capabilities (`domain=quota_bypass`) für Support/Admin ohne harte Limits. |
| **Begründung** | Betrieb und Demos ohne Plan-Upgrade. |
| **Quelle** | `club_quota_bypass.py`; `entitlements.py` |
| **Tragfähigkeit** | **mittel** |
| **Einschränkung** | Missbrauchsrisiko — nur dokumentierte Grants. |
---
## Nicht übernehmen
1. **Mitai `auth.check_feature_access` für Shinkan-Vereinslimits** — profil-zentriert, falscher Subjekt-Scope.
2. **Tier-Logik in Frontend-Widgets** — gehört in Entitlements-Response.
3. **Enforcement ohne Probe-Phase** — bricht bestehende Vereine ohne Vorwarnung.
4. **Capabilities ohne DB-Sync aus Registry** — siehe Rights-Registry-Dokument.
---
## Verwandte Dokumentation
- [CAPABILITY_CATALOG.v1.md](../../../.claude/docs/technical/CAPABILITY_CATALOG.v1.md)
- [CLUB_MEMBERSHIP_AND_FEATURES.v1.md](../../../.claude/docs/technical/CLUB_MEMBERSHIP_AND_FEATURES.v1.md)
- [RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md](./RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md)
- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md)