"""Pydantic models for Lambda event validation.""" from __future__ import annotations from typing import Any, Literal, Optional from pydantic import BaseModel, ConfigDict, Field from src.enums import EventType, TargetType class PaymentAllocationEventMetadata(BaseModel): """Metadata section for PaymentAllocationEvent.""" model_config = ConfigDict(extra='ignore') correlation_id: Optional[str] = Field( None, description='Correlation ID for tracing' ) target_id: int = Field(..., description='Primary key of target entity') target_type: Literal[TargetType.STATEMENT_PERIOD_PAYMENT_ENTITY] = Field( ..., description='Entity type (e.g., statement_period_payment_entity)' ) class PaymentAllocationEventDetail(BaseModel): """Event detail section for PaymentAllocationEvent.""" model_config = ConfigDict(extra='ignore') metadata: PaymentAllocationEventMetadata = Field(..., description='Event metadata') class PaymentAllocationEvent(BaseModel): """EventBridge event for payment allocation (from outbox).""" model_config = ConfigDict(extra='ignore', populate_by_name=True) detail_type: Literal[EventType.CLOSE_BALANCE_COMPLETED] = Field( ..., description='Event type', alias='detail-type', ) detail: PaymentAllocationEventDetail = Field(..., description='Event details') class SimplePaymentAllocationEvent(BaseModel): """Simple event for manual triggering / testing.""" statement_period_payment_entity_id: int def parse_event(raw: dict[str, Any]) -> int: """Parse event and return statement_period_payment_entity_id. Accepts either an EventBridge envelope (with detail-type/detail) or a simple event with just statement_period_payment_entity_id. Args: raw: Raw event dictionary Returns: The statement_period_payment_entity_id Raises: ValidationError: If event structure is invalid for both formats """ if 'detail-type' in raw: eb_event = PaymentAllocationEvent(**raw) return eb_event.detail.metadata.target_id simple_event = SimplePaymentAllocationEvent(**raw) return simple_event.statement_period_payment_entity_id