"""Typed contracts for the Repairs domain.""" from datetime import datetime from typing import Any, Literal from uuid import UUID from pydantic import AwareDatetime, BaseModel, ConfigDict, Field RepairReason = Literal[ "HARDWARE_FAILURE", "LOW_HASHRATE", "CONTROL_BOARD", "HASHBOARD", "PSU", "FAN", "OVERHEATING", "NETWORKING", "PREVENTIVE_MAINTENANCE", "INSPECTION", "OTHER", ] RepairStatus = Literal[ "OPEN", "IN_PROGRESS", "WAITING_FOR_PARTS", "READY_FOR_TEST", "COMPLETED", "CANCELLED", ] RepairEventType = Literal[ "REPAIR_STARTED", "INITIAL_NOTE", "REPAIR_COMPLETED", ] RepairEligibleLifecycle = Literal["active", "spare"] RepairPostLifecycle = Literal["active", "spare"] RepairMinerLifecycle = Literal["active", "spare", "retired", "in_repair"] class BeginRepairRequest(BaseModel): model_config = ConfigDict(extra="forbid") miner_id: UUID reason: RepairReason notes: str | None = Field(default=None, max_length=4000) class RepairCompleteRequest(BaseModel): model_config = ConfigDict(extra="forbid") target_lifecycle: RepairPostLifecycle completion_summary: str | None = Field(default=None, max_length=4000) class RepairStartedPayload(BaseModel): reason: RepairReason from_lifecycle: RepairEligibleLifecycle to_lifecycle: Literal["in_repair"] = "in_repair" class InitialRepairNotePayload(BaseModel): note: str = Field(min_length=1, max_length=4000) class RepairCompletedPayload(BaseModel): previous_miner_lifecycle: Literal["in_repair"] = "in_repair" resulting_miner_lifecycle: RepairPostLifecycle pre_repair_lifecycle: RepairEligibleLifecycle | None = None completion_summary: str | None = Field(default=None, max_length=4000) class BeginRepairResult(BaseModel): repair_id: UUID miner_id: UUID status: Literal["OPEN"] reason: RepairReason opened_at: datetime opened_by: UUID class BeginRepairResponse(BaseModel): data: BeginRepairResult meta: dict[str, object] = Field(default_factory=dict) error: None = None class RepairActor(BaseModel): user_id: UUID display_name: str class RepairDetail(BaseModel): repair_id: UUID miner_id: UUID miner_asset_id: str | None = None status: RepairStatus reason: RepairReason opened_at: AwareDatetime opened_by: RepairActor closed_at: AwareDatetime | None = None closed_by: RepairActor | None = None miner_lifecycle: RepairMinerLifecycle latest_event_sequence: int | None = Field(default=None, ge=1) class RepairTimelineEvent(BaseModel): event_id: UUID sequence: int = Field(ge=1) event_type: RepairEventType actor: RepairActor occurred_at: AwareDatetime payload: dict[str, Any] class RepairTimeline(BaseModel): repair_id: UUID events: list[RepairTimelineEvent] = Field(default_factory=list) class RepairDetailResponse(BaseModel): data: RepairDetail meta: dict[str, object] = Field(default_factory=dict) error: None = None class RepairTimelineResponse(BaseModel): data: RepairTimeline meta: dict[str, object] = Field(default_factory=dict) error: None = None