Run the missed sweep in the API and publish quest-missed on SSE
WHY: The nightly missed-quest sweep only existed on the Home Assistant plane (the rollover listener fired hass.bus), so the API service - now the writer of record with its own settings store and SSE stream - had no way to announce missed quests, and an admin could not trigger a catch-up run after downtime. - Extract the sweep policy (watermark read, list_missed_unswept query, documented payload build, watermark write, per-database lock) into the HA-free core (core/sweep.py), building each event through the shared events payload builder so the shape cannot drift; the integration's sweep.py becomes a thin shim that fires the returned events on hass.bus, keeping its signature. - Admin trigger POST /api/v1/admin/missed-sweep: ONE clock read, ONE core call, each returned event published on the SSE stream through the existing publish_quest_missed helper; returns the fired count. Watermark makes a same-day rerun silent and a post-downtime run sweep the accumulated window once. - Daily scheduler (api/scheduler.py) wired in the lifespan: reads day_rollover_time fresh each cycle, runs the sweep at the rollover, publishes on the app publisher, backs off and logs on failure, cancels cleanly on shutdown; injectable clock/sleep for tests. - Tests: route trigger over a live uvicorn server with a live SSE stream (one transition per instance with documented fields, same-day rerun silent, post-downtime catch-up once, non-admin 403 / absent 401) plus the scheduler rollover/cancellation test.
This commit is contained in:
@@ -198,6 +198,12 @@ core_dao_children = importlib.import_module(
|
||||
#: delegating.
|
||||
core_dao_rules = importlib.import_module(f"{_CORE_MODULE_NAME}.dao_rules")
|
||||
|
||||
#: The HA-free missed sweep (``core.sweep.run_missed_sweep`` +
|
||||
#: ``SWEEP_WATERMARK_KEY``) the admin plane's trigger route calls and
|
||||
#: the daily scheduler runs — the ONE sweep policy the integration's
|
||||
#: bus shim shares.
|
||||
core_sweep = importlib.import_module(f"{_CORE_MODULE_NAME}.sweep")
|
||||
|
||||
__all__ = [
|
||||
"core",
|
||||
"core_children",
|
||||
@@ -218,4 +224,5 @@ __all__ = [
|
||||
"core_snapshot",
|
||||
"core_settings",
|
||||
"core_settings_store",
|
||||
"core_sweep",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user