2 Commits

Author SHA1 Message Date
Knacky
55f993fa24 fix(backend): sprint 5 post-review — name fallback, isinstance guards, 400 tests
- create_simulation: name falls back to template.name when template_id provided
  and name is absent/empty (AC-27.1)
- templates POST/PATCH: isinstance(list) check on technique_ids/tactic_ids
  before resolving, returns 400 with clear message
- 5 new tests: unknown technique_id → 400 (POST+PATCH), unknown tactic_id → 400
  (POST+PATCH), name fallback to template.name
- mypy: merged template branch into if/else to eliminate union-attr false positives

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 07:04:25 +02:00
Knacky
1f327e9aa8 feat(backend): sprint 5 — SimulationTemplate CRUD + instantiation
- SimulationTemplate model + migration 0005 (CREATE TABLE + name index)
- 5 CRUD endpoints under /api/templates (admin|redteam only, SOC 403)
- POST /api/engagements/<eid>/simulations extended with optional template_id
- serialize_template() reusing _enrich_techniques/_enrich_tactics helpers
- IntegrityError → 409 for duplicate name on both POST and PATCH
- 28 new tests (CRUD, RBAC, dedup, instantiation, migration round-trip)
- 221 tests pass; ruff clean; mypy clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 06:25:19 +02:00