Kairo-Jinkendo/docs/sprints/Sprint0_AP0_7_Completion_Report_v0.1.md

343 lines
10 KiB
Markdown
Raw Normal View History

# AP0.7 – Abschlussbericht Tenant Hardening, Actor Directory & Data Layer Minimum
**Status:** abgeschlossen
**Stand:** 2026-07-05
**Branch:** `develop`
**Version:** Backend `0.7.0-ap0.7` · Frontend `0.7.0-ap0.7` · Schema `006` (unverändert)
---
## 1. Scope und Einordnung
AP0.7 ist ein **Basis-Härtungsauftrag** — keine neuen großen Fachfeatures.
| Teil | Ziel | Status |
|------|------|--------|
| A | Tenant Hardening | ✓ Invarianten dokumentiert, bestehende Endpoints geprüft, Tests ergänzt |
| B | Actor Directory | ✓ `GET /api/actors`, `GET /api/actors/{id}`, ActorSelect mit echter Liste |
| C | Data Layer Minimum | ✓ `backend/data_layer/`, Workspace-Endpoints, Widget-Integration |
| D | Audit-Härtung | ✓ Bewertung dokumentiert — `actor_id`-Spalte bewusst zurückgestellt |
**Keine neue Migration** — Read-Models nutzen bestehendes Schema `006`.
---
## 2. Umgesetzte Dateien
### Backend (neu)
| Datei | Zweck |
|-------|--------|
| `backend/data_layer/__init__.py` | Data-Layer-Paket |
| `backend/data_layer/actions.py` | Open/blocked Actions (Read) |
| `backend/data_layer/initiatives.py` | Active Initiatives (Read) |
| `backend/data_layer/actors.py` | Actor Workload (Read) |
| `backend/data_layer/workspace.py` | Workspace Summary |
| `backend/routers/actors.py` | Actor Directory API |
| `backend/routers/workspace.py` | Workspace Read API |
| `backend/rights_registrations/workspace_ops.py` | `kairo.actor.read`, `kairo.workspace.read` |
| `backend/tests/test_ap07.py` | AP0.7 Tests (14 Tests) |
### Backend (geändert)
| Datei | Änderung |
|-------|----------|
| `backend/services/actors.py` | `list_actors`, `get_actor` |
| `backend/routers/actions.py` | `/me/open` delegiert an Data Layer |
| `backend/main.py` | Router actors + workspace |
| `backend/version.py` | `0.7.0-ap0.7` |
| `backend/tests/test_rights_registry.py` | 18 Capabilities |
### Frontend (neu/geändert)
| Datei | Zweck |
|-------|--------|
| `frontend/src/api/workspace.js` | Workspace API-Client |
| `frontend/src/hooks/useActors.js` | Actor Directory Hook + Fallback |
| `frontend/src/widgets/WorkspaceSummaryWidget.jsx` | Überblick-Karte |
| `frontend/src/api/actors.js` | `listActors`, Fallback beibehalten |
| Widgets, `ActorSelect`, `ActionForm`, `InitiativeDetailPage` | Data-Layer-Endpoints, echte Actors |
| `frontend/src/registry/widgetRegistry.js` | + `kairo.workspace_summary` |
### Doku
| Datei | Zweck |
|-------|--------|
| `docs/architecture/Kairo_Tenant_Invariants_v0.1.md` | 10 Tenant-Invarianten |
| `README.md` | AP0.7 API, Capabilities |
---
## 3. Tenant Hardening
**Ergebnis der Code-Prüfung:** Bestehende fachliche Services (AP0.5) waren bereits tenant-sicher aufgebaut.
| Prüfpunkt | Ergebnis |
|-----------|----------|
| `tenant_id` aus Context, nicht Body | ✓ alle Router |
| Queries mit `tenant_id`-Filter | ✓ Services + Data Layer |
| Cross-Tenant → 404 | ✓ Initiatives, Actions, Actors |
| Assignment tenant-sicher | ✓ `_actor_in_tenant()` |
| Keine Client-`tenant_id` | ✓ |
**Gefundene Mandantenrisiken:** Keine neuen Lücken in AP0.5-Code. AP0.7 schließt die fehlende Actor-Directory-Isolation und Workspace-Aggregations-Tests ab.
---
## 4. Tenant-Invarianten
Verbindlich dokumentiert in `docs/architecture/Kairo_Tenant_Invariants_v0.1.md` (10 Invarianten + Anti-Patterns).
---
## 5. Actor Directory
### Endpoints
| Endpoint | Capability | Verhalten |
|----------|------------|-----------|
| `GET /api/actors` | `kairo.actor.read` | Aktive Actors des Tenants; optional `actor_type`, `q`, `include_inactive` |
| `GET /api/actors/{id}` | `kairo.actor.read` | Detail; Cross-Tenant → 404 |
### Response-Shape
```json
{ "id": "...", "name": "...", "actor_type": "human|agent|working_group|external_system", "is_active": true }
```
`user_id` wird **nicht** exponiert (Datenschutz).
### Default Grants `kairo.actor.read`
Portal Admin/User, Tenant Owner/Admin/Member — Begründung: Assignment-UI und Workspace-Workload für alle operativen Tenant-Mitglieder.
---
## 6. ActorSelect / Assignment UX
- `useActors()` lädt `/api/actors`
- `ActorSelect` zeigt Name + Typ (deutsche Labels)
- Mehrfachauswahl für Assignments
- Fallback auf Human Actor aus Context bei API-Fehler
- Loading/Error/Empty States
- Maßnahmen können Agents/Working Groups aus dem Tenant zugewiesen werden
---
## 7. Data Layer Struktur
```text
backend/data_layer/
actions.py — get_my_open_actions, get_my_blocked_actions, get_all_my_open_actions
initiatives.py — get_active_initiatives
actors.py — get_actor_workload
workspace.py — get_workspace_summary
```
### Abgrenzung
| Schicht | Verantwortung |
|---------|---------------|
| Router | HTTP, Capability-Gates, Serialisierung |
| Data Layer | Read-Aggregation, tenant-scoped Queries, DTOs |
| Services | Write/CRUD, Domänenvalidierung, Audit |
`/api/actions/me/open` bleibt für Abwärtskompatibilität; delegiert intern an Data Layer.
---
## 8. Workspace Summary
`GET /api/workspace/summary` → `kairo.workspace.read`
```json
{
"open_actions_count": 0,
"blocked_actions_count": 0,
"active_initiatives_count": 0,
"done_actions_recent_count": 0
}
```
- Personal (current actor): open, blocked, done (7 Tage via `updated_at`)
- Tenant-weit: `active_initiatives_count` (status active/paused)
Frontend: `WorkspaceSummaryWidget` im Workspace.
---
## 9. Actor Workload Basic
`GET /api/workspace/actors/workload` — pro aktivem Actor im Tenant:
```json
{
"actor_id": "...",
"display_name": "...",
"actor_type": "human",
"open_actions": 3,
"blocked_actions": 1,
"in_progress_actions": 2
}
```
Noch **kein dediziertes UI-Widget** — Endpoint für spätere Dashboards; API + Tests vorhanden.
---
## 10. Neue/geänderte API-Endpunkte
Siehe README AP0.7-Abschnitt. Keine Write-Endpoints hinzugefügt.
---
## 11. Capability-Nutzung
| Capability | Neu? | Grants | Verwendung |
|------------|------|--------|------------|
| `kairo.actor.read` | ✓ | Member+ | Actor Directory |
| `kairo.workspace.read` | ✓ | Member+ | Workspace Data Layer |
| `kairo.actor.manage` | — | unverändert | Actor-Verwaltung (AP0.2) |
| `kairo.action.read` | — | unverändert | CRUD-Read, `/me/open` |
| `kairo.initiative.read` | — | unverändert | Initiatives |
**Entscheidung:** Kein separates `kairo.workspace.metrics.read` — ein Read-Key für alle Workspace-Read-Models.
Gesamt: **18 Capabilities** (vorher 16).
---
## 12. Audit-Härtung / actor_id-Bewertung
**Ist-Zustand:** `audit_log` hat `user_id`, `tenant_id`, `details` (JSONB). Kein `actor_id`-Spalte.
**Bewertung:**
| Option | Empfehlung |
|--------|------------|
| `actor_id` in `details` | ✓ bereits bei Assignments (`actor_ids`) |
| `actor_id` als Spalte | **Zurückgestellt** — Migration 007 + Backfill; sinnvoll in AP0.8 (Audit/Admin) |
| Risiko ohne Spalte | Gering für Sprint 0 — Actor aus Context + details ausreichend für Nachvollziehbarkeit |
Keine Migration in AP0.7 (Basis-Härtung ohne Schema-Change).
---
## 13. Frontend-Integration
| Widget/Komponente | Vor AP0.7 | Nach AP0.7 |
|-------------------|-----------|------------|
| MyOpenActionsWidget | `/api/actions/me/open` + Client-Filter | `/api/workspace/actions/open` |
| BlockedActionsWidget | `/me/open` + Filter | `/api/workspace/actions/blocked` |
| InitiativesWidget | `/api/initiatives` + Client-Filter | `/api/workspace/initiatives/active?limit=5` |
| WorkspaceSummaryWidget | — | `/api/workspace/summary` |
| ActorSelect | Context-Fallback only | `/api/actors` + Fallback |
**Keine fachliche KPI-Berechnung mehr in Widgets** (Filter/Slice entfernt).
AP0.6b Look & Feel unverändert.
---
## 14. Tests und Verifikation
### Backend (`test_ap07.py`)
- Actor Directory: List, Filter, Inactive, Detail, Cross-Tenant
- Workspace: Summary, Open, Blocked, Initiatives, Workload, Cross-Tenant
- Capabilities: Member hat `kairo.actor.read`, `kairo.workspace.read`
- Assignment an Tenant-Actor
### Frontend
- Vitest: 9/9 grün (Registry inkl. `workspace_summary`)
- Build: OK
### CI
pytest im Backend-Container (wie bisher) — erwartet grün mit +14 Tests.
---
## 15. Übernommene Muster aus Mitai
- Zentrale Data-Layer-Schicht für Read/Aggregation
- Widgets konsumieren vorbereitete Daten
- Trennung Rohdaten / Kennzahlen / UI
**Nicht übernommen:** Mitai Tracking/Gesundheits-KPIs, Tier/Billing.
---
## 16. Übernommene Muster aus Shinkan
- Tenant-sichere Queries mit Context-`tenant_id`
- Capability Gates pro Endpoint
- Cross-Tenant → 404
- Access-Layer-Denken (Data Layer als Read-Access)
**Nicht übernommen:** Vereins-/Trainingslogik.
---
## 17. Bewusst nicht übernommene Muster
- Analytics-Plattform, Zeitreihen, Forecasting
- Actor-Admin-UI, Actor-Erstellung in GUI
- `audit_log.actor_id` Migration
- Backend-Widget-Registry
- Program-Director-Algorithmus
---
## 18. Abweichungen von der Spezifikation
| Thema | Abweichung | Begründung |
|-------|------------|------------|
| Actor Workload UI | nur API, kein Widget | Endpoint für später; kein UI-Scope |
| Breakpoint Shell | unverändert 1024px | AP0.6b unverändert |
| `/api/actions/me/open` | beibehalten | Abwärtskompatibilität |
| `done_actions_recent_count` | 7-Tage-Fenster via `updated_at` | pragmatisch, dokumentiert |
---
## 19. Offene Entscheidungen
1. **`audit_log.actor_id`** — Migration in AP0.8?
2. **Actor Workload Widget** — wann in Workspace anzeigen?
3. **Initiative bearbeiten in UI** — weiter offen aus AP0.6
4. **Foundation AP0.5 Audit/Admin-UI** — backlog
---
## 20. Empfehlung für AP0.8
Kleinster Nutzwert (Priorität):
1. **Audit/Admin minimal** — Audit-Log lesbar, optional `actor_id`-Spalte
2. **Initiative bearbeiten in UI** — PATCH existiert
3. **Actor Workload Widget** — kleine Karte im Workspace
4. **Kommentare pro Maßnahme** — Kollaboration ohne Domänen-Explosion
Danach Sprint-1-Fachscope gemäß Product Spec.
---
## Abnahme-Checkliste AP0.7
| Kriterium | Erfüllt |
|-----------|---------|
| Tenant-Invarianten dokumentiert | ✓ |
| Fachliche Endpoints tenant-geprüft | ✓ |
| Cross-Tenant-Tests | ✓ |
| `GET /api/actors` | ✓ |
| ActorSelect echte Liste | ✓ |
| Tenant-Actor-Zuweisung | ✓ |
| Data Layer Minimum | ✓ |
| Workspace Summary | ✓ |
| Blocked/Active zentral | ✓ |
| Actor Workload Basic | ✓ (API) |
| Frontend nutzt Data Layer | ✓ |
| Keine großen Fachfeatures | ✓ |
| AP0.6b UX erhalten | ✓ |