"""Pydantic record types mirroring the SQLite tables. Every numeric column documented as ``NUMERIC`` in ``state/migrations/0001_init.sql`` is exposed as :class:`decimal.Decimal` on the Python side. The repository layer is responsible for serialising to ``TEXT`` (using ``str``) when writing and parsing back when reading, so precision is never lost via ``float`` coercion. """ from __future__ import annotations from datetime import datetime from decimal import Decimal from typing import Literal from uuid import UUID from pydantic import BaseModel, ConfigDict, Field __all__ = [ "DecisionRecord", "DvolSnapshot", "InstructionRecord", "ManualAction", "PositionRecord", "PositionStatus", "SystemStateRecord", ] PositionStatus = Literal[ "proposed", "awaiting_fill", "open", "closing", "closed", "cancelled", ] class PositionRecord(BaseModel): """Row of the ``positions`` table.""" model_config = ConfigDict(extra="forbid") proposal_id: UUID spread_type: str asset: str = "ETH" expiry: datetime short_strike: Decimal long_strike: Decimal short_instrument: str long_instrument: str n_contracts: int spread_width_usd: Decimal spread_width_pct: Decimal credit_eth: Decimal credit_usd: Decimal max_loss_usd: Decimal spot_at_entry: Decimal dvol_at_entry: Decimal delta_at_entry: Decimal eth_price_at_entry: Decimal proposed_at: datetime opened_at: datetime | None = None closed_at: datetime | None = None close_reason: str | None = None debit_paid_eth: Decimal | None = None pnl_eth: Decimal | None = None pnl_usd: Decimal | None = None status: PositionStatus created_at: datetime updated_at: datetime class InstructionRecord(BaseModel): """Row of the ``instructions`` table.""" model_config = ConfigDict(extra="forbid") instruction_id: UUID proposal_id: UUID kind: Literal["open_combo", "close_combo"] payload_json: str sent_at: datetime acknowledged_at: datetime | None = None filled_at: datetime | None = None cancelled_at: datetime | None = None actual_fill_eth: Decimal | None = None actual_fees_eth: Decimal | None = None class DecisionRecord(BaseModel): """Row of the ``decisions`` table. ``id`` is :class:`int` and may be ``None`` before the row has been inserted; the repository sets it after the auto-increment fires. """ model_config = ConfigDict(extra="forbid") id: int | None = None decision_type: Literal["entry_check", "exit_check", "kelly_recalib"] proposal_id: UUID | None = None timestamp: datetime inputs_json: str outputs_json: str action_taken: str | None = None notes: str | None = None class DvolSnapshot(BaseModel): """Row of the ``dvol_history`` table.""" model_config = ConfigDict(extra="forbid") timestamp: datetime dvol: Decimal eth_spot: Decimal class ManualAction(BaseModel): """Row of the ``manual_actions`` table.""" model_config = ConfigDict(extra="forbid") id: int | None = None kind: Literal[ "approve_proposal", "reject_proposal", "force_close", "arm_kill", "disarm_kill", ] proposal_id: UUID | None = None payload_json: str | None = None created_at: datetime consumed_at: datetime | None = None consumed_by: str | None = None result: str | None = None class SystemStateRecord(BaseModel): """Singleton row of the ``system_state`` table.""" model_config = ConfigDict(extra="forbid") id: int = Field(default=1) kill_switch: int = 0 kill_reason: str | None = None kill_at: datetime | None = None last_health_check: datetime last_kelly_calib: datetime | None = None config_version: str started_at: datetime