2d2dda53-55ae-439d-a1d0-7a40ff9671a9 — Admin routes: history query and CSV export (Feature 16 — NestQuest API Service)
Done-condition (verbatim)
Admin routes for history: a query returning completion events for a filter (all / reversals / missed) over a date range, and a CSV export of the same filtered range. Each validates input and calls core with no business logic in the handler. Tests as an admin confirm the query returns the expected events for each filter and the CSV carries the documented columns and the filtered rows.
Changes
custom_components/nestquest/core/history.py (new) — HA-free history layer: a query over a closed date range for the all / reversals / missed filter (missed derived the domain way, never stored) and a CSV serializer over the same filtered rows with a documented, stable column set.
api/routes_admin.py — GET /api/v1/admin/history (JSON query) and GET /api/v1/admin/history.csv (same filters, text/csv attachment), thin adapters on the ONE require_admin dependency; narrow error mapping.
api/nestquest_core.py — re-exports the history module.
tests/test_api_admin_history.py (new) — seeds completions, a reversal and a past-due open (missed) instance; asserts each filter's rows and the CSV header/rows (parsed with csv.reader); non-admin refused.
Verification
TZ=UTC uv run pytest -q → 1750 passed
TZ=UTC uv run pytest -q tests/test_api_admin_history.py → 14 passed
Baseline on the feature branch: 1736 passed.
Opened by the controller on the developer's behalf after the developer's headless session ended before opening the PR; the branch and commit are the developer's (471ca2309d).
## Maestro task
`2d2dda53-55ae-439d-a1d0-7a40ff9671a9` — Admin routes: history query and CSV export (Feature 16 — NestQuest API Service)
## Done-condition (verbatim)
Admin routes for history: a query returning completion events for a filter (all / reversals / missed) over a date range, and a CSV export of the same filtered range. Each validates input and calls core with no business logic in the handler. Tests as an admin confirm the query returns the expected events for each filter and the CSV carries the documented columns and the filtered rows.
## Changes
- **custom_components/nestquest/core/history.py (new)** — HA-free history layer: a query over a closed date range for the `all` / `reversals` / `missed` filter (`missed` derived the domain way, never stored) and a CSV serializer over the same filtered rows with a documented, stable column set.
- **api/routes_admin.py** — GET /api/v1/admin/history (JSON query) and GET /api/v1/admin/history.csv (same filters, text/csv attachment), thin adapters on the ONE require_admin dependency; narrow error mapping.
- **api/nestquest_core.py** — re-exports the history module.
- **tests/test_api_admin_history.py (new)** — seeds completions, a reversal and a past-due open (missed) instance; asserts each filter's rows and the CSV header/rows (parsed with csv.reader); non-admin refused.
## Verification
- `TZ=UTC uv run pytest -q` → 1750 passed
- `TZ=UTC uv run pytest -q tests/test_api_admin_history.py` → 14 passed
- Baseline on the feature branch: 1736 passed.
Opened by the controller on the developer's behalf after the developer's headless session ended before opening the PR; the branch and commit are the developer's (471ca2309d4cbb3d622707b53c3588d6acdaf5be).
The admin History screen (ADMIN-SPEC 1g) had no API: the read
primitives existed (append-only completion-event reads, derived-state
missed logic) but nothing assembled them, so the admin PWA could not
render the event log or export it. Feature 13's export service was
superseded by the Admin PWA and remains unimplemented by design.
Add a Home-Assistant-free core history layer (core/history.py) that
owns every rule so the two routes cannot drift: one query over the
closed due-date range [start, end] for filter all (every completion
event) / reversals (uncompleted only) / missed (DERIVED past-due open
instances via the existing completion.list_missed_for_child rule --
never stored, never appended); strict ISO date and filter validation
raising ValueError naming filter/start/end; and a csv-module serializer
with a stable documented header (ADMIN-SPEC 5 event-row fields) so the
CSV export is the SAME filtered range as the query, through one
export_history_csv call. Admin routes GET /api/v1/admin/history and
/history.csv are thin adapters on the existing admin router (the one
require_admin dependency; no new auth check), mapping malformed input
to 422 and never 500. completion_events stays append-only: history
only reads.
Tests (tests/test_api_admin_history.py) drive the ASGI app as an admin
via the shared JWT harness: seeded completion + reversal + past-due
open instances prove each filter's rows, the CSV header/rows via
csv.reader, due-date range scoping, 403/401 refusals, and 422s for
unknown filter, non-strict dates and inverted ranges.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Maestro task
2d2dda53-55ae-439d-a1d0-7a40ff9671a9— Admin routes: history query and CSV export (Feature 16 — NestQuest API Service)Done-condition (verbatim)
Admin routes for history: a query returning completion events for a filter (all / reversals / missed) over a date range, and a CSV export of the same filtered range. Each validates input and calls core with no business logic in the handler. Tests as an admin confirm the query returns the expected events for each filter and the CSV carries the documented columns and the filtered rows.
Changes
all/reversals/missedfilter (missedderived the domain way, never stored) and a CSV serializer over the same filtered rows with a documented, stable column set.Verification
TZ=UTC uv run pytest -q→ 1750 passedTZ=UTC uv run pytest -q tests/test_api_admin_history.py→ 14 passedOpened by the controller on the developer's behalf after the developer's headless session ended before opening the PR; the branch and commit are the developer's (
471ca2309d).Independent Claude Sonnet 5 review completed for this exact commit.