mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix(gateway): notify_list/get/ack call NotificationDeliveryService (not Service)
Wave 1 wired notify_list/get/ack into ContentActions but pointed them at `self.notifications` (which is NotificationService — sender side, with send_blocker_notification / send_qa_ready_notification / etc.). The read methods (list_for_agent, get_for_recipient_and_mark_read, acknowledge) live on `NotificationDeliveryService` instead. Smoke run 2026-05-11 surfaced this immediately: AttributeError: 'NotificationService' object has no attribute 'list_for_agent' Fixes: - roboco/api/deps.py — import NotificationDeliveryService and wire it in as a new ContentActionsDeps field `notification_delivery`. - roboco/services/gateway/content_actions.py — add notification_delivery to ContentActionsDeps (Optional with `None` default for back-compat with any tests that don't supply it). Point notify_list, notify_get, notify_ack at self._deps.notification_delivery. - tests/unit/gateway/test_content_actions.py — _make_deps adds a default AsyncMock for notification_delivery so existing tests continue to pass. Quality: ruff + mypy clean. 505 unit tests pass.
This commit is contained in:
@@ -31,6 +31,7 @@ from roboco.services.git import GitService
|
|||||||
from roboco.services.journal import JournalService
|
from roboco.services.journal import JournalService
|
||||||
from roboco.services.messaging import MessagingService
|
from roboco.services.messaging import MessagingService
|
||||||
from roboco.services.notification import NotificationService
|
from roboco.services.notification import NotificationService
|
||||||
|
from roboco.services.notification_delivery import NotificationDeliveryService
|
||||||
from roboco.services.permissions import AgentContext, PermissionService
|
from roboco.services.permissions import AgentContext, PermissionService
|
||||||
from roboco.services.repositories import resolve_agent_identity, resolve_agent_uuid
|
from roboco.services.repositories import resolve_agent_identity, resolve_agent_uuid
|
||||||
from roboco.services.task import TaskService
|
from roboco.services.task import TaskService
|
||||||
@@ -528,6 +529,7 @@ async def get_content_actions(
|
|||||||
journal=JournalService(db_session),
|
journal=JournalService(db_session),
|
||||||
workspace=WorkspaceService(db_session),
|
workspace=WorkspaceService(db_session),
|
||||||
notifications=NotificationService(),
|
notifications=NotificationService(),
|
||||||
|
notification_delivery=NotificationDeliveryService(db_session),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -200,6 +200,10 @@ class ContentActionsDeps:
|
|||||||
journal: Any
|
journal: Any
|
||||||
workspace: Any
|
workspace: Any
|
||||||
notifications: Any
|
notifications: Any
|
||||||
|
# Wave 1 added inbox-read verbs (notify_list/get/ack) that live on
|
||||||
|
# `NotificationDeliveryService`, not `NotificationService`. Keeping
|
||||||
|
# them separate so the sender vs receiver concerns stay split.
|
||||||
|
notification_delivery: Any = None
|
||||||
|
|
||||||
|
|
||||||
_VALID_NOTIFY_PRIORITIES: frozenset[str] = frozenset(p.value for p in _comms.Priority)
|
_VALID_NOTIFY_PRIORITIES: frozenset[str] = frozenset(p.value for p in _comms.Priority)
|
||||||
@@ -788,7 +792,7 @@ class ContentActions:
|
|||||||
the verb is documented to soft-block on unread notifications, but
|
the verb is documented to soft-block on unread notifications, but
|
||||||
previously there was no way for the agent to read or acknowledge them.
|
previously there was no way for the agent to read or acknowledge them.
|
||||||
"""
|
"""
|
||||||
items = await self.notifications.list_for_agent(
|
items = await self._deps.notification_delivery.list_for_agent(
|
||||||
agent_id=agent_id,
|
agent_id=agent_id,
|
||||||
unread_only=unread_only,
|
unread_only=unread_only,
|
||||||
pending_ack_only=pending_ack_only,
|
pending_ack_only=pending_ack_only,
|
||||||
@@ -824,7 +828,7 @@ class ContentActions:
|
|||||||
) -> Envelope:
|
) -> Envelope:
|
||||||
"""Read one notification (also marks it read)."""
|
"""Read one notification (also marks it read)."""
|
||||||
try:
|
try:
|
||||||
n = await self.notifications.get_for_recipient_and_mark_read(
|
n = await self._deps.notification_delivery.get_for_recipient_and_mark_read(
|
||||||
notification_id=notification_id,
|
notification_id=notification_id,
|
||||||
agent_id=agent_id,
|
agent_id=agent_id,
|
||||||
)
|
)
|
||||||
@@ -892,7 +896,7 @@ class ContentActions:
|
|||||||
Returns ``not_authorized`` if the caller isn't a recipient.
|
Returns ``not_authorized`` if the caller isn't a recipient.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
n = await self.notifications.acknowledge(
|
n = await self._deps.notification_delivery.acknowledge(
|
||||||
notification_id=notification_id,
|
notification_id=notification_id,
|
||||||
agent_id=agent_id,
|
agent_id=agent_id,
|
||||||
ack_type="received",
|
ack_type="received",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ def _make_deps(**overrides: AsyncMock) -> ContentActionsDeps:
|
|||||||
journal = overrides.get("journal", AsyncMock())
|
journal = overrides.get("journal", AsyncMock())
|
||||||
workspace = overrides.get("workspace", AsyncMock())
|
workspace = overrides.get("workspace", AsyncMock())
|
||||||
notifications = overrides.get("notifications", AsyncMock())
|
notifications = overrides.get("notifications", AsyncMock())
|
||||||
|
notification_delivery = overrides.get("notification_delivery", AsyncMock())
|
||||||
return ContentActionsDeps(
|
return ContentActionsDeps(
|
||||||
task=task,
|
task=task,
|
||||||
git=git,
|
git=git,
|
||||||
@@ -43,6 +44,7 @@ def _make_deps(**overrides: AsyncMock) -> ContentActionsDeps:
|
|||||||
journal=journal,
|
journal=journal,
|
||||||
workspace=workspace,
|
workspace=workspace,
|
||||||
notifications=notifications,
|
notifications=notifications,
|
||||||
|
notification_delivery=notification_delivery,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user