SSE: publish uncompleted, child-day-complete and missed transitions
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.
This commit is contained in:
+14
-1
@@ -69,6 +69,7 @@ from api.nestquest_core import (
|
||||
core_settings,
|
||||
core_snapshot,
|
||||
)
|
||||
from api import transitions as api_transitions
|
||||
|
||||
#: The instance DAO, imported on the app's core copy for the
|
||||
#: child-mismatch guard on the complete route.
|
||||
@@ -283,13 +284,14 @@ async def panel_complete_instance(
|
||||
detail="Quest instance not found for this child",
|
||||
)
|
||||
|
||||
now = _local_now()
|
||||
try:
|
||||
result = await core_completion.complete_instance(
|
||||
database,
|
||||
instance_id,
|
||||
actor_source="panel",
|
||||
actor_child_id=body.actor_child_id,
|
||||
now=_local_now(),
|
||||
now=now,
|
||||
)
|
||||
except ValueError as error:
|
||||
message = str(error)
|
||||
@@ -312,6 +314,17 @@ async def panel_complete_instance(
|
||||
database, instance_id, was_on_time=result.was_on_time
|
||||
)
|
||||
request.app.state.publisher.publish(event_type, payload)
|
||||
# THEN evaluate the day-complete rule off the completed event's
|
||||
# payload (the core builder decides when the child's whole day
|
||||
# is cleared — a zero-quest day and a non-today instance never
|
||||
# fire it). ``today`` comes from the route's single clock read
|
||||
# so the calendar date can never disagree with the completion's.
|
||||
await api_transitions.publish_child_day_complete(
|
||||
database,
|
||||
payload,
|
||||
now.date(),
|
||||
request.app.state.publisher,
|
||||
)
|
||||
return {"status": str(result)}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user