8c9ba5363c
All Workstream C–F tasks completed: - C: drag+selection conflict fix (FloatingActionBar clears on drag start) - D: SSE edge-case tests (hide-during-reconnect, first-ever-failure) - E: scenario module unit tests — 31 tests across all 4 scenario modules - F: .env.example expanded, plan and roadmap updated Co-Authored-By: claude-flow <ruv@ruv.net>
81 lines
4.3 KiB
Markdown
81 lines
4.3 KiB
Markdown
# Plan: Scenario Regression Depth + Housekeeping
|
|
|
|
Stand: 2026-04-02
|
|
|
|
---
|
|
|
|
# Workstream E: Scenario Regression Depth
|
|
|
|
## Anforderungsanalyse
|
|
|
|
Vier Szenario-Module haben **keine direkten Unit-Tests**:
|
|
|
|
| Datei | Inhalt | Lücke |
|
|
|-------|--------|-------|
|
|
| `scenario-shared.ts` | Pure helpers: `roundToTenths`, `getScenarioAvailability`, `collectScenarioSkillSet`, `calculateScenarioEntryHours` | Keine Tests |
|
|
| `scenario-baseline.ts` | `readProjectScenarioBaseline` — lädt Assignments/Demands, berechnet Kosten/Stunden | Keine Tests |
|
|
| `scenario-apply.ts` | `applyProjectScenario` — CANCELLED/update/create Branches, appliedCount | Keine Tests |
|
|
| `scenario-simulation.ts` | `simulateProjectScenario` — Baseline vs. Szenario-Delta, Warnungen, Skill-Coverage | Keine Tests |
|
|
|
|
Bestehende Coverage: `scenario-router.test.ts` (Auth-Guards), `scenario-procedure-support.test.ts` (Delegation), `assistant-tools-scenarios.test.ts` (1 Integration-Test) — alles Delegation, keine Business-Logik.
|
|
|
|
## Betroffene Pakete & Dateien
|
|
|
|
| Paket | Datei | Art |
|
|
|-------|-------|-----|
|
|
| `packages/api` | `src/__tests__/scenario-shared.test.ts` | create |
|
|
| `packages/api` | `src/__tests__/scenario-apply.test.ts` | create |
|
|
| `packages/api` | `src/__tests__/scenario-baseline.test.ts` | create |
|
|
| `packages/api` | `src/__tests__/scenario-simulation.test.ts` | create |
|
|
|
|
## Task-Liste
|
|
|
|
- [x] **E-1a:** `scenario-shared.test.ts` — Pure-Helper-Tests (keine Mocks außer resource-capacity)
|
|
- `roundToTenths`: 0.15 → 0.2, 0.34 → 0.3, ganzer Integer bleibt
|
|
- `getScenarioAvailability`: null → DEFAULT_AVAILABILITY; valides Objekt wird durchgereicht
|
|
- `collectScenarioSkillSet`: null → leeres Set; leeres Array → leeres Set; doppelte Skills dedupliziert; lowercase-Normalisierung; leere Strings gefiltert; Mixed case dedupliziert
|
|
- `calculateScenarioEntryHours`: ohne resourceId → delegiert an `calculateAllocation`; mit resourceId → delegiert an `calculateEffectiveBookedHours`
|
|
- Mock: `@capakraken/engine/allocation` und `../lib/resource-capacity.js`
|
|
|
|
- [x] **E-1b:** `scenario-apply.test.ts` — CRUD-Branch-Tests
|
|
- NOT_FOUND wenn `project.findUnique` null zurückgibt
|
|
- `remove: true` + `assignmentId` → `assignment.update` mit `status: "CANCELLED"`, appliedCount = 0 (cancel trifft `continue` vor `created.push`)
|
|
- `assignmentId` ohne remove → `assignment.update` mit neuen Daten, appliedCount = 1
|
|
- kein `assignmentId`, kein `resourceId` → Zeile wird übersprungen, appliedCount = 0
|
|
- kein `assignmentId`, hat `resourceId` → `assignment.create` mit korrektem `dailyCostCents`, appliedCount = 1
|
|
- Mehrere Changes → korrekter appliedCount summiert
|
|
|
|
- [x] **E-1c:** `scenario-baseline.test.ts` — Baseline-Lade-Tests
|
|
- NOT_FOUND wenn Projekt nicht gefunden
|
|
- Leeres Projekt (keine Assignments, keine Demands) → `totalCostCents: 0`, `totalHours: 0`, `assignments: []`, `demands: []`
|
|
- Assignment mit bekanntem `lcrCents` und `hoursPerDay` → `costCents` korrekt berechnet
|
|
- CANCELLED Assignments werden herausgefiltert (kommen nicht in `baselineAllocations`)
|
|
- Demands werden korrekt gemappt (kein `costCents`, hat `headcount`, `roleName` aus roleEntity)
|
|
- `totalCostCents` ist Summe aller Assignment-`costCents`
|
|
|
|
- [x] **E-1d:** `scenario-simulation.test.ts` — Simulations-Logik-Tests
|
|
- NOT_FOUND wenn Projekt nicht gefunden
|
|
- remove-Change → Assignment fehlt im Scenario-headcount (`delta.headcount < 0`)
|
|
- Neues Assignment hinzufügen → `delta.headcount > 0`
|
|
- Budget-Warnung wenn `scenarioCostCents > budgetCents` → warnings enthält "exceeds budget"
|
|
- Skill-Coverage: Szenario mit mehr Skills → `delta.skillCoveragePct > 100`
|
|
- Szenario ohne Änderungen aber mit bestehenden Assignments → `delta.costCents = 0`, `delta.hours = 0`
|
|
|
|
## Abhängigkeiten
|
|
|
|
- E-1a und E-1b können **parallel** geschrieben werden (separate Dateien)
|
|
- E-1c und E-1d können **parallel** geschrieben werden
|
|
- Keine Abhängigkeiten zwischen allen vier
|
|
|
|
## Akzeptanzkriterien
|
|
|
|
- [x] `pnpm test:unit` läuft grün
|
|
- [x] Alle 4 neuen Test-Dateien existieren mit ≥ 4 Tests jeweils (4 Dateien, 31 Tests, alle grün)
|
|
|
|
---
|
|
|
|
# Workstream F: .env.example + Docs Housekeeping
|
|
|
|
- [x] **F-1:** `.env.example` committen (commit 1ec56aa — erweitert auf ~85 Zeilen mit vollständiger Dokumentation)
|
|
- [x] **F-2:** `plan.md` nach Abschluss mit erledigten Tasks aktualisieren
|