"""Processing result models.""" from dataclasses import dataclass, field from typing import Generic, TypeVar from pydantic import BaseModel, Field from schemas.columns import ProcessingStatus from schemas.graphql import AbacusContract, AbacusContractWithLifecyclesInput T = TypeVar('T') # --------------------------------------------------------------------------- # Build results (returned by ContractInputBuilder.build) # --------------------------------------------------------------------------- @dataclass(frozen=True) class BuildSuccess: """Successful build — contains the GraphQL input and any defaults applied.""" input: AbacusContractWithLifecyclesInput defaults_applied: tuple[str, ...] = () @dataclass(frozen=True) class BuildSkip: """Row was skipped during build due to missing or invalid data.""" reason: str BuildResult = BuildSuccess | BuildSkip class GraphQLResult(BaseModel, Generic[T]): """Generic result from a GraphQL operation. T is the response data type on success (e.g., AbacusContract). """ status: ProcessingStatus = Field(...) data: T | None = Field(default=None) error: str | None = Field(default=None) class SkippedRow(BaseModel): """A row that was skipped during processing.""" row: int = Field(..., description='1-based row index') data: dict = Field(...) reason: str = Field(...) class ErrorRow(BaseModel): """A row that failed during processing.""" row: int = Field(..., description='1-based row index') data: dict = Field(...) result: GraphQLResult[AbacusContract] = Field(...) @dataclass class ProcessingResults: """Accumulated results from a batch processing run.""" success: list[GraphQLResult[AbacusContract]] = field(default_factory=list) errors: list[ErrorRow] = field(default_factory=list) skipped: list[SkippedRow] = field(default_factory=list)