"""Pydantic contracts for the inventory domain.""" from datetime import datetime from typing import Literal from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, IPvAnyAddress LifecycleStatus = Literal["active", "spare", "retired", "in_repair"] class InventoryTag(BaseModel): id: UUID name: str created_at: datetime updated_at: datetime class InventoryActiveRepair(BaseModel): id: UUID status: str reason: str class InventoryMinerSummary(BaseModel): id: UUID asset_id: str | None = None current_mac: str | None = None current_ip: str | None = None model: str | None = None miner_sn: str | None = None lifecycle_status: LifecycleStatus runtime_status: str site_id: UUID | None = None site_name: str | None = None room_id: UUID | None = None room_name: str | None = None location_position_id: UUID | None = None rack_label: str | None = None shelf_label: str | None = None position_label: str | None = None position_index: int | None = None observed_at: datetime | None = None hashrate_ths: float | None = None power_w: float | None = None chip_temp_max_c: float | None = None hash_stable: bool | None = None active_repair: InventoryActiveRepair | None = None tags: list[InventoryTag] = Field(default_factory=list) created_at: datetime updated_at: datetime last_seen_at: datetime | None = None class InventoryMinerDetail(InventoryMinerSummary): hostname: str | None = None control_board_sn: str | None = None psu_serial: str | None = None firmware_version: str | None = None notes: str | None = None first_seen_at: datetime | None = None class InventoryAssetIDHistoryEntry(BaseModel): old_asset_id: str | None = None new_asset_id: str changed_at: datetime changed_by: UUID changed_by_display_name: str class InventoryCreateRequest(BaseModel): asset_id: str = Field(min_length=1, max_length=120) current_mac: str | None = Field(default=None, max_length=64) current_ip: IPvAnyAddress | None = None hostname: str | None = Field(default=None, max_length=255) miner_sn: str | None = Field(default=None, max_length=255) control_board_sn: str | None = Field(default=None, max_length=255) psu_serial: str | None = Field(default=None, max_length=255) model: str | None = Field(default=None, max_length=255) firmware_version: str | None = Field(default=None, max_length=255) lifecycle_status: str = "active" site_id: UUID | None = None room_id: UUID | None = None notes: str | None = None tags: list[str] = Field(default_factory=list) class InventoryMetadataUpdateRequest(BaseModel): model_config = ConfigDict(extra="forbid") asset_id: str | None = Field(default=None, max_length=120) miner_sn: str | None = Field(default=None, max_length=255) psu_serial: str | None = Field(default=None, max_length=255) model: str | None = Field(default=None, max_length=255) notes: str | None = None class InventoryUpdateRequest(BaseModel): asset_id: str | None = Field(default=None, max_length=120) current_mac: str | None = Field(default=None, max_length=64) current_ip: IPvAnyAddress | None = None hostname: str | None = Field(default=None, max_length=255) miner_sn: str | None = Field(default=None, max_length=255) control_board_sn: str | None = Field(default=None, max_length=255) psu_serial: str | None = Field(default=None, max_length=255) model: str | None = Field(default=None, max_length=255) firmware_version: str | None = Field(default=None, max_length=255) lifecycle_status: str | None = None site_id: UUID | None = None room_id: UUID | None = None notes: str | None = None tags: list[str] | None = None class InventorySearchFilters(BaseModel): query: str | None = None asset_id: str | None = None lifecycle_status: str | None = None model: str | None = None runtime_status: str | None = None repair: Literal["active", "none"] | None = None operational_state: Literal[ "online", "offline", "unknown", "unstable", "repair", "spare", "retired" ] | None = None problems: bool = False site_id: UUID | None = None room_id: UUID | None = None tags: list[str] = Field(default_factory=list) limit: int = Field(default=100, ge=1, le=500) offset: int = Field(default=0, ge=0) class InventorySiteOption(BaseModel): id: UUID name: str class InventoryRoomOption(BaseModel): id: UUID site_id: UUID name: str class InventoryLocationOptions(BaseModel): sites: list[InventorySiteOption] = Field(default_factory=list) rooms: list[InventoryRoomOption] = Field(default_factory=list) class InventoryListMeta(BaseModel): limit: int offset: int returned: int location_options: InventoryLocationOptions = Field(default_factory=InventoryLocationOptions) class InventoryMinerListResponse(BaseModel): data: list[InventoryMinerSummary] meta: InventoryListMeta error: None = None class InventoryMinerDetailResponse(BaseModel): data: InventoryMinerDetail meta: dict[str, object] = Field(default_factory=dict) error: None = None class InventoryAssetIDHistoryResponse(BaseModel): data: list[InventoryAssetIDHistoryEntry] meta: dict[str, object] = Field(default_factory=dict) error: None = None class InventoryFleetAttentionSummary(BaseModel): offline: int unknown: int unstable: int repair: int class InventoryFleetSummary(BaseModel): total: int runtime_online: int runtime_offline: int runtime_unknown: int lifecycle_in_repair: int lifecycle_spare: int lifecycle_retired: int attention: InventoryFleetAttentionSummary