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 (final)
Branch: develop · Dev-Deploy und Tests grün
Version: Backend 0.7.0-ap0.7 · Frontend 0.7.0-ap0.7 · Schema 006 (unverändert)
Wesentliche Commits: db06af0 (Implementierung), 02b3b17 (Fix Überblick-Widget Overflow)
1. Scope und Einordnung
AP0.7 ist ein Basis-Härtungsauftrag — keine neuen großen Fachfeatures.
| Teil | Ziel | Status |
|---|---|---|
| A | Tenant Hardening | ✓ Invarianten dokumentiert, Endpoints geprüft, Tests ergänzt |
| B | Actor Directory | ✓ GET /api/actors, ActorSelect mit echter Liste |
| C | Data Layer Minimum | ✓ backend/data_layer/, Workspace-Endpoints, Widget-Integration |
| D | Audit-Härtung | ✓ Bewertung — actor_id-Spalte bewusst zurückgestellt |
Keine neue Migration — Read-Models nutzen Schema 006.
Produktfrage beantwortet: Kairo steht vor weiterem Fachausbau auf einer tenant-sicheren Basis mit Actor Directory und zentraler Read-Schicht.
2. Definition of Done — Prüfmatrix
2.1 AP0.7-Auftrag (Abnahmekriterien)
| Kriterium | Ergebnis | Nachweis |
|---|---|---|
| Tenant-Invarianten dokumentiert | ✓ | Kairo_Tenant_Invariants_v0.1.md |
| Fachliche Endpoints tenant-geprüft | ✓ | Code-Review Initiatives/Actions/Actors |
| Cross-Tenant-Tests | ✓ | test_ap07.py, test_initiatives_actions.py |
GET /api/actors |
✓ | Router + 14 AP0.7-Tests |
| ActorSelect echte Liste | ✓ | useActors() + /api/actors |
| Maßnahmen Tenant-Actors zuweisbar | ✓ | Assignment-Tests + UI |
| Data Layer Minimum | ✓ | backend/data_layer/ |
| Workspace Summary | ✓ | API + WorkspaceSummaryWidget |
| Blocked/Active zentral | ✓ | /api/workspace/actions/* |
| Actor Workload Basic | ✓ | API (kein UI-Widget) |
| Frontend nutzt Data Layer | ✓ | Widgets ohne Client-Aggregation |
| Keine großen Fachfeatures | ✓ | Read-only Erweiterung |
| AP0.6b UX erhalten | ✓ | Look & Feel unverändert |
| Tests grün | ✓ | pytest + Vitest 9/9 |
| README/Doku | ✓ | README, Tenant-Invarianten, dieser Bericht |
2.2 Scope Teil A–D
| Teil | Ergebnis |
|---|---|
| A — Tenant Hardening | ✓ 10 Invarianten, keine neuen Leaks gefunden |
| B — Actor Directory | ✓ List + Detail, kairo.actor.read |
| C — Data Layer | ✓ 5 Read-Funktionen, 5 Workspace-Endpoints |
| D — Audit | ✓ actor_id-Spalte zurückgestellt, begründet |
2.3 Tests
| Test | Ergebnis | Nachweis |
|---|---|---|
test_ap07.py |
✓ 14/14 | Actor, Workspace, Cross-Tenant, Capabilities |
test_rights_registry.py |
✓ | 18 Capabilities |
| Vitest Frontend | ✓ 9/9 | Registry inkl. workspace_summary |
vite build |
✓ | Production-Build |
| Manueller UI-Smoke | ✓ | User: Überblick-Overflow gemeldet → Fix verifiziert („ok“) |
2.4 Post-QA Bugfix
| Issue | Fix | Status |
|---|---|---|
| Überblick-Widget: Kennzahlen ragen über Kartenrand | 02b3b17 — volle Grid-Breite, 2×2/4-Spalten responsive, minmax(0,1fr) |
✓ behoben, User bestätigt |
3. Umgesetzte Dateien
Backend (neu)
| Datei | Zweck |
|---|---|
backend/data_layer/ |
Read-Models: actions, initiatives, actors, workspace |
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 |
14 AP0.7-Tests |
Backend (geändert)
| Datei | Änderung |
|---|---|
backend/services/actors.py |
list_actors, get_actor |
backend/routers/actions.py |
/me/open → Data Layer |
backend/main.py |
Router actors + workspace |
backend/version.py |
0.7.0-ap0.7 |
Frontend (neu/geändert)
| Datei | Zweck |
|---|---|
frontend/src/api/workspace.js |
Workspace API-Client |
frontend/src/hooks/useActors.js |
Actor Directory + Fallback |
frontend/src/widgets/WorkspaceSummaryWidget.jsx |
Überblick-Karte |
Widgets, ActorSelect, ActionForm, InitiativeDetailPage |
Data Layer + echte Actors |
frontend/src/styles/pages.css |
Summary-Metrics (Post-QA-Fix) |
Doku
| Datei | Zweck |
|---|---|
docs/architecture/Kairo_Tenant_Invariants_v0.1.md |
Mandanten-Invarianten |
README.md |
AP0.7 API, Capabilities, Smoke-Test |
4. Tenant Hardening
Ergebnis: AP0.5-Services waren bereits tenant-sicher (tenant_id aus Context, Queries gefiltert, Cross-Tenant → 404).
AP0.7 ergänzt: Actor-Directory-Isolation, Workspace-Data-Layer-Tests, verbindliche Invarianten-Doku.
Gefundene Mandantenrisiken: Keine neuen Lücken. Actor-Zuweisungen weiter über _actor_in_tenant().
5. Tenant-Invarianten
10 verbindliche Invarianten in docs/architecture/Kairo_Tenant_Invariants_v0.1.md:
- Fachliche Tabellen mit
tenant_id tenant_idaus TenantContext- Queries filtern nach
tenant_id - Fremde IDs → 404
- Assignments tenant-intern
- User ≠ Actor
- Actors tenant-scoped
- Audit mit
tenant_id - Neue Tabellen: Tenant-Entscheidung
- Router delegieren an Services/Data Layer
6. Actor Directory
| Endpoint | Capability | Verhalten |
|---|---|---|
GET /api/actors |
kairo.actor.read |
Aktive Tenant-Actors; Filter actor_type, q, include_inactive |
GET /api/actors/{id} |
kairo.actor.read |
Detail; Cross-Tenant → 404 |
Response: { id, name, actor_type, is_active } — ohne user_id.
Grants kairo.actor.read: Portal Admin/User, Tenant Owner/Admin/Member — für Assignment-UI und Workload für alle operativen Mitglieder.
7. ActorSelect / Assignment UX
useActors()lädt/api/actors- Mehrfachauswahl, Typ-Labels (Mensch, Agent, …)
- Fallback auf Human Actor bei API-Fehler
- Loading/Error/Empty States
- Agents/Working Groups aus dem Tenant zuweisbar
8. Data Layer Struktur
backend/data_layer/
actions.py — get_my_open_actions, get_my_blocked_actions
initiatives.py — get_active_initiatives
actors.py — get_actor_workload
workspace.py — get_workspace_summary
| Schicht | Verantwortung |
|---|---|
| Router | HTTP, Capability-Gates |
| Data Layer | Read-Aggregation, tenant-scoped |
| Services | Write/CRUD, Audit |
9. Workspace Summary
GET /api/workspace/summary:
{
"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)
- Tenant-weit: aktive/pausierte Vorhaben
Frontend: WorkspaceSummaryWidget — volle Grid-Breite, responsive 2×2 / 4 Spalten.
10. Actor Workload Basic
GET /api/workspace/actors/workload — Counts pro Actor (open, blocked, in_progress).
Nur API — kein UI-Widget in AP0.7 (bewusst für AP0.8).
11. Neue/geänderte API-Endpunkte
| Endpoint | Methode | Capability |
|---|---|---|
/api/actors |
GET | kairo.actor.read |
/api/actors/{id} |
GET | kairo.actor.read |
/api/workspace/summary |
GET | kairo.workspace.read |
/api/workspace/actions/open |
GET | kairo.workspace.read |
/api/workspace/actions/blocked |
GET | kairo.workspace.read |
/api/workspace/initiatives/active |
GET | kairo.workspace.read |
/api/workspace/actors/workload |
GET | kairo.workspace.read |
12. Capability-Nutzung
| Capability | Neu | Grants |
|---|---|---|
kairo.actor.read |
✓ | Member+ |
kairo.workspace.read |
✓ | Member+ |
Gesamt: 18 Capabilities (vorher 16). Kein separates kairo.workspace.metrics.read.
13. Audit-Härtung / actor_id-Bewertung
| Frage | Antwort |
|---|---|
actor_id als Spalte jetzt? |
Nein — Migration 007 + Backfill → AP0.8 |
Reicht details? |
✓ für Assignments (actor_ids) |
| Risiko | Gering für Sprint 0 |
14. Frontend-Integration
| Widget | Datenquelle (nach AP0.7) |
|---|---|
| WorkspaceSummaryWidget | /api/workspace/summary |
| MyOpenActionsWidget | /api/workspace/actions/open |
| BlockedActionsWidget | /api/workspace/actions/blocked |
| InitiativesWidget | /api/workspace/initiatives/active?limit=5 |
| ActorSelect | /api/actors |
Keine fachliche KPI-Berechnung in Widgets.
15. Übernommene Muster aus Mitai
- Zentrale Data-Layer-Schicht
- Widgets konsumieren vorbereitete Daten
- Trennung Rohdaten / Kennzahlen / UI
16. Übernommene Muster aus Shinkan
- Tenant-sichere Queries
- Capability Gates
- Cross-Tenant → 404
- Access-Layer-Denken
17. Bewusst nicht übernommene Muster
- Analytics-Plattform, Forecasting, KI
- Actor-Admin-UI
audit_log.actor_idMigration- Backend-Widget-Registry
- Actor Workload UI-Widget
18. Abweichungen von der Spezifikation
| Thema | Abweichung | Begründung |
|---|---|---|
| Actor Workload | nur API | UI in AP0.8 |
/api/actions/me/open |
beibehalten | Abwärtskompatibilität |
done_actions_recent_count |
7-Tage-Fenster | pragmatisch via updated_at |
19. Offene Entscheidungen
audit_log.actor_id— Migration AP0.8?- Actor Workload Widget — wann sichtbar?
- Initiative bearbeiten in UI — PATCH existiert
- Foundation Audit/Admin-UI — backlog
20. Empfehlung für AP0.8
- Audit/Admin minimal — Audit-Log lesbar, optional
actor_id-Spalte - Actor Workload Widget — kleine Karte im Workspace
- Initiative bearbeiten in UI
- Kommentare pro Maßnahme (optional)
Danach Sprint-1-Fachscope gemäß Product Spec.
Manueller Smoke-Test (Referenz)
- Login → Workspace → Überblick mit 4 Kennzahlen, kein Overflow
- Offene / blockierte Maßnahmen in separaten Widgets
- Vorhaben-Detail → Maßnahme anlegen → mehrere Actors in ActorSelect
- Agent zuweisen → speichern → Assignment sichtbar
- Status blocked → erscheint nur im Blockiert-Widget
- API:
curl /api/actors,/api/workspace/summarymit Token
Abnahme-Checkliste AP0.7 (final)
| Kriterium | Erfüllt |
|---|---|
| Tenant-Invarianten | ✓ |
| Actor Directory | ✓ |
| Data Layer | ✓ |
| Workspace Summary | ✓ |
| Frontend Integration | ✓ |
| Tests grün | ✓ |
| AP0.6b UX | ✓ |
| Post-QA Überblick-Fix | ✓ |