v0.17.0 — ### Added
- **T-101** Live polling of the static's open reports — **manual watchlist** strategy (decision recorded 2026-05-24 in IDEAS.md). User pastes a report code or FFLogs URL; the poll…
- T-101 Live polling of the static's open reports — manual watchlist strategy (decision recorded 2026-05-24 in IDEAS.md). User pastes a report code or FFLogs URL; the poller fetches new fights+events on its next pass.
- New
watched_reportstable (alembic51d86f5d4e40):codePK,label,active,added_at,last_polled_at,last_error. 15 tables in dev DB. jobs/poll_watched.py::poll_once(session, client)— iterates active rows, calls existing T-004ingest_report+ T-005ingest_events_for_report(with explicit commits per the bug discovered shipping T-103). Skips ledger-completerows so no API calls are wasted (PLAN Invariant 1). Errors are captured per-row inlast_errorrather than crashing the pass.python -m jobs.poll_watchedruns one pass — user wraps in cron/Task Scheduler for periodic execution.- CRUD routes:
GET /api/watched-reports,POST(accepts bare code or fullhttps://www.fflogs.com/reports/<code>URL — regex-extracts the code),PATCH /api/watched-reports/{code}(toggle active, edit label),DELETE /api/watched-reports/{code}. 409 on duplicate watch, 404 on unknown, 422 on empty input. - React
WatchedReports.jsxpanel mounted at the top of the Reports tab — input form, per-row toggle (active/paused) and remove, last-poll timestamp + last-error display, code+label list with monospace code display. - 13 new tests (9 API + 4 poller with mocked FFLogsClient covering empty-watchlist / complete-skip / inactive-skip / error-capture). 158 tests total passing.
Deployment shape
- One-shot script + cron rather than in-process scheduler — keeps the FastAPI server focused on serving requests and lets the user choose cadence externally. For dev:
python -m jobs.poll_watched. For prod: wrap in cron / Task Scheduler / a while-loop, whatever fits the host.