Doku AP0.7: Abschlussbericht v0.2 (final) mit DoD-Matrix und QA-Fix
All checks were successful
Deploy Development / deploy (push) Successful in 48s
Test Suite / pytest-backend (push) Successful in 42s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 12s
All checks were successful
Deploy Development / deploy (push) Successful in 48s
Test Suite / pytest-backend (push) Successful in 42s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 12s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
02b3b17269
commit
a01457debb
|
|
@ -219,7 +219,7 @@ cd frontend && npm install && npm run test && npm run build
|
||||||
6. PWA: Manifest unter `/manifest.webmanifest` erreichbar; „App installieren“ im Browser prüfbar
|
6. PWA: Manifest unter `/manifest.webmanifest` erreichbar; „App installieren“ im Browser prüfbar
|
||||||
7. AP0.7: ActorSelect lädt `/api/actors`; Maßnahme einem Agent zuweisen; Workspace-Überblick sichtbar
|
7. AP0.7: ActorSelect lädt `/api/actors`; Maßnahme einem Agent zuweisen; Workspace-Überblick sichtbar
|
||||||
|
|
||||||
Abschlussberichte: `docs/sprints/Sprint0_AP0_6_Completion_Report_v0.1.md`, `docs/sprints/Sprint0_AP0_6b_Completion_Report_v0.2.md`, `docs/sprints/Sprint0_AP0_7_Completion_Report_v0.1.md`
|
Abschlussberichte: `docs/sprints/Sprint0_AP0_6_Completion_Report_v0.1.md`, `docs/sprints/Sprint0_AP0_6b_Completion_Report_v0.2.md`, `docs/sprints/Sprint0_AP0_7_Completion_Report_v0.2.md`
|
||||||
|
|
||||||
### Registries (AP0.4)
|
### Registries (AP0.4)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,342 +0,0 @@
|
||||||
# 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 | ✓ |
|
|
||||||
342
docs/sprints/Sprint0_AP0_7_Completion_Report_v0.2.md
Normal file
342
docs/sprints/Sprint0_AP0_7_Completion_Report_v0.2.md
Normal file
|
|
@ -0,0 +1,342 @@
|
||||||
|
# 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`:
|
||||||
|
|
||||||
|
1. Fachliche Tabellen mit `tenant_id`
|
||||||
|
2. `tenant_id` aus TenantContext
|
||||||
|
3. Queries filtern nach `tenant_id`
|
||||||
|
4. Fremde IDs → 404
|
||||||
|
5. Assignments tenant-intern
|
||||||
|
6. User ≠ Actor
|
||||||
|
7. Actors tenant-scoped
|
||||||
|
8. Audit mit `tenant_id`
|
||||||
|
9. Neue Tabellen: Tenant-Entscheidung
|
||||||
|
10. 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
|
||||||
|
|
||||||
|
```text
|
||||||
|
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`:
|
||||||
|
|
||||||
|
```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)
|
||||||
|
- 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_id` Migration
|
||||||
|
- 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
|
||||||
|
|
||||||
|
1. `audit_log.actor_id` — Migration AP0.8?
|
||||||
|
2. Actor Workload Widget — wann sichtbar?
|
||||||
|
3. Initiative bearbeiten in UI — PATCH existiert
|
||||||
|
4. Foundation Audit/Admin-UI — backlog
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 20. Empfehlung für AP0.8
|
||||||
|
|
||||||
|
1. **Audit/Admin minimal** — Audit-Log lesbar, optional `actor_id`-Spalte
|
||||||
|
2. **Actor Workload Widget** — kleine Karte im Workspace
|
||||||
|
3. **Initiative bearbeiten in UI**
|
||||||
|
4. **Kommentare pro Maßnahme** (optional)
|
||||||
|
|
||||||
|
Danach Sprint-1-Fachscope gemäß Product Spec.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Manueller Smoke-Test (Referenz)
|
||||||
|
|
||||||
|
1. Login → Workspace → **Überblick** mit 4 Kennzahlen, kein Overflow
|
||||||
|
2. Offene / blockierte Maßnahmen in separaten Widgets
|
||||||
|
3. Vorhaben-Detail → Maßnahme anlegen → **mehrere Actors** in ActorSelect
|
||||||
|
4. Agent zuweisen → speichern → Assignment sichtbar
|
||||||
|
5. Status blocked → erscheint nur im Blockiert-Widget
|
||||||
|
6. API: `curl /api/actors`, `/api/workspace/summary` mit 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 | ✓ |
|
||||||
Loading…
Reference in New Issue
Block a user