# MinerOps Repair Domain Model ## Purpose This design guide describes repair-domain concepts, relationships, lifecycle, invariants, and operational boundaries. Implemented repository behavior and approved task specifications remain authoritative. ## Core Concepts ### Miner A durable physical mining asset whose identity is independent of IP address, MAC address, control board, hostname, location, and repair state. ### Repair A bounded operational episode for one miner. It has one start, zero or one completion, immutable timeline events, actors, and timestamps. ### Repair Event An immutable fact ordered by explicit sequence. Implemented event types are `REPAIR_STARTED`, `INITIAL_NOTE`, and `REPAIR_COMPLETED`. ### Network Identity History `miner_network_identities` associates MAC, IP, and hostname observations with a durable miner and identifies current versus historical rows. It is not a separate asset identity. ### Proposed Component History Task 004 proposes preserving control-board replacement details without redefining the miner. No dedicated immutable component-history table currently exists; the legacy generic maintenance-event table is not the modular repair timeline. ### Proposed Repair Part Entry Task 005 proposes a record of a part installed, removed, or consumed during a repair. It is not a warehouse inventory transaction, and no `repair_parts` table currently exists. ## Relationships Current relationships: ```text Miner -> many Repairs -> ordered Repair Events Miner -> Network Identity History ``` Control-board replacement history and repair-part entries are proposed extensions, not implemented relationships. ## Lifecycle Current miner states relevant to repair: - `active` - `spare` - `in_repair` - `retired` Eligible Begin Repair sources: - active - spare Eligible Return to Service destinations: - active - spare Terminal: - retired The repair schema defines these statuses: - Active: `OPEN`, `IN_PROGRESS`, `WAITING_FOR_PARTS`, `READY_FOR_TEST` - Terminal: `COMPLETED`, `CANCELLED` The modular API currently creates repairs as `OPEN` and can complete any active repair. It does not provide status-transition or cancellation routes. The implemented modular workflow is therefore: ```text OPEN -> COMPLETED ``` The other active values remain valid schema states for compatibility and later explicit workflows. Cancellation or abandonment requires a separate task. ## Current Workflow ```text Miner active/spare -> Begin Repair -> Miner in_repair -> Timeline events -> Return to Service -> Miner active/spare -> Repair completed ``` ## Invariants - replacing a board or MAC must not create a new miner - asset-ID and network-identity history must be preserved - no more than one active repair per miner is database-enforced - modular repair actions require the miner and repair state to agree - Return to Service prevents a completed repair from leaving the miner in `in_repair` - multi-record transitions are atomic - events are append-only and explicitly sequenced - actor comes from authentication - timestamps are server/database controlled - new completions require completion time, actor, and eligible resulting lifecycle - legacy unknown values remain unknown rather than fabricated ## Transaction Boundaries ### Begin Repair Lock miner, create repair, transition miner to `in_repair`, append start event. ### Return to Service Lock miner, lock repair, validate active state, complete repair, transition miner to active/spare, append completion event. ### Proposed Control Board Replacement Task 004 proposes locking miner, active repair, and network-identity rows; validating MAC ownership; updating current projections; and appending one event. ### Proposed Repair Part Recording Task 005 proposes locking the affected repair or repair-part row, adding or voiding the entry, and appending the corresponding event atomically. ## Lock Order Use: ```text Miner -> Repair -> related rows ``` This aligns workflows and reduces deadlock risk. ## Commands vs CRUD Implemented explicit commands: - Begin Repair - Return to Service Proposed explicit commands: - Replace Control Board - Record Repair Part - Void Repair Part Avoid generic repair patches for meaningful operations. ## Read Models Implemented modular reads: - repair detail - ordered repair timeline The integrated application also has legacy repair-queue, parts-summary, and miner network-identity reads. Those routes are compatibility behavior, not the proposed Task 004 or Task 005 read models. Proposed focused reads include repair parts and control-board replacement history. Read models do not weaken write invariants. ## Permissions Implemented permissions: - `repairs.read` - `repairs.create` - `repairs.complete` Proposed permissions: - `repairs.parts.manage` - `miners.replace_control_board` Task 005 reuses `repairs.read` for its proposed read route. Roles receive capabilities; endpoints should not hard-code role names when permission checks exist. ## Legacy Data Preserve truth, allow nullable historical fields where necessary, enforce stronger rules for new or updated rows, use PostgreSQL `NOT VALID` constraints where appropriate, and never backfill invented actors, states, or events. ## Future Extensions Repair cancellation, diagnosis, work orders, technician assignment, burn-in testing, photos, warranty/RMA, component inventory, and donor-unit tracking should each arrive through explicit tasks.