Include Loyalty/Communication/Sports Center backends and registry updates alongside production nginx and compose wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
64 lines
1.7 KiB
Python
64 lines
1.7 KiB
Python
"""Communication event publisher — EventEnvelope contracts; no bus consumers yet."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Protocol
|
|
from uuid import UUID, uuid4
|
|
|
|
from shared.events import EventEnvelope
|
|
|
|
from app.core.config import settings
|
|
from app.events.types import CommunicationEventType
|
|
|
|
|
|
class EventPublisher(Protocol):
|
|
def publish(
|
|
self,
|
|
*,
|
|
event_type: CommunicationEventType,
|
|
aggregate_type: str,
|
|
aggregate_id: UUID,
|
|
tenant_id: UUID,
|
|
payload: dict[str, Any] | None = None,
|
|
) -> EventEnvelope: ...
|
|
|
|
|
|
class InMemoryEventPublisher:
|
|
"""Records published envelopes for tests and local verification."""
|
|
|
|
def __init__(self) -> None:
|
|
self.published: list[EventEnvelope] = []
|
|
|
|
def publish(
|
|
self,
|
|
*,
|
|
event_type: CommunicationEventType,
|
|
aggregate_type: str,
|
|
aggregate_id: UUID,
|
|
tenant_id: UUID,
|
|
payload: dict[str, Any] | None = None,
|
|
) -> EventEnvelope:
|
|
envelope = EventEnvelope(
|
|
event_id=uuid4(),
|
|
event_type=event_type.value,
|
|
aggregate_type=aggregate_type,
|
|
aggregate_id=str(aggregate_id),
|
|
tenant_id=tenant_id,
|
|
source_service=settings.service_name,
|
|
payload=payload or {},
|
|
)
|
|
self.published.append(envelope)
|
|
return envelope
|
|
|
|
|
|
_default_publisher = InMemoryEventPublisher()
|
|
|
|
|
|
def get_event_publisher() -> InMemoryEventPublisher:
|
|
return _default_publisher
|
|
|
|
|
|
def reset_event_publisher() -> InMemoryEventPublisher:
|
|
global _default_publisher
|
|
_default_publisher = InMemoryEventPublisher()
|
|
return _default_publisher
|