"""قرارداد مشترک رویدادها (Async Events) برای الگوی Outbox/Inbox. همه سرویس‌ها رویدادها را با این ساختار منتشر و مصرف می‌کنند تا ارتباط بدون اتصال مستقیم دیتابیس ممکن شود. """ from __future__ import annotations import enum from datetime import datetime, timezone from typing import Any from uuid import UUID, uuid4 from pydantic import BaseModel, Field class EventStatus(str, enum.Enum): """وضعیت پردازش یک رویداد در Outbox.""" PENDING = "pending" PROCESSED = "processed" FAILED = "failed" # نمونه انواع رویدادهای شناخته‌شده پلتفرم (قابل توسعه). class CoreEventType(str, enum.Enum): TENANT_CREATED = "tenant.created" TENANT_SUSPENDED = "tenant.suspended" TENANT_ACTIVATED = "tenant.activated" SUBSCRIPTION_CREATED = "subscription.created" SUBSCRIPTION_UPDATED = "subscription.updated" DOMAIN_CREATED = "domain.created" FEATURE_ACCESS_CHANGED = "feature_access.changed" class IdentityEventType(str, enum.Enum): USER_REGISTERED = "user.registered" USER_UPDATED = "user.updated" USER_DISABLED = "user.disabled" TENANT_MEMBER_ADDED = "tenant_member.added" TENANT_MEMBER_REMOVED = "tenant_member.removed" TENANT_MEMBER_ROLE_CHANGED = "tenant_member.role_changed" class EventEnvelope(BaseModel): """پاکت استاندارد یک رویداد که بین سرویس‌ها منتقل می‌شود.""" event_id: UUID = Field(default_factory=uuid4) event_type: str aggregate_type: str aggregate_id: str | None = None tenant_id: UUID | None = None source_service: str payload: dict[str, Any] = Field(default_factory=dict) occurred_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) def to_dict(self) -> dict[str, Any]: return self.model_dump(mode="json")