No description
Stage 11 backend (services/team_shape.py + api/team_shape.py):
- Ports V1's calculate_team_shape with the bug-4 fix already applied:
total_hours / manual_override on RatecardLine are per-1-asset; the
aggregator multiplies by line.volume.
- Programme roles never see efficiency cuts. Per-discipline efficiency
is capped at MAX_EFFICIENCY (90%).
- GET /opportunities/{id}/team-shape supports two modes:
* `efficiency_pct=N` blanket reduction across delivery roles, OR
* `discipline_overrides=<JSON>` per-discipline rates (Stage 10
efficiency profile output).
- Smoke-tested: 5,620.5 hrs / 3.12 FTE on the Versuni opportunity;
applying efficiency_pct=50 correctly halves to 2,810.25 hrs / 1.56 FTE.
Stage 11 frontend (Stage11TeamShape.tsx + api/teamShape.ts):
- Stats card (total / delivery / programme / adjusted FTE).
- Blanket efficiency slider 0–90% (disabled when per-discipline mode is
active so the two modes don't fight).
- One slider card per discipline showing live percentage; clearing all
reverts to the blanket slider.
- Per-discipline FTE table with Total hrs / FTE / Eff% / Adjusted hrs /
Adjusted FTE columns. Programme roles tagged with a badge.
Stage 6/7/8 backend tests (parallel test agent, +27 tests):
- test_assets.py (10): CRUD + sort_order auto-increment + cascade
delete + 400/404 paths + skipped real-Claude normalize.
- test_matching.py (10): 400 on no-assets, GET shape + ordering,
selection toggle deselects siblings, deselect leaves siblings alone,
cross-opp 404, skipped real-Claude run.
- test_ratecard.py (7): 400/404 paths, end-to-end build+get with the
bug-4 invariant explicitly asserted (line.base_hours == total_hours;
summary.total_hours == sum(base × volume)), no-selection skip,
rebuild idempotence, two-asset volume aggregation splits 1:2.
Suite: 100 collected, 95 passed, 5 skipped (all real-Anthropic), 0 failed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| backend | ||
| frontend | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||