Capability-Katalog Shinkan v1
Status: Konzept (verbindliche Zieldefinition; M3 teilweise umgesetzt)
Stand: 2026-06-06
Bezüge: ACCESS_LAYER_AND_GOVERNANCE_PLAN.md (Stufe E), MULTI_TENANCY_RBAC_ARCHITECTURE.md, CLUB_MEMBERSHIP_AND_FEATURES.v1.md, MEMBERSHIP_RBAC_DECISIONS_2026-06.md (Produktentscheidungen)
1. Zweck
Dieses Dokument definiert benannte Capabilities (Wer darf welche Funktion ausführen?) — getrennt von:
- Governance (Darf ich dieses Objekt lesen/ändern? →
visibility, club_id, created_by)
- Feature-Limits (Wie viel darf der Verein? →
CLUB_MEMBERSHIP_AND_FEATURES.v1.md)
Capabilities beantworten: „Darf ein Trainer mit Rolle X die Funktion Y im Verein Z überhaupt nutzen?“
2. Namenskonvention
{domain}.{action}[.{qualifier}]
| Segment |
Beispiele |
domain |
exercises, media, planning, org, platform |
action |
read, create, update, delete, manage, execute |
qualifier |
ai.suggest, join_request, inbox.review |
CRUD-Mapping:
| Aktion |
Capability-Suffix |
Bedeutung |
| Lesen (Listen/Detail) |
.read |
Navigation + API-Lesen erlaubt |
| Anlegen |
.create |
POST/INSERT |
| Bearbeiten |
.update |
PUT/PATCH (eigenes + berechtigtes Fremdes) |
| Löschen |
.delete |
DELETE (strenger als update) |
| Verwalten |
.manage |
Org-Funktionen, Freigaben, Mitglieder |
| Ausführen (ohne Persistenz) |
.execute |
z. B. KI-Vorschau, Coach-Lauf |
Objektbezogene Feinheiten (nur Ersteller, nur Vereinsadmin des Objekt-Vereins) bleiben in Governance — Capabilities sind das Tür-Schloss davor.
3. Account-Lifecycle (Voraussetzung für Capabilities)
account_state |
Bedingung |
Typische Capabilities |
anonymous |
Keine Session |
nur öffentliche Routen (/login, Rechtstexte, clubs/public-directory) |
unverified |
Session, email_verified=false |
account.resend_verification, account.logout |
verified_pending_club |
Verifiziert, keine aktive club_members |
club.join_request, club.creation_request (M7), account.settings — kein Lesezugriff auf Domänen-Inhalte (siehe Entscheidungs-Doc §1.1) |
active_member |
Mind. eine aktive Vereinsmitgliedschaft |
Domänen-Capabilities gemäß Vereinsrolle |
platform_admin |
role ∈ admin, superadmin |
platform.* zusätzlich |
Regel: Domänen-Capabilities (exercises.*, planning.*, …) erfordern mindestens active_member, sofern nicht platform_admin.
4. Rollen-Scopes
4.1 Portal-Rollen (profiles.role)
| Rolle |
Scope |
Kurz |
user |
Portal |
Standard nach Registrierung (Zielbild; heute oft trainer Legacy) |
trainer |
Portal |
Legacy — mittelfristig durch user + Vereinsrollen ersetzen |
admin |
Portal |
Plattform-Admin (Vereine anlegen, erweiterte Ops) |
superadmin |
Portal |
Vollzugriff Plattform + Superadmin-Werkzeuge |
4.2 Vereinsrollen (club_member_roles.role_code)
| Rolle |
Fachlich |
club_admin |
Vereinsorganisation, Mitglieder, Struktur |
trainer |
Planung, Übungen, Durchführung |
content_editor |
Inhalte pflegen (Bibliothek) |
division_lead |
Spartenleitung (später division-scope) |
Mehrfachrollen pro Mitgliedschaft sind möglich (OR-Verknüpfung der Capabilities).
4.3 Mapping heutiger Helfer → Capabilities
Heutiger Code (club_tenancy.py) |
Ziel-Capability-Cluster |
can_manage_club_org |
org.structure.manage, org.members.manage, org.inbox.review |
can_plan_in_club |
planning.*, exercises.create/update, modules.*, framework.* |
is_platform_admin |
platform.* (Bypass Mandant, Audit-Pflicht) |
is_superadmin |
platform.superadmin.* |
5. Capability-Katalog (v1)
Legende Spalten:
- Min. Account:
verified_pending_club | active_member | platform_admin
- Vereinsrollen: leer = alle aktiven Mitglieder; sonst mindestens eine Rolle
- Feature-ID: optionales Kontingent (siehe Club-Membership-Doc); leer = kein Limit
- Governance: zusätzliche Objektprüfung ja/nein
5.1 Account & Onboarding
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Endpoints / UI |
account.settings.read |
unverified |
— |
— |
GET /profiles/me, Einstellungen |
account.settings.update |
unverified |
— |
— |
PUT /profiles/{id} (eigenes Profil) |
account.password.change |
unverified |
— |
— |
PUT /api/auth/pin |
account.resend_verification |
unverified |
— |
— |
POST /api/auth/resend-verification |
club.directory.read |
verified_pending_club |
— |
— |
GET /clubs/public-directory |
club.join_request.create |
verified_pending_club |
— |
— |
POST /me/club-join-requests, Registrierung mit requested_club_id |
club.join_request.withdraw |
verified_pending_club |
— |
— |
DELETE /me/club-join-requests/{id} |
club.join_request.read_own |
verified_pending_club |
— |
— |
GET /me/club-join-requests |
5.2 Organisation (Verein)
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Endpoints / UI |
org.club.read |
active_member |
* |
— |
GET /clubs, GET /clubs/{id} (eigene Vereine) |
org.club.create |
platform_admin |
— |
— |
POST /clubs |
org.club.update |
platform_admin |
club_admin |
— |
PUT /clubs/{id} |
org.club.delete |
platform_admin |
— |
— |
DELETE /clubs/{id} |
org.structure.manage |
active_member |
club_admin |
training_groups |
Sparten, Gruppen CRUD |
org.members.read |
active_member |
club_admin |
— |
GET /clubs/{id}/members |
org.members.manage |
active_member |
club_admin |
active_members |
POST/PUT/DELETE Mitglieder |
org.members.directory |
active_member |
* |
— |
GET /clubs/{id}/members/directory (ohne E-Mail für Nicht-Admins) |
org.join_request.review |
active_member |
club_admin |
— |
Join-Request accept/reject, Inbox |
org.inbox.read |
active_member |
club_admin |
— |
Posteingang Join + Content-Reports |
5.3 Übungen
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Governance |
exercises.read |
active_member |
* |
— |
ja (visibility) |
exercises.create |
active_member |
trainer, content_editor, club_admin, division_lead |
exercises |
— |
exercises.update |
active_member |
trainer, content_editor, club_admin, division_lead |
— |
ja |
exercises.delete |
active_member |
club_admin (+ Ersteller privat) |
— |
ja |
exercises.bulk_metadata |
active_member |
content_editor, club_admin |
— |
ja |
exercises.ai.suggest |
active_member |
trainer, content_editor, club_admin |
ai_calls |
— |
exercises.ai.regenerate |
active_member |
trainer, content_editor, club_admin |
ai_calls |
ja (edit) |
exercises.media.read |
active_member |
* |
— |
ja |
exercises.media.upload |
active_member |
trainer, content_editor, club_admin |
exercise_media |
ja |
exercises.variants.manage |
active_member |
trainer, content_editor, club_admin |
— |
ja |
Representative Endpoints: /api/exercises*, /api/exercises/ai/*, Medien-Datei-Download.
5.4 Medien-Bibliothek (Archiv)
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Governance |
media.library.read |
active_member |
* |
— |
ja |
media.library.upload |
active_member |
trainer, content_editor, club_admin |
exercise_media |
ja |
media.library.update |
active_member |
trainer, content_editor, club_admin |
— |
ja |
media.library.lifecycle |
active_member |
trainer, club_admin |
— |
ja |
media.rights.declare |
active_member |
trainer, club_admin |
— |
ja |
media.admin.rights_review |
platform_admin |
— |
— |
Plattform-Admin Legacy-Review |
5.5 Trainingsmodule & Rahmenprogramme
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Governance |
modules.read |
active_member |
* |
— |
ja |
modules.create |
active_member |
trainer, content_editor, club_admin |
training_programs |
— |
modules.update |
active_member |
trainer, content_editor, club_admin |
— |
ja |
modules.delete |
active_member |
club_admin (+ Ersteller) |
— |
ja |
framework.read |
active_member |
* |
— |
ja |
framework.create |
active_member |
trainer, club_admin |
training_programs |
— |
framework.update |
active_member |
trainer, club_admin |
— |
ja |
framework.delete |
active_member |
club_admin (+ Ersteller) |
— |
ja |
plan_templates.read |
active_member |
* |
— |
ja |
plan_templates.manage |
active_member |
trainer, club_admin |
— |
ja |
5.6 Progressionspfade
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Governance |
progression.read |
active_member |
* |
— |
ja |
progression.manage |
active_member |
trainer, content_editor, club_admin |
— |
ja |
5.7 Planung & Durchführung
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Governance |
planning.calendar.read |
active_member |
* |
— |
ja (Gruppe/Verein) |
planning.units.create |
active_member |
trainer, club_admin, division_lead |
training_units |
ja |
planning.units.update |
active_member |
trainer, club_admin, division_lead |
— |
ja |
planning.units.delete |
active_member |
club_admin, trainer (eigene) |
— |
ja |
planning.units.run |
active_member |
trainer, club_admin, division_lead |
— |
ja |
planning.coach.execute |
active_member |
trainer, club_admin |
— |
ja |
planning.ai.suggest |
active_member |
trainer, club_admin |
ai_calls |
— |
planning.ai.progression_path |
active_member |
trainer, club_admin |
ai_calls |
— |
5.8 Fähigkeiten & Scoring
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
Governance |
skills.catalog.read |
active_member |
* |
— |
globaler Katalog |
skills.discovery.read |
active_member |
trainer, content_editor |
— |
— |
skill_profiles.read |
active_member |
* |
— |
ja (Artefakt) |
5.9 Governance & Meldungen
| Capability-ID |
Min. Account |
Vereinsrollen |
Feature-ID |
governance.content_report.create |
active_member |
* |
— |
governance.content_report.review |
active_member |
club_admin |
— |
governance.change_request.* |
active_member |
content_editor, club_admin |
— |
5.10 Plattform (nur Portal-Admin / Superadmin)
| Capability-ID |
Min. Account |
Portal-Rolle |
Feature-ID |
platform.admin.access |
platform_admin |
admin, superadmin |
— |
platform.users.manage |
platform_admin |
superadmin |
— |
platform.catalogs.manage |
platform_admin |
superadmin |
— |
platform.maturity_models.manage |
platform_admin |
superadmin |
— |
platform.wiki_import.execute |
platform_admin |
superadmin |
wiki_import |
platform.ai_prompts.manage |
platform_admin |
superadmin |
— |
platform.exercise_enrichment.execute |
platform_admin |
superadmin |
ai_calls |
platform.user_content.moderate |
platform_admin |
superadmin |
— |
platform.legal_documents.manage |
platform_admin |
superadmin |
— |
platform.media_storage.manage |
platform_admin |
superadmin |
— |
platform.club_creation.approve |
platform_admin |
superadmin |
— |
Geplant: club.creation_request.submit → verified_pending_club; Freigabe über platform.club_creation.approve.
6. Standard-Zuordnung Vereinsrolle → Capabilities (v1, fest)
Diese Tabelle ist die initiale Grant-Matrix (club_role_capability_grants). Später durch Custom Roles ersetzbar — gleiche Capability-IDs.
| Capability-Cluster |
club_admin |
trainer |
content_editor |
division_lead |
org.structure.manage |
✓ |
— |
— |
✓ (eigene Sparte, später) |
org.members.manage |
✓ |
— |
— |
— |
org.join_request.review |
✓ |
— |
— |
— |
exercises.read |
✓ |
✓ |
✓ |
✓ |
exercises.create/update |
✓ |
✓ |
✓ |
✓ |
exercises.delete |
✓ |
— |
— |
— |
exercises.ai.* |
✓ |
✓ |
✓ |
✓ |
media.library.* |
✓ |
✓ |
✓ |
✓ |
modules.* / framework.* |
✓ |
✓ |
✓ |
✓ |
planning.* |
✓ |
✓ |
— |
✓ |
planning.coach.execute |
✓ |
✓ |
— |
✓ |
governance.content_report.review |
✓ |
— |
— |
— |
7. API-Vertrag (Ziel)
7.1 Effektive Rechte für Frontend
GET /api/me/entitlements?club_id={optional}
Antwort (Ausschnitt):
{
"account_state": "active_member",
"portal_role": "user",
"club_id": 12,
"club_roles": ["trainer"],
"capabilities": {
"exercises.read": true,
"exercises.ai.suggest": true,
"org.members.manage": false
},
"features": {
"ai_calls": { "allowed": true, "used": 4, "limit": 50, "remaining": 46, "reset_at": "2026-07-01T00:00:00Z" }
}
}
Frontend: Navigation und Buttons nur aus dieser Antwort — keine duplizierten Rollen-Checks in JSX (Ausnahme: rein kosmetische Labels).
7.2 Backend-Enforcement
Zentral (Zielmodul authorization/capabilities.py oder Erweiterung club_tenancy.py):
assert_capability(tenant, "exercises.ai.suggest", club_id=tenant.effective_club_id)
assert_club_feature(tenant, "ai_calls", club_id=tenant.effective_club_id) # siehe Club-Membership-Doc
# + bestehende Governance auf Objekt-Ebene
8. Implementierungsreihenfolge (Capabilities)
| Phase |
Inhalt |
| C0 |
Account-Gates (unverified, verified_pending_club) — ohne Capability-DB |
| C1 |
capabilities + club_role_capability_grants seed aus §5–6 |
| C2 |
GET /api/me/entitlements + Frontend-Nav |
| C3 |
Enforcement: KI-Endpoints, exercises.create, planning.* |
| C4 |
Restliche Router schrittweise; Audit in ACCESS_LAYER_ENDPOINT_AUDIT.md |
| C5 |
Custom Roles (optional) — gleiche IDs |
9. Abgrenzung & Drift-Schutz
- Neue Nutzerfunktion →
register_capability() in rights_registrations/<modul>.py, dann Endpoint mit probe_capability. Namenskonvention hier dokumentieren — kein Bulk-Seed in Migrationen.
- Kontingent →
register_feature() im selben Modul; Consume über consume_club_feature_with_usage.
- Kein paralleles
if (user.role === 'trainer') für Sicherheit — nur UX-Fallback.
- Capability ≠ Feature:
exercises.ai.suggest (darf ich?) vs. ai_calls (wie viel übrig?).
- Plattform-Admin-Bypass dokumentieren und auditieren (
platform_admin sieht Mandant, nicht automatisch alle Quotas).
Siehe docs/working/RIGHTS_AND_FEATURES_REGISTRY.md (Registry-first, ersetzt Katalog-first aus 079).
10. Referenzen
| Dokument |
Inhalt |
CLUB_MEMBERSHIP_AND_FEATURES.v1.md |
Vereinsabo, Feature-Registry, Kontingente |
ACCESS_LAYER_AND_GOVERNANCE_PLAN.md |
TenantContext, Governance, Stufe E |
MULTI_TENANCY_RBAC_ARCHITECTURE.md |
§4.6 Vereinsabo-Zielbild |
ACCESS_LAYER_ENDPOINT_AUDIT.md |
Endpoint-Pflege |
Mitai FEATURE_ENFORCEMENT.md |
4-Phasen-Rollout-Vorbild |
Changelog
- 2026-06-06: v1 — Initial-Katalog aus Ist-Code (
club_tenancy, Router-Inventar) + Ziel-Onboarding.