# AP0.5 – Abschlussbericht Minimaler Vorhaben- und Maßnahmen-Slice **Status:** abgeschlossen **Stand:** 2026-07-05 (final) **Branch:** `develop` · Dev-Deploy und Test Suite grün · Schema `006` **Version:** `0.5.0-ap0.5` **Scope-Entscheidung:** [ADP_AP0_5_Sprint0_Scope_Shift_v0.1.md](../architecture/ADP_AP0_5_Sprint0_Scope_Shift_v0.1.md) — Foundation-AP0.5 (Audit/Admin) → **AP0.6** verschoben. --- ## 1. Scope und Einordnung AP0.5 liefert den **ersten fachlich nutzbaren Kairo-Slice**: Ein angemeldeter Actor kann innerhalb eines Tenants Vorhaben und Maßnahmen verwalten, Actors zuweisen und offene Maßnahmen abrufen. | Anforderung (AP0.5) | Status | |---------------------|--------| | Migration `006` (initiatives, actions, action_assignments) | ✓ | | Tenant-Bezug für alle Objekte | ✓ | | Owner Actor für Initiative | ✓ | | Action gehört zu Initiative | ✓ | | Action → ein oder mehrere Actors (Assignments) | ✓ | | CRUD-Minimum Initiatives | ✓ | | CRUD-Minimum Actions | ✓ | | Endpoint „Meine offenen Maßnahmen“ | ✓ | | Statusmodell minimal | ✓ | | Priority minimal | ✓ | | Capability-Gates (4 neue Capabilities) | ✓ | | Audit bei Create/Update/Statuswechsel | ✓ | | Tests (Isolation, CRUD, Assignment, Status) | ✓ | | README/API-Doku | ✓ | | CI pytest grün | ✓ (55/55 nach Seed-Fix) | **Bewusst nicht in AP0.5:** Projects, Milestones, Programs, Reviews, Evidence, Blocker, KI/Prompt-Erweiterung, MCP, automatische Priorisierung, komplexe UI, Workflow Engine, Foundation-AP0.5 (Audit/Admin-UI). **Wesentliche Commits:** `afa6815` (Implementierung), `a34a614` (Cleanup-Seed FK-Fix). --- ## 2. Definition of Done — Prüfmatrix ### 2.1 AP0.5-Auftrag (fachlich) | Kriterium | Ergebnis | Nachweis | |-----------|----------|----------| | Vorhaben anlegen | ✓ | `POST /api/initiatives`, `test_initiative_crud` | | Maßnahmen erfassen | ✓ | `POST /api/initiatives/{id}/actions` | | Actors zuweisen | ✓ | `PUT /api/actions/{id}/assignments`, `test_action_assignments` | | Status ändern | ✓ | `PATCH`, `test_action_crud_and_status_change` | | Offene Maßnahmen abrufen | ✓ | `GET /api/actions/me/open`, `test_my_open_actions` | | Tenant-Isolation | ✓ | 3 Isolation-Tests | | Tests grün | ✓ | CI Job `pytest-backend` | ### 2.2 Principle Gate (G-01–G-12) | ID | Prinzip | AP0.5 | |----|---------|-------| | G-01 | Tenant-first | ✓ `tenant_id` serverseitig | | G-02 | Actor-first | ✓ Assignments an Actors | | G-03 | TenantContext | ✓ `require_capability` | | G-04 | Auth/Capability/Feature getrennt | ✓ | | G-05 | Rights Registry | ✓ `initiative_ops.py` | | G-10 | Audit | ✓ 9 Audit-Actions | | G-11 | Migration Standard | ✓ `006_*` nummeriert | | G-12 | Fail-Fast Startup | ✓ Migration beim Start | ### 2.3 Sprint-0 DoD (Foundation §12) — mit ADP | Kriterium | Status | Anmerkung | |-----------|--------|-----------| | Migrationen funktionieren | ✓ | 001–006 | | Tenant/User/Actor/Membership | ✓ | AP0.2 | | TenantContext, Capability, Prompt, Audit | ✓ | AP0.2–0.4 | | Tests Kernmodelle | ✓ | inkl. AP0.5 | | README aktuell | ✓ | AP0.5-Abschnitt | | Keine hardcodierten Rechte | ✓ | | | Vorhaben nicht in Sprint 0 | ⚠ | **ADP begründet** — minimaler Slice | | Foundation-AP0.5 Audit/Admin | ✗ | → AP0.6 | ### 2.4 User Story S0-07 (Audit) | Feld (Foundation) | AP0.5 | |-------------------|-------| | Tenant | ✓ `tenant_id` | | Aktion | ✓ `action` | | Zeitpunkt | ✓ `created_at` | | Entity | ✓ in `details` (JSON) | | Actor | ✗ nur `user_id` (bekannt seit AP0.2) | --- ## 3. Umgesetzte Dateien ### 3.1 Migration & Schema | Datei | Zweck | |-------|--------| | `backend/migrations/006_initiatives_actions.sql` | initiatives, actions, action_assignments | ### 3.2 Services | Datei | Zweck | |-------|--------| | `backend/services/initiatives.py` | Vorhaben-CRUD, Validierung, Audit | | `backend/services/actions.py` | Maßnahmen-CRUD, Assignments, offene Maßnahmen | ### 3.3 API & Capabilities | Datei | Zweck | |-------|--------| | `backend/routers/initiatives.py` | Initiative-Endpoints + nested Actions | | `backend/routers/actions.py` | Action-Endpoints + `/me/open` | | `backend/rights_registrations/initiative_ops.py` | 4 Capabilities | | `backend/main.py` | Router-Mount | | `backend/version.py` | `0.5.0-ap0.5`, Schema `006` | ### 3.4 Tests, Seeds, Doku | Datei | Zweck | |-------|--------| | `backend/tests/test_initiatives_actions.py` | 11 Tests AP0.5 | | `backend/tests/test_migrations.py` | Migration 006 | | `backend/tests/test_rights_registry.py` | 16 Capabilities | | `backend/seeds/seed_001_cleanup_pytest_artifacts.dev.sql` | Initiatives vor Actor-Löschung (FK-Fix) | | `README.md` | API-Doku AP0.5 | | `docs/MIGRATIONS.md` | Migrationstabelle 001–006 | | `docs/architecture/ADP_AP0_5_Sprint0_Scope_Shift_v0.1.md` | Scope-Entscheidung | | `frontend/src/App.jsx` | Header AP0.5 | --- ## 4. Neue Migrationen **`006_initiatives_actions.sql`** | Tabelle | Spalten (Kern) | |---------|----------------| | `initiatives` | `tenant_id`, `title`, `goal`, `status`, `priority`, `owner_actor_id` | | `actions` | `tenant_id`, `initiative_id`, `title`, `description`, `status`, `priority` | | `action_assignments` | `tenant_id`, `action_id`, `actor_id` — UNIQUE `(action_id, actor_id)` | CHECK-Constraints für Status und Priority. `owner_actor_id` → `actors` ON DELETE **RESTRICT**. --- ## 5. Datenmodell ``` tenants └── initiatives id, tenant_id, title, goal, status, priority owner_actor_id → actors created_at, updated_at └── actions [ON DELETE CASCADE] id, tenant_id, initiative_id, title, description status, priority └── action_assignments [ON DELETE CASCADE von action] id, tenant_id, action_id, actor_id ``` --- ## 6. Endpoints | Endpoint | Methode | Capability | |----------|---------|------------| | `/api/initiatives` | GET | `kairo.initiative.read` | | `/api/initiatives` | POST | `kairo.initiative.manage` | | `/api/initiatives/{id}` | GET/PATCH/DELETE | read / manage | | `/api/initiatives/{id}/actions` | GET/POST | `kairo.action.read` / manage | | `/api/actions/{id}` | GET/PATCH/DELETE | action.read / manage | | `/api/actions/{id}/assignments` | PUT | `kairo.action.manage` | | `/api/actions/me/open` | GET | `kairo.action.read` | `tenant_id` ausschließlich aus `TenantContext` — nie aus Client-Body. Details und curl-Beispiele: `README.md`. --- ## 7. Statusmodell **Initiative:** `active` · `paused` · `completed` · `archived` **Action:** `open` · `in_progress` · `blocked` · `done` · `discarded` **Priorität:** `low` · `normal` · `high` **Offen** (`/api/actions/me/open`): Status ∈ `{open, in_progress, blocked}` und zugewiesen an `ctx.actor_id`. Sortierung: Priority high→low, dann `updated_at DESC`. --- ## 8. Assignment-Modell - n:m über `action_assignments` - `PUT /api/actions/{id}/assignments` ersetzt die komplette Liste - Beim Create optional `assigned_actor_ids` - Assignee-Actors müssen im gleichen Tenant und aktiv sein - Cross-Tenant-Zuweisung → HTTP 400 --- ## 9. Capability-Nutzung | Capability | Default-Grants | |------------|----------------| | `kairo.initiative.read` | portal user/admin, tenant owner/admin/member | | `kairo.initiative.manage` | portal admin, tenant owner/admin/member | | `kairo.action.read` | portal user/admin, tenant owner/admin/member | | `kairo.action.manage` | portal admin, tenant owner/admin/member | Enforcement: `require_capability()` → `require_tenant_context` → Probe/Enforce via `CAPABILITY_ENFORCE`. --- ## 10. Tenant-Isolation - Alle Queries: `WHERE tenant_id = %s` aus `ctx.tenant_id` - Fremde IDs → **404** (kein Leak) - Cross-Tenant-Actor → **400** - Tests: `test_tenant_isolation_initiatives`, `test_tenant_isolation_actions`, `test_cross_tenant_actor_assignment_rejected` --- ## 11. Audit | Audit-Action | Trigger | |--------------|---------| | `initiative.created` | POST Initiative | | `initiative.updated` | PATCH Initiative | | `initiative.status_changed` | PATCH mit Statusänderung | | `initiative.deleted` | DELETE Initiative | | `action.created` | POST Action | | `action.updated` | PATCH Action | | `action.status_changed` | PATCH mit Statusänderung | | `action.assigned` | PUT Assignments | | `action.deleted` | DELETE Action | Nachweis: `test_audit_on_create_and_status_change`. **Lücke (S0-07):** kein `actor_id`-Feld in `audit_log` — nur `user_id`. Offen für AP0.6. --- ## 12. Tests & CI ### 12.1 Testabdeckung AP0.5 | Test | Abdeckung | |------|-----------| | `test_initiative_crud` | Create, List, Get, Update, Delete | | `test_action_crud_and_status_change` | Lifecycle + Status | | `test_action_assignments` | Multi-Actor | | `test_my_open_actions` | Filter offen/erledigt/nicht zugewiesen | | `test_tenant_isolation_*` | Cross-Tenant 404 | | `test_cross_tenant_actor_assignment_rejected` | FK-Logik | | `test_audit_on_create_and_status_change` | Audit-Log | | `test_member_has_initiative_capabilities` | Grants | | `test_unauthenticated_rejected` | Auth-Gate | | `test_invalid_status_rejected` | Pydantic | ### 12.2 CI-Nachweis | Lauf | Ergebnis | |------|----------| | Erster Push `afa6815` | 53 passed, **2 failed** (Cleanup-Seed FK) | | Fix `a34a614` | **55 passed**, 0 failed | Fehlerursache: `initiatives.owner_actor_id` RESTRICT verhinderte Actor-Löschung im pytest-Cleanup. Fix: Initiatives vor Actors in `seed_001_cleanup_pytest_artifacts.dev.sql` löschen. --- ## 13. Abweichungen von Foundation / Designprinzipien | Thema | Abweichung | Begründung / ADP | |-------|------------|------------------| | AP-Nummerierung | AP0.5 ≠ Foundation-AP0.5 | ADP Scope-Verschiebung | | Vorhaben in Sprint 0 | minimaler Slice | ADP Option B | | Audit Actor-Feld | nur `user_id` | AP0.2-Schema, AP0.6 | | GUI | keine Vorhaben-UI | bewusst minimal | | Feature Registry | keine initiative-Features | Capabilities reichen | **Eingehalten:** Tenant/Actor/Capability-Trennung; keine hardcodierten Rechte; nummerierte Migration; kein Mitai/Shinkan-Domänencode. --- ## 14. Bewusst nicht übernommen - Projects, Milestones, Programs, Reviews, Evidence, Blocker - KI/Prompt-Erweiterung, MCP, Workflow Engine - Automatische Priorisierung - Foundation-AP0.5: Admin-Routen, Admin-Seite, granulares Registry-Audit - GUI für Vorhaben/Maßnahmen (Swagger/API) --- ## 15. Empfehlung AP0.6 **Foundation-AP0.5 nachziehen (Audit & Admin):** - Granulares Audit (optional `actor_id` in `audit_log`) - Minimale Admin-Routen oder Admin-Seite - Entitlements-/Registry-Prüfbarkeit in GUI **Alternativ fachlich:** Kommentare pro Maßnahme (`action_comments`) — siehe v0.1 §11. --- ## Referenzen - Auftrag: AP0.5 Minimaler Vorhaben- und Maßnahmen-Slice (Cursor) - ADP: `docs/architecture/ADP_AP0_5_Sprint0_Scope_Shift_v0.1.md` - Foundation: `docs/sprints/Jinkendo_Kairo_04_Sprint0_Foundation_v0.3.md` § AP0.5, §12, §13 - Principle Gate: `docs/architecture/Kairo_Sprint0_Principle_Gate_v0.1.md` - Vorgänger: `docs/sprints/Sprint0_AP0_4_Completion_Report_v0.2.md` - v0.1: `docs/sprints/Sprint0_AP0_5_Completion_Report_v0.1.md`