Co-authored-by: Cursor <cursoragent@cursor.com>
10 KiB
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
{ "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/actorsActorSelectzeigt 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
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
{
"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:
{
"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_idMigration- 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
audit_log.actor_id— Migration in AP0.8?- Actor Workload Widget — wann in Workspace anzeigen?
- Initiative bearbeiten in UI — weiter offen aus AP0.6
- Foundation AP0.5 Audit/Admin-UI — backlog
20. Empfehlung für AP0.8
Kleinster Nutzwert (Priorität):
- Audit/Admin minimal — Audit-Log lesbar, optional
actor_id-Spalte - Initiative bearbeiten in UI — PATCH existiert
- Actor Workload Widget — kleine Karte im Workspace
- 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 | ✓ |