feat: Activity History system — full audit coverage, UI, AI tools
Infrastructure (Phase 1): - AuditLog schema: add source, entityName, summary fields + index - createAuditEntry() helper: auto-diff, auto-summary, fire-and-forget - auditLog query router: list, getByEntity, getTimeline, getActivitySummary Audit Coverage (Phase 2 — 14 routers, 50+ mutations): - vacation: create, approve, reject, cancel, batch ops (8 mutations) - user: create, updateRole, setPermissions, resetPermissions (5 mutations) - entitlement: set, bulkSet (3 mutations) - client: create, update, delete, batchUpdateSortOrder - org-unit: create, update, deactivate - country: create, update, createCity, updateCity, deleteCity - management-level: createGroup, updateGroup, createLevel, updateLevel, deleteLevel - settings: updateSystemSettings (sensitive fields sanitized), testSmtp - blueprint: create, update, updateRolePresets, delete, batchDelete, setGlobal - rate-card: create, update, deactivate, addLine, updateLine, deleteLine, replaceLines - calculation-rules: create, update, delete - effort-rule: create, update, delete - experience-multiplier: create, update, delete - utilization-category: create, update Admin UI (Phase 3): - /admin/activity-log page with global searchable timeline - Filters: entity type, action, user, date range, text search - Expandable before/after diff view per entry - Summary cards showing top entity types by change count - EntityHistory reusable component for entity detail pages - Sidebar nav link with clock icon AI Assistant (Phase 4): - query_change_history tool: "Who changed project X?" - get_entity_timeline tool: "What happened to resource Y?" Regression: 283 engine + 37 staffing tests pass. TypeScript clean. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -1,125 +1,237 @@
|
||||
# Unified Skills Hub — Plan
|
||||
# Activity History System — Detailed Plan
|
||||
|
||||
## Anforderungsanalyse
|
||||
|
||||
**Was:** Die zwei getrennten Skill-Seiten (`/analytics/skills` = SkillsAnalytics, `/analytics/skill-marketplace` = SkillMarketplace) zu **einer einzigen, nutzerfreundlichen Skills-Hub-Seite** zusammenfuehren.
|
||||
**Ziel:** Ein lueckenloses Aenderungsprotokoll, das jede Mutation im System erfasst und ueber UI und AI Assistant abfragbar macht. Nutzer sollen fragen koennen: "Wer hat die Buchung von Person X geaendert?" oder "Was ist in den letzten Tagen bei Projekt Y passiert?"
|
||||
|
||||
**Problem heute:**
|
||||
- **SkillsAnalytics** (496 LOC): Skill-Tabelle mit Filtern, People Finder (AND/OR Suche), XLSX Export, Skill Distribution Chart, Skill Gap Alerts
|
||||
- **SkillMarketplace** (346 LOC): Skill-Suche mit Verfuegbarkeitsfilter, Skill Gap Heat Map (Supply vs Demand), Skill Distribution Chart (dupliziert!)
|
||||
- **Ueberlappung:** Beide haben `ProficiencyBadge`, `PROFICIENCY_CLASSES`, `SkillDistributionChart`, aehnliche Tabellen
|
||||
- **Verwirrung:** User muss zwei Seiten besuchen fuer zusammenhaengende Informationen
|
||||
- **Inkonsistenz:** Analytics hat kein Dark-Theme auf manchen Elementen, Marketplace hat es
|
||||
**Ist-Zustand:**
|
||||
- AuditLog-Modell existiert (entityType, entityId, action, userId, changes JSONB, createdAt)
|
||||
- 10 von 36 Routern loggen Aenderungen (44% Abdeckung)
|
||||
- userId wird nur in ~60% der Faelle erfasst
|
||||
- Kein Query-Endpoint (write-only)
|
||||
- Keine UI zum Anzeigen der Historie
|
||||
- AI Assistant kann keine Historie abfragen
|
||||
- Inkonsistente before/after Snapshots
|
||||
|
||||
**Ziel:** Eine Seite `/analytics/skills` mit Tab-basiertem Layout:
|
||||
**Soll-Zustand:**
|
||||
- 100% Mutation-Abdeckung ueber alle Router
|
||||
- Konsistente before/after Snapshots mit User-Attribution
|
||||
- Query-API mit Filtern (entityType, entityId, userId, dateRange, action)
|
||||
- Admin-UI: `/admin/activity-log` mit suchbarer, filterbarer Timeline
|
||||
- Entity-Detail-Seiten: "History"-Tab/-Drawer auf Project/Resource/Allocation
|
||||
- AI Assistant Tool: `query_change_history` fuer natuerlichsprachliche Abfragen
|
||||
- Change-Source Tracking: UI vs API vs AI vs Import
|
||||
|
||||
```
|
||||
+-------------------------------------------------------------+
|
||||
| Skills Hub [Export] |
|
||||
| 125 resources . 47 distinct skills |
|
||||
+----------+----------+----------+-------------+--------------+
|
||||
| Overview | Search | Gaps | People | Distribution |
|
||||
+----------+----------+----------+-------------+--------------+
|
||||
| |
|
||||
| [Tab content area] |
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
---
|
||||
|
||||
## Architektur-Entscheidungen
|
||||
|
||||
### 1. Audit Middleware statt manuelle Calls
|
||||
**Entscheidung:** tRPC Middleware die automatisch vor/nach jeder Mutation auditiert
|
||||
**Grund:** Eliminiert vergessene `auditLog.create()` Calls, garantiert 100% Abdeckung
|
||||
**Umsetzung:** Middleware auf `protectedProcedure` die:
|
||||
- Vor der Mutation: Entity-Snapshot speichert (before)
|
||||
- Nach der Mutation: Neuen Snapshot speichert (after)
|
||||
- Diff berechnet und AuditLog-Entry erstellt
|
||||
|
||||
### 2. Standardisiertes Changes-Format
|
||||
```typescript
|
||||
interface AuditChanges {
|
||||
before?: Record<string, unknown>; // Snapshot vor der Aenderung
|
||||
after?: Record<string, unknown>; // Snapshot nach der Aenderung
|
||||
diff?: Record<string, { old: unknown; new: unknown }>; // Nur geaenderte Felder
|
||||
metadata?: {
|
||||
source: "ui" | "api" | "ai" | "import" | "cron"; // Wer hat die Aenderung ausgeloest
|
||||
reason?: string; // Optionaler Kommentar
|
||||
ip?: string; // Request IP (optional)
|
||||
batchId?: string; // Fuer Bulk-Operationen
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Betroffene Pakete & Dateien
|
||||
### 3. Schema-Erweiterungen
|
||||
```prisma
|
||||
model AuditLog {
|
||||
// Existierende Felder behalten
|
||||
id String @id @default(cuid())
|
||||
entityType String
|
||||
entityId String
|
||||
action AuditAction
|
||||
userId String?
|
||||
user User? @relation(fields: [userId], references: [id])
|
||||
changes Json @db.JsonB
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
// NEU: Zusaetzliche Felder
|
||||
source String? // "ui" | "api" | "ai" | "import" | "cron"
|
||||
entityName String? // Menschenlesbarer Name (z.B. "Porsche Taycan Project")
|
||||
summary String? // Einzeiler: "Changed status from DRAFT to ACTIVE"
|
||||
|
||||
@@index([entityType, entityId])
|
||||
@@index([userId])
|
||||
@@index([createdAt])
|
||||
@@index([entityType, createdAt]) // NEU: Fuer sortierte Timeline-Queries
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Betroffene Pakete & Dateien
|
||||
|
||||
| Paket | Dateien | Art der Aenderung |
|
||||
|-------|---------|------------------|
|
||||
| `apps/web` | `src/components/analytics/SkillsHub.tsx` | **create** — neue unified component |
|
||||
| `apps/web` | `src/components/analytics/skills/OverviewTab.tsx` | **create** — KPI cards + distribution chart |
|
||||
| `apps/web` | `src/components/analytics/skills/SearchTab.tsx` | **create** — skill search + availability (from Marketplace) |
|
||||
| `apps/web` | `src/components/analytics/skills/GapsTab.tsx` | **create** — supply/demand gap analysis (from Marketplace) |
|
||||
| `apps/web` | `src/components/analytics/skills/PeopleFinderTab.tsx` | **create** — AND/OR skill search (from Analytics) |
|
||||
| `apps/web` | `src/components/analytics/skills/shared.tsx` | **create** — ProficiencyBadge, GapIndicator, constants |
|
||||
| `apps/web` | `src/app/(app)/analytics/skills/page.tsx` | **edit** — render SkillsHub statt SkillsAnalytics |
|
||||
| `apps/web` | `src/app/(app)/analytics/skill-marketplace/page.tsx` | **edit** — redirect to /analytics/skills |
|
||||
| `apps/web` | `src/components/layout/AppShell.tsx` | **edit** — remove "Skill Marketplace" nav link |
|
||||
| `packages/api` | `src/router/resource.ts` | **edit** — add unified getSkillsHub query |
|
||||
| `packages/db` | `prisma/schema.prisma` | **edit** — AuditLog um source, entityName, summary erweitern |
|
||||
| `packages/api` | `src/lib/audit.ts` | **create** — `createAuditEntry()` Helper + `auditMiddleware` |
|
||||
| `packages/api` | `src/router/audit-log.ts` | **create** — Query-Router (list, getByEntity, getTimeline) |
|
||||
| `packages/api` | `src/router/index.ts` | **edit** — auditLog Router registrieren |
|
||||
| `packages/api` | `src/router/assistant-tools.ts` | **edit** — `query_change_history` Tool hinzufuegen |
|
||||
| `packages/api` | 26 Router-Dateien | **edit** — fehlende audit Calls nachruesten |
|
||||
| `apps/web` | `src/app/(app)/admin/activity-log/page.tsx` | **create** — Activity Log Seite |
|
||||
| `apps/web` | `src/components/admin/ActivityLogClient.tsx` | **create** — Suchbare Timeline |
|
||||
| `apps/web` | `src/components/ui/EntityHistory.tsx` | **create** — Wiederverwendbare History-Komponente |
|
||||
| `apps/web` | `src/components/layout/AppShell.tsx` | **edit** — Nav-Link fuer Activity Log |
|
||||
|
||||
### Task-Liste
|
||||
---
|
||||
|
||||
- [ ] **Task 1:** Shared utilities extrahieren -> `skills/shared.tsx`
|
||||
- `ProficiencyBadge`, `GapIndicator`, `PROFICIENCY_CLASSES`, `PROFICIENCY_LABELS`, `proficiencyClasses()`
|
||||
- Einmal definieren, ueberall nutzen
|
||||
## Task-Liste (atomare Schritte)
|
||||
|
||||
- [ ] **Task 2:** API: neuen `getSkillsHub` Query -> `resource.ts`
|
||||
- Kombiniert alle Daten in einem Call:
|
||||
- `aggregated` (from getSkillsAnalytics)
|
||||
- `searchResults` (from getSkillMarketplace)
|
||||
- `gapData` (from getSkillMarketplace)
|
||||
- `distribution` (from both, dedupliziert)
|
||||
- `totalResources`, `totalSkillEntries`
|
||||
- Alte Queries behalten (AI Assistant nutzt sie)
|
||||
### Phase 1: Infrastruktur (Basis)
|
||||
|
||||
- [ ] **Task 3:** OverviewTab bauen -> `skills/OverviewTab.tsx`
|
||||
- KPI Cards: Total Resources, Total Skills, Avg Proficiency, Skill Gaps Count
|
||||
- Top 10 Skills Tabelle (sortierbar)
|
||||
- Skill Distribution Chart (lazy-loaded)
|
||||
- Quick filters: Category, Min Count
|
||||
- [ ] **Task 1:** Schema erweitern → `packages/db/prisma/schema.prisma`
|
||||
- `source String?`, `entityName String?`, `summary String?` hinzufuegen
|
||||
- Index `@@index([entityType, createdAt])` hinzufuegen
|
||||
- `prisma db push` + `prisma generate`
|
||||
|
||||
- [ ] **Task 4:** SearchTab bauen -> `skills/SearchTab.tsx`
|
||||
- Skill name Suche (debounced)
|
||||
- Min Proficiency Filter (1-5 Buttons)
|
||||
- "Available in 30 days" Toggle
|
||||
- Ergebnis-Tabelle: Resource, Chapter, Skill, Proficiency, Utilization, Available From
|
||||
- Links zu `/resources/[id]`
|
||||
- [ ] **Task 2:** Audit Helper erstellen → `packages/api/src/lib/audit.ts`
|
||||
- `createAuditEntry(db, params)` — standardisierter Audit-Entry-Creator
|
||||
- Params: `{ entityType, entityId, entityName, action, userId, before?, after?, source?, summary? }`
|
||||
- Automatische Diff-Berechnung wenn before + after vorhanden
|
||||
- Automatische Summary-Generierung aus Diff (z.B. "Updated name, status, budgetCents")
|
||||
- `computeDiff(before, after)` — gibt nur geaenderte Felder zurueck
|
||||
|
||||
- [ ] **Task 5:** GapsTab bauen -> `skills/GapsTab.tsx`
|
||||
- Supply vs Demand Tabelle
|
||||
- Supply/Demand Bar Visualisierung
|
||||
- Gap Indicator (shortage/surplus/balanced)
|
||||
- Sortierbar nach groesstem Gap
|
||||
- Click auf Skill -> fuellt Search Tab
|
||||
- [ ] **Task 3:** Query Router erstellen → `packages/api/src/router/audit-log.ts`
|
||||
- `list` query (controllerProcedure): paginiert, filterbar nach entityType, entityId, userId, action, dateRange, source
|
||||
- `getByEntity` query: alle Entries fuer eine Entity, chronologisch
|
||||
- `getTimeline` query: globale Timeline aller Aenderungen, gruppierbar nach Tag
|
||||
- `getActivitySummary` query: Zusammenfassung (counts pro entityType, pro action, pro User) fuer einen Zeitraum
|
||||
- Registrieren in `router/index.ts`
|
||||
|
||||
- [ ] **Task 6:** PeopleFinderTab bauen -> `skills/PeopleFinderTab.tsx`
|
||||
- Multi-rule Builder: Skill + Min Proficiency pro Regel
|
||||
- AND/OR Operator Toggle
|
||||
- Chapter Filter
|
||||
- Ergebnis-Tabelle mit Match Score
|
||||
- XLSX Export Button
|
||||
### Phase 2: Audit-Abdeckung erweitern
|
||||
|
||||
- [ ] **Task 7:** SkillsHub zusammenfuegen -> `SkillsHub.tsx`
|
||||
- Tab Navigation (Overview, Search, Gaps, People Finder)
|
||||
- Header mit KPI Summary + Export Button
|
||||
- Tab State via URL search params
|
||||
- Lazy-load Tabs fuer Performance
|
||||
- [ ] **Task 4:** Kritische Router nachruesteen (Parallel-fähig, 4 Agents)
|
||||
- **Agent A:** `vacation.ts` (8 Mutations), `entitlement.ts` (2), `user.ts` (9)
|
||||
- **Agent B:** `client.ts` (5), `org-unit.ts` (3), `country.ts` (5), `management-level.ts` (5)
|
||||
- **Agent C:** `rate-card.ts` (7), `blueprint.ts` (6), `settings.ts` (3), `calculation-rules.ts` (3)
|
||||
- **Agent D:** `webhook.ts` (4), `comment.ts` (3), `notification.ts` (nur create/task), `dispo.ts` (4)
|
||||
- Jeder Agent: `import { createAuditEntry } from "../lib/audit.js"` verwenden
|
||||
- userId immer aus `ctx.dbUser?.id` nehmen
|
||||
|
||||
- [ ] **Task 8:** Routing + Navigation aktualisieren
|
||||
- `/analytics/skills/page.tsx` -> rendert `<SkillsHub />`
|
||||
- `/analytics/skill-marketplace/page.tsx` -> redirect zu `/analytics/skills?tab=search`
|
||||
- AppShell: "Skill Marketplace" entfernen, "Skills Analytics" umbenennen zu "Skills Hub"
|
||||
- [ ] **Task 5:** Bestehende Audit-Calls standardisieren
|
||||
- Alle 37 existierenden `auditLog.create` Calls auf `createAuditEntry()` Helper umstellen
|
||||
- userId konsistent aus Context nehmen
|
||||
- before/after Snapshots wo fehlend ergaenzen
|
||||
- `source: "ui"` als Default setzen
|
||||
|
||||
- [ ] **Task 9:** Dark Theme durchgaengig
|
||||
- Alle Elemente mit `dark:` Varianten
|
||||
- Konsistenz mit dem Rest der App
|
||||
### Phase 3: UI
|
||||
|
||||
### Abhaengigkeiten
|
||||
- Task 1 muss zuerst (shared utilities fuer alle Tabs)
|
||||
- Task 2 kann parallel zu Task 1 (API aendern)
|
||||
- Tasks 3-6 koennen parallel nach Task 1 (4 Tabs, unabhaengige Dateien)
|
||||
- Task 7 benoetigt Tasks 3-6 (importiert alle Tabs)
|
||||
- Task 8 benoetigt Task 7 (Routing zeigt auf neue Komponente)
|
||||
- Task 9 kann parallel zu Task 8
|
||||
- [ ] **Task 6:** Activity Log Admin-Seite → `ActivityLogClient.tsx`
|
||||
- Globale, suchbare Timeline aller Aenderungen
|
||||
- Filter: Entity-Typ (Project/Resource/Allocation/...), User, Action, Datum
|
||||
- Jeder Eintrag zeigt: Zeitstempel, User (Avatar + Name), Entity (verlinkt), Action-Badge, Summary
|
||||
- Expandierbares Detail: before/after Diff-View (JSON oder tabellarisch)
|
||||
- Pagination (50 pro Seite)
|
||||
- Sidebar Nav-Link unter Admin: "Activity Log"
|
||||
|
||||
- [ ] **Task 7:** Entity History Komponente → `EntityHistory.tsx`
|
||||
- Wiederverwendbar fuer Project/Resource/Allocation Detail-Seiten
|
||||
- Props: `entityType: string, entityId: string`
|
||||
- Chronologische Liste der Aenderungen fuer diese Entity
|
||||
- Kompakte Darstellung: User, Action, Summary, Zeitstempel
|
||||
- Optional: als Tab oder Drawer auf Detail-Seiten einbinden
|
||||
|
||||
- [ ] **Task 8:** History-Tab auf Detail-Seiten integrieren
|
||||
- `/projects/[id]` → "History" Tab mit `<EntityHistory entityType="project" entityId={id} />`
|
||||
- `/resources/[id]` → "History" Tab
|
||||
- Optional spaeter: Allocation Detail, Estimate Detail
|
||||
|
||||
### Phase 4: AI Assistant Integration
|
||||
|
||||
- [ ] **Task 9:** AI Tool erstellen → `assistant-tools.ts`
|
||||
- `query_change_history` Tool:
|
||||
- Input: `{ entityType?, entityId?, userId?, search?, daysBack?, limit? }`
|
||||
- Ruft `auditLog.list` mit Filtern auf
|
||||
- Formatiert Ergebnis menschenlesbar:
|
||||
```
|
||||
[2026-03-22 14:30] admin@planarchy.dev UPDATED Project "Porsche Taycan"
|
||||
→ Changed status from DRAFT to ACTIVE
|
||||
→ Changed budgetCents from 500000 to 750000
|
||||
```
|
||||
- `get_entity_timeline` Tool:
|
||||
- Input: `{ entityType, entityId, limit? }`
|
||||
- Gibt chronologische History fuer eine Entity zurueck
|
||||
- Beide Tools mit Permission `VIEW_PROJECTS` oder `VIEW_RESOURCES` je nach entityType
|
||||
|
||||
---
|
||||
|
||||
## Abhaengigkeiten
|
||||
|
||||
```
|
||||
Task 1 (Schema) ──► Task 2 (Helper) ──► Task 3 (Query Router)
|
||||
└──► Task 4a-d (Parallel: 26 Router)
|
||||
└──► Task 5 (Bestehende Calls)
|
||||
Task 3 ──► Task 6 (UI: Activity Log)
|
||||
──► Task 7 (UI: Entity History)
|
||||
──► Task 9 (AI Tools)
|
||||
Task 7 ──► Task 8 (Integration in Detail-Seiten)
|
||||
```
|
||||
|
||||
- Tasks 4a-d koennen **parallel** ausgefuehrt werden (unterschiedliche Dateien)
|
||||
- Tasks 6, 7, 9 koennen **parallel** nach Task 3
|
||||
- Task 8 benoetigt Task 7
|
||||
|
||||
---
|
||||
|
||||
## Akzeptanzkriterien
|
||||
|
||||
### Akzeptanzkriterien
|
||||
- [ ] `pnpm --filter @planarchy/web exec tsc --noEmit` — keine neuen Errors
|
||||
- [ ] `/analytics/skills` zeigt die vereinte Seite mit 4 Tabs
|
||||
- [ ] `/analytics/skill-marketplace` redirected zu `/analytics/skills?tab=search`
|
||||
- [ ] Alle Features beider Seiten sind auf der neuen Seite verfuegbar
|
||||
- [ ] Dark Theme funktioniert durchgehend
|
||||
- [ ] Sidebar zeigt nur noch "Skills Hub" statt zwei Links
|
||||
- [ ] XLSX Export funktioniert weiterhin
|
||||
- [ ] People Finder AND/OR Suche funktioniert
|
||||
- [ ] Skill Gap Heat Map mit Supply/Demand funktioniert
|
||||
- [ ] Availability Filter (30 Tage) funktioniert
|
||||
- [ ] `pnpm test:unit` — alle Tests gruen
|
||||
- [ ] **100% Mutation-Abdeckung:** Jede Mutation in jedem Router erzeugt einen AuditLog-Entry
|
||||
- [ ] **Konsistente userId:** Jeder Entry hat den ausfuehrenden User
|
||||
- [ ] **before/after:** UPDATE-Actions haben immer before + after Snapshots
|
||||
- [ ] **Query-API:** `trpc.auditLog.list` liefert paginierte, filterbare Ergebnisse
|
||||
- [ ] **Admin UI:** `/admin/activity-log` zeigt globale Timeline mit Filtern
|
||||
- [ ] **Entity History:** Project/Resource Detail-Seiten zeigen Aenderungs-Historie
|
||||
- [ ] **AI Assistant:** "Wer hat die Buchung von Person X geaendert?" wird korrekt beantwortet
|
||||
- [ ] **AI Assistant:** "Was ist bei Projekt Y in den letzten Tagen passiert?" liefert Ergebnis
|
||||
|
||||
### Risiken & offene Fragen
|
||||
- **API Performance:** Ein kombinierter Query koennte langsamer sein -> Loesung: Lazy-load per Tab, Query nur wenn Tab aktiv
|
||||
- **URL State:** Aktiver Tab via `?tab=search` Query Param persistiert
|
||||
- **Export:** Nur aktiver Tab exportierbar
|
||||
- **Backwards-Kompatibilitaet:** AI Assistant Tools nutzen alte Queries -> behalten
|
||||
---
|
||||
|
||||
## Risiken & offene Fragen
|
||||
|
||||
### Risiken
|
||||
- **Performance:** Audit-Middleware auf jeder Mutation koennte Latenz erhoehen
|
||||
→ Mitigation: Audit-Writes fire-and-forget (non-blocking), oder nach Response
|
||||
- **Storage:** JSONB Snapshots koennen gross werden
|
||||
→ Mitigation: Nur geaenderte Felder in `diff` speichern, nicht volle Snapshots
|
||||
- **Migration:** 37 bestehende Calls umstellen birgt Regressions-Risiko
|
||||
→ Mitigation: Schrittweise, mit Tests pro Router
|
||||
|
||||
### Offene Fragen
|
||||
1. **Retention:** Wie lange sollen Audit-Logs aufbewahrt werden? (Vorschlag: 2 Jahre)
|
||||
2. **Granularitaet:** Sollen READ-Zugriffe geloggt werden? (Vorschlag: Nein, nur Mutations)
|
||||
3. **DSGVO:** Muessen Audit-Logs bei User-Loeschung anonymisiert werden?
|
||||
4. **Notifications:** Sollen bestimmte Aenderungen (z.B. Projekt-Status) automatisch Notifications ausloesen?
|
||||
5. **Middleware vs Manual:** Soll der Audit-Helper manuell oder als tRPC-Middleware eingebaut werden?
|
||||
→ Empfehlung: Manuell mit Helper-Funktion, da Middleware die Entity-Snapshots nicht automatisch kennt
|
||||
|
||||
---
|
||||
|
||||
## Geschaetzter Aufwand
|
||||
|
||||
| Phase | Aufwand | Parallelisierbar |
|
||||
|-------|---------|-----------------|
|
||||
| Phase 1: Infrastruktur | 1 Tag | Nein (sequenziell) |
|
||||
| Phase 2: Audit-Abdeckung | 1 Tag | Ja (4 Agents parallel) |
|
||||
| Phase 3: UI | 1 Tag | Ja (2 Agents parallel) |
|
||||
| Phase 4: AI Integration | 0.5 Tag | Ja (mit Phase 3) |
|
||||
| **Gesamt** | **~3.5 Tage** | |
|
||||
|
||||
Reference in New Issue
Block a user