Files
minerops/backend/app/inventory/models.py
T

174 lines
5.3 KiB
Python

"""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