"""Deduplicated informed-decision notification receipts. The signed-in overview is the review entry point. A receipt stores and announces only memo id, question, class, and submitter. Replays of the same delivery id return the retained receipt; a different body conflicts and leaves the original readable. """ from __future__ import annotations from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.asyncio import AsyncSession from api.models.agent_message import AgentMessage from api.models.memo_notification import MemoNotificationReceipt from api.services.informed_decision_contract import Notification from api.services.repository_aliases import canonicalize_repository_slug NOTIFICATION_SENDER = "informed-decision" NOTIFICATION_RECIPIENT = "bernd" class NotificationConflict(Exception): def __init__(self, receipt: MemoNotificationReceipt) -> None: self.receipt = receipt async def accept_notification( session: AsyncSession, delivery_id: str, notice: Notification ) -> tuple[MemoNotificationReceipt, bool]: existing = await session.get(MemoNotificationReceipt, delivery_id) if existing is not None: if existing.body_digest != notice.body_digest: raise NotificationConflict(existing) return existing, True message = AgentMessage( from_agent=await canonicalize_repository_slug(session, NOTIFICATION_SENDER), to_agent=await canonicalize_repository_slug(session, NOTIFICATION_RECIPIENT), subject=notice.message_subject(), body=notice.message_text(), kind="message", ) session.add(message) await session.flush() receipt = MemoNotificationReceipt( delivery_id=delivery_id, body_digest=notice.body_digest, memo_id=notice.memo_id, question=notice.question, memo_class=notice.memo_class, submitter=notice.submitter, message_id=message.id, authoritative_review="signed-in-overview", ) session.add(receipt) try: await session.commit() except IntegrityError: await session.rollback() existing = await session.get(MemoNotificationReceipt, delivery_id) if existing is None: raise if existing.body_digest != notice.body_digest: raise NotificationConflict(existing) return existing, True await session.refresh(receipt) return receipt, False