Co-authored-by: dev_agent <17+dev_agent@code.cubecraftcreations.com> Co-committed-by: dev_agent <17+dev_agent@code.cubecraftcreations.com>
84 lines
2.8 KiB
Python
84 lines
2.8 KiB
Python
"""Reusable SSE transition publishers for the API service (task 44c93cfd).
|
|
|
|
Each helper wraps the ONE publisher on ``app.state.publisher`` with a
|
|
single documented transition: it builds the payload through the core
|
|
event builders (``nestquest_core.events``) — never hand-built here —
|
|
and fans it out with :meth:`~api.events.TransitionPublisher.publish`.
|
|
|
|
The uncomplete route (follow-up task da0226b3) and the API-side missed
|
|
sweep do not exist yet; these helpers are the functions they will call,
|
|
and the SSE tests exercise them directly. Fan-out stays fire-and-forget
|
|
(see api/events.py): a slow subscriber drops the event and recovers by
|
|
polling the snapshot.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import datetime
|
|
|
|
from api.nestquest_core import core_events
|
|
|
|
|
|
async def publish_quest_uncompleted(
|
|
database: object, instance_id: int, publisher: object
|
|
) -> None:
|
|
"""Publish ONE ``nestquest_quest_uncompleted`` event for an actual
|
|
reversal of ``instance_id``.
|
|
|
|
The payload is built by the core builder
|
|
(:func:`nestquest_core.events.build_quest_uncompleted_events`);
|
|
this helper only picks the single event out of the builder's list
|
|
and publishes it.
|
|
"""
|
|
events = await core_events.build_quest_uncompleted_events(
|
|
database, instance_id
|
|
)
|
|
for event_type, payload in events:
|
|
publisher.publish(event_type, payload)
|
|
|
|
|
|
async def publish_quest_missed(
|
|
database: object, instance_id: int, publisher: object
|
|
) -> None:
|
|
"""Publish ONE ``nestquest_quest_missed`` event for ``instance_id``.
|
|
|
|
The payload is built by the core builder
|
|
(:func:`nestquest_core.events.build_quest_missed_event`), which
|
|
mirrors the documented sweep payload exactly (§3 of
|
|
design/ENTITIES-AND-SERVICES.md).
|
|
"""
|
|
event_type, payload = await core_events.build_quest_missed_event(
|
|
database, instance_id
|
|
)
|
|
publisher.publish(event_type, payload)
|
|
|
|
|
|
async def publish_child_day_complete(
|
|
database: object,
|
|
completed_payload: dict,
|
|
today: datetime.date,
|
|
publisher: object,
|
|
) -> bool:
|
|
"""Publish ``nestquest_child_day_complete`` when a completion
|
|
cleared the child's whole day; return whether one was published.
|
|
|
|
The day-complete rule lives entirely in the core builder
|
|
(:func:`nestquest_core.events.build_child_day_complete_event`):
|
|
it returns ``None`` when the day did not clear (a zero-quest day
|
|
or a non-today instance) and this helper publishes nothing then.
|
|
"""
|
|
event = await core_events.build_child_day_complete_event(
|
|
database, completed_payload, today=today
|
|
)
|
|
if event is None:
|
|
return False
|
|
event_type, payload = event
|
|
publisher.publish(event_type, payload)
|
|
return True
|
|
|
|
|
|
__all__ = [
|
|
"publish_child_day_complete",
|
|
"publish_quest_missed",
|
|
"publish_quest_uncompleted",
|
|
]
|