Files
minerops/backend/alembic/versions/0005_miner_inventory.py
T

155 lines
9.2 KiB
Python

"""create miner inventory tables
Revision ID: 0005_miner_inventory
Revises: 0004_scan_runs_results
Create Date: 2026-07-08
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql
revision: str = "0005_miner_inventory"
down_revision: Union[str, None] = "0004_scan_runs_results"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"miners",
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True, server_default=sa.text("gen_random_uuid()")),
sa.Column("site_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("sites.id", ondelete="SET NULL"), nullable=True),
sa.Column("room_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("rooms.id", ondelete="SET NULL"), nullable=True),
sa.Column("asset_tag", sa.Text(), nullable=True),
sa.Column("current_mac", sa.Text(), nullable=True),
sa.Column("current_ip", postgresql.INET(), nullable=True),
sa.Column("hostname", sa.Text(), nullable=True),
sa.Column("miner_sn", sa.Text(), nullable=True),
sa.Column("power_sn", sa.Text(), nullable=True),
sa.Column("model", sa.Text(), nullable=True),
sa.Column("miner_type", sa.Text(), nullable=True),
sa.Column("api_version", sa.Text(), nullable=True),
sa.Column("firmware_version", sa.Text(), nullable=True),
sa.Column("platform", sa.Text(), nullable=True),
sa.Column("chip", sa.Text(), nullable=True),
sa.Column("status", sa.Text(), nullable=False, server_default=sa.text("'discovered'")),
sa.Column("notes", sa.Text(), nullable=True),
sa.Column("first_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("last_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
)
op.create_index("idx_miners_site_id", "miners", ["site_id"])
op.create_index("idx_miners_room_id", "miners", ["room_id"])
op.create_index("idx_miners_current_ip", "miners", ["current_ip"])
op.create_index("idx_miners_current_mac", "miners", ["current_mac"])
op.create_index("idx_miners_miner_sn", "miners", ["miner_sn"])
op.create_index("idx_miners_status", "miners", ["status"])
op.create_index("idx_miners_last_seen_at", "miners", ["last_seen_at"])
op.create_table(
"miner_network_identities",
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True, server_default=sa.text("gen_random_uuid()")),
sa.Column("miner_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("miners.id", ondelete="CASCADE"), nullable=False),
sa.Column("mac_address", sa.Text(), nullable=False),
sa.Column("ip_address", postgresql.INET(), nullable=True),
sa.Column("hostname", sa.Text(), nullable=True),
sa.Column("source", sa.Text(), nullable=False, server_default=sa.text("'scanner'")),
sa.Column("is_current", sa.Boolean(), nullable=False, server_default=sa.text("true")),
sa.Column("first_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("last_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
)
op.create_index("idx_miner_network_identities_miner_id", "miner_network_identities", ["miner_id"])
op.create_index("idx_miner_network_identities_mac_address", "miner_network_identities", ["mac_address"])
op.create_index("idx_miner_network_identities_ip_address", "miner_network_identities", ["ip_address"])
op.create_index("idx_miner_network_identities_is_current", "miner_network_identities", ["is_current"])
op.create_table(
"miner_hashboards",
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True, server_default=sa.text("gen_random_uuid()")),
sa.Column("miner_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("miners.id", ondelete="CASCADE"), nullable=False),
sa.Column("slot", sa.Integer(), nullable=False),
sa.Column("pcb_sn", sa.Text(), nullable=True),
sa.Column("chip_data", sa.Text(), nullable=True),
sa.Column("temperature_c", sa.Numeric(), nullable=True),
sa.Column("chip_frequency", sa.Numeric(), nullable=True),
sa.Column("mhs_av", sa.Numeric(), nullable=True),
sa.Column("mhs_1m", sa.Numeric(), nullable=True),
sa.Column("mhs_15m", sa.Numeric(), nullable=True),
sa.Column("hs_rt", sa.Numeric(), nullable=True),
sa.Column("factory_ghs", sa.Numeric(), nullable=True),
sa.Column("effective_chips", sa.Integer(), nullable=True),
sa.Column("upfreq_complete", sa.Integer(), nullable=True),
sa.Column("raw_json", postgresql.JSONB(), nullable=True),
sa.Column("first_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("last_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.UniqueConstraint("miner_id", "slot", name="uq_miner_hashboards_miner_slot"),
)
op.create_index("idx_miner_hashboards_miner_id", "miner_hashboards", ["miner_id"])
op.create_index("idx_miner_hashboards_pcb_sn", "miner_hashboards", ["pcb_sn"])
op.create_table(
"miner_status_snapshots",
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True, server_default=sa.text("gen_random_uuid()")),
sa.Column("miner_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("miners.id", ondelete="CASCADE"), nullable=False),
sa.Column("observed_ip", postgresql.INET(), nullable=True),
sa.Column("observed_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
sa.Column("mhs_av", sa.Numeric(), nullable=True),
sa.Column("mhs_1m", sa.Numeric(), nullable=True),
sa.Column("mhs_15m", sa.Numeric(), nullable=True),
sa.Column("hs_rt", sa.Numeric(), nullable=True),
sa.Column("power_w", sa.Numeric(), nullable=True),
sa.Column("power_rate_w_per_th", sa.Numeric(), nullable=True),
sa.Column("env_temp_c", sa.Numeric(), nullable=True),
sa.Column("chip_temp_min_c", sa.Numeric(), nullable=True),
sa.Column("chip_temp_max_c", sa.Numeric(), nullable=True),
sa.Column("chip_temp_avg_c", sa.Numeric(), nullable=True),
sa.Column("fan_speed_in_rpm", sa.Integer(), nullable=True),
sa.Column("fan_speed_out_rpm", sa.Integer(), nullable=True),
sa.Column("uptime_seconds", sa.BigInteger(), nullable=True),
sa.Column("hash_stable", sa.Boolean(), nullable=True),
sa.Column("pool_rejected_percent", sa.Numeric(), nullable=True),
sa.Column("raw_summary_json", postgresql.JSONB(), nullable=True),
sa.Column("raw_version_json", postgresql.JSONB(), nullable=True),
sa.Column("raw_miner_info_json", postgresql.JSONB(), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
)
op.create_index("idx_miner_status_snapshots_miner_id", "miner_status_snapshots", ["miner_id"])
op.create_index("idx_miner_status_snapshots_observed_at", "miner_status_snapshots", ["observed_at"])
def downgrade() -> None:
op.drop_index("idx_miner_status_snapshots_observed_at", table_name="miner_status_snapshots")
op.drop_index("idx_miner_status_snapshots_miner_id", table_name="miner_status_snapshots")
op.drop_table("miner_status_snapshots")
op.drop_index("idx_miner_hashboards_pcb_sn", table_name="miner_hashboards")
op.drop_index("idx_miner_hashboards_miner_id", table_name="miner_hashboards")
op.drop_table("miner_hashboards")
op.drop_index("idx_miner_network_identities_is_current", table_name="miner_network_identities")
op.drop_index("idx_miner_network_identities_ip_address", table_name="miner_network_identities")
op.drop_index("idx_miner_network_identities_mac_address", table_name="miner_network_identities")
op.drop_index("idx_miner_network_identities_miner_id", table_name="miner_network_identities")
op.drop_table("miner_network_identities")
op.drop_index("idx_miners_last_seen_at", table_name="miners")
op.drop_index("idx_miners_status", table_name="miners")
op.drop_index("idx_miners_miner_sn", table_name="miners")
op.drop_index("idx_miners_current_mac", table_name="miners")
op.drop_index("idx_miners_current_ip", table_name="miners")
op.drop_index("idx_miners_room_id", table_name="miners")
op.drop_index("idx_miners_site_id", table_name="miners")
op.drop_table("miners")