Source code for corvix.notifications.models

"""Domain event models for notification delivery."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime


@dataclass(slots=True)
[docs] class NotificationEvent: """Canonical event produced when a new unread notification is detected. This is the payload passed to every delivery target. It is deliberately decoupled from the internal ``NotificationRecord`` so targets only depend on this stable interface. """
[docs] event_id: str
"""Stable identifier: ``{account_id}:{thread_id}``."""
[docs] thread_id: str
[docs] repository: str
[docs] reason: str
[docs] subject_title: str
[docs] subject_type: str
[docs] web_url: str | None
[docs] updated_at: datetime
[docs] score: float
[docs] unread: bool
[docs] account_id: str = "primary"
@dataclass(slots=True)
[docs] class DeliveryResult: """Result of a single target's delivery attempt."""
[docs] target: str
[docs] events_attempted: int
[docs] events_delivered: int
[docs] errors: list[str] = field(default_factory=list)
@property
[docs] def success(self) -> bool: return len(self.errors) == 0
@dataclass(slots=True)
[docs] class DispatchResult: """Aggregated result of a fan-out dispatch to all enabled targets."""
[docs] events: list[NotificationEvent]
[docs] results: list[DeliveryResult] = field(default_factory=list)
@property
[docs] def total_delivered(self) -> int: return sum(r.events_delivered for r in self.results)
@property
[docs] def total_errors(self) -> int: return sum(len(r.errors) for r in self.results)