diff --git a/.claude/docs/technical/DESIGN_PRINCIPLES_RELOCATED.md b/.claude/docs/technical/DESIGN_PRINCIPLES_RELOCATED.md new file mode 100644 index 0000000..0aae184 --- /dev/null +++ b/.claude/docs/technical/DESIGN_PRINCIPLES_RELOCATED.md @@ -0,0 +1,9 @@ +# Designprinzipien — verschoben + +Die **Jinkendo-Produktfamilie Designprinzipien** (Index + Shinkan-Serie) liegen nicht mehr hier. + +**Neuer Standort (Shinkan-Serie):** [docs/jinkendo-family/design-principles/DESIGN_PRINCIPLES_INDEX.md](../../../docs/jinkendo-family/design-principles/DESIGN_PRINCIPLES_INDEX.md) + +**Mitai-Serie:** [mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/](file:///c:/Dev/mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/README.md) + +**Abgleich:** [docs/jinkendo-family/DESIGN_PRINCIPLES_ALIGNMENT.md](../../../docs/jinkendo-family/DESIGN_PRINCIPLES_ALIGNMENT.md) diff --git a/docs/jinkendo-family/DESIGN_PRINCIPLES_ALIGNMENT.md b/docs/jinkendo-family/DESIGN_PRINCIPLES_ALIGNMENT.md new file mode 100644 index 0000000..b686a18 --- /dev/null +++ b/docs/jinkendo-family/DESIGN_PRINCIPLES_ALIGNMENT.md @@ -0,0 +1,358 @@ +# Designprinzipien – Abgleich Mitai ↔ Shinkan + +**Status:** Review / Entscheidungsgrundlage +**Stand:** 2026-07-04 +**Zweck:** Widersprüche, bewusste Abweichungen und Implementierungslücken zwischen den Designprinzipien-Serien identifizieren — Basis für **Familien-Entscheidungen** und langfristige Konvergenz von Mitai und Shinkan. + +**Quellen:** + +| App | Index | +|-----|--------| +| Mitai (Foundation) | [mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/README.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/README.md) — 9 Module | +| Shinkan | [design-principles/DESIGN_PRINCIPLES_INDEX.md](./design-principles/DESIGN_PRINCIPLES_INDEX.md) — 15 Module | + +--- + +## 1. Kurzfassung + +| Kategorie | Anzahl | Bedeutung | +|-----------|--------|-----------| +| **Familien-Konsens** | 12 Muster | In beiden Serien gleich oder kompatibel — **verbindlich für neue Apps** | +| **Bewusste Produkt-Abweichung** | 8 | Fachlich/Architektur begründet — **nicht angleichen**, aber im Familienmodell verankern | +| **Konzeptuelle Spannung** | 6 | Widersprüche oder gegenläufige Defaults — **Familien-Entscheidung nötig** | +| **Ist vs. Prinzip (Schuld)** | 14+ | Mindestens eine App verletzt eigene oder Schwester-Prinzipien — **Remediation** | +| **Nur Shinkan** | 6 Module | Mandanten-/Domänen-Bausteine ohne Mitai-Pendant | +| **Nur Mitai (reifer)** | 3 Muster | Data Layer, Widget-Dashboard, Universal Import — Shinkan vereinfacht oder fehlt | + +**Kernbefund:** Mitai und Shinkan teilen dieselbe **technische Basis** (Auth, Migration, Nav-SSoT, Registry-Denken, Probe→Enforce), divergieren aber strukturell bei **Entitlement-Subjekt** (Profil vs. Verein), **Berechnungsarchitektur** (generischer Data Layer vs. domänenspezifisches Scoring) und **KI-Reife** (Unified Executor vs. schmale Laufzeit). + +--- + +## 2. Familien-Konsens (für neue Produkte übernehmen) + +Diese Muster sind in beiden Serien explizit oder implizit tragfähig: + +| # | Muster | Mitai | Shinkan | +|---|--------|-------|---------| +| F1 | Server-Sessions + `Depends(require_auth)` | Auth #1–3 | Auth #1–2 | +| F2 | `profile_id` aus Session, nie aus Client-Header | Auth #3 | Auth #3 | +| F3 | Auth getrennt von Authorization/Entitlements | Auth #10 | Capabilities + Access Layer | +| F4 | Nummerierte SQL-Migrationen + Tracking beim Container-Start | Migration #1–5 | Migration #1–3 | +| F5 | Fail-fast, kein Auto-Rollback | Migration #5 | Migration #2 | +| F6 | `appNav` / zentrale Nav-Config als SSoT | Navigation #1 | Navigation #1 | +| F7 | Admin als eigener Hub/Realm | Navigation #6–7 | Navigation #2 | +| F8 | DB-konfigurierbare KI-Prompts (nicht hardcoded Prod) | Prompt #2 | AI Runtime #2 | +| F9 | Template vs. Kontext/Daten trennen | Prompt #5 | AI Runtime #4 | +| F10 | Ingest ≠ Interpretation beim Import | Import #2 | Wiki Import #1 | +| F11 | Preview/Dry-Run vor Massenimport | Import #3+ | Wiki Import #2 | +| F12 | 4-Phasen-Rollout Entitlements (Log → Enforce) | Feature #8 | Capability #2 | + +**Empfehlung:** Als **`JINKENDO_FOUNDATION_CHECKLIST`** in künftigen Apps verpflichtend; Details pro Modul in den Einzeldokumenten. + +--- + +## 3. Modul-Abgleich (9 vergleichbare Paare) + +Legende **Bewertung:** + +| Symbol | Bedeutung | +|--------|-----------| +| ✅ | Prinzipien aligned / kompatibel | +| ⚠️ | Teilweise aligned; Lücken in Implementierung oder Doku | +| 🔀 | Bewusste Produkt-Divergenz (kein Bug) | +| ❌ | Widerspruch oder gegenläufiges Konzept — Entscheidung nötig | +| 🏗️ | Ist-Stand verletzt dokumentierte Prinzipien (Architekturschuld) | + +--- + +### 3.1 Prompt Engine (Mitai #1) ↔ AI Prompt Runtime (Shinkan #5) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| Single Entry Point | `execute_prompt` / Unified System | `ai_prompt_runtime` + verteilte Orchestratoren | ❌ Konzept | +| Prompt-Typen | base / pipeline / workflow | nur slug + Mustache | 🔀 Shinkan bewusst schlanker | +| Platzhalter-Registry | zentral, API-Verträge | Kontext-Arten (`AiPromptContextKind`), kein Registry-Katalog | ⚠️ | +| Data Layer-Anbindung | Layer 1 → Resolver | Domänen-Builder ad hoc | ⚠️ | +| Debug/Preview | ausgereift | Admin-Vorschau, weniger Runtime-Transparenz | ⚠️ | +| Feature-Gating an Execute | teils fehlend (Legacy) | Capability geplant, teils Probe | 🏗️ beide | + +**Widersprüche / gegenläufig:** + +- Mitai: **Ein Executor** ist Kernprinzip. Shinkan: **kein** vergleichbarer Executor — Planungs-KI umgeht teils die Laufzeit. +- Beide warnen vor **parallelen KI-Pfaden**; beide haben sie noch (Mitai `insights.py`, Shinkan Router-OpenRouter). + +**Familien-Entscheidung (Vorschlag):** + +| Option | Inhalt | +|--------|--------| +| **Zielbild** | Gemeinsame **`prompt_executor`-Fassade** (Package oder Copy mit Namespace); Shinkan-Kontext-Builder als Plugins | +| **Shinkan-Roadmap** | Planungs-Orchestrierung in Laufzeit ziehen; keine Workflow-Graphs vor Planungs-Kontext-Reife | +| **Nicht kopieren** | Mitai: doppelte Pipeline-Modelle, PLACEHOLDER_MAP-Duplikat, Roh-SQL im Executor | + +--- + +### 3.2 Data Layer (Mitai #2) ↔ Skill Scoring (Shinkan #8) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| Berechnungs-SSoT | `data_layer/` Layer 0→1→2 | nur `skill_scoring.py` | ❌ Abdeckung | +| Router delegieren | explizites Prinzip #13 | Skill-Router ja; Planung teils nicht | ⚠️ | +| Confidence / data_points | Pflicht-Metadaten | nicht analog | 🔀 Domäne anders | +| Chart/KPI-Anbindung | Layer 2b Adapter | KPI-Dashboard ruft Router-Helfer | ⚠️ | +| Import-Grenze | keine Scores beim Insert | Wiki: explizit kein Scoring beim Insert | ✅ | + +**Widerspruch:** + +- Mitai postuliert **generische Berechnungsschicht** für die ganze App. Shinkan hat **kein** Data Layer — nur ein **domänenspezifisches** Scoring-Modul. Das ist keine Implementierungslücke allein, sondern **unterschiedliche Architektur-Tiefe**. + +**Familien-Entscheidung (Vorschlag):** + +| Option | Inhalt | +|--------|--------| +| **Familien-Prinzip** | „Berechnungen in benannter Schicht, nicht in Router/React“ — **Ja** | +| **Implementierung** | Mitai: `data_layer/` bleibt Referenz. Shinkan: Skill Scoring **ist** Layer-1-Vorbild; langfristig **`planning_metrics/`** o. ä. statt Router-SQL | +| **Nicht verallgemeinern** | Mitai-Formeln (TDEE, WHR) — nur Schichtenmodell übernehmen | + +--- + +### 3.3 Feature & Entitlement (Mitai #3) ↔ Capability & Club Features (Shinkan #2) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| Subjekt | **Profil** + Tier | **Verein** (`club_id`) + Plan | ❌ Scope | +| Auflösungs-API | `check_feature_access` | `check_capability` + `club_features` + `/me/entitlements` | 🔀 | +| Rollout 4 Phasen | ja | ja (Env-Flags) | ✅ | +| Registry | DB `features` + Tiers | Code-Registry → DB Sync | ⚠️ | +| Capabilities vs. Features | Features only | Capabilities **und** Kontingente getrennt | 🔀 Shinkan feiner | +| Widget/Layout-Gating | zentral | Entitlements-API, kein Widget-Layout | ⚠️ | + +**Größter Familien-Konflikt:** + +Mitai-Dokument #3 „Nicht übernehmen“ Punkt 10: *„Profile as Entitlement-Subject — Multi-App-Familie braucht separates Identity/Subscription-Boundary.“* +Shinkan **ist** die Antwort mit Verein als Subjekt — aber es gibt **kein gemeinsames Familienmodell**, das Profil-Tier **und** Org-Limits kombiniert. + +**Familien-Entscheidung (Vorschlag):** + +``` +Entitlement-Subjekt (familie): + ├── account (profile_id) → Tier, persönliche Limits (Mitai) + └── tenant (club_id?) → Org-Plan, Capabilities (Shinkan, optional null) + +API: GET /me/entitlements?tenant_id= +Enforcement: eine resolve_entitlement(subject, capability|feature) +``` + +| App | Remediation | +|-----|-------------| +| Mitai | Org-Scope reservieren; Tier-Drift (#3 Schuld) bereinigen | +| Shinkan | `CLUB_FEATURE_ENFORCE=1` produktiv; Mitai-Legacy `check_feature_access` nicht nutzen (bereits Regel) | + +--- + +### 3.4 Registry / Plugin (Mitai #4) ↔ Rights Registry (Shinkan #3) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| Registry-first | Platzhalter, Widgets, CSV-Module | Capabilities + Features only | ⚠️ Abdeckung | +| Validierung an Grenze | ja | ja (`register_*` wirft) | ✅ | +| Runtime + DB | Dual (Katalog + DB-Overrides) | Code → DB Upsert | ✅ | +| Dual Registry FE/BE | Widgets + `registerDashboardWidgets` | nicht vorhanden | 🔀 | +| Metadaten-Tiefe | nach Risiko (Matrix in Doc) | schlankere Dataclasses | ✅ | + +**Kein Widerspruch** — Shinkan Rights Registry ist **Teilmenge** des Mitai-Meta-Musters. + +**Familien-Entscheidung:** Mitai-Registry-Matrix (Platzhalter / UI-Plugin / Import-Modul / Rechte) als **Familien-Taxonomie**; Shinkan erweitert um Import-/Prompt-Registry wenn Wiki-Import generisch wird. + +--- + +### 3.5 Auth & Session (Mitai #5 ↔ Shinkan #4) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| Session-Modell | opaque token | gleich (shared `auth.py`) | ✅ | +| Depends-Pattern | ja | ja (+ TenantContext) | ✅ | +| IDOR Profile-Header | dokumentierte Schwäche | Shinkan: Session-only betont | ⚠️ prüfen | +| RBAC | `role` admin/user | Portal-Rolle **+** Vereinsrollen | 🔀 | +| Rate Limiting | ja | (Mitai-spezifisch in Router) | ⚠️ | +| Feature-Flags in Session | Legacy-Spalten | Account-Lifecycle separat | 🏗️ Mitai | + +**Gegenläufig:** Shinkan **erweitert** Auth um Mandanten — darf Mandantenlogik **nicht** in `auth.py` legen (Shinkan-Prinzip „Nicht übernehmen“). + +**Familien-Entscheidung:** Gemeinsames Auth-Modul; **TenantContext** als optionales Add-on-Pattern für mandantenfähige Apps. + +--- + +### 3.6 Universal Import (Mitai #6) ↔ Wiki Import (Shinkan #11) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| Ingest ≠ Interpretation | ✅ | ✅ | ✅ | +| Modul-Registry | zentral | fehlt (wiki-hardcoded) | ⚠️ | +| SAVEPOINT pro Zeile | ja | nicht dokumentiert | ⚠️ | +| Vorlagen/Mappings | generisch | SMW-Kategorien via Env | 🔀 | +| Feature-Limits | an Import gebunden | Admin-only | ⚠️ | + +**Kein Konflikt** — unterschiedliche Reife. Shinkan ist **Spezialfall** des Mitai-Musters. + +**Familien-Entscheidung:** Neue Import-Quellen über **Universal-Import-Gerüst** (Mitai); Wiki als `import_type=mediawiki` registrieren. + +--- + +### 3.7 Dashboard Widgets (Mitai #7) ↔ Dashboard KPIs (Shinkan #14) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| UX-Modell | konfigurierbares Widget-Layout | festes KPI-Aggregat | ❌ UX-Konzept | +| Chatty Client vermeiden | via Widget-Daten | via `/dashboard/kpis` | ✅ Ziel | +| Entitlements | `allowed` pro Widget | TenantContext auf KPIs | ✅ | +| Data Layer | Widgets konsumieren Layer 1 | intern Router-Helfer | ⚠️ | + +**Gegenläufig:** Mitai: **Nutzer konfiguriert Dashboard**. Shinkan: **Produkt definiert feste Kacheln** — bewusste MVP-Vereinfachung. + +**Familien-Entscheidung:** + +| App-Typ | Dashboard-Pattern | +|---------|-------------------| +| Personal Tracking (Mitai) | Widget-Katalog + Layout-JSON | +| Trainer/Verein (Shinkan) | Aggregierte KPI-Endpoints ausreichend; Widget-System optional Phase 2 | +| Neue App | Aggregat-Endpoint **mindestens**; Widget-System wenn Personalisierung nötig | + +--- + +### 3.8 Navigation / IA (Mitai #8 ↔ Shinkan #12) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| appNav SSoT | ja | ja | ✅ | +| Admin-Hub | Shell + Hub-Gruppen | horizontale `AdminPageNav` | ⚠️ | +| Breakpoint 1024px | explizit | „prüfen“ | ⚠️ | +| Onboarding-Nav | — | reduziert ohne Verein | 🔀 Shinkan | +| adminNav.js SSoT | empfohlen | hardcoded Array in JSX | 🏗️ Shinkan | +| Safe Area PWA | ja | Design-System, weniger explizit | ⚠️ | + +**Familien-Entscheidung:** `appNav.js` + **`adminNav.js`** als Pflicht; Shinkan `AdminPageNav` refactoren. + +--- + +### 3.9 Migration & Deploy (Mitai #9 ↔ Shinkan #13) + +| Aspekt | Mitai | Shinkan | Bewertung | +|--------|-------|---------|-----------| +| XXX_*.sql + schema_migrations | ✅ | ✅ | ✅ | +| Startup vor App | ✅ | ✅ | ✅ | +| develop/main | ✅ | ✅ | ✅ | +| Feste Ports | ✅ | ✅ | ✅ | +| Immutabler Docker-Build | dokumentiert | nicht im Shinkan-Doc | ⚠️ Doku | +| Health-Check / PG wait | ausführlich | kürzer | ⚠️ Doku | + +**Aligned** — Shinkan-Dokument ist **Untermenge**; Implementierung vermutlich gleich (shared Infra). + +--- + +## 4. Nur Shinkan (6 Module) — Einordnung für die Familie + +| Modul | Familien-Relevanz | Mitai-Bezug | +|-------|-------------------|------------| +| **Access Layer & Tenant** | **Pflicht** für mandantenfähige Apps | Mitai #3 fordert Org-Boundary — hier ausformuliert | +| **Media Assets & Archiv** | Optional (Content-Apps) | — | +| **Exercise Catalog** | Shinkan-Domäne | — | +| **Training Planning** | Shinkan-Domäne | — | +| **Content Reports (P-13)** | Empfohlen für UGC/Plattform | — | +| **Maturity Models** | Optional (Kompetenz-Apps) | — | + +**Kein Widerspruch zu Mitai** — ergänzen das Familienmodell um **Mandant + Content-Governance**. + +--- + +## 5. Querschnitt: Ist-Stand vs. dokumentierte Prinzipien + +Gemeinsame **Architekturschuld** (beide Apps verletzen teils eigene „Nicht übernehmen“-Listen): + +| Thema | Mitai | Shinkan | +|-------|-------|---------| +| Parallele KI-Pfade | `insights.py` Legacy | OpenRouter direkt in Routern | +| Entitlement Enforcement | teils UI-only / Legacy-Spalten | Env Probe-only | +| Registry-Sync / Duplikat | PLACEHOLDER_MAP + Registry | Capabilities-Sync, kein Prompt-Registry | +| Frontend ohne Backend-Gate | teils | Capabilities Probe | +| Dokumentations-Drift | Tier vs. Enforcement-Docs | Endpoint-Audit unvollständig | +| Monolithische Pages/Client | God Pages, api.js | God Pages, api.js (Roadmap Phase 4) | +| Fehlende JSON-Schema-KI | TODO | TODO (explizit vermeiden) | + +--- + +## 6. Entscheidungs-Matrix (Priorisiert) + +| Prio | Entscheidung | Betroffene Apps | Empfohlene Familien-Regel | +|------|--------------|-----------------|---------------------------| +| **P0** | Entitlement-Subjekt: Profil **und** optional Tenant | Mitai, Shinkan, neu | Ein API-Shape `/me/entitlements`; zwei Subjekt-Ebenen | +| **P0** | Kein Client-`profile_id` für AuthZ | alle | Session-only; Tenant via Header + Membership | +| **P1** | KI: ein Executor pro App | Mitai (fertig), Shinkan (Ziel) | `execute_prompt(slug, context_dto)` | +| **P1** | Berechnungs-SSoT-Schicht | Shinkan erweitern | Mindestens ein `*/metrics.py` pro Domäne mit KPIs | +| **P1** | Enforcement produktiv | beide | Phase 4 Enforce in Prod für kritische Features | +| **P2** | Registry-Taxonomie vereinheitlichen | beide | Rechte / Platzhalter / Import / UI-Plugin | +| **P2** | Admin-Nav SSoT | Shinkan | `adminNav.js` wie Mitai | +| **P2** | Import: Universal + Spezialmodule | Shinkan | Wiki als registriertes Modul | +| **P3** | Dashboard: Aggregat vs. Widgets | produktabhängig | Entscheidungsbaum §3.7 | +| **P3** | Shared `auth.py` / `db_init` | beide | Monorepo-Package oder Sync-Disziplin | + +--- + +## 7. Konvergenz-Roadmap (langfristig) + +```mermaid +flowchart LR + subgraph foundation [Familien-Foundation] + M9[Migration] + M5[Auth] + F3[Entitlements 2-Ebenen] + R4[Registry Meta] + end + + subgraph mitai [Mitai] + DL[Data Layer] + PE[Prompt Engine] + DW[Dashboard Widgets] + end + + subgraph shinkan [Shinkan] + AL[Access Layer] + AR[AI Runtime → Executor] + SS[Skill Scoring → Layer 1] + end + + M9 --> mitai + M9 --> shinkan + M5 --> mitai + M5 --> shinkan + F3 --> mitai + F3 --> shinkan + R4 --> mitai + R4 --> shinkan + AL -.->|Mandanten-Apps| foundation + PE -.->|Konvergenz| AR + DL -.->|Schichtenmodell| SS +``` + +| Phase | Mitai | Shinkan | +|-------|-------|---------| +| **Kurz** | Legacy KI-Pfade entfernen; Enforcement-Doku vereinheitlichen | Access-Layer-Audit abschließen; `CAPABILITY_ENFORCE` | +| **Mittel** | Org-Scope in Entitlements vorbereiten | `ai_prompt_runtime` → Unified Executor; Router-Helfer statt KPI-Duplikat | +| **Lang** | SSO/Identity (Vision) | Data-Layer-ähnliche Module für Planung; optional Widget-Dashboard | + +--- + +## 8. Nächste Schritte + +1. **Review-Workshop:** Tabelle §6 P0–P1 durchgehen und Familien-Regeln verbindlich markieren. +2. ~~**`FAMILY_ENTITLEMENT_MODEL.md`** anlegen (P0)~~ → [FAMILY_ENTITLEMENT_MODEL.md](./FAMILY_ENTITLEMENT_MODEL.md) (Entwurf 2026-07-04) +3. **Shinkan-Index** und **Mitai-Foundation-README** auf dieses Dokument verlinken. +4. **`FAMILY_ENTITLEMENT_MODEL.md`** — Entwurf angelegt (§6 Produkt-Abweichungen, §8 Regeln neue Apps). +5. Pro **P1-Punkt** Issue/Remediation-Eintrag in jeweiliger `SCHULDEN_UND_REMEDIATION` / Mitai-Äquivalent. + +--- + +## 9. Changelog + +| Datum | Änderung | +|-------|----------| +| 2026-07-04 | Erstfassung Abgleich Mitai Foundation (9) ↔ Shinkan (15) | diff --git a/docs/jinkendo-family/FAMILY_ENTITLEMENT_MODEL.md b/docs/jinkendo-family/FAMILY_ENTITLEMENT_MODEL.md new file mode 100644 index 0000000..b5df696 --- /dev/null +++ b/docs/jinkendo-family/FAMILY_ENTITLEMENT_MODEL.md @@ -0,0 +1,316 @@ +# Familien-Modell: Entitlements & Limits + +**Status:** Entwurf / verbindliche Zielrichtung (mit bewussten Produkt-Ausnahmen) +**Stand:** 2026-07-04 +**Bezüge:** + +- [DESIGN_PRINCIPLES_ALIGNMENT.md](./DESIGN_PRINCIPLES_ALIGNMENT.md) — Abgleich Mitai ↔ Shinkan +- Mitai: [FEATURE_ENTITLEMENT_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/FEATURE_ENTITLEMENT_DESIGN_PRINCIPLES.md) +- Shinkan: [CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md](./design-principles/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md) + +--- + +## 1. Zweck + +Dieses Dokument definiert das **gemeinsame Entitlement-Modell** der Jinkendo-Produktfamilie: + +- **Was** für neue Apps und Refactors **Standard** ist +- **Welche Produkt-Profile** welche Scopes nutzen (Account, Tenant, beides, keins) +- **Wie** bewusste Abweichungen dokumentiert werden — Abweichung ist erlaubt, **Undokumentiertheit** nicht + +**Nicht enthalten:** Stripe/SSO (`auth.jinkendo.de`), vollständige Billing-Implementierung, app-spezifische Feature-IDs. + +--- + +## 2. Leitgedanke: Vier getrennte Fragen + +Jede geschützte Aktion durchläuft konzeptionell **vier unabhängige Prüfungen**. Nicht jede App implementiert alle vier — siehe §6. + +| # | Frage | Familien-Begriff | Typische Quelle | +|---|--------|------------------|-----------------| +| **A** | Wer ist eingeloggt? | **Auth** (Identität) | Session → `profile_id` | +| **B** | Darf diese Rolle die **Funktion** ausführen? | **Capability** (Permission) | Rollen-Matrix, `min_account_state` | +| **C** | Ist das **Kontingent** erschöpft? | **Feature / Limit** (Quota) | Plan, Tier, Usage-Zähler | +| **D** | Darf ich **dieses Objekt** lesen/ändern? | **Governance** (Object ACL) | `visibility`, `club_id`, Owner | + +``` +Request → Auth (A) → [Capability (B)] → [Feature-Limit (C)] → [Governance (D)] → Handler +``` + +**Familien-Regel:** B, C und D **nicht** in React-Widgets oder Router-Inline-Logik vermischen — jeweils eine Auflösungsfunktion pro Ebene. + +**Shinkan-Ergänzung:** Governance ist dort ausgebaut (`TenantContext`, Access Layer); Mitai fokussiert A+B+C auf Profil-Ebene. + +--- + +## 3. Familien-Standard: Zwei Subjekt-Ebenen + +Limits und Pläne können an **zwei Subjekte** hängen. Beide sind im Familienmodell **first-class** — Apps wählen, welche sie nutzen (§6). + +| Subjekt | ID | Typische Frage | Beispiel | +|---------|-----|----------------|----------| +| **Account** | `profile_id` | Was darf **ich** als Nutzer (Tarif)? | Mitai Free vs. Premium | +| **Tenant** | `tenant_id` (z. B. `club_id`) | Was darf **meine Organisation**? | Shinkan Vereinsplan, KI-Kontingent | + +### 3.1 Auflösungs-Reihenfolge (wenn beide Ebenen aktiv) + +Für eine Aktion mit Capability `X` und Feature `Y`: + +1. **Account-Lifecycle** — z. B. E-Mail verifiziert, Onboarding abgeschlossen +2. **Capability(B)** — Rolle darf Funktion (Account- und/oder Tenant-Rollen) +3. **Feature(C)** — Kontingent am **primären Billing-Subjekt** der App (siehe Produkt-Profil) +4. **Governance(D)** — Objekt sichtbar/bearbeitbar + +**AND-Verknüpfung:** Alle aktiven Ebenen müssen passieren. Ausnahmen nur in §6.3 dokumentiert. + +### 3.2 Primäres Billing-Subjekt pro App + +| Profil | Primäres Subjekt für Limits | Capability-Subjekt | +|--------|----------------------------|-------------------| +| Personal App (Mitai) | **Account** | Account | +| Mandanten-App (Shinkan) | **Tenant** | Account + Tenant-Rolle | +| Hybrid (Zukunft) | konfigurierbar | beide | + +--- + +## 4. Familien-Standard: Capabilities vs. Features + +| Konzept | Familien-Definition | Subjekt | Beispiel | +|---------|---------------------|---------|----------| +| **Capability** | Binäre oder rollenbasierte **Erlaubnis** („darf ich?“) | meist Account + Tenant-Kontext | `exercises.ai.suggest` | +| **Feature** | **Kontingent** oder Boolean-Limit („wie oft/noch?“) | Account **oder** Tenant | `ai_calls` / Monat | +| **Verknüpfung** | Capability kann `linked_feature_id` haben | — | KI-Capability → KI-Kontingent | + +**Familien-Regel:** + +- Capabilities **registry-first** registrieren (Code → DB-Sync, Shinkan-Muster). +- Feature-IDs **nicht** in UI hardcoden — nur aus Entitlements-Response. +- `NULL` Limit = unbegrenzt; `0` = deaktiviert (Mitai-Semantik, familienweit). + +--- + +## 5. Familien-Standard: API & Enforcement + +### 5.1 Ziel-API (neue Apps) + +Ein **einheitlicher Snapshot** für das Frontend: + +``` +GET /api/me/entitlements + ?tenant_id= + +Response (skizziert): +{ + "account": { + "profile_id": 1, + "account_state": "active_member", + "tier_id": "premium", // optional, Account-Apps + "features": { "ai_calls": { "allowed", "used", "limit", "remaining", "reset_at" } }, + "capabilities": { "analysis.run": { "allowed": true, "reason": null } } + }, + "tenant": { // null wenn App keinen Tenant kennt + "tenant_id": 42, + "tenant_type": "club", + "plan_id": "pro", + "features": { ... }, + "capabilities": { ... }, + "roles": ["trainer"] + }, + "enforcement": { + "capabilities": "enforce|probe", + "features": "enforce|probe" + } +} +``` + +**Familien-Regel:** UI liest **nur** diesen Snapshot (oder domänenspezifische Teilmenge) — keine parallelen `/subscription/me` + `/features/usage` + Ad-hoc-Checks in neuen Apps. + +### 5.2 Ist-API (bestehende Apps — Abweichung dokumentiert) + +| App | Endpoint heute | Familien-Ziel | +|-----|----------------|---------------| +| **Mitai** | `/subscription/me`, `/features/usage`, `check_feature_access` | Snapshot schrittweise; Account-Block reicht | +| **Shinkan** | `GET /api/me/entitlements?club_id=` | Tenant-Block + Capabilities; Account-Tier fehlt bewusst | + +Migration: **kein Big-Bang** — alte Endpoints als Facade auf Snapshot mappen. + +### 5.3 Vier-Phasen-Rollout (familienweit verbindlich) + +| Phase | Verhalten | Env-Beispiel | +|-------|-----------|--------------| +| **1** | Cleanup Legacy-Flags | — | +| **2** | **Probe** — JSON-Log, HTTP 200 | `*_ENFORCE=0` | +| **3** | Frontend-Gates aus Entitlements | — | +| **4** | **Enforce** — HTTP 403 | `*_ENFORCE=1` | + +**Familien-Regel:** Phase 4 für **neue** kritische Features von Anfang an planbar; Bestands-Apps dürfen in Phase 2–3 bleiben bis kalibriert. + +### 5.4 Enforcement-Priorität + +1. **API** — autoritativ (`403`) +2. **Frontend** — UX (Badges, disabled Buttons) +3. **Niemals** — nur UI ohne API-Gate + +--- + +## 6. Produkt-Profile & bewusste Abweichungen + +Abweichungen vom Familien-Standard sind **zulässig**, wenn sie in der Tabelle **§6.2** stehen und begründet sind. + +### 6.1 Profil-Matrix (Soll) + +| Profil | Apps | Account-Limits | Tenant-Limits | Capabilities | Governance (Objekt) | +|--------|------|----------------|---------------|--------------|---------------------| +| **P1 Personal** | Mitai | ✅ primär | ❌ | ✅ Account | minimal / privat | +| **P2 Mandant** | Shinkan | ⚠️ Lifecycle only | ✅ primär | ✅ Account + Tenant-Rollen | ✅ Access Layer | +| **P3 Minimal** | Miken, Ikigai (geplant) | optional | ❌ | optional | minimal | +| **P4 Hybrid** | (Reserve) | ✅ | ✅ | ✅ beide | ✅ | + +### 6.2 Registrierter Abweichungs-Katalog + +| ID | App | Abweichung vom Familien-Standard | Begründung | Review | +|----|-----|----------------------------------|------------|--------| +| **DEV-01** | Mitai | Kein `tenant`-Block in Entitlements | Persönliche Tracking-App; kein Verein | Beibehalten (P1) | +| **DEV-02** | Mitai | Kein Capability-Katalog (nur Features+Tier) | RBAC = admin/user ausreichend | Optional später `account.*` Capabilities | +| **DEV-03** | Mitai | Mehrere Nutzer-APIs statt einem Snapshot | Historisch gewachsen | Facade → Snapshot (mittelfristig) | +| **DEV-04** | Mitai | Legacy Session-Spalten (`ai_enabled`, …) parallel Features | Migrationsschuld | Bereinigen, nicht in neue Apps | +| **DEV-05** | Shinkan | Kein Account-Tier / `profiles.tier` | Verein zahlt, nicht Trainer | Beibehalten (P2) | +| **DEV-06** | Shinkan | Capabilities **und** Governance (zwei Achsen) | Trainer vs. Objekt-Rechte | Familien-Vorbild für P2/P4 | +| **DEV-07** | Shinkan | `check_feature_access` (Mitai-Legacy) explizit verboten | Falsches Subjekt | Beibehalten | +| **DEV-08** | Shinkan | Enforcement oft Probe-only | Rollout-Sicherheit | → Phase 4 bis Datum X | +| **DEV-09** | Shinkan | Inventar-Features live gezählt | Drift-Vermeidung | Abweichung OK; in P2 dokumentieren | +| **DEV-10** | Beide | Kein atomares Check+Increment | Race bei Parallel-Requests | Familien-Backlog; Workaround dokumentieren | +| **DEV-11** | Neue Apps | dürfen **nur** Account **oder** nur Tenant wählen | MVP | Eintrag hier anlegen vor Launch | + +**Neue Abweichung:** Zeile in §6.2 + ggf. ein Satz im App-`CLAUDE.md`. + +### 6.3 Dokumentierte Ausnahmen (Bypass) + +| Ausnahme | Apps | Regel | +|----------|------|-------| +| Plattform-Admin Audit | Shinkan | Quota-Bypass über Grants, nicht pauschal superadmin | +| Admin ohne Auto-Bypass | Mitai | Admins unterliegen Limits (Produktentscheid) | +| Öffentliche Routen ohne Auth | alle | Kein Entitlement-Check | + +--- + +## 7. Mapping: Familien-Begriff ↔ Implementierung + +### 7.1 Mitai (Profil P1) + +| Familien | Mitai-Implementierung | +|----------|----------------------| +| Account-Features | `features`, `tier_limits`, `user_feature_usage` | +| Account-Tier | `get_effective_tier()`, `access_grants` | +| Check | `check_feature_access(profile_id, feature_id)` | +| Increment | `increment_feature_usage(profile_id, …)` | +| UI | `UsageBadge`, Widget `allowed` | + +### 7.2 Shinkan (Profil P2) + +| Familien | Shinkan-Implementierung | +|----------|-------------------------| +| Tenant-Features | `club_plan_limits`, `club_feature_usage`, `club_features.py` | +| Tenant-Plan | `get_effective_club_plan(club_id)` | +| Capabilities | `check_capability`, `capabilities` + `rights_registry` | +| Snapshot | `build_me_entitlements()` → `GET /me/entitlements` | +| Governance | `TenantContext`, `club_tenancy` — **kein** Ersatz für Capabilities | + +### 7.3 Gemeinsame Muster (copy-ready) + +| Muster | Mitai | Shinkan | +|--------|-------|---------| +| Feature-Registry in DB | ✅ | ✅ (`app='shinkan'`) | +| Plan × Feature Matrix | `tier_limits` | `club_plan_limits` | +| Admin-Override | `user_feature_restrictions` | `club_feature_overrides` | +| Promo/Trial | `access_grants` | `club_access_grants` | +| 4-Phasen-Rollout | ✅ | ✅ | +| Registry-first neue IDs | ⚠️ teils hardcoded | ✅ `rights_registrations/` | + +--- + +## 8. Entscheidungsregeln für neue Produkte + +### 8.1 Pflicht (alle Apps mit Auth) + +- [ ] Session → `profile_id`; kein Client-Header als Autorität +- [ ] Entitlements-Auflösung **eine Funktion pro Ebene** (Capability, Feature) +- [ ] API-Enforcement vor UI-Gate +- [ ] 4-Phasen-Rollout dokumentiert +- [ ] Produkt-Profil (P1–P4) gewählt + Abweichungen in §6.2 + +### 8.2 Wenn Personal App (P1) + +- [ ] Primäres Subjekt = Account +- [ ] `tenant`-Block in API = `null` (DEV-01-Analog) +- [ ] Feature-Registry + Tier-Matrix + +### 8.3 Wenn Mandanten-App (P2) + +- [ ] Primäres Subjekt = Tenant +- [ ] `TenantContext` + Governance getrennt von Capabilities +- [ ] Capabilities registry-first +- [ ] Account nur Lifecycle (verified, member) — kein Tier nötig (DEV-05-Analog erlaubt) + +### 8.4 Wenn Minimal App (P3) + +- [ ] Explizit: „keine Limits“ oder nur Boolean-Features — in §6.2 eintragen +- [ ] Kein halbes Mitai-v9c kopieren + +--- + +## 9. Konvergenz-Roadmap (optional, nicht blockierend) + +| Schritt | Mitai | Shinkan | Familie | +|---------|-------|---------|---------| +| **Kurz** | Legacy Session-Flags entfernen | `CAPABILITY_ENFORCE` / `CLUB_FEATURE_ENFORCE` Prod | DEV-04, DEV-08 schließen | +| **Mittel** | `/me/entitlements` Account-Block | Snapshot um `tenant`-Typ metadata erweitern | Facade alte APIs | +| **Lang** | Optional `tenant_id` reservieren (null) | Optional Account-Tier für Cross-Sell | Shared package `jinkendo_entitlements` | +| **Vision** | SSO + zentraler Billing | Vereins-Abo Stripe | `CENTRAL_SUBSCRIPTION_SYSTEM` | + +**Wichtig:** Konvergenz ist **empfohlen**, nicht Pflicht — solange §6.2 aktuell bleibt. + +--- + +## 10. Anti-Patterns (familienweit verboten) + +1. Tier- oder Plan-Namen in React-Komponenten hardcoden +2. Limit-Logik nur im Frontend +3. Shinkan-Vereinslimits über Mitai `check_feature_access(profile_id)` +4. Capability-Check durch Governance ersetzen (oder umgekehrt) +5. Neue Feature-IDs nur in SQL-Migration ohne Registry +6. Enforcement Phase 4 „vergessen“ bei paid Features ohne dokumentierte Probe-Phase +7. Undokumentierte Produkt-Abweichung (nicht in §6.2) + +--- + +## 11. Offene Familien-Entscheidungen (Backlog) + +| ID | Frage | Optionen | Default wenn unentschieden | +|----|-------|----------|----------------------------| +| **FD-01** | Atomares check+increment | DB-Lock / Transaction / Queue | Status quo + Retry-Hinweis in Doku | +| **FD-02** | Shared Python-Modul | Monorepo-Paket vs. Copy+Sync | Copy+Sync mit gleicher API-Shape | +| **FD-03** | Capability-Namespace global | `jinkendo.*` vs. app-prefix | `{app}.{domain}.{action}` | +| **FD-04** | Mitai bekommt Capability-Layer? | ja/nein/später | nein (DEV-02) bis Bedarf | +| **FD-05** | Ein `features.app` für alle Apps | gemeinsame DB vs. pro Deploy | pro Deploy (heute) | + +--- + +## 12. Verwandte Dokumente + +| Dokument | Inhalt | +|----------|--------| +| [DESIGN_PRINCIPLES_ALIGNMENT.md](./DESIGN_PRINCIPLES_ALIGNMENT.md) | Vollständiger Mitai ↔ Shinkan Abgleich | +| [design-principles/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md](./design-principles/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md) | Shinkan Ist-Prinzipien | +| [ACCESS_LAYER_DESIGN_PRINCIPLES.md](./design-principles/ACCESS_LAYER_DESIGN_PRINCIPLES.md) | Governance (Ebene D) | +| Mitai Foundation #3 | Feature & Entitlement Ist Mitai | +| Shinkan `CLUB_MEMBERSHIP_AND_FEATURES.v1.md` | Vereins-Abo Detail | +| Shinkan `CAPABILITY_CATALOG.v1.md` | Capability-IDs | + +--- + +## 13. Changelog + +| Datum | Änderung | +|-------|----------| +| 2026-07-04 | Entwurf: Familien-Standard, Produkt-Profile P1–P4, Abweichungs-Katalog DEV-01–11 | diff --git a/docs/jinkendo-family/README.md b/docs/jinkendo-family/README.md new file mode 100644 index 0000000..564790c --- /dev/null +++ b/docs/jinkendo-family/README.md @@ -0,0 +1,48 @@ +# Jinkendo Produktfamilie – Dokumentation + +**Zweck:** Querschnitts-Dokumentation, die **über einzelne Apps hinaus** gilt (Mitai, Shinkan, künftige Schwester-Produkte). + +**Stand:** 2026-07-04 + +--- + +## Inhalt + +| Verzeichnis | Zweck | +|-------------|--------| +| [design-principles/](./design-principles/) | Extrahierte **Designprinzipien** pro Modul — Foundation für neue Apps und Familien-Review | + +--- + +## Designprinzipien + +**Einstieg Shinkan:** [design-principles/DESIGN_PRINCIPLES_INDEX.md](./design-principles/DESIGN_PRINCIPLES_INDEX.md) + +**Einstieg Mitai (Foundation):** [mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/README.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/README.md) + +**Abgleich & Entscheidungen:** [DESIGN_PRINCIPLES_ALIGNMENT.md](./DESIGN_PRINCIPLES_ALIGNMENT.md) — Widersprüche, Abweichungen, Familien-Entscheidungs-Matrix + +Die Serie dokumentiert: + +- **Mitai** (9 Module) — Referenzimplementierung unter `mitai-jinkendo/.claude/docs/jinkendo-foundation/` +- **Shinkan** (15 Module) — in [design-principles/](./design-principles/) + +Geplanter nächster Schritt: **FD-***-Entscheidungen im [FAMILY_ENTITLEMENT_MODEL.md](./FAMILY_ENTITLEMENT_MODEL.md) durcharbeiten; Enforcement Phase 4 wo vorgesehen. + +| Dokument | Inhalt | +|----------|--------| +| [DESIGN_PRINCIPLES_ALIGNMENT.md](./DESIGN_PRINCIPLES_ALIGNMENT.md) | Mitai ↔ Shinkan Abgleich | +| [FAMILY_ENTITLEMENT_MODEL.md](./FAMILY_ENTITLEMENT_MODEL.md) | **Familien-Standard** Entitlements + Produkt-Abweichungen | + +--- + +## Bezug zu App-spezifischer Doku + +| Ebene | Ort (Beispiel Shinkan) | +|-------|-------------------------| +| **Familie** (Prinzipien) | `docs/jinkendo-family/` | +| **App-Architektur** | `docs/architecture/` | +| **Technische Specs** | `.claude/docs/technical/` | +| **Agent-Regeln** | `.claude/rules/`, `CLAUDE.md` | + +Implementierungsdetails und Domänen-Specs bleiben in den jeweiligen App-Repositories; Designprinzipien beschreiben **übertragbare Muster** und **bewusste Lücken**. diff --git a/docs/jinkendo-family/design-principles/ACCESS_LAYER_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/ACCESS_LAYER_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..17161a7 --- /dev/null +++ b/docs/jinkendo-family/design-principles/ACCESS_LAYER_DESIGN_PRINCIPLES.md @@ -0,0 +1,170 @@ +# Access Layer & Tenant – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Access Layer & Tenant Governance“ — keine Shinkan-Gesamtarchitektur, keine Kampfsport-Domänenlogik + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 1 von 15 +**Mitai-Vergleich:** kein direktes Gegenstück (Mitai ist profil-zentriert, kein Vereins-Mandant) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| TenantContext | `backend/tenant_context.py` | +| Governance-Helfer | `backend/club_tenancy.py` | +| Listenfilter SQL | `library_content_visibility_sql()` in `tenant_context.py` | +| Endpoint-Audit | `.claude/docs/working/ACCESS_LAYER_ENDPOINT_AUDIT.md` | +| Cursor-Regel | `.cursor/rules/access-layer.mdc` | +| Heuristik-Check | `backend/scripts/check_access_layer_hints.py` | +| Normative Spec | `.claude/docs/technical/ACCESS_LAYER_AND_GOVERNANCE_PLAN.md` | + +--- + +## Modul + +**Access Layer & Tenant Governance** + +Zentraler Querschnitt für Mandanten-Kontext (`club_id`), Sichtbarkeit (`private`/`club`/`official`) und einheitliche Les-/Schreibregeln für Bibliotheksartefakte (Übungen, Medien, Rahmenprogramme, Vorlagen, Progressionsgraphen). + +--- + +## Fachliche Verantwortung + +1. **TenantContext pro HTTP-Request** — Auflösung aus Session + Header `X-Active-Club-Id` + Profilfeld `active_club_id`. +2. **Datenisolierung** — `club_id` als Grenze für vereinsgeteilte Inhalte; Cross-Verein ausgeschlossen. +3. **Einheitliche Sichtbarkeits-Semantik** — gleiche Enums und Prüflogik über alle Bibliotheksmodule. +4. **Governance-Transitionen** — Regeln beim Wechsel `private` → `club` → `official` und beim Löschen. +5. **Listenfilter** — SQL-Baustein statt „SELECT *“ in jedem Router. + +### Administrierte Konfigurationen + +| Konfiguration | Speicherort | Inhalt | +|---------------|-------------|--------| +| Aktiver Verein | `profiles.active_club_id` | Persistierter UI-Kontext | +| Request-Override | Header `X-Active-Club-Id` | Client-seitiger Mandantenwechsel | +| Sichtbarkeit | Spalte `visibility` je Objekt | `private`, `club`, `official` | +| Vereinszuordnung | Spalte `club_id` | Pflicht bei `club`-Inhalten | + +### Bewusst nicht hardcodiert + +- Welche Objekte welchen Verein haben (Daten) +- Individuelle Freigabeentscheidungen (Workflow) + +### Hardcodiert (Code) + +- Enum-Werte und Leseregeln in `club_tenancy.py` / `library_content_visibility_sql` +- Plattform-Admin-Ausnahmen (`is_platform_admin`, `is_superadmin`) +- Rollencodes für Schreib-/Löschregeln (`club_admin`, `trainer`, …) + +--- + +## Designprinzipien + +### 1. Ein Mandant pro Request (`TenantContext`) + +| | | +|---|---| +| **Prinzip** | `Depends(get_tenant_context)` liefert `profile_id`, `global_role`, `effective_club_id`, Mitgliedschaften — einmal pro Request. | +| **Begründung** | Kein verteiltes „Rates“ aus Headers; konsistente Filter in allen Routern. | +| **Quelle** | `tenant_context.py`; `ACCESS_LAYER_AND_GOVERNANCE_PLAN.md` §2 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Nicht alle Endpoints migriert; Audit-Tabelle zeigt Restbestand mit nur `require_auth`. | + +### 2. `club_id` als Datenisolierungsgrenze + +| | | +|---|---| +| **Prinzip** | Vereinsgeteilte Inhalte sind nur für aktive Mitglieder des Objekt-`club_id` lesbar — nie Cross-Verein. | +| **Begründung** | Mandantenfähigkeit für Vereinsplattform; Compliance bei geteilten Trainingsinhalten. | +| **Quelle** | `library_content_visibility_sql()`; Tests `test_access_layer*.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | `division`-Verschärfung noch nicht durchgängig; reserviert im Plan. | + +### 3. Einheitliche Visibility-Semantik + +| | | +|---|---| +| **Prinzip** | `private` \| `club` \| `official` mit gleicher Bedeutung für Übungen, Medien, Rahmen, Module, Graphen. | +| **Begründung** | Nutzer und Trainer verstehen ein Freigabemodell; UI-Feld „Freigabelevel“ durchgängig. | +| **Quelle** | `club_tenancy.py`; `FACHLICHE_NUTZERFUNKTIONEN.md` §4.7 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | `community`-Stufe nur dokumentiert, nicht implementiert. | + +### 4. Zentraler SQL-Filter für Bibliothekslisten + +| | | +|---|---| +| **Prinzip** | Listen nutzen `library_content_visibility_sql(alias, profile_id, role, effective_club_id)` — nicht handgeschriebene WHERE-Kopien. | +| **Begründung** | Drift-Vermeidung; ein Fix gilt für alle Kataloge. | +| **Quelle** | `tenant_context.py`; Router `exercises.py`, `training_framework_programs.py`, … | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Einzelne Legacy-Queries können noch abweichen. | + +### 5. Governance-Transitionen explizit prüfen + +| | | +|---|---| +| **Prinzip** | Wechsel von `visibility`/`club_id` über `assert_library_content_governance_transition` + `assert_valid_governance_visibility`. | +| **Begründung** | „Privat → Verein teilen“ und „official herabstufen“ sind sicherheitsrelevante Aktionen. | +| **Quelle** | `club_tenancy.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Nicht jedes Modul ruft Transition-Helper bei PATCH auf. | + +### 6. Löschregeln nach Visibility-Stufe + +| | | +|---|---| +| **Prinzip** | `assert_library_content_deletable`: privat → Ersteller/Vereinsadmin-Kontext; club → Vereinsadmin; official → Plattform-Admin. | +| **Begründung** | Schutz vor versehentlichem Löschen fremder oder offizieller Inhalte. | +| **Quelle** | `club_tenancy.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Medien-Lifecycle hat zusätzliche Stufen (Papierkorb) — Schnittmenge beachten. | + +### 7. Aktiver Verein: Header + Profil synchron + +| | | +|---|---| +| **Prinzip** | Frontend sendet `X-Active-Club-Id`; Backend validiert gegen Mitgliedschaft; Profil speichert `active_club_id`. | +| **Begründung** | Einheitlicher Mandanten-Kontext über API und UI. | +| **Quelle** | `frontend/src/api/client.js` (`mergeActiveClubHeader`); `profiles` Router | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Onboarding-Nutzer ohne Verein: eingeschränkter Nav-Modus. | + +### 8. Plattform-Admin als Audit-Pfad, nicht als Bypass + +| | | +|---|---| +| **Prinzip** | Plattform-Admins sehen fremde `club`-Inhalte nur mit expliziter Regel (Mitgliedschaft oder Audit-Ausnahme in SQL). | +| **Begründung** | Superuser-Zugriff ohne Mandanten-Leak in normalen Trainer-Flows. | +| **Quelle** | `library_content_visibility_sql` — `club_ok_plat`-Zweig | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Feinheiten zwischen `admin` und `superadmin` (z. B. `official`, Legal Hold) separat geregelt. | + +### 9. Endpoint-Audit als lebendes Inventar + +| | | +|---|---| +| **Prinzip** | Jeder sicherheitsrelevante Endpoint-Eintrag in `ACCESS_LAYER_ENDPOINT_AUDIT.md`; PR-Checkliste verlangt Update. | +| **Begründung** | Sichtbarkeit des Migrationsstands; kein stilles Ausweichen auf `require_auth` allein. | +| **Quelle** | `.claude/docs/working/ACCESS_LAYER_ENDPOINT_AUDIT.md`; `check_access_layer_hints.py` | +| **Tragfähigkeit** | **hoch** (prozessual) | +| **Einschränkung** | CI-Strict-Modus optional, nicht überall aktiv. | + +--- + +## Nicht übernehmen + +1. **Endpoints nur mit `require_auth`** bei tenant-sensitiven Daten — führt zu IDOR und fehlenden Listenfiltern. +2. **Visibility-Logik pro Router duplizieren** — historische Drift zwischen Übungen und Planung. +3. **`division` vor stabiler Vereins-Isolation** — Reihenfolge im Plan: erst Stufe C, dann D. +4. **Community-Freigabe ohne additive Felder** — würde `club`-Isolation brechen. +5. **Client-seitige Mandantenfilter ohne Server-Enforcement** — UI-Hiding reicht nicht. + +--- + +## Verwandte Dokumentation + +- [ACCESS_LAYER_AND_GOVERNANCE_PLAN.md](../../../.claude/docs/technical/ACCESS_LAYER_AND_GOVERNANCE_PLAN.md) +- [MULTI_TENANCY_RBAC_ARCHITECTURE.md](../../../.claude/docs/technical/MULTI_TENANCY_RBAC_ARCHITECTURE.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/AI_PROMPT_RUNTIME_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/AI_PROMPT_RUNTIME_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..3a05cbd --- /dev/null +++ b/docs/jinkendo-family/design-principles/AI_PROMPT_RUNTIME_DESIGN_PRINCIPLES.md @@ -0,0 +1,140 @@ +# AI Prompt Runtime – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „AI Prompt Runtime“ — Shinkan-KI-Schicht, keine Planungs-Gesamtarchitektur + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 5 von 15 +**Mitai-Vergleich:** [PROMPT_ENGINE_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/PROMPT_ENGINE_DESIGN_PRINCIPLES.md) (#1) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| Laufzeit | `backend/ai_prompt_runtime.py`, `backend/prompt_resolver.py` | +| Domänen-Orchestrierung | `backend/exercise_ai.py`, `backend/planning_exercise_*.py` | +| OpenRouter | `backend/openrouter_chat.py` | +| Admin | `backend/routers/ai_prompts_admin.py` | +| Zielbild | `.claude/docs/technical/AI_PROMPT_TARGET_ARCHITECTURE.md` | +| Job-Kontext | `backend/ai_prompt_job.py`, `backend/ai_prompt_context.py` | + +--- + +## Modul + +**AI Prompt Runtime** + +Schmale Ausführungsschicht für admin-konfigurierbare Prompts in `ai_prompts`: Laden, Mustache-Rendering, Kontext-Arten, OpenRouter-Aufruf. **Kein** vollständiges Unified Prompt System wie Mitai (keine Workflows/Pipelines in Produktion). + +--- + +## Fachliche Verantwortung + +1. **Prompt-Laden aus DB** — `load_ai_prompt_row`, `load_and_render_ai_prompt` +2. **Platzhalter-Ersetzung** — Mustache `{{key}}` via `prompt_resolver.py` +3. **Kontext-Arten** — `AiPromptContextKind` trennt Übungs-KI vs. Planungs-KI +4. **Domänen-Builder** — `exercise_ai`, Planungs-Pipelines bauen Variablen-Maps +5. **Admin CRUD + Preview** — ohne LLM in Preview-Pfaden wo vorgesehen + +--- + +## Designprinzipien + +### 1. Eine Laufzeit-Fassade für DB-Prompts + +| | | +|---|---| +| **Prinzip** | Produktive Aufrufe laden Slugs über `ai_prompt_runtime` — nicht Roh-SQL auf `ai_prompts` in Routern. | +| **Begründung** | Einheitliches inactive-Handling, Modell-Feld, Render-Metadaten. | +| **Quelle** | `AI_PROMPT_TARGET_ARCHITECTURE.md` §2.1; `ai_prompt_runtime.py` | +| **Tragfähigkeit** | **hoch** (Zielrichtung) | +| **Einschränkung** | Planungs-KI hat noch verteilte Orchestratoren; kein einzelner `execute_prompt` wie Mitai. | + +### 2. Konfigurierbare Bibliothek in `ai_prompts` + +| | | +|---|---| +| **Prinzip** | Template-Texte in DB; Admins ändern ohne Deploy (`ai_prompts_admin`). | +| **Begründung** | Gleiches Familien-Muster wie Mitai Prompt-Bibliothek. | +| **Quelle** | Migration 069+; Admin-UI | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Keine Pipeline/Workflow-Typen; Slugs hardcoded in `context_kind_for_slug`. | + +### 3. Kontext-Namespaces statt globaler Platzhalter-Soup + +| | | +|---|---| +| **Prinzip** | `AiPromptContextKind` (z. B. `exercise_form_ai`, `planning_exercise_search`) begrenzt erlaubte Builder. | +| **Begründung** | Planungs-Kontext wächst ohne Kollision mit Übungs-Keys. | +| **Quelle** | `AI_PROMPT_TARGET_ARCHITECTURE.md` §2.3 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Noch keine zentrale Platzhalter-Registry wie Mitai — Mustache ad hoc pro Builder. | + +### 4. Trennung Template vs. Domänen-Kontext + +| | | +|---|---| +| **Prinzip** | UI/Router liefern Pydantic-DTOs → Builder erzeugen `variables`-Map → `render_mustache_template`. | +| **Begründung** | Prompt-Autoren ändern Text, nicht Python in Routern. | +| **Quelle** | `prompt_resolver.py`; `ExerciseFormAiPromptContext` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Große Planungs-Kontexte noch nicht vollständig über DTOs. | + +### 5. Transport (OpenRouter) getrennt von Semantik + +| | | +|---|---| +| **Prinzip** | `openrouter_chat.py` für HTTP; Validierung/JSON-Parsing in Domänen-Schicht. | +| **Begründung** | Modellwechsel ohne Router-Anpassung. | +| **Quelle** | `AI_PROMPT_TARGET_ARCHITECTURE.md` §2.2 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Modell teils global Env, teils Spalte `openrouter_model` — Konvergenz offen. | + +### 6. Reset-to-default für System-Prompts + +| | | +|---|---| +| **Prinzip** | `default_template` + Admin-Reset — kein vollständiges Versionsmodell. | +| **Begründung** | Familien-Muster aus Mitai; Schutz vor Fehlkonfiguration. | +| **Quelle** | Migration 069 | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Keine Historie benutzerdefinierter Änderungen. | + +### 7. Admin-only Schreiben, authentifiziertes Ausführen + +| | | +|---|---| +| **Prinzip** | Prompt-CRUD nur Admin; Ausführung mit Capability + Feature-Kontingent. | +| **Begründung** | Systemkonfiguration vs. Nutzung; Kostenkontrolle. | +| **Quelle** | `ai_prompts_admin.py`; `exercises.ai.suggest` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Enforcement teils noch Probe-Phase. | + +### 8. Skill-Retrieval orthogonal zu Prompts + +| | | +|---|---| +| **Prinzip** | `ai_skill_retrieval_profiles` steuert Katalog für `{{skills_catalog}}` — unabhängig vom Prompt-Text. | +| **Begründung** | Anweisung vs. Kontextfenster trennbar konfigurierbar. | +| **Quelle** | `AI_PROMPT_TARGET_ARCHITECTURE.md` §3.3 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +--- + +## Nicht übernehmen (Shinkan-Ist / Mitai-Vermeidung) + +1. **Direkte OpenRouter-Calls in Routern** ohne Laufzeit-Schicht — historische Schuld, abbauen. +2. **Hardcodierte Prompt-Strings in Produktion** — nur Fallback/Dev. +3. **Mitai-Workflow-Graph vorreifen** — Shinkan braucht erst Planungs-Kontext-Reife. +4. **Globale Platzhalter-Map ohne Namespace** — Mitai-Lektion `PLACEHOLDER_MAP`-Duplikat. +5. **Fehlende JSON-Schema-Validierung** bei `output_format=json` — Mitai-TODO übernehmen vermeiden. + +--- + +## Verwandte Dokumentation + +- [AI_PROMPT_TARGET_ARCHITECTURE.md](../../../.claude/docs/technical/AI_PROMPT_TARGET_ARCHITECTURE.md) +- [AI_PROMPT_SYSTEM_SPEC.md](../../../.claude/docs/technical/AI_PROMPT_SYSTEM_SPEC.md) +- [PLANNING_PROGRESSION_GRAPH_KI.md](../../architecture/PLANNING_PROGRESSION_GRAPH_KI.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/AUTH_SESSION_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/AUTH_SESSION_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..ca3b3ad --- /dev/null +++ b/docs/jinkendo-family/design-principles/AUTH_SESSION_DESIGN_PRINCIPLES.md @@ -0,0 +1,114 @@ +# Auth & Session – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Auth & Session“ — gemeinsame Mitai-Basis in Shinkan + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 4 von 15 +**Mitai-Vergleich:** [AUTH_SESSION_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/AUTH_SESSION_DESIGN_PRINCIPLES.md) (#5) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| Auth-Kern | `backend/auth.py` | +| Router | `backend/routers/auth.py`, `profiles.py` | +| Frontend | `frontend/src/context/AuthContext.jsx`, `frontend/src/api/client.js` | +| Account-Lifecycle | `backend/account_lifecycle.py` | + +--- + +## Modul + +**Auth & Session** + +Token-basierte Server-Sessions (`sessions`-Tabelle), bcrypt-Passwörter, FastAPI-Dependencies `require_auth` / `require_admin`. Geteilter Code mit Mitai (App-Familie). + +--- + +## Fachliche Verantwortung + +1. **Login/Logout/Session-Lebensdauer** +2. **Passwort-Hashing** (bcrypt, Legacy-SHA256-Upgrade) +3. **Auth-Dependencies** für Router +4. **Account-States** (Verifizierung, Onboarding-Gates) + +--- + +## Designprinzipien + +### 1. Server-Side Sessions mit Token + +| | | +|---|---| +| **Prinzip** | `X-Auth-Token` Header → Lookup in `sessions` mit Ablaufzeit. | +| **Begründung** | Widerrufbar; kein JWT-Drift zwischen Apps. | +| **Quelle** | `auth.py` `get_session`, `require_auth` | +| **Tragfähigkeit** | **hoch** (Familien-Standard) | +| **Einschränkung** | Kein Refresh-Token-Rotation-Modell. | + +### 2. `require_auth` als separater Depends-Parameter + +| | | +|---|---| +| **Prinzip** | `session: dict = Depends(require_auth)` — nie in Header-Default eingebettet. | +| **Begründung** | Bekannter FastAPI-Footgun führt zu ungeschützten Endpoints. | +| **Quelle** | `CLAUDE.md` Kritische Regeln | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Code-Review/Lint erzwingt das nicht automatisch. | + +### 3. Profile-ID immer aus Session + +| | | +|---|---| +| **Prinzip** | `profile_id` aus `session['profile_id']`, nie aus Client-Header als Autorität. | +| **Begründung** | IDOR-Vermeidung. | +| **Quelle** | Architektur-Regeln; Shinkan ergänzt `TenantContext.profile_id` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Mitai-Dokument nennt Profile-Header-Schwäche — in Shinkan prüfen ob analog. | + +### 4. bcrypt für alle Passwort-Operationen + +| | | +|---|---| +| **Prinzip** | `hash_pin` / `verify_pin` mit bcrypt; SHA256 nur Legacy-Verify + Upgrade. | +| **Begründung** | Familien-konsistente Kryptografie. | +| **Quelle** | `auth.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 5. Portal-Rollen vs. Vereinsrollen trennen + +| | | +|---|---| +| **Prinzip** | `profiles.role` (admin/superadmin/user) ≠ `club_member_roles` im Verein. | +| **Begründung** | Shinkan-Mandantenmodell; Plattform-Admin ≠ Vereins-Trainer. | +| **Quelle** | `club_tenancy.py`; `TenantContext.global_role` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | UI muss beide Ebenen korrekt anzeigen. | + +### 6. Account-Lifecycle als Capability-Voraussetzung + +| | | +|---|---| +| **Prinzip** | `min_account_state` auf Capabilities (z. B. verifiziertes Mitglied). | +| **Begründung** | Gates vor sensiblen Aktionen ohne Sonderchecks in Routern. | +| **Quelle** | `account_lifecycle.py`; `capabilities.py` | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Nicht alle Flows nutzen Lifecycle einheitlich. | + +--- + +## Nicht übernehmen + +1. **Auth-Parameter in Header-Defaults vermischen** — dokumentierter Anti-Pattern. +2. **Client-gesteuerte `profile_id`** für Autorisierung. +3. **Shinkan-spezifische Mandantenlogik in `auth.py`** — gehört in `tenant_context.py`. + +--- + +## Verwandte Dokumentation + +- [ACCESS_LAYER_DESIGN_PRINCIPLES.md](./ACCESS_LAYER_DESIGN_PRINCIPLES.md) +- Mitai: [AUTH_SESSION_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/AUTH_SESSION_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..0ea9728 --- /dev/null +++ b/docs/jinkendo-family/design-principles/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md @@ -0,0 +1,125 @@ +# 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) diff --git a/docs/jinkendo-family/design-principles/CONTENT_REPORTS_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/CONTENT_REPORTS_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..0441592 --- /dev/null +++ b/docs/jinkendo-family/design-principles/CONTENT_REPORTS_DESIGN_PRINCIPLES.md @@ -0,0 +1,117 @@ +# Content Reports (P-13) – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Content Reports“ — Meldeverfahren, Posteingang, Legal Hold + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 10 von 15 +**Mitai-Vergleich:** — (Compliance-spezifisch) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| API | `backend/routers/content_reports.py` | +| Legal Hold | `backend/media_legal_hold.py` | +| Inbox-Integration | `GET /api/me/inbox/content-reports` | +| Frontend | `InboxPage.jsx` | +| Migration | 052, 053 | + +--- + +## Modul + +**Content Reports & Compliance (P-13)** + +Meldeverfahren für problematische Inhalte (Medien, Übungen), Admin-Posteingang mit Statusworkflow, Priorisierung sensibler Gründe, Anbindung Legal Hold und Medien-Audit. + +--- + +## Designprinzipien + +### 1. Eine Tabelle, ein Workflow — keine separate Admin-Queue + +| | | +|---|---| +| **Prinzip** | `content_reports` + bestehende Inbox-UI für Änderungsanfragen und Meldungen. | +| **Begründung** | Admin-Arbeit an einem Ort; weniger Navigations-Fragmentierung. | +| **Quelle** | `content_reports.py` Docstring | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Zwei Vorgangstypen in einer UI — klare Typ-Kennzeichnung nötig. | + +### 2. Melden optional ohne Auth (eingeschränkt) + +| | | +|---|---| +| **Prinzip** | Anonym/offline Meldung für `official`-Medien erlaubt; sonst Auth empfohlen. | +| **Begründung** | DSA-Anforderungen; öffentliche Plattform-Inhalte meldbar. | +| **Quelle** | Router-Berechtigungen | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Missbrauchsschutz (Rate Limit) prüfen. | + +### 3. Priorität bei sensiblen Gründen + +| | | +|---|---| +| **Prinzip** | `minors`, `illegal_content`, `youth_protection` → HIGH_PRIORITY automatisch. | +| **Begründung** | SLA und Admin-Aufmerksamkeit fachlich korrekt. | +| **Quelle** | `HIGH_PRIORITY_REASONS` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 4. Rollengetrennte Sicht (Plattform vs. Verein) + +| | | +|---|---| +| **Prinzip** | Plattform-Admin: alle; Club-Admin: nur Vereinsmedien-Meldungen. | +| **Begründung** | Mandanten-Grenze auch im Compliance-Kontext. | +| **Quelle** | Router-Listenfilter | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 5. Legal Hold nur Superadmin aus Meldung + +| | | +|---|---| +| **Prinzip** | Mapping `report_reason` → `legal_hold reason_code`; `set_legal_hold` superadmin-geschützt. | +| **Begründung** | Hochrisiko-Aktion; Anschluss P-11. | +| **Quelle** | `_REASON_TO_HOLD_CODE`; `media_legal_hold.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 6. Audit-Spur bei Medien-Meldungen + +| | | +|---|---| +| **Prinzip** | `media_asset_audit_log` Event `content_report_filed` bei media_asset-Bezug. | +| **Begründung** | Lifecycle-Entscheidungen nachvollziehbar. | +| **Quelle** | Migration 053; `write_audit_log_entry` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 7. E-Mail best-effort, kein Hard-Fail + +| | | +|---|---| +| **Prinzip** | Bestätigung an Melder + Admin-Benachrichtigung; SMTP-Fehler blockieren Speichern nicht. | +| **Begründung** | Meldung geht nicht verloren wenn Mail down. | +| **Quelle** | Router-Implementierung | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Admins müssen Posteingang auch ohne Mail prüfen. | + +--- + +## Nicht übernehmen + +1. **Separate Compliance-Queue-App** — Inbox-Reuse ist bewusst. +2. **Legal Hold durch Club-Admin** — Superadmin-only. +3. **Meldungen ohne Statusworkflow/Archiv** — Wiedereröffnen muss möglich sein. +4. **Fehlende Verknüpfung Medien-Lifecycle** — Hold muss Purge blockieren. + +--- + +## Verwandte Dokumentation + +- [MEDIA_ASSETS_DESIGN_PRINCIPLES.md](./MEDIA_ASSETS_DESIGN_PRINCIPLES.md) +- [ACCESS_LAYER_DESIGN_PRINCIPLES.md](./ACCESS_LAYER_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/DASHBOARD_KPI_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/DASHBOARD_KPI_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..cbe47ff --- /dev/null +++ b/docs/jinkendo-family/design-principles/DASHBOARD_KPI_DESIGN_PRINCIPLES.md @@ -0,0 +1,105 @@ +# Dashboard KPIs – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Dashboard KPI Aggregation“ — vereinfacht vs. Mitai Widgets + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 14 von 15 +**Mitai-Vergleich:** [DASHBOARD_WIDGETS_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/DASHBOARD_WIDGETS_DESIGN_PRINCIPLES.md) (#7, vereinfacht) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| API | `backend/routers/dashboard.py` — `GET /api/dashboard/kpis` | +| Frontend | Dashboard/Übersicht-Page | +| Refaktor-Kontext | `docs/architecture/SCHULDEN_UND_REMEDIATION.md` A3, B1 | + +--- + +## Modul + +**Dashboard KPI Aggregation** + +Ein Backend-Roundtrip liefert Übungs-KPIs, YTD-Einheiten, Trainings-Home (nächste Termine, Vermerke, offene Rückschau) — Ersatz für mehrere parallele Client-Listen-Calls. + +--- + +## Designprinzipien + +### 1. Aggregierter Endpoint statt Chatty Client + +| | | +|---|---| +| **Prinzip** | `GET /dashboard/kpis` ruft intern `list_exercises_like_get` + `list_training_units` mit gleichen Filtern wie zuvor im UI. | +| **Begründung** | Weniger Latenz; eine TenantContext-Auflösung; Refaktor Phase 1 Dashboard. | +| **Quelle** | `dashboard.py`; SCHULDEN A3/B1 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Noch keine konfigurierbaren Widgets wie Mitai. | + +### 2. Gleiche Filtersemantik wie Einzel-Endpoints + +| | | +|---|---| +| **Prinzip** | KPI-Zählungen nutzen dieselben Helfer wie `/exercises` und `/training-units` — keine zweite Query-Logik. | +| **Begründung** | Zahlen auf Dashboard = Zahlen in Fachmodulen. | +| **Quelle** | Import aus `exercises`, `training_planning` Routern | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Interne Funktionsaufrufe statt HTTP — Kopplung an Router-Helfer. | + +### 3. TenantContext für Mandanten-KPIs + +| | | +|---|---| +| **Prinzip** | `Depends(get_tenant_context)` — assigned_to_me, created_by_me respektieren Verein/Rolle. | +| **Begründung** | Keine globalen KPIs für Trainer fremder Vereine. | +| **Quelle** | `get_dashboard_kpis` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 4. Festes Dashboard-Layout (kein Widget-Katalog) + +| | | +|---|---| +| **Prinzip** | Shinkan-Übersicht zeigt definierte Kacheln — nicht nutzerkonfigurierbares Layout-JSON. | +| **Begründung** | MVP-Fokus Trainer-Verein; weniger Komplexität als Mitai. | +| **Quelle** | Produktentscheidung vs. Mitai #7 | +| **Tragfähigkeit** | **mittel** (bewusste Vereinfachung) | +| **Einschränkung** | Erweiterung braucht Backend+Frontend-Change, nicht Admin-Config. | + +### 5. Profil nicht redundant laden + +| | | +|---|---| +| **Prinzip** | Dashboard soll Auth-Profil nutzen — kein zweites `/profiles/me` nach Login+Reload (E2E Test 8). | +| **Begründung** | Architekturschuld A3 explizit adressiert. | +| **Quelle** | `tests/dev-smoke-test.spec.js`; Roadmap | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Frontend-Umsetzung muss mitziehen. | + +### 6. Slice-Logik für Trainings-Home im Backend + +| | | +|---|---| +| **Prinzip** | `_slice_training_home_notes` filtert Einheiten mit Vermerken — max. N Stück serverseitig. | +| **Begründung** | Kleiner Payload; klare Semantik. | +| **Quelle** | `dashboard.py` | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Grenzwert hardcoded — ggf. Query-Param später. | + +--- + +## Nicht übernehmen + +1. **Drei parallele fast gleiche `listTrainingUnits`-Calls** im Client — behoben durch KPI-Endpoint. +2. **Mitai Widget-Dual-Registry vorreifen** ohne Produktbedarf — Over-Engineering für Shinkan MVP. +3. **KPI-Berechnung im Frontend** aus Volllisten — skaliert nicht. +4. **Dashboard ohne Tenant-Filter** — Mandanten-Leak. + +--- + +## Verwandte Dokumentation + +- [docs/architecture/SCHULDEN_UND_REMEDIATION.md](../../architecture/SCHULDEN_UND_REMEDIATION.md) +- Mitai: [DASHBOARD_WIDGETS_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/DASHBOARD_WIDGETS_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/DESIGN_PRINCIPLES_INDEX.md b/docs/jinkendo-family/design-principles/DESIGN_PRINCIPLES_INDEX.md new file mode 100644 index 0000000..b9f65fd --- /dev/null +++ b/docs/jinkendo-family/design-principles/DESIGN_PRINCIPLES_INDEX.md @@ -0,0 +1,143 @@ +# Designprinzipien – Index (Jinkendo Produktfamilie) + +**Status:** Arbeitspapier / Übergabe +**Stand:** 2026-07-04 +**Zweck:** Zentraler Einstieg für **tragfähige Designprinzipien** der Jinkendo-Produktfamilie — Shinkan-Serie (15 Module), Abgleich mit Mitai (9 Module), Basis für Schwester-Apps. + +**Nicht enthalten:** App-Gesamtarchitektur, domänenspezifische Fachlogik im Detail, vollständige API-Referenz. + +**Ablage (Shinkan-Serie):** `docs/jinkendo-family/design-principles/*_DESIGN_PRINCIPLES.md` +**Übergeordnet:** [docs/jinkendo-family/README.md](../README.md) +**Mitai-Serie:** [mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/](file:///c:/Dev/mitai-jinkendo/.claude/docs/jinkendo-foundation/design-principles/README.md) +**Abgleich Mitai ↔ Shinkan:** [DESIGN_PRINCIPLES_ALIGNMENT.md](../DESIGN_PRINCIPLES_ALIGNMENT.md) + +--- + +## Wofür diese Serie? + +Shinkan implementiert wiederkehrende **Querschnittsmuster** (Mandanten-Zugriff, Capabilities, Medien-Archiv, Planungsdomäne, KI-Laufzeit, Import, Navigation, Deploy) sowie **domänenspezifische Bausteine** (Übungskatalog, Fähigkeiten-Scoring, Trainingsplanung, Compliance-Meldungen). Die 15 Dokumente destillieren daraus: + +- **Was** übertragbar ist (Prinzip + Begründung + Tragfähigkeit) +- **Was** bewusst nicht kopiert werden soll („Nicht übernehmen“) +- **Wo** im Code nachgeschaut werden kann (Pfade, Specs) +- **Mitai-Abgleich** — welches Schwester-Dokument vergleichbar ist + +Jedes Dokument ist **eigenständig lesbar**; dieser Index ordnet Abhängigkeiten, Lese-Reihenfolge und den geplanten Familien-Review. + +--- + +## Dokumente (15/15) + +| # | Modul | Datei | Kernidee (1 Satz) | Mitai-Vergleich | +|---|-------|-------|-------------------|-----------------| +| 1 | Access Layer & Tenant | [ACCESS_LAYER_DESIGN_PRINCIPLES.md](./ACCESS_LAYER_DESIGN_PRINCIPLES.md) | Ein `TenantContext` pro Request; einheitliche `visibility`/`club_id`-Semantik für Bibliotheksartefakte. | — (Shinkan-spezifisch) | +| 2 | Capability & Club Features | [CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md](./CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md) | Capabilities + Vereins-Kontingente; `GET /me/entitlements`; 4-Phasen-Rollout mit Env-Flags. | #3 Feature & Entitlement | +| 3 | Rights Registry | [RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md](./RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md) | Module registrieren Capabilities/Features bei Startup — kein vollständiger Vorab-Katalog in Migrationen. | #4 Registry / Plugin | +| 4 | Auth & Session | [AUTH_SESSION_DESIGN_PRINCIPLES.md](./AUTH_SESSION_DESIGN_PRINCIPLES.md) | Server-Sessions, `require_auth` als Depends; gemeinsame Mitai-Basis. | #5 Auth & Session | +| 5 | AI Prompt Runtime | [AI_PROMPT_RUNTIME_DESIGN_PRINCIPLES.md](./AI_PROMPT_RUNTIME_DESIGN_PRINCIPLES.md) | Schmale Laufzeit (`ai_prompt_runtime`); DB-Templates + Mustache; Kontext-Arten pro Domäne. | #1 Prompt Engine | +| 6 | Media Assets & Archiv | [MEDIA_ASSETS_DESIGN_PRINCIPLES.md](./MEDIA_ASSETS_DESIGN_PRINCIPLES.md) | Physisches Asset einmal, mehrfach verknüpft; Lifecycle, Legal Hold, Inline-Rich-Text. | — | +| 7 | Exercise Catalog | [EXERCISE_CATALOG_DESIGN_PRINCIPLES.md](./EXERCISE_CATALOG_DESIGN_PRINCIPLES.md) | Übung als Kernobjekt; Varianten, Governance, Progressionsgraph, Kombinationsübungen. | — | +| 8 | Skill Scoring | [SKILL_SCORING_DESIGN_PRINCIPLES.md](./SKILL_SCORING_DESIGN_PRINCIPLES.md) | Regelbasiertes gewichtetes Profil; Peer-Vergleich nur unter gleichem Artefakttyp. | #2 Data Layer (teilweise) | +| 9 | Training Planning | [TRAINING_PLANNING_DESIGN_PRINCIPLES.md](./TRAINING_PLANNING_DESIGN_PRINCIPLES.md) | Einheiten mit Phasen/Streams; Rahmen-Bibliothek + Module; Coach/Durchführung getrennt. | — | +| 10 | Content Reports (P-13) | [CONTENT_REPORTS_DESIGN_PRINCIPLES.md](./CONTENT_REPORTS_DESIGN_PRINCIPLES.md) | Melde-Workflow in Posteingang; Priorität sensibler Gründe; Legal-Hold-Anschluss. | — | +| 11 | Wiki Import | [WIKI_IMPORT_DESIGN_PRINCIPLES.md](./WIKI_IMPORT_DESIGN_PRINCIPLES.md) | SMW-API-Ingest + Mapper; Preview/Dry-Run; Duplikat-Tracking — kein Raw-Wiki in DB. | #6 Universal Import | +| 12 | Navigation / IA | [NAVIGATION_IA_DESIGN_PRINCIPLES.md](./NAVIGATION_IA_DESIGN_PRINCIPLES.md) | `appNav.js` als SSoT; Admin-Hub horizontal; Onboarding-Nav ohne Verein. | #8 Navigation / IA | +| 13 | Migration & Deploy | [MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md](./MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md) | `XXX_*.sql` beim Container-Start; develop/main → Dev/Prod; fail-fast. | #9 Migration & Deploy | +| 14 | Dashboard KPIs | [DASHBOARD_KPI_DESIGN_PRINCIPLES.md](./DASHBOARD_KPI_DESIGN_PRINCIPLES.md) | Aggregierter `/dashboard/kpis`-Roundtrip statt mehrerer Listen-Calls. | #7 Dashboard Widgets (vereinfacht) | +| 15 | Maturity Models | [MATURITY_MODELS_DESIGN_PRINCIPLES.md](./MATURITY_MODELS_DESIGN_PRINCIPLES.md) | Kontextsensitive Matrix-Auflösung; Export/Import-Stack für Admin-Portabilität. | — | + +--- + +## Empfohlene Lesereihenfolge + +### Schnellüberblick (45 Min) + +1. [ACCESS_LAYER_DESIGN_PRINCIPLES.md](./ACCESS_LAYER_DESIGN_PRINCIPLES.md) — Shinkan-Kernunterscheidung zu Mitai +2. [RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md](./RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md) — Meta-Muster für Erweiterbarkeit +3. [MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md](./MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md) — Familien-Basis + +### Vollständige Implementierung (neues Produkt) + +``` +Foundation: (13) Migration & Deploy → (4) Auth → (1) Access Layer → (2) Capabilities → (3) Registry +Domäne: (7) Exercise Catalog → (6) Media → (9) Training Planning → (8) Skill Scoring +Erweiterung: (5) AI Prompt Runtime → (11) Wiki Import → (15) Maturity Models +Compliance: (10) Content Reports +Oberfläche: (12) Navigation → (14) Dashboard KPIs +``` + +### Nur Familien-Review (Mitai ↔ Shinkan) + +| Mitai-Dokument | Shinkan-Gegenstück | Review-Fokus | +|----------------|-------------------|--------------| +| #1 Prompt Engine | #5 AI Prompt Runtime | Executor-Reife, Registry, Workflows | +| #2 Data Layer | #8 Skill Scoring | Berechnungs-SSoT vs. Router-Duplikat | +| #3 Feature & Entitlement | #2 Capability & Club Features | Subjekt: Profil vs. Verein | +| #4 Registry | #3 Rights Registry | Registrierungsmuster | +| #5 Auth | #4 Auth & Session | Gemeinsamer Code, IDOR-Risiken | +| #6 Universal Import | #11 Wiki Import | Ingest ≠ Interpretation | +| #7 Dashboard Widgets | #14 Dashboard KPIs | Konfigurierbarkeit vs. Aggregation | +| #8 Navigation | #12 Navigation | appNav-Pattern | +| #9 Migration & Deploy | #13 Migration & Deploy | Gleiches Startup-Muster | + +--- + +## Querschnittsthemen (über alle Docs) + +| Thema | Primär | Ergänzend | +|-------|--------|-----------| +| Mandanten-Isolation (`club_id`) | #1 Access Layer | #6 Media, #7 Exercise, #9 Planning | +| Sichtbarkeit `private`/`club`/`official` | #1 Access Layer | #6 Media, #7 Exercise | +| Capability-Gating | #2 Entitlement | #3 Registry, #5 AI Runtime | +| Validierung an der Grenze | #3 Registry | #6 Inline-Media, #11 Import-Mapper | +| Single Source of Truth (Berechnung) | #8 Skill Scoring | #5 AI Kontext-Builder | +| Dual Registry (Code + DB) | #3 Rights Registry | #2 Capabilities in DB | +| Bekannte Lücken dokumentieren | alle „Nicht übernehmen“ | Endpoint-Audit, Architekturschuld | + +--- + +## Verwandte normative Docs (Shinkan-spezifisch) + +| Thema | Agent-Guide / Spec | +|-------|-------------------| +| Zugriffsschicht | [ACCESS_LAYER_AND_GOVERNANCE_PLAN.md](../../../.claude/docs/technical/ACCESS_LAYER_AND_GOVERNANCE_PLAN.md), [ACCESS_LAYER_ENDPOINT_AUDIT.md](../../../.claude/docs/working/ACCESS_LAYER_ENDPOINT_AUDIT.md) | +| Capabilities | [CAPABILITY_CATALOG.v1.md](../../../.claude/docs/technical/CAPABILITY_CATALOG.v1.md) | +| Vereins-Features | [CLUB_MEMBERSHIP_AND_FEATURES.v1.md](../../../.claude/docs/technical/CLUB_MEMBERSHIP_AND_FEATURES.v1.md) | +| Medien | [MEDIA_ASSETS_AND_ARCHIVE_SPEC.md](../../../.claude/docs/technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md) | +| KI-Zielbild | [AI_PROMPT_TARGET_ARCHITECTURE.md](../../../.claude/docs/technical/AI_PROMPT_TARGET_ARCHITECTURE.md) | +| Planung Streams | [PARALLEL_TRAINING_STREAMS_SPEC.md](../../../.claude/docs/technical/PARALLEL_TRAINING_STREAMS_SPEC.md) | +| Skill Scoring | [SKILL_SCORING_SPEC.md](../../../.claude/docs/technical/SKILL_SCORING_SPEC.md) | +| Architektur-Schuld | [docs/architecture/SCHULDEN_UND_REMEDIATION.md](../../architecture/SCHULDEN_UND_REMEDIATION.md) | + +--- + +## Übergabe-Checkliste (Familien-Review) + +``` +[ ] Pro Modul: Prinzipien vs. Mitai-Gegenstück abgleichen +[ ] Architekturschuld pro Modul in SCHULDEN_UND_REMEDIATION / „Nicht übernehmen“ verknüpfen +[ ] Gemeinsame Familien-Prinzipien aus Übereinstimmungen ableiten +[ ] Abweichungen bewusst dokumentieren (z. B. Vereins- vs. Profil-Entitlements) +[ ] Shared Code (auth.py, db_init) — eine Quelle oder Fork-Drift? +``` + +--- + +## Pflege + +| Aktion | Wo | +|--------|-----| +| Neues Querschnittsmodul extrahiert | Neues `*_DESIGN_PRINCIPLES.md` + Zeile in Tabelle oben | +| Shinkan-Implementierung ändert Muster | Betroffenes Einzeldokument + ggf. Querschnittstabelle | +| Mitai-Review abgeschlossen | Abschnitt „Familien-Prinzipien“ (separates Doc, Backlog) | + +--- + +## Changelog Index + +| Datum | Änderung | +|-------|----------| +| 2026-07-04 | Verweis auf [FAMILY_ENTITLEMENT_MODEL.md](../FAMILY_ENTITLEMENT_MODEL.md) | +| 2026-07-04 | Verweis auf [DESIGN_PRINCIPLES_ALIGNMENT.md](../DESIGN_PRINCIPLES_ALIGNMENT.md) | +| 2026-07-04 | Shinkan-Serie nach `docs/jinkendo-family/design-principles/` verschoben (Familien-Foundation) | +| 2026-07-04 | Index angelegt; Serie 1–15 aus Shinkan-Ist-Stand extrahiert | diff --git a/docs/jinkendo-family/design-principles/EXERCISE_CATALOG_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/EXERCISE_CATALOG_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..96f2e7d --- /dev/null +++ b/docs/jinkendo-family/design-principles/EXERCISE_CATALOG_DESIGN_PRINCIPLES.md @@ -0,0 +1,128 @@ +# Exercise Catalog – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Exercise Catalog“ — Kernobjekt Übung, Varianten, Graphen, Kombination + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 7 von 15 +**Mitai-Vergleich:** — (domänenspezifisch) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| API | `backend/routers/exercises.py`, `exercise_progression_graphs.py` | +| Rich-Text | `backend/exercise_rich_text.py` | +| KI | `backend/exercise_ai.py` | +| Frontend | `frontend/src/pages/Exercises*.jsx`, Tab-Formular | +| Specs | `EXERCISES_ARCHITECTURE.md`, `EXERCISES_API_SPEC.md`, Kombinations-Spec | + +--- + +## Modul + +**Exercise Catalog** + +Shinkans Kernobjekt: Übungen mit mehrdimensionaler Einordnung (Skills, Fokus, Stile), Varianten, Progressionsgraphen, Kombinationsübungen (`method_archetype`, Stationen), Governance und Medien-Anbindung. + +--- + +## Designprinzipien + +### 1. Übung als zentrales Aggregate Root + +| | | +|---|---| +| **Prinzip** | Varianten, Medien, Skills, Graph-Knoten hängen an `exercises.id` — Owner/Governance auf Eltern-Übung. | +| **Begründung** | Eine Freigabe- und Lösch-Semantik; Varianten ohne eigenen Owner. | +| **Quelle** | `FACHLICHE_NUTZERFUNKTIONEN.md` §4.1, §4.7 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Große Monolith-Router/Seiten — Refaktor-Roadmap. | + +### 2. Tab-Formular statt Scroll-Monolith + +| | | +|---|---| +| **Prinzip** | Register: Stammdaten · Anleitung · Einordnung · Kombination · Varianten · Medien — Varianten/Medien erst nach erstem Save. | +| **Begründung** | UX für komplexe Objekte; klare Abhängigkeiten (IDs für Medien/Varianten). | +| **Quelle** | Nutzerfunktionen §4.1 | +| **Tragfähigkeit** | **hoch** (UI-Muster) | +| **Einschränkung** | Frontend-God-Page-Schuld dokumentiert. | + +### 3. Mehrdimensionale Filter-SSoT + +| | | +|---|---| +| **Prinzip** | Suche/Filter über Skills, Fokus, Stil, Zielgruppe, Status, Freigabelevel — Backend-Query + gespeicherte Präferenzen. | +| **Begründung** | Trainer finden Inhalte in großen Vereins-Katalogen. | +| **Quelle** | `SEARCH_FILTER_SPEC.md`; `exercises.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Performance schwere Listen — Baseline/Roadmap. | + +### 4. Varianten mit Voraussetzungskette + +| | | +|---|---| +| **Prinzip** | `exercise_variants` mit Reihenfolge, optional `prerequisite_variant_id`. | +| **Begründung** | Didaktische Abstufung innerhalb einer Übung. | +| **Quelle** | Migration 030; Planung nutzt Varianten-ID pro Eintrag | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 5. Progressionsgraph als gerichtete Übungs-Beziehungen + +| | | +|---|---| +| **Prinzip** | Knoten = Übungen/Varianten; Kanten = „weiter“-Beziehungen; eigener Router + UI in Übungswelt. | +| **Begründung** | Didaktik und Planungs-KI nutzen denselben Graph. | +| **Quelle** | `exercise_progression_graphs.py`; `PLANNING_PROGRESSION_GRAPH_KI.md` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Graph-Editor-Komplexität; KI-Artefakte separat. | + +### 6. Kombinationsübungen als Sonderform im gleichen Katalog + +| | | +|---|---| +| **Prinzip** | `exercise_type=combination` mit Stationen, `method_archetype`, optionalem `method_profile`. | +| **Begründung** | In Planung wie normale Übung; Coach zeigt Stations-Layer. | +| **Quelle** | Migration 056/057; Kombinations-Spec V2 | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Archetyp-Stufen B/C noch ausbaubar. | + +### 7. Governance integriert (nicht separates CMS) + +| | | +|---|---| +| **Prinzip** | `visibility`, `status` (draft/review/…), Access-Layer-Lösch/Transition-Regeln. | +| **Begründung** | Trainer-Workflow ohne externes Freigabe-Tool. | +| **Quelle** | `club_tenancy.py`; Content Change Requests → Posteingang | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Formales Review-Workflow noch leichtgewichtig. | + +### 8. Rich-Text-Felder mit Inline-Medien + +| | | +|---|---| +| **Prinzip** | Einheitliche Platzhalter/Render für `summary`, `goal`, `execution`, … | +| **Begründung** | Medienreicher Inhalt ohne iframe-Split. | +| **Quelle** | `exercise_rich_text.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +--- + +## Nicht übernehmen + +1. **Varianten mit eigenem Owner/Freigabe** — widerspricht Domänenmodell. +2. **Übungsliste ohne Tenant-Filter** — Access-Layer-Pflicht. +3. **KI-generierte Übungen ohne Governance-Felder** — immer draft/private Default. +4. **Progressionsgraph-Logik im Frontend allein** — Server validiert Kanten. + +--- + +## Verwandte Dokumentation + +- [EXERCISES_ARCHITECTURE.md](../../../.claude/docs/technical/EXERCISES_ARCHITECTURE.md) +- [MEDIA_ASSETS_DESIGN_PRINCIPLES.md](./MEDIA_ASSETS_DESIGN_PRINCIPLES.md) +- [SKILL_SCORING_DESIGN_PRINCIPLES.md](./SKILL_SCORING_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/MATURITY_MODELS_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/MATURITY_MODELS_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..1ea4c1b --- /dev/null +++ b/docs/jinkendo-family/design-principles/MATURITY_MODELS_DESIGN_PRINCIPLES.md @@ -0,0 +1,117 @@ +# Maturity Models – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Maturity Models / Fähigkeitsmatrix“ — kontextsensitive Auflösung + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 15 von 15 +**Mitai-Vergleich:** — (domänenspezifisch) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| API | `backend/routers/maturity_models.py`, `matrix_editor.py`, `matrix_stack_bundle.py` | +| Admin-UI | `/admin/maturity-models` | +| Import | Wiki-Import Typ Modelle; Matrix-Stack Export/Import | +| Spec | `.claude/docs/technical/SKILLS_MATRIX_SPEC.md` | + +--- + +## Modul + +**Maturity Models & Matrix Stack** + +Matrixbasierte Reifegradmodelle mit Stufen und Zelltexten; kontextsensitive Auflösung über Bindings (Fokusbereich, Stilrichtung, Zielgruppe); Admin-Export/Import einzelner Modelle und Komplett-Stack. + +--- + +## Designprinzipien + +### 1. Kontext-Bindings M:N (leer = überall) + +| | | +|---|---| +| **Prinzip** | Modell verknüpft mit Fokus/Stil/Zielgruppe; leere Bindings = global gültig. | +| **Begründung** | Ein Stack deckt mehrere Trainingskontexte ab. | +| **Quelle** | `maturity_models.py` `_attach_context` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Auflösungs-Priorität bei mehreren Treffern dokumentieren. | + +### 2. Resolve-API für Laufzeit-Nutzung + +| | | +|---|---| +| **Prinzip** | Authentifizierte Nutzer listen/auflösen; Admin-only für Roh-ID-GET in Admin-UI. | +| **Begründung** | Trainer sehen passende Matrix; Rohdaten-Edit geschützt. | +| **Quelle** | Router-Docstring; Rollen-Checks | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 3. Matrix-Editor als separates Admin-Tool + +| | | +|---|---| +| **Prinzip** | `matrix_editor` Router für Zellbearbeitung — nicht im Trainer-Flow. | +| **Begründung** | Komplexe UI; Plattform-Redaktionsaufgabe. | +| **Quelle** | Admin-Nav „Fähigkeitsmatrix“ | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Frontend-Komplexität — eigene Schuld-Kategorie. | + +### 4. Stack-Bundle Export/Import + +| | | +|---|---| +| **Prinzip** | `matrix_stack_bundle` — Komplett-Stack zwischen Umgebungen (Dev→Prod, Backup). | +| **Begründung** | Analog Prompt Import/Export — Konfiguration versionierbar außerhalb DB. | +| **Quelle** | Admin-Werkzeuge; Wiki-Import ergänzt | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Kein Diff/Merge wie Mitai Prompt-Import. | + +### 5. Plattform-Admin-Schreibschutz + +| | | +|---|---| +| **Prinzip** | Schreiben nur `admin`/`superadmin`; Lesen breiter für authentifizierte Nutzer (Resolve). | +| **Begründung** | Offizielle Kompetenzrahmen zentral gepflegt. | +| **Quelle** | `_require_admin` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 6. Integration Wiki-Import für Modelle + +| | | +|---|---| +| **Prinzip** | SMW-Kategorie Modelle → Import-Pfad neben Übungen/Skills. | +| **Begründung** | Bestehende Wissensbasis karatetrainer.net nutzen. | +| **Quelle** | `import_wiki.py` `CATEGORY_MODELS` | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Gap-Analyse SMW — nicht alle Wiki-Felder gemappt. | + +### 7. Orthogonal zu Skill Scoring + +| | | +|---|---| +| **Prinzip** | Matrix = beschreibende Stufen; Skill Scoring = gewichtete Übungs-Aggregation — getrennte Module. | +| **Begründung** | Keine Vermischung von Kompetenz-Raster und Trainings-KPI. | +| **Quelle** | Domänen-Trennung in Specs | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | UI kann beides nebenan zeigen — klare Labels nötig. | + +--- + +## Nicht übernehmen + +1. **Matrix-Zellen in Übungs-Score-Formel mischen** — ohne fachliche Spec. +2. **Trainer-Edit globaler offizieller Matrizen** — Admin-only. +3. **Import ohne Stack-Integrität** — Bundle-Validierung beachten. +4. **Resolve ohne Kontext-Parameter** wenn Mehrdeutigkeit — falsche Matrix. + +--- + +## Verwandte Dokumentation + +- [SKILLS_MATRIX_SPEC.md](../../../.claude/docs/technical/SKILLS_MATRIX_SPEC.md) +- [WIKI_IMPORT_DESIGN_PRINCIPLES.md](./WIKI_IMPORT_DESIGN_PRINCIPLES.md) +- [SKILL_SCORING_DESIGN_PRINCIPLES.md](./SKILL_SCORING_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/MEDIA_ASSETS_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/MEDIA_ASSETS_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..7e0f185 --- /dev/null +++ b/docs/jinkendo-family/design-principles/MEDIA_ASSETS_DESIGN_PRINCIPLES.md @@ -0,0 +1,119 @@ +# Media Assets & Archiv – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Media Assets & Archiv“ — physische Medien, Lifecycle, Inline + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 6 von 15 +**Mitai-Vergleich:** — (Mitai hat kein vergleichbares Medien-Archiv) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| API | `backend/routers/media_assets.py`, `platform_media_storage.py` | +| Speicher | `backend/media_storage.py`, `MEDIA_ROOT` | +| Rechte/Audit | `backend/media_rights.py`, `media_legal_hold.py` | +| Inline Rich-Text | `backend/exercise_rich_text.py` | +| Retention-Job | `backend/scripts/media_retention_job.py` | +| Spec | `.claude/docs/technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md` | + +--- + +## Modul + +**Media Assets & Archiv** + +Zentrale Verwaltung physischer Dateien (`media_assets`), Verknüpfung zu Übungen (`exercise_media`), mehrstufiger Lifecycle (Papierkorb, Legal Hold), Inline-Einbettung in Rich-Text. + +--- + +## Designprinzipien + +### 1. Physisches Asset einmal, mehrfach verknüpft + +| | | +|---|---| +| **Prinzip** | Datei in `media_assets`; Übungen referenzieren via `exercise_media.media_asset_id`. | +| **Begründung** | Keine Dubletten auf Platte; Wiederverwendung im Archiv. | +| **Quelle** | `MEDIA_ASSETS_AND_ARCHIVE_SPEC.md` §1 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Legacy-Pfade ohne Asset-ID können noch existieren. | + +### 2. Gleiche Visibility-Semantik wie Übungen + +| | | +|---|---| +| **Prinzip** | `private`/`club`/`official` + `club_id` — Access Layer für Download und Liste. | +| **Begründung** | Ein Freigabemodell für alle Bibliotheksartefakte. | +| **Quelle** | Spec §4; `media_rights.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Promotion Übung→official muss Assets mithheben — UI-Dialog Pflicht. | + +### 3. Lifecycle getrennt von Übungs-Verknüpfung + +| | | +|---|---| +| **Prinzip** | Verknüpfung in Übung lösen ≠ Asset physisch löschen; Papierkorb-Stufen separat. | +| **Begründung** | Trainer dürfen Link entfernen ohne Archiv-Löschrecht. | +| **Quelle** | Spec §5 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Retention-Job muss in Betrieb überwacht werden. | + +### 4. Legal Hold blockiert automatisierten Lifecycle + +| | | +|---|---| +| **Prinzip** | `legal_hold` schützt Asset vor Purge; Anbindung an Content Reports (Superadmin). | +| **Begründung** | Compliance bei Meldungen (P-11/P-13). | +| **Quelle** | `media_legal_hold.py`; `content_reports.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 5. Inline-Medien: kanonisches Markup + Validierung + +| | | +|---|---| +| **Prinzip** | `{{exerciseMedia:id}}` → ``; IDs müssen zur Übung gehören. | +| **Begründung** | Ein Render-Pfad; keine broken References nach Medien-Löschung. | +| **Quelle** | `exercise_rich_text.py`; Spec §11 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Beim Erst-Anlegen der Übung keine Inline-Refs (Chicken-Egg). | + +### 6. Speicher-Abstraktion (local + konfigurierbarer Root) + +| | | +|---|---| +| **Prinzip** | `get_effective_media_root()` + `library/…`-Pfadkonvention; kein hardcodierter `/app/media` in Routern. | +| **Begründung** | NAS/externer Speicher vorbereitet. | +| **Quelle** | `media_storage.py`; `platform_media_storage` | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | S3-Backend noch nicht vollständig. | + +### 7. Audit-Log für sensitive Aktionen + +| | | +|---|---| +| **Prinzip** | `media_asset_audit_log` bei Meldungen, Hold, kritischen Lifecycle-Events. | +| **Begründung** | Nachvollziehbarkeit für Admins und Compliance. | +| **Quelle** | `media_rights.write_audit_log_entry` | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Nicht jede Admin-Aktion geloggt. | + +--- + +## Nicht übernehmen + +1. **Download nur mit Übungs-ID ohne Asset-Governance** — Seitenkanal-Risiko. +2. **Copyright leer bei `official`** — Spec verbietet das fachlich. +3. **Physisches Löschen bei Referenzanzahl > 0** — Spec §5.3. +4. **Embed-URLs durch Lifecycle-Purge** — Embeds haben anderen Lebenszyklus. + +--- + +## Verwandte Dokumentation + +- [MEDIA_ASSETS_AND_ARCHIVE_SPEC.md](../../../.claude/docs/technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md) +- [ACCESS_LAYER_DESIGN_PRINCIPLES.md](./ACCESS_LAYER_DESIGN_PRINCIPLES.md) +- [CONTENT_REPORTS_DESIGN_PRINCIPLES.md](./CONTENT_REPORTS_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..699ff08 --- /dev/null +++ b/docs/jinkendo-family/design-principles/MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md @@ -0,0 +1,117 @@ +# Migration & Deploy – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Migration & Deploy“ — Schema-Evolution, Container-Start + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 13 von 15 +**Mitai-Vergleich:** [MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md) (#9) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| DB-Init | `backend/db_init.py` | +| Migrationen | `backend/migrations/XXX_*.sql` | +| Version | `backend/version.py` (`DB_SCHEMA_VERSION`, `MODULE_VERSIONS`) | +| Docker | `docker-compose.yml`, `docker-compose.dev-env.yml` | +| Deploy | develop → dev.shinkan · main → shinkan (Pi) | + +--- + +## Modul + +**Migration & Deploy** + +Nummerierte SQL-Migrationen beim Container-Start, Tracking in `schema_migrations`, Git-Branch → Umgebung, fail-fast ohne Auto-Rollback. + +--- + +## Designprinzipien + +### 1. Nummerierte Migrationen `XXX_*.sql` + +| | | +|---|---| +| **Prinzip** | Nur nummerierte Dateien in `backend/migrations/`; lexikographische Reihenfolge. | +| **Begründung** | Familien-Standard Mitai/Shinkan; vorhersagbare Anwendung. | +| **Quelle** | `db_init.py`; `CLAUDE.md` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Manuelle Nummern-Kollisionen vermeiden — Team-Disziplin. | + +### 2. Startup vor App — Migrationen blockieren Start bei Fehler + +| | | +|---|---| +| **Prinzip** | `db_init.py` wartet auf Postgres, wendet fehlende Migrationen an, dann FastAPI. | +| **Begründung** | Keine App mit veraltetem Schema. | +| **Quelle** | Container-Entrypoint / startup | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Kein automatisches Rollback — manuelle Recovery. | + +### 3. `schema_migrations` Tracking-Tabelle + +| | | +|---|---| +| **Prinzip** | Jede angewendete Datei wird persistiert; Wiederholung überspringt Bekannte. | +| **Begründung** | Idempotenz über Deploys hinweg. | +| **Quelle** | `ensure_migration_table`, `get_applied_migrations` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Geänderte Migration nach Apply — nicht neu ausführen (neue Nummer). | + +### 4. `DB_SCHEMA_VERSION` als dokumentierter Stand + +| | | +|---|---| +| **Prinzip** | `version.py` führt Schema-Version; MODULE_VERSIONS für Subsysteme. | +| **Begründung** | Support und Handover wissen erwarteten Stand. | +| **Quelle** | `backend/version.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Manuell pflegen bei Migration — Drift möglich. | + +### 5. develop/main → Dev/Prod mit festen Ports + +| | | +|---|---| +| **Prinzip** | Dev 3098/8098 · Prod 3003/8003 — nie ändern ohne explizite Freigabe. | +| **Begründung** | Deploy-Infrastruktur auf Pi/Synology stabil. | +| **Quelle** | `CLAUDE.md` Deployment | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 6. Neue Spalten nur via Migration + +| | | +|---|---| +| **Prinzip** | Kein ad-hoc ALTER in Routern; Coding Rules. | +| **Begründung** | Reproduzierbare Umgebungen. | +| **Quelle** | `.claude/rules/CODING_RULES.md` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 7. IF NOT EXISTS / defensive SQL wo sinnvoll + +| | | +|---|---| +| **Prinzip** | Migrationen tolerant bei Wiederanlauf in Dev — aber Tracking verhindert Doppel-Apply. | +| **Begründung** | Recovery in Entwicklung erleichtern. | +| **Quelle** | Mitai-Migrations-Muster | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Nicht alles idempotent — komplexe Migrationen brauchen Transaktion. | + +--- + +## Nicht übernehmen + +1. **Manuelle psql-Schritte in Prod** ohne nummerierte Migration im Repo. +2. **Schema-Drift nur in schema.sql** ohne Migration — Init vs. Upgrade verwechseln. +3. **Auto-Rollback bei fehlgeschlagener Migration** — fail-fast, manuell fixen. +4. **Port-Änderung ohne Infra-Update** — bricht Fritz!Box/NAS-Routing. + +--- + +## Verwandte Dokumentation + +- [DATABASE_SCHEMA.md](../../../.claude/docs/technical/DATABASE_SCHEMA.md) +- Mitai: [MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/NAVIGATION_IA_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/NAVIGATION_IA_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..3a640c9 --- /dev/null +++ b/docs/jinkendo-family/design-principles/NAVIGATION_IA_DESIGN_PRINCIPLES.md @@ -0,0 +1,107 @@ +# Navigation / IA – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Navigation & Information Architecture“ + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 12 von 15 +**Mitai-Vergleich:** [NAVIGATION_IA_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/NAVIGATION_IA_DESIGN_PRINCIPLES.md) (#8) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| Hauptnav | `frontend/src/config/appNav.js` | +| Admin-Nav | `frontend/src/components/AdminPageNav.jsx` | +| Shells | `RequireAdmin`, App-Layout in `App.jsx` | +| Return-Kontext | `.claude/docs/technical/NAV_RETURN_CONTEXT_SPEC.md` | +| Styles | `frontend/src/app.css` (`.admin-top-nav`, Bottom-Nav) | + +--- + +## Modul + +**Navigation / IA** + +Single Source of Truth für Hauptnavigation (Mobile Bottom + Desktop Sidebar), separater Admin-Hub, Onboarding-Nav ohne Vereinsfeatures, rollen- und kontextabhängige Einblendung (Posteingang, Admin). + +--- + +## Designprinzipien + +### 1. `appNav.js` als SSoT für Hauptnavigation + +| | | +|---|---| +| **Prinzip** | `getMainNavItems(isAdmin, opts)` liefert Route, Label, Icon — eine Liste für Mobile und Desktop. | +| **Begründung** | Gleiches Familien-Muster wie Mitai `appNav`; keine divergierenden Nav-Arrays. | +| **Quelle** | `appNav.js` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Tiefe Unterrouten (Übung bearbeiten) nicht in Top-Nav — Shell/Back. | + +### 2. Admin als separater Hub + +| | | +|---|---| +| **Prinzip** | `/admin/*` mit horizontaler `AdminPageNav` — Plattform-Werkzeuge gebündelt. | +| **Begründung** | Trainer-Nav bleibt schlank; Admin-IA skaliert unabhängig. | +| **Quelle** | `AdminPageNav.jsx` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Admin-Nav hardcoded Array — kein `adminNav.js` SSoT wie Mitai ideal. | + +### 3. Onboarding-Nav reduziert + +| | | +|---|---| +| **Prinzip** | `getOnboardingNavItems()` — nur Verein + Einstellungen ohne Übungen/Planung. | +| **Begründung** | Nutzer ohne Vereinsmitgliedschaft nicht in leere Bereiche führen. | +| **Quelle** | `appNav.js` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 4. Kontextabhängige Items (Posteingang) + +| | | +|---|---| +| **Prinzip** | `showInbox` Flag steuert Posteingang-Eintrag — Berechtigung aus Entitlements/Rolle. | +| **Begründung** | Kein toter Nav-Link für Trainer ohne Inbox-Recht. | +| **Quelle** | `baseItems({ showInbox })` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Logik zur `showInbox`-Setzung in App.jsx pflegen. | + +### 5. Responsive: Bottom-Nav Mobile, Sidebar Desktop + +| | | +|---|---| +| **Prinzip** | Gleiche Items, unterschiedliche Präsentation; CSS-Variablen für Abstände. | +| **Begründung** | PWA-typisches Muster; 80px Bottom-Padding für Nav. | +| **Quelle** | `app.css`; Design-System in `CLAUDE.md` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Breakpoint-Konsistenz mit Mitai (1024px) prüfen beim Familien-Review. | + +### 6. Return-Kontext für tiefe Bearbeitung + +| | | +|---|---| +| **Prinzip** | Spez `NAV_RETURN_CONTEXT_SPEC` — zurück zur Herkunftsliste mit Filter-State. | +| **Begründung** | Übungs-Editor aus Suche/Planung ohne Navigations-Verlust. | +| **Quelle** | Return-Context Spec | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Nicht alle Flows implementiert. | + +--- + +## Nicht übernehmen + +1. **Zwei unterschiedliche Nav-Arrays** für Mobile vs. Desktop. +2. **Admin-Routen in Haupt-Bottom-Nav** mischen (außer ein Admin-Einstieg). +3. **Hardcodierte Nav in jeder Page** — zentral in `appNav.js`. +4. **Fehlender Onboarding-Gate** — volle Nav ohne Verein verwirrt. + +--- + +## Verwandte Dokumentation + +- [NAV_RETURN_CONTEXT_SPEC.md](../../../.claude/docs/technical/NAV_RETURN_CONTEXT_SPEC.md) +- Mitai: [NAVIGATION_IA_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/NAVIGATION_IA_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..4fdf12f --- /dev/null +++ b/docs/jinkendo-family/design-principles/RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md @@ -0,0 +1,114 @@ +# Rights Registry – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Rights Registry“ — Capabilities & Features zur Laufzeit registrieren + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 3 von 15 +**Mitai-Vergleich:** [REGISTRY_PLUGIN_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/REGISTRY_PLUGIN_DESIGN_PRINCIPLES.md) (#4) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| Registry-Kern | `backend/rights_registry.py` | +| Modul-Registrierungen | `backend/rights_registrations/` (`exercises.py`, `planning.py`, `platform.py`, `club_creation.py`) | +| Startup-Sync | Import in `backend/main.py` | +| Tests | `backend/tests/test_rights_registry.py` | + +--- + +## Modul + +**Rights Registry (Registry-first für Capabilities & Features)** + +Module deklarieren bei Implementierung, welche Rechte und Kontingente sie anbieten. Beim App-Start werden Definitionen in die DB synchronisiert (`capabilities`, `features`, Default-Grants). + +--- + +## Fachliche Verantwortung + +1. **Runtime-Registrierung** — `register_capability()`, `register_feature()` vor DB-Sync. +2. **Modul-Ownership** — Jedes Feature/Capability trägt `module`-Feld für Admin-Filter „Rollen & Rechte“. +3. **Default Club Grants** — Rollen → Capability-Mapping bei Erst-Sync. +4. **Kein vollständiger Vorab-Katalog in SQL-Migration** — nur was Module wirklich liefern. + +--- + +## Designprinzipien + +### 1. Registry-first statt Migrations-Monolith + +| | | +|---|---| +| **Prinzip** | Neue Rechte erscheinen durch Code-Registrierung + Startup-Upsert — nicht durch manuelle 079-Katalog-Migration pro Feature. | +| **Begründung** | Modul und Recht entstehen zusammen; weniger vergessene Katalog-Einträge. | +| **Quelle** | `rights_registry.py`; Docstring; `rights_registrations/` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Erste Basismigration seedet noch initiale Zeilen. | + +### 2. Modul-Datei pro Domäne + +| | | +|---|---| +| **Prinzip** | `rights_registrations/exercises.py` registriert nur Übungs-Rechte; Planung/Platform analog. | +| **Begründung** | Ownership klar; Merge-Konflikte lokalisiert. | +| **Quelle** | `rights_registrations/__init__.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Import-Reihenfolge muss in `main.py` garantiert sein. | + +### 3. Frozen Dataclass-Definitionen + +| | | +|---|---| +| **Prinzip** | `CapabilityRegistration` / `FeatureRegistration` als immutable `@dataclass(frozen=True)`. | +| **Begründung** | Keine nachträgliche Mutation nach Registrierung. | +| **Quelle** | `rights_registry.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 4. Validierung an der Registrierungsgrenze + +| | | +|---|---| +| **Prinzip** | `register_*` wirft bei fehlendem `id` oder `module`. | +| **Begründung** | Fehler beim Import/Startup, nicht erst im Admin-UI. | +| **Quelle** | `rights_registry.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Keine Schema-Validierung für `limit_type`/`reset_period` zur Compile-Zeit. | + +### 5. DB als persistierter Katalog, Code als SSoT für neue IDs + +| | | +|---|---| +| **Prinzip** | Startup `sync_rights_registry_to_db()` upsertet aus In-Memory-Registry. | +| **Begründung** | Admin-UI liest DB; Entwickler erweitern Code-Registry. | +| **Quelle** | `rights_registry.py`; `main.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Deaktivierte Capabilities in DB vs. fehlende im Code — Reconcile-Policy dokumentieren. | + +### 6. Default Grants als Code-Daten + +| | | +|---|---| +| **Prinzip** | `default_club_grants: (role_code, capability_id)` pro Capability. | +| **Begründung** | Neue Module bringen sinnvolle Standard-Rollen mit. | +| **Quelle** | `rights_registrations/exercises.py` | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Admin-Overrides in DB können bei Re-Sync überschrieben werden — ON CONFLICT-Verhalten beachten. | + +--- + +## Nicht übernehmen + +1. **Capabilities nur in SQL-Migration pflegen** — driftet vom implementierten Modul weg. +2. **Registrierung ohne Endpoint-Verdrahtung** — Spec: „nur Rechte mit echter Endpoint-Verdrahtung“. +3. **Zweite Registry-Philosophie** für Custom Roles — gleiche Capability-IDs wiederverwenden (Plan Stufe E). + +--- + +## Verwandte Dokumentation + +- [CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md](./CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md) +- [CAPABILITY_CATALOG.v1.md](../../../.claude/docs/technical/CAPABILITY_CATALOG.v1.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/SKILL_SCORING_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/SKILL_SCORING_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..c5fb249 --- /dev/null +++ b/docs/jinkendo-family/design-principles/SKILL_SCORING_DESIGN_PRINCIPLES.md @@ -0,0 +1,107 @@ +# Skill Scoring – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Skill Scoring & Profile“ — gewichtete Fähigkeiten-KPIs + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 8 von 15 +**Mitai-Vergleich:** [DATA_LAYER_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/DATA_LAYER_DESIGN_PRINCIPLES.md) (#2, analog: Berechnungs-SSoT) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| Kern | `backend/skill_scoring.py` | +| Profile-API | `backend/routers/skill_profiles.py` | +| Planungs-Vorschläge | Planung-Router + Fähigkeiten-Seite | +| Spec | `.claude/docs/technical/SKILL_SCORING_SPEC.md` | + +--- + +## Modul + +**Skill Scoring & Profiles** + +Regelbasierte Aggregation von `exercise_skills` über Artefakte (Module, Rahmenprogramme, Pläne, Graphen) zu gewichteten Profilen mit Peer-Vergleich innerhalb desselben Artefakttyps. + +--- + +## Designprinzipien + +### 1. Berechnung in einer Schicht (`skill_scoring.py`) + +| | | +|---|---| +| **Prinzip** | Scores, Gewichte, Peer-Perzentile — nicht in React oder Router-SQL duplizieren. | +| **Begründung** | Analog Mitai Data Layer: Charts, Listen-KPIs, Planungs-Vorschläge nutzen dieselbe Logik. | +| **Quelle** | `SKILL_SCORING_SPEC.md`; `skill_scoring.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Einzelne UI-Fallbacks können noch vereinfacht rechnen. | + +### 2. Gewichtung aus Trainings-Signalen + +| | | +|---|---| +| **Prinzip** | Dauer, Vorkommen, Intensität (`niedrig`/`mittel`/`hoch`), Stufen-Spanne — explizite Multiplikatoren. | +| **Begründung** | Nachvollziehbares Ranking ohne Black-Box-ML. | +| **Quelle** | `_INTENSITY_MULT`, `_level_range_multiplier` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | `is_primary` / `development_contribution` bewusst ignoriert. | + +### 3. Peer-Vergleich nur unter gleichem Artefakttyp + +| | | +|---|---| +| **Prinzip** | Modul vs. Modul, Rahmen vs. Rahmen — nie Modul vs. Plan gemischt. | +| **Begründung** | Fachlich sinnvoller Vergleich; vermeidet irreführende Prozentwerte. | +| **Quelle** | Phase 3 Lieferung; Nutzerfunktionen §4.2 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | UI muss Typ-Kontext klar labeln. | + +### 4. Sichtbarkeits-filterte Peer-Menge + +| | | +|---|---| +| **Prinzip** | Peer-Pool = nur für Nutzer sichtbare Artefakte (Access Layer). | +| **Begründung** | Keine Leaks über Scores fremder Vereins-Inhalte. | +| **Quelle** | `skill_scoring.py` + Tenant-Filter in Aufrufern | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Performance bei großen Pools. | + +### 5. Planungs-Vorschläge aus Profil-Delta + +| | | +|---|---| +| **Prinzip** | Fähigkeiten-Schwerpunkte → sortierte Vorschläge für Module/Rahmen/Regressionspfade. | +| **Begründung** | Schließt Loop zwischen Katalog und Planung. | +| **Quelle** | Fähigkeiten-Seite Phase 3 | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | KI-Suche über Volltext — Backlog. | + +### 6. Default-Minuten für fehlende Dauer + +| | | +|---|---| +| **Prinzip** | `DEFAULT_ITEM_MINUTES` / `GRAPH_DEFAULT_ITEM_MINUTES` als explizite Konstanten. | +| **Begründung** | Deterministische Scores bei unvollständigen Planungsdaten. | +| **Quelle** | `skill_scoring.py` | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Fachlich kalibrierbar — dokumentieren statt verstecken. | + +--- + +## Nicht übernehmen + +1. **Score-Berechnung im Frontend** für Listen-KPIs. +2. **Peer-Vergleich über Artefakttypen hinweg** — irreführend. +3. **ML-Black-Box statt regelbasierter Gewichte** — ohne explizite Produktentscheidung. +4. **Ignorieren der Tenant-Sichtbarkeit** im Peer-Pool. + +--- + +## Verwandte Dokumentation + +- [SKILL_SCORING_SPEC.md](../../../.claude/docs/technical/SKILL_SCORING_SPEC.md) +- [EXERCISE_CATALOG_DESIGN_PRINCIPLES.md](./EXERCISE_CATALOG_DESIGN_PRINCIPLES.md) +- [TRAINING_PLANNING_DESIGN_PRINCIPLES.md](./TRAINING_PLANNING_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/TRAINING_PLANNING_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/TRAINING_PLANNING_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..32b4645 --- /dev/null +++ b/docs/jinkendo-family/design-principles/TRAINING_PLANNING_DESIGN_PRINCIPLES.md @@ -0,0 +1,129 @@ +# Training Planning – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „Training Planning“ — Einheiten, Phasen, Rahmen, Coach + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 9 von 15 +**Mitai-Vergleich:** — (domänenspezifisch) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| Kalender-Einheiten | `backend/routers/training_planning.py` | +| Module | `backend/routers/training_modules.py` | +| Rahmen | `backend/routers/training_framework_programs.py` | +| Phasen/Streams | Migration 063; `PARALLEL_TRAINING_STREAMS_SPEC.md` | +| Frontend | `TrainingPlanningPage`, `TrainingCoachPage`, `TrainingUnitRunPage` | +| Utils | `frontend/src/utils/trainingPlanUtils.js` | + +--- + +## Modul + +**Training Planning & Frameworks** + +Planbare Trainingseinheiten mit Sektionen, **Phasen** (Ganzgruppe/Parallel) und **Streams**, Bibliotheks-**Rahmenprogramme** (Ziele/Slots), **Trainingsmodule**, Materialisierung aus Slots, Durchführungs- und Coaching-Ansichten. + +--- + +## Designprinzipien + +### 1. Einheit als planbares Aggregate + +| | | +|---|---| +| **Prinzip** | `training_units` + `training_unit_sections` + Items; Kopf: Gruppe, Datum, Trainer, Status. | +| **Begründung** | Klare Grenze Kalender vs. Bibliothek. | +| **Quelle** | Domain Model; `training_planning.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Große Router-Datei — Refaktor-Schuld. | + +### 2. Phasen/Streams als explizites Modell (nicht Marker-Sektionen) + +| | | +|---|---| +| **Prinzip** | `training_unit_phases` + `training_unit_parallel_streams`; Sektionen an Phase oder Stream gebunden. | +| **Begründung** | Breakout-Trainings fachlich korrekt; Coach/Rejoin-Logik. | +| **Quelle** | `PARALLEL_TRAINING_STREAMS_SPEC.md` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Legacy-Einheiten → Default-Ganzgruppenphase; Vorlagen-Phasen teils offen. | + +### 3. API: verschachtelte `phases` + flache `sections` + +| | | +|---|---| +| **Prinzip** | GET liefert beides; PUT akzeptiert `phases` atomar; höchstens eines von phases/sections/exercises pro Request. | +| **Begründung** | Frontend normalisiert; Server validiert CHECK-Regeln. | +| **Quelle** | Spec §4; Planning-Router | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Server-Spiegelung neuer Abschnitte in phases — Handover offen. | + +### 4. Rahmen-Bibliothek: Slot = Blueprint-Unit + +| | | +|---|---| +| **Prinzip** | `framework_slot_id` auf Blueprint-`training_units`; Materialisierung → Kalender-Einheit für Gruppe. | +| **Begründung** | Wiederverwendbare Programme ohne Duplikat-Logik pro Slot-Typ. | +| **Quelle** | Migration 035–037 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | UI „Aus Rahmen übernehmen“ nicht flächendeckend. | + +### 5. Trainingsmodule als wiederverwendbare Übungsfolgen + +| | | +|---|---| +| **Prinzip** | Bibliotheks-Objekt mit Skill-Profil; Übernahme in geplante Einheit. | +| **Begründung** | Trainer-Bausteine zwischen Einzelübung und Rahmen. | +| **Quelle** | `training_modules.py`; Skill Scoring Phase 3 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 6. Drei Durchführungsmodi getrennt + +| | | +|---|---| +| **Prinzip** | Planung (edit) · Plan & Ablauf (run) · Coaching (step timeline, Stream-Picks, Nachbereitung). | +| **Begründung** | Unterschiedliche UX und Payloads; Coach speichert → Run-Ansicht. | +| **Quelle** | Nutzerfunktionen §4.4; `TrainingCoachPage` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Stream-Tabs in Run-Ansicht optional offen. | + +### 7. Governance über Gruppe/Verein, keine neuen Mandanten-Entitäten + +| | | +|---|---| +| **Prinzip** | Einheit → `training_group` → Verein; Access Layer für Bibliotheks-Rahmen/Module. | +| **Begründung** | Planung erbt Organisations-Kontext. | +| **Quelle** | `PARALLEL_TRAINING_STREAMS_SPEC.md` §4 | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Stream-Trainer-Zuweisung UI unvollständig. | + +### 8. Kombinationsübungen in Planung transparent + +| | | +|---|---| +| **Prinzip** | Items ohne Variante; Coach zeigt Stations-Kandidaten + Archetyp-Hinweise. | +| **Begründung** | Gleiche Item-Schicht für Standard- und Kombi-Übungen. | +| **Quelle** | Migration 057; Kombinations-Spec Anhang A | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Archetyp-Stufen B/C ausbaubar. | + +--- + +## Nicht übernehmen + +1. **Parallele Phasen als reine UI-Konvention ohne DB-Phasen** — Minimalvariante verworfen. +2. **Rahmen-Slots als separate Exercise-Join-Tabelle** — Legacy `training_framework_slot_exercises` abgelöst. +3. **Planungs-KI direkt in Router-Strings** — AI Prompt Runtime nutzen. +4. **Blueprint-Einheiten in Kalenderlisten** — Filter `framework_slot_id IS NOT NULL`. + +--- + +## Verwandte Dokumentation + +- [PARALLEL_TRAINING_STREAMS_SPEC.md](../../../.claude/docs/technical/PARALLEL_TRAINING_STREAMS_SPEC.md) +- [TRAINING_FRAMEWORK_SPEC.md](../../../.claude/docs/technical/TRAINING_FRAMEWORK_SPEC.md) +- [SKILL_SCORING_DESIGN_PRINCIPLES.md](./SKILL_SCORING_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md) diff --git a/docs/jinkendo-family/design-principles/WIKI_IMPORT_DESIGN_PRINCIPLES.md b/docs/jinkendo-family/design-principles/WIKI_IMPORT_DESIGN_PRINCIPLES.md new file mode 100644 index 0000000..267c6d8 --- /dev/null +++ b/docs/jinkendo-family/design-principles/WIKI_IMPORT_DESIGN_PRINCIPLES.md @@ -0,0 +1,118 @@ +# Wiki Import – Designprinzipien (Extraktion) + +**Status:** Analyse / Arbeitspapier +**Stand:** 2026-07-04 +**Geltungsbereich:** Modul „MediaWiki Import“ — SMW-Ingest, Mapping, Tracking + +**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 11 von 15 +**Mitai-Vergleich:** [UNIVERSAL_IMPORT_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/UNIVERSAL_IMPORT_DESIGN_PRINCIPLES.md) (#6) + +**Kernkomponenten:** + +| Bereich | Pfade | +|---------|-------| +| Router | `backend/routers/import_wiki.py`, `import_wiki_admin.py` | +| Client | `backend/smw_client.py` | +| Mapper | `backend/smw_mapper.py` | +| Tracking | `wiki_import_log`, `wiki_import_references` | +| Spec | `.claude/docs/technical/MEDIAWIKI_IMPORT_SPEC.md` | + +--- + +## Modul + +**Wiki Import (Semantic MediaWiki)** + +Import von Übungen, Fähigkeiten, Methoden und Reifegradmodellen aus externem Wiki via API — Preview, Dry-Run, Duplikat-Erkennung, Admin-only. + +--- + +## Designprinzipien + +### 1. Ingest ≠ Interpretation + +| | | +|---|---| +| **Prinzip** | `SmwClient` holt Rohdaten; `smw_mapper` mappt auf Shinkan-Modelle — getrennte Schichten. | +| **Begründung** | Analog Mitai Import: Transport/Parser ≠ Domänen-Insert. | +| **Quelle** | `import_wiki.py`; Mitai Universal Import | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Keine generische Import-Registry wie Mitai CSV — wiki-spezifisch. | + +### 2. Preview und Dry-Run vor Execute + +| | | +|---|---| +| **Prinzip** | `/preview` zeigt Kandidaten; `dry_run=true` ohne DB-Schreiben. | +| **Begründung** | Admin sieht Auswirkungen; sichere Iteration. | +| **Quelle** | `ImportExecuteRequest` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 3. Duplikat-Tracking über Wiki-Referenzen + +| | | +|---|---| +| **Prinzip** | `wiki_import_references` speichert Wiki-Titel ↔ Shinkan-ID für Re-Import. | +| **Begründung** | Idempotenz und Update statt blindem Duplicate. | +| **Quelle** | Domain Model Import-Tabellen | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Gap-Analyse in `SMW_IMPORTER_GAP_ANALYSIS.md` beachten. | + +### 4. Import-Typ als expliziter Parameter + +| | | +|---|---| +| **Prinzip** | `import_type`: `exercise` \| `skill` \| `method` \| Modelle — eigener Mapper-Pfad. | +| **Begründung** | Klare Verantwortung pro Ziel-Entität. | +| **Quelle** | `map_wiki_to_*` in `smw_mapper.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | Kein Plug-in-Registry-Pattern wie Mitai Module-Registry. | + +### 5. Superadmin/Admin-only Execute + +| | | +|---|---| +| **Prinzip** | `require_admin` auf Execute — Massenimport ist Plattform-Risiko. | +| **Begründung** | Governance und Datenqualität. | +| **Quelle** | `import_wiki.py` | +| **Tragfähigkeit** | **hoch** | +| **Einschränkung** | — | + +### 6. Kategorie aus Env mit Fallback + +| | | +|---|---| +| **Prinzip** | `MEDIAWIKI_CATEGORY_*` Env-Variablen; leere Query → Default je Typ. | +| **Begründung** | Wiki-Struktur konfigurierbar ohne Code-Deploy. | +| **Quelle** | `CATEGORY_EXERCISES` etc. | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Hardcoded Wiki-URL in Doku — Umgebungsspezifisch halten. | + +### 7. Background Tasks für lange Imports + +| | | +|---|---| +| **Prinzip** | FastAPI `BackgroundTasks` für Execute — HTTP nicht blockieren. | +| **Begründung** | Große Kategorien ohne Timeout. | +| **Quelle** | Execute-Endpoint | +| **Tragfähigkeit** | **mittel** | +| **Einschränkung** | Kein Job-Status-Polling-UI wie Mitai — Log-Tabelle nutzen. | + +--- + +## Nicht übernehmen + +1. **Rohe Wiki-HTML ungemappt in DB** — immer Mapper. +2. **Import ohne Log/Re-Import-Referenz** — Duplikat-Chaos. +3. **Trainer-self-service Wiki-Import** — Admin-only. +4. **Skill-Scoring beim Insert** — Scores gehören in `skill_scoring`-Schicht. + +--- + +## Verwandte Dokumentation + +- [MEDIAWIKI_IMPORT_SPEC.md](../../../.claude/docs/technical/MEDIAWIKI_IMPORT_SPEC.md) +- [EXERCISE_CATALOG_DESIGN_PRINCIPLES.md](./EXERCISE_CATALOG_DESIGN_PRINCIPLES.md) +- Mitai: [UNIVERSAL_IMPORT_DESIGN_PRINCIPLES.md](file:///c:/Dev/mitai-jinkendo/.claude/docs/technical/UNIVERSAL_IMPORT_DESIGN_PRINCIPLES.md) +- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md)