feat: add miner detail view

This commit is contained in:
lussierj committed 2026-08-17 18:43:20 +00:00
1 parent b8b741ccee
commit 19fc29c72c
22 files changed
+1882 -10

No files matched your search

+71
View File
@@ -59,6 +59,66 @@ MINER_SELECT = f"""
) tag_data ON true
"""
MINER_CURRENT_SELECT = f"""
SELECT
miners.id,
miners.site_id,
miners.room_id,
miners.asset_tag,
miners.current_mac,
host(miners.current_ip) AS current_ip,
miners.hostname,
miners.miner_sn,
miners.control_board_sn,
miners.power_sn,
miners.model,
miners.firmware_version,
miners.lifecycle_status,
miners.status,
miners.notes,
miners.first_seen_at,
miners.last_seen_at,
miners.created_at,
miners.updated_at,
tag_data.tags,
latest.observed_at,
latest.hashrate_ths,
latest.power_w,
latest.chip_temp_max_c,
latest.hash_stable
FROM miners
LEFT JOIN LATERAL (
SELECT COALESCE(
jsonb_agg(
jsonb_build_object(
'id', tags.id,
'name', tags.name,
'created_at', tags.created_at,
'updated_at', tags.updated_at
)
ORDER BY lower({TAG_TRIMMED_NAME_SQL}), tags.id
),
'[]'::jsonb
) AS tags
FROM miner_tags
JOIN tags ON tags.id = miner_tags.tag_id
WHERE miner_tags.miner_id = miners.id
) tag_data ON true
LEFT JOIN LATERAL (
SELECT snapshots.observed_at,
ROUND((snapshots.mhs_av / 1000000.0)::numeric, 2)::float
AS hashrate_ths,
ROUND(snapshots.power_w::numeric, 2)::float AS power_w,
ROUND(snapshots.chip_temp_max_c::numeric, 2)::float
AS chip_temp_max_c,
snapshots.hash_stable
FROM miner_status_snapshots AS snapshots
WHERE snapshots.miner_id = miners.id
ORDER BY snapshots.observed_at DESC, snapshots.id DESC
LIMIT 1
) latest ON true
"""
ACTIVE_REPAIR_STATUSES = (
"OPEN",
"IN_PROGRESS",
@@ -260,6 +320,17 @@ class InventoryRepository:
with connection.cursor(row_factory=dict_row) as cur:
return self._fetch_miner(cur, "miners.id = %s", (miner_id,))
def get_current_miner_by_id(self, miner_id: UUID) -> dict | None:
"""Return Inventory identity with its latest factual telemetry."""
with self._connection_scope() as connection:
with connection.cursor(row_factory=dict_row) as cur:
cur.execute(
f"{MINER_CURRENT_SELECT} WHERE miners.id = %s",
(miner_id,),
)
row = cur.fetchone()
return dict(row) if row else None
def get_miner_by_id_for_update(self, miner_id: UUID) -> dict | None:
with self._connection_scope() as connection:
with connection.cursor(row_factory=dict_row) as cur:
+7
View File
@@ -137,6 +137,13 @@ class InventoryService:
raise MinerNotFound(miner_id)
return self._detail_model(row)
def get_current_miner(self, miner_id: UUID) -> InventoryMinerDetail:
"""Return current Inventory identity and the latest observation."""
row = self.repository.get_current_miner_by_id(miner_id)
if not row:
raise MinerNotFound(miner_id)
return self._detail_model(row)
def get_asset_id_history(
self,
miner_id: UUID,