v0.28.0 — **Phase 3 begins**
- **`analysis/strat_config.py`** — canonical JSON shapes + validators + CRUD helpers. Decisions captured 2026-05-24: - **mit_plan = structured slots**: `{slots: [{ability_id, expe…
Added — T-301 strat_config editor
analysis/strat_config.py— canonical JSON shapes + validators + CRUD helpers. Decisions captured 2026-05-24:- mit_plan = structured slots:
{slots: [{ability_id, expected_role, window_offset_ms}, …]}.expected_roleis one of the 8 FFXIV roles (MT/OT/H1/H2/D1/D2/D3/D4),"any", or null. - assignments = role-based:
{role_map: {slot_name: role}}where role is in the same set. - mechanic_ref = compound
"{ability_game_id}_{occurrence_idx}"— explicitly per-occurrence so Akh Morn x4 can carry distinct mit plans per cast (user noted recurring mechanics don't necessarily share mit plans).
- mit_plan = structured slots:
- Schema reuses the existing
strat_configtable (T-003 created it). No migration needed. - API:
GET /api/encounters/{id}/strat-config(list + role catalog),GET .../{mechanic_ref}(one),PUT .../{mechanic_ref}(upsert),DELETE .../{mechanic_ref}. All validation errors return 422 with detail. - React
StratEditor.jsxmounted as a third sub-tab in Encounters (alongside Fight map / Compare):- Mechanic picker on the left — defaults to raidwide/tankbuster/aoe_party/enrage (the ones likely to need a strat), "show all mechanics" toggle for the full list. Configured mechanics get a ★ marker.
- Per-mechanic editor on the right — mit-slot table (ability dropdown sourced from T-108's
mit_party/mit_self/mit_boss_debufflabels), assignment table forslot_name → role. Save / Delete buttons; per-save status pill.
- 18 new tests (9 pure-function: encoding/decoding/validation; 9 API: CRUD + compound-key separation + replacement + 404 + validation errors). 231 tests total.
Scheduled
- T-309 Drag-and-drop visual strat editor — polish on T-301's form-based editor. Captured in IDEAS.md + scheduled in PLAN §11 Phase 3 (not gating 1.0.0). Defer until T-301's form-based editor proves to be the bottleneck.