"""Kafka event schemas.""" from __future__ import annotations from typing import Any from pydantic import BaseModel, ConfigDict, Field from src.enums import DebeziumOperation class DebeziumCDCEvent(BaseModel): """Debezium Change Data Capture event. Represents a database change event captured by Debezium. """ model_config = ConfigDict(extra='ignore') op: DebeziumOperation = Field( ..., description='Operation type (c=create, u=update, d=delete, r=read)' ) before: dict[str, Any] | None = Field( None, description='Row state before the change (null for inserts)' ) after: dict[str, Any] | None = Field( None, description='Row state after the change (null for deletes)' ) ts_ms: int | None = Field(None, description='Timestamp in milliseconds') class KafkaRecord(BaseModel): """Individual Kafka record from MSK event source. Represents a single message from a Kafka topic partition. """ topic: str = Field(..., description='Kafka topic name') partition: int = Field(..., description='Topic partition number') offset: int = Field(..., description='Message offset within partition') timestamp: int = Field(..., description='Message timestamp in milliseconds') key: str | None = Field(None, description='Base64-encoded message key') value: str = Field(..., description='Base64-encoded message value') class KafkaEvent(BaseModel): """AWS Lambda event from MSK/Kafka event source. Lambda receives Kafka messages in batches grouped by topic-partition. The records field is a dictionary where keys are "{topic}-{partition}" and values are lists of KafkaRecord objects. """ model_config = ConfigDict(extra='ignore') eventSource: str = Field( ..., description="Event source identifier (e.g., 'aws:kafka')" ) records: dict[str, list[KafkaRecord]] = Field( ..., description="Records grouped by topic-partition (key format: 'topic-partition')", )