diff --git a/docs/sprints/Sprint0_AP0_3_Completion_Report_v0.1.md b/docs/sprints/Sprint0_AP0_3_Completion_Report_v0.1.md deleted file mode 100644 index e872297..0000000 --- a/docs/sprints/Sprint0_AP0_3_Completion_Report_v0.1.md +++ /dev/null @@ -1,213 +0,0 @@ -# AP0.3 – Abschlussbericht Capability / Rights Registry & Entitlements Snapshot - -**Status:** abgeschlossen -**Stand:** 2026-07-04 -**Branch:** `develop` - ---- - -## 1. Umgesetzte Dateien - -| Datei | Zweck | -|-------|--------| -| `backend/migrations/004_capabilities_registry.sql` | Tabellen `capabilities`, `role_capability_grants` | -| `backend/rights_registry.py` | In-Memory-Registry, Validierung, DB-Sync, Grant-Lookup | -| `backend/rights_registrations/__init__.py` | Side-Effect-Import aller Modul-Registrierungen | -| `backend/rights_registrations/platform.py` | Platform-Capabilities | -| `backend/rights_registrations/tenant_ops.py` | Tenant-/Actor-Capabilities | -| `backend/capabilities.py` | Auflösung, `check_capability`, `require_capability` | -| `backend/entitlements.py` | Entitlements-Snapshot-Builder | -| `backend/sync_rights_registry.py` | CLI-Sync beim Container-Start | -| `backend/tenant_context.py` | `TenantContext.capabilities` | -| `backend/routers/me.py` | `/entitlements`, `/admin/demo` | -| `backend/entrypoint.sh` | Rights-Sync nach Seeds | -| `backend/version.py` | `0.3.0-ap0.3`, Schema `004` | -| `backend/tests/test_rights_registry.py` | Registry + Sync | -| `backend/tests/test_capabilities.py` | Grants, enforce/probe, Demo-Endpoint | -| `backend/tests/test_entitlements.py` | Snapshot-Form | -| `backend/tests/conftest.py` | Registry-Sync in Test-Session | -| `README.md` | API-Doku AP0.3 | - ---- - -## 2. Neue Migrationen - -**`004_capabilities_registry.sql`** - -- **`capabilities`** — `capability_key`, `module`, `description`, `is_active` -- **`role_capability_grants`** — `role_scope` (`portal` \| `tenant`), `role_code`, `capability_key` - -Kein Feature-/Limit-Schema in AP0.3 (bewusst AP0.4-Vorbereitung). - ---- - -## 3. Registry-Struktur - -``` -backend/ -├── rights_registry.py # register_capability(), sync_rights_registry_to_db() -├── rights_registrations/ -│ ├── __init__.py # import platform, tenant_ops -│ ├── platform.py # admin, context, entitlements -│ └── tenant_ops.py # tenant.manage, actor.manage -└── sync_rights_registry.py # Startup nach Migrationen/Seeds -``` - -**Registrierungsmodell:** `@dataclass(frozen=True) CapabilityRegistration` mit `key`, `module`, `description`, `default_grants: (role_scope, role_code)`. - -**Startup:** `entrypoint.sh` → `python sync_rights_registry.py` (überspringbar via `SKIP_RIGHTS_SYNC=1`). - ---- - -## 4. Endpoints - -| Endpoint | Methode | Auth / Gate | Neu/Geändert | -|----------|---------|-------------|--------------| -| `/api/me/context` | GET | Session | **Geändert** — enthält `capabilities[]` | -| `/api/me/entitlements` | GET | Session | **Neu** | -| `/api/me/admin/demo` | GET | Session + `kairo.admin.access` | **Neu** (Beispiel `require_capability`) | - -Bestehende Auth-/Me-Endpunkte unverändert in Signatur. - ---- - -## 5. Capability-Auflösungslogik - -``` -Session (portal_role, active_tenant_id) - → tenant_membership → tenant_role (optional) - → load_grants_for_roles(portal_role, tenant_role) - SELECT capability_key FROM role_capability_grants - JOIN capabilities WHERE role_scope/role_code match - → Union Portal-Grants + Tenant-Grants - → TenantContext.capabilities (frozenset) -``` - -**`require_capability(key)`:** prüft `key in ctx.capabilities`. - -| Modus | Env | Verhalten | -|-------|-----|-----------| -| probe | `CAPABILITY_ENFORCE=probe` (Default) | Zugriff erlaubt, Audit `capability.denied` | -| enforce | `CAPABILITY_ENFORCE=enforce` | HTTP 403 bei fehlendem Grant | - ---- - -## 6. Initiale Capabilities & Default-Grants - -| Capability | Portal admin | Portal user | Tenant owner | Tenant admin | Tenant member | -|------------|:------------:|:-----------:|:------------:|:------------:|:-------------:| -| `kairo.admin.access` | ✓ | | | | | -| `kairo.tenant.manage` | ✓ | | ✓ | ✓ | | -| `kairo.actor.manage` | ✓ | | ✓ | ✓ | | -| `kairo.context.read` | ✓ | ✓ | ✓ | ✓ | ✓ | -| `kairo.entitlements.read` | ✓ | ✓ | ✓ | ✓ | ✓ | - ---- - -## 7. Tests und Testergebnis - -```bash -docker compose -f docker-compose.dev-env.yml exec backend pip install -r requirements-dev.txt -docker compose -f docker-compose.dev-env.yml exec backend python -m pytest tests -ra -vv -``` - -| Testdatei | Abdeckung | -|-----------|-----------| -| `test_rights_registry.py` | 5 Capabilities registriert, Sync idempotent, DB-Zeilen | -| `test_capabilities.py` | Admin erlaubt, Member verweigert (enforce), Owner-Grants, probe-Modus | -| `test_entitlements.py` | Snapshot account/tenant/actor/roles/capabilities/enforcement | -| `test_migrations.py` | Migration 004 erkannt | - -*(Lokale Ausführung in dieser Session über CI/Dev-Container nach Push.)* - ---- - -## 8. Übernommene Muster aus Shinkan - -| Muster | Kairo-Umsetzung | -|--------|-----------------| -| Registry-first | `rights_registry.py` + `rights_registrations/` | -| `register_capability()` mit Validierung | Pflichtfelder `key`, `module`, `description` | -| Frozen Dataclass-Definitionen | `CapabilityRegistration` | -| Startup-Sync Registry → DB | `sync_rights_registry_to_db()` | -| Modul-Ownership (`module`-Feld) | `platform`, `tenant` | -| Default Grants in Code | `default_grants` pro Capability | -| `require_capability` Dependency | `capabilities.py` | -| `/api/me/entitlements` Snapshot | `entitlements.py` | -| Probe vs. Enforce | `CAPABILITY_ENFORCE` | - -**Nicht übernommen:** `club_id`, Vereinsrollen, Übungs-/Trainings-Capabilities, Club-Feature-Kontingente, `club_quota_bypass`. - ---- - -## 9. Übernommene Muster aus Mitai - -| Muster | Kairo-Umsetzung | -|--------|-----------------| -| Entitlements als zentrale Auflösungsschicht | `build_entitlements_snapshot()` | -| Probe-vs-Enforce-Denken | Default `probe`, optional `enforce` | -| Feature-Registry-Idee vorbereitet | `features: {}` im Snapshot, Enforcement `probe` | - -**Nicht übernommen:** Tier/Subscription, Usage-Zähler, `check_feature_access`-Legacy, Account-Tier-Limits. - ---- - -## 10. Bewusst nicht übernommen - -- Shinkan-/Mitai-Domänenbegriffe (`club`, `profile`, Tier) -- Feature-Limits, Billing, Coupons, Usage-Zähler -- Prompt Registry, Vorhaben-/Projektlogik -- MCP, produktive Admin-UI -- Capabilities nur in SQL-Migration pflegen -- Governance/Object-ACL (AP später) - ---- - -## 11. Abweichungen von Designprinzipien - -| Thema | Abweichung | Begründung | -|-------|------------|------------| -| Entitlements-Struktur | flache + verschachtelte Blöcke | Kairo Hybrid: Account + Tenant laut Family Model | -| Feature-Registry | leeres Objekt | AP0.4-Scope | -| Admin-Grant-Overrides in DB | Sync fügt nur hinzu (`ON CONFLICT DO NOTHING`) | Sprint-0-Minimal; kein Admin-UI für Overrides | -| `linked_feature_id` | nicht modelliert | Keine Feature-Limits in AP0.3 | - -**Eingehalten:** Auth / Capability / Feature getrennt; Prüfung zentral; Portal- vs. Tenant-Rolle getrennt; TenantContext als Auflösungsschicht. - ---- - -## 12. Offene Entscheidungen - -1. **Prod `CAPABILITY_ENFORCE`** — Default `probe`; wann auf `enforce` umstellen? -2. **Grant-Overrides** — Admin bearbeitet Grants in DB vs. Re-Sync aus Code -3. **Prod-pytest-Cleanup** für `*@example.com` (aus AP0.2) -4. **Feature-Registry** — Modell und Sync in AP0.4 -5. **Frontend** — Entitlements-gestütztes UI-Gating statt Debug-JSON - ---- - -## 13. Empfehlung für AP0.4 - -Laut Foundation-Dokument **AP0.4 – Prompt, Feature, Config Registry**: - -- Feature Registry (Metadaten, ohne Limits in Sprint 0) -- PromptTemplate / PromptVersion / Placeholder -- ConfigurationEntry -- Einfaches Prompt-Rendering mit Placeholder-Validation -- `features`-Block in Entitlements mit Registry-Sync (ohne Billing) - -Optional vor AP0.4: Prod-Cleanup-Seed für pytest-Artefakte; Frontend zeigt `/api/me/entitlements`. - ---- - -## Referenzen - -- `docs/sprints/Jinkendo_Kairo_04_Sprint0_Foundation_v0.3.md` § AP0.3, §9 Entitlements -- `docs/reference/design-principles/shinkan/RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md` -- `docs/reference/design-principles/shinkan/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md` -- `docs/reference/design-principles/alignment/FAMILY_ENTITLEMENT_MODEL.md` -- Vorgänger: `docs/sprints/Sprint0_AP0_2_Completion_Report_v0.2.md` - ---- - -*Abgeschlossen im Rahmen Sprint 0 – AP0.3.* diff --git a/docs/sprints/Sprint0_AP0_3_Completion_Report_v0.2.md b/docs/sprints/Sprint0_AP0_3_Completion_Report_v0.2.md new file mode 100644 index 0000000..e553cc3 --- /dev/null +++ b/docs/sprints/Sprint0_AP0_3_Completion_Report_v0.2.md @@ -0,0 +1,246 @@ +# AP0.3 – Abschlussbericht Capability / Rights Registry & Entitlements Snapshot + +**Status:** abgeschlossen +**Stand:** 2026-07-04 (final) +**Branch:** `develop` · Dev-Deploy und Test Suite grün · Prod stabil (Stand Nutzer) + +--- + +## 1. Scope und Einordnung + +AP0.3 liefert die **minimale Capability-/Rights-Grundlage** und den **Entitlements-Snapshot** für Sprint 0. Auth, TenantContext und Sessions stammen aus AP0.2; AP0.3 ergänzt Registry, DB-Sync, zentrale Capability-Prüfung und `/api/me/entitlements`. + +| Anforderung (AP0.3) | Status | +|---------------------|--------| +| Migration Capabilities + Role-Grants | ✓ | +| Runtime Registry + Modul-Registrierungen | ✓ | +| Startup-Sync Registry → DB | ✓ | +| TenantContext.capabilities | ✓ | +| `require_capability()` Dependency | ✓ | +| `GET /api/me/entitlements` | ✓ | +| Beispiel-Endpoint mit Capability-Gate | ✓ | +| Tests (Registry, Sync, Auflösung, Enforce/Probe) | ✓ | +| Trennung Auth / Capability / Feature | ✓ | + +**Bewusst nicht in AP0.3:** Feature-Limits, Billing, Usage-Zähler, Prompt Registry, produktive Admin-UI, Governance/Object-ACL. + +--- + +## 2. Umgesetzte Dateien + +| Datei | Zweck | +|-------|--------| +| `backend/migrations/004_capabilities_registry.sql` | Tabellen `capabilities`, `role_capability_grants` | +| `backend/rights_registry.py` | In-Memory-Registry, Validierung, DB-Sync, Grant-Lookup | +| `backend/rights_registrations/__init__.py` | Side-Effect-Import aller Modul-Registrierungen | +| `backend/rights_registrations/platform.py` | Platform-Capabilities | +| `backend/rights_registrations/tenant_ops.py` | Tenant-/Actor-Capabilities | +| `backend/capabilities.py` | Auflösung, `check_capability`, `require_capability` | +| `backend/entitlements.py` | Entitlements-Snapshot-Builder | +| `backend/sync_rights_registry.py` | CLI-Sync beim Container-Start | +| `backend/tenant_context.py` | `TenantContext.capabilities` | +| `backend/routers/me.py` | `/entitlements`, `/admin/demo` | +| `backend/entrypoint.sh` | Rights-Sync nach Seeds | +| `backend/version.py` | `0.3.0-ap0.3`, Schema `004` | +| `backend/tests/test_rights_registry.py` | Registry + Sync | +| `backend/tests/test_capabilities.py` | Grants, enforce/probe, Demo-Endpoint | +| `backend/tests/test_entitlements.py` | Snapshot-Form | +| `backend/tests/conftest.py` | Registry-Sync in Test-Session | +| `frontend/src/App.jsx` | Header AP0.3; `/api/me/context` zeigt Capabilities | +| `README.md` | API-Doku AP0.3 | + +**Wesentliche Commits:** `910b1d7` (Implementierung), `eaa0e25` (pytest-Fix), `4069cb0` (GUI-Sprint-Label). + +--- + +## 3. Neue Migrationen + +**`004_capabilities_registry.sql`** + +- **`capabilities`** — `capability_key`, `module`, `description`, `is_active` +- **`role_capability_grants`** — `role_scope` (`portal` \| `tenant`), `role_code`, `capability_key` + +Kein Feature-/Limit-Schema (Vorbereitung AP0.4). + +--- + +## 4. Registry-Struktur + +``` +backend/ +├── rights_registry.py +├── rights_registrations/ +│ ├── __init__.py +│ ├── platform.py # admin, context, entitlements +│ └── tenant_ops.py # tenant.manage, actor.manage +└── sync_rights_registry.py +``` + +**Modell:** `@dataclass(frozen=True) CapabilityRegistration` mit `key`, `module`, `description`, `default_grants`. + +**Startup:** `entrypoint.sh` → `python sync_rights_registry.py` (`SKIP_RIGHTS_SYNC=1` zum Überspringen). + +--- + +## 5. Endpoints + +| Endpoint | Methode | Auth / Gate | Status | +|----------|---------|-------------|--------| +| `/api/me/context` | GET | Session | geändert — `capabilities[]` | +| `/api/me/entitlements` | GET | Session | neu | +| `/api/me/admin/demo` | GET | Session + `kairo.admin.access` | neu (Beispiel `require_capability`) | + +OpenAPI (Dev): `/api/docs` + +--- + +## 6. Capability-Auflösungslogik + +``` +Session (portal_role, active_tenant_id) + → tenant_role aus Membership (optional) + → load_grants_for_roles(portal_role, tenant_role) + → Union Portal-Grants + Tenant-Grants + → TenantContext.capabilities (frozenset) +``` + +**`require_capability(key)`:** prüft Mitgliedschaft in `ctx.capabilities`. + +| Modus | Env | Verhalten | +|-------|-----|-----------| +| probe | `CAPABILITY_ENFORCE=probe` (Default) | Zugriff erlaubt; Verweigerung → Audit `capability.denied` | +| enforce | `CAPABILITY_ENFORCE=enforce` | HTTP 403 ohne Grant | + +--- + +## 7. Initiale Capabilities + +| Capability | Portal admin | Portal user | Tenant owner | Tenant admin | Tenant member | +|------------|:------------:|:-----------:|:------------:|:------------:|:-------------:| +| `kairo.admin.access` | ✓ | | | | | +| `kairo.tenant.manage` | ✓ | | ✓ | ✓ | | +| `kairo.actor.manage` | ✓ | | ✓ | ✓ | | +| `kairo.context.read` | ✓ | ✓ | ✓ | ✓ | ✓ | +| `kairo.entitlements.read` | ✓ | ✓ | ✓ | ✓ | ✓ | + +--- + +## 8. Tests und Verifikation + +### pytest (CI, Dev-Container) + +```bash +docker compose -f docker-compose.dev-env.yml exec backend python -m pytest tests -ra -vv +``` + +| Testdatei | Abdeckung | Status | +|-----------|-----------|--------| +| `test_rights_registry.py` | 5 Capabilities, Sync idempotent | ✓ | +| `test_capabilities.py` | Admin/Member enforce, Owner-Grants, probe | ✓ | +| `test_entitlements.py` | Snapshot-Struktur | ✓ | +| `test_migrations.py` | Migration 004 | ✓ | +| Gesamt Test Suite (Gitea) | nach Push `develop` | ✓ (Nutzer bestätigt) | + +### Manuell (Dev-GUI) + +| Prüfung | Ergebnis | +|---------|----------| +| Login `lars@stommer.com` | ✓ | +| `/api/me/context` → `capabilities` sichtbar | ✓ | +| API Health → `"schema": "004"` | ✓ | +| Header Sprint-Anzeige AP0.3 | ✓ (nach `4069cb0`) | + +**Hinweis:** Entitlements und Admin-Demo sind in der GUI noch nicht als eigene Karten — prüfbar über Swagger (`/api/docs`) oder DevTools. + +--- + +## 9. Übernommene Muster aus Shinkan + +| Muster | Kairo-Umsetzung | +|--------|-----------------| +| Registry-first | `rights_registry.py` + `rights_registrations/` | +| `register_capability()` mit Validierung | Pflichtfelder `key`, `module`, `description` | +| Frozen Dataclass-Definitionen | `CapabilityRegistration` | +| Startup-Sync Registry → DB | `sync_rights_registry_to_db()` | +| Modul-Ownership | `platform`, `tenant` | +| Default Grants in Code | `default_grants` pro Capability | +| `require_capability` Dependency | `capabilities.py` | +| `/api/me/entitlements` Snapshot | `entitlements.py` | +| Probe vs. Enforce | `CAPABILITY_ENFORCE` | + +**Nicht übernommen:** `club_id`, Vereinsrollen, Übungs-/Trainingsrechte, Club-Feature-Kontingente. + +--- + +## 10. Übernommene Muster aus Mitai + +| Muster | Kairo-Umsetzung | +|--------|-----------------| +| Entitlements als zentrale Schicht | `build_entitlements_snapshot()` | +| Probe-vs-Enforce-Denken | Default `probe`, optional `enforce` | +| Feature-Registry vorbereitet | `features: {}` im Snapshot | + +**Nicht übernommen:** Tier/Subscription, Usage-Zähler, Billing, Legacy `check_feature_access`. + +--- + +## 11. Bewusst nicht übernommen + +- Shinkan-/Mitai-Domänenbegriffe (`club`, `profile`, Tier) +- Feature-Limits, Billing, Coupons +- Prompt Registry, Vorhaben-/Projektlogik +- MCP, produktive Admin-UI (nur Debug-JSON + Swagger) +- Capabilities nur in SQL pflegen +- Governance/Object-ACL + +--- + +## 12. Abweichungen von Designprinzipien + +| Thema | Abweichung | Begründung | +|-------|------------|------------| +| Entitlements-Struktur | Account- + Tenant-Block | Kairo Hybrid laut Family Entitlement Model | +| Feature-Registry | leeres Objekt | AP0.4 | +| Grant-Overrides | Sync nur additive Grants | Sprint-0-Minimal | +| `linked_feature_id` | nicht modelliert | Keine Limits in AP0.3 | +| Frontend | kein Entitlements-Panel | Minimal-UI; AP0.4/UX optional | + +**Eingehalten:** zentrale Capability-Prüfung; Portal- vs. Tenant-Rolle getrennt; TenantContext als Auflösungsschicht. + +--- + +## 13. Offene Entscheidungen + +1. **Prod `CAPABILITY_ENFORCE=enforce`** — wann umstellen? +2. **Grant-Overrides in DB** vs. reiner Code-Kanon +3. **Prod-pytest-Cleanup** (`*@example.com`) — aus AP0.2 offen +4. **Frontend:** Entitlements-Karte + Admin-Demo-Button +5. **Feature-Registry** — AP0.4 + +--- + +## 14. Empfehlung für AP0.4 + +Laut Foundation **AP0.4 – Prompt, Feature, Config Registry**: + +- Feature Registry (Metadaten, ohne Billing-Limits in Sprint 0) +- PromptTemplate / PromptVersion / Placeholder +- ConfigurationEntry +- Prompt-Rendering mit Placeholder-Validation +- `features`-Block in Entitlements mit Registry-Sync + +Optional vor AP0.4: Prod-Cleanup-Seed; GUI-Entitlements; `CAPABILITY_ENFORCE=enforce` in Prod nach Kalibrierung. + +--- + +## Referenzen + +- `docs/sprints/Jinkendo_Kairo_04_Sprint0_Foundation_v0.3.md` § AP0.3, §9 +- `docs/reference/design-principles/shinkan/RIGHTS_REGISTRY_DESIGN_PRINCIPLES.md` +- `docs/reference/design-principles/shinkan/CAPABILITY_ENTITLEMENT_DESIGN_PRINCIPLES.md` +- `docs/reference/design-principles/alignment/FAMILY_ENTITLEMENT_MODEL.md` +- Vorgänger: `docs/sprints/Sprint0_AP0_2_Completion_Report_v0.2.md` + +--- + +*Abgeschlossen im Rahmen Sprint 0 – AP0.3. Ersetzt `Sprint0_AP0_3_Completion_Report_v0.1.md`.*