SSE: publish uncompleted, child-day-complete and missed #155

Member

Maestro task: 44c93cfd-79f8-4d47-a807-e9b8613992f1

Done-condition (controller re-scoped 2026-09-23): The SSE publisher supports the remaining three documented transitions on the same stream: quest-uncompleted, child-day-complete, and quest-missed, with payloads built by the core event builders (add a core quest-missed builder mirroring the documented sweep payload if none exists). child-day-complete is wired into the panel complete route so it is published when a completion clears the childs whole day, carrying quests_due and quests_completed. Tests subscribe to the stream and assert each of the three event types and their documented payload fields.

Changes:

  • core/events.py: new build_quest_missed_event mirroring the documented sweep payload exactly (reuses _instance_payload and _now_stamp); existing builders untouched.
  • api/transitions.py (new): reusable publish helpers publish_quest_uncompleted / publish_quest_missed / publish_child_day_complete, each building payloads through the core builders and publishing via the ONE publisher on app.state.publisher.
  • api/routes_panel.py: on an actual transition the complete route publishes quest-completed first, then evaluates the day-complete rule via publish_child_day_complete using the completed payload and today from the route single clock read (hoisted). No-op re-complete publishes nothing; zero-quest day and non-today instance never fire (core builder rule unchanged).
  • tests: core key-set test for the missed builder (tests/test_events.py); three new SSE tests (tests/test_api_sse.py) driving uncompleted, day-complete (last quest of day through the panel route) and missed through the real stream; the existing no-op test now drains the day-complete frame Ada single-quest day produces.

Scope per the controller note: quest-uncompleted and quest-missed are published through the reusable API functions the later uncomplete route (da0226b3) and missed sweep will call; wiring them into routes/the sweep is deferred.

Tests (TZ=UTC):

  • uv run pytest -q: 1612 passed in 9.54s (baseline 1608 + 4 new)
  • uv run pytest -q tests/test_api_sse.py: 6 passed in 2.07s
Maestro task: 44c93cfd-79f8-4d47-a807-e9b8613992f1 Done-condition (controller re-scoped 2026-09-23): The SSE publisher supports the remaining three documented transitions on the same stream: quest-uncompleted, child-day-complete, and quest-missed, with payloads built by the core event builders (add a core quest-missed builder mirroring the documented sweep payload if none exists). child-day-complete is wired into the panel complete route so it is published when a completion clears the childs whole day, carrying quests_due and quests_completed. Tests subscribe to the stream and assert each of the three event types and their documented payload fields. Changes: - core/events.py: new build_quest_missed_event mirroring the documented sweep payload exactly (reuses _instance_payload and _now_stamp); existing builders untouched. - api/transitions.py (new): reusable publish helpers publish_quest_uncompleted / publish_quest_missed / publish_child_day_complete, each building payloads through the core builders and publishing via the ONE publisher on app.state.publisher. - api/routes_panel.py: on an actual transition the complete route publishes quest-completed first, then evaluates the day-complete rule via publish_child_day_complete using the completed payload and today from the route single clock read (hoisted). No-op re-complete publishes nothing; zero-quest day and non-today instance never fire (core builder rule unchanged). - tests: core key-set test for the missed builder (tests/test_events.py); three new SSE tests (tests/test_api_sse.py) driving uncompleted, day-complete (last quest of day through the panel route) and missed through the real stream; the existing no-op test now drains the day-complete frame Ada single-quest day produces. Scope per the controller note: quest-uncompleted and quest-missed are published through the reusable API functions the later uncomplete route (da0226b3) and missed sweep will call; wiring them into routes/the sweep is deferred. Tests (TZ=UTC): - uv run pytest -q: 1612 passed in 9.54s (baseline 1608 + 4 new) - uv run pytest -q tests/test_api_sse.py: 6 passed in 2.07s
dev_agent added 1 commit 2026-09-22 23:20:33 -04:00
The panel stream so far carried only quest-completed. This adds the
three remaining documented transitions (§3) so the panel UI can react
to reversals, full days, and nightly misses through the same ONE
publisher:

- core/events.py gains build_quest_missed_event, mirroring the
  sweep's hand-built payload exactly (shared _instance_payload shape),
  so the API plane publishes the same shape the integration sweep fires.
- api/transitions.py adds the reusable publish helpers the later
  uncomplete route (da0226b3) and the API-side missed sweep will call;
  payloads are always built by the core builders, never hand-built.
- The panel complete route now evaluates the day-complete rule on an
  actual transition, off the completed event's payload and the route's
  single clock read; the core builder still decides, so a zero-quest
  day and a non-today instance never fire it and a no-op re-complete
  publishes nothing.
- Tests drive all three transitions through the real SSE stream
  (server-loop scheduling for the not-yet-routed helpers) and assert
  every documented payload field.
review_agent left a comment
Member

Independent Claude Sonnet 5 review completed for this exact commit.

Independent Claude Sonnet 5 review completed for this exact commit.
dev_agent merged commit d4a55b6b40 into feature/cd03735b-2498-4b34-b84c-c1cb2b271ba7-nestquest-api-service 2026-09-22 23:25:07 -04:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Maniacs_Mansion/NestQuest#155