v0.23.0 — ### Added
- **Poll-now button** on each watchlist row — calls `POST /api/watched-reports/{code}/poll` which wraps `ingest_report` + `ingest_events_for_report` with proper commits and per-ca…
- Poll-now button on each watchlist row — calls
POST /api/watched-reports/{code}/pollwhich wrapsingest_report+ingest_events_for_reportwith proper commits and per-call error capture, so users never hit the half-committed-session footgun (the bug that broke FRU dev ingest twice during T-103/T-104). Synchronous: returns only after the ingest finishes (or fails). UI shows a per-row status snippet ("ingested · fights+208 · events+29725" / "already complete · no work" / error message). jobs/poll_watched.pyrefactored:_poll_one_row()extracted as the canonical ingest-one-report path;poll_once()and the newpoll_one_by_code()both go through it. 50-line dedup.- 2 new API tests for the Poll-now endpoint (404 when not watching; skips-complete behavior). 192 tests total.
Changed
DEFAULT_ENCOUNTERSinjobs/backfill_field.pyexpanded to include TOP (1068) and DSR (1065) alongside FRU (1079) + current Savage tier (101–105). Verified encounter IDs against FFLogs'worldData.encounter(id).name. Other ultimates (TEA=1075, UWU=1074, UCoB=1073) documented in the comment for one-line future addition.FieldStats.jsxencounter-name lookup table updated to renderTOP/DSRinstead of raw IDs.
Scheduled (no code)
- T-109 — Tighten T-004's combatant filter for Ultimate reports. PLAN §11 Phase 1 table updated. Captured in IDEAS.md: T-004's
type == "Player"filter onmasterData.actorslets ~12k NPC actors leak through per Ultimate report (verified on FRU: 208 fights × ~12k = 2.5M combatant rows). Fix: intersect masterData with the per-fight active-source set during ingest, dropping rows that never appear assource_idin cast/damage events. Workarounds in T-203/T-206 still function after the fix; they just become redundant.