Admin routes: history query and CSV export
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.
This commit is contained in:
@@ -116,6 +116,11 @@ core_snapshot = importlib.import_module(f"{_CORE_MODULE_NAME}.snapshot")
|
||||
#: ``uncomplete_instance``) the panel's write routes call.
|
||||
core_completion = importlib.import_module(f"{_CORE_MODULE_NAME}.completion")
|
||||
|
||||
#: The read-only history layer (``core.history.query_history``,
|
||||
#: ``export_history_csv``, ``rows_to_csv``) the admin plane's history
|
||||
#: query and CSV export routes call.
|
||||
core_history = importlib.import_module(f"{_CORE_MODULE_NAME}.history")
|
||||
|
||||
#: The transition-event builders (``core.events.build_quest_completed_event``
|
||||
#: et al.) the panel's write routes build their SSE events with.
|
||||
core_events = importlib.import_module(f"{_CORE_MODULE_NAME}.events")
|
||||
@@ -192,6 +197,7 @@ __all__ = [
|
||||
"core_dao_rules",
|
||||
"core_db",
|
||||
"core_events",
|
||||
"core_history",
|
||||
"core_materialize",
|
||||
"core_migrations",
|
||||
"core_presence",
|
||||
|
||||
Reference in New Issue
Block a user