"""DTO ответов Synapse — только то, что реально возвращает API v1 (docs/05)."""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
@dataclass(frozen=True, slots=True)
class Event:
"""Ответ POST /api/v1/events (202): событие принято в очередь."""
id: str
status: str
deduplicated: bool = False
@dataclass(frozen=True, slots=True)
class BatchRejection:
"""Один элемент batch-ответа с ok=false."""
index: int
detail: str
@dataclass(frozen=True, slots=True)
class BatchResult:
"""Позиция в списке совпадает с порядком исходных events."""
results: list[Event | BatchRejection] = field(default_factory=list)
@property
def accepted(self) -> list[Event]:
return [r for r in self.results if isinstance(r, Event)]
@property
def rejected(self) -> list[BatchRejection]:
return [r for r in self.results if isinstance(r, BatchRejection)]
@property
def all_accepted(self) -> bool:
return not self.rejected
@dataclass(frozen=True, slots=True)
class Delivery:
channel: str
target: str | None
status: str
attempts: int
error: str | None
rendered_message: str | None
@dataclass(frozen=True, slots=True)
class EventStatus:
"""Ответ GET /api/v1/events/{id}."""
id: str
source: str
subject: str
action: str
priority: str
status: str
created_at: datetime
expires_at: datetime | None
deliveries: list[Delivery] = field(default_factory=list)