From 93e034ea07beb7e93a475ebf1222e8edddce3b00 Mon Sep 17 00:00:00 2001 From: JC Date: Tue, 28 Jul 2026 17:51:41 +0000 Subject: [PATCH] docs: add architecture decision records --- docs/DECISIONS.md | 372 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 372 insertions(+) create mode 100644 docs/DECISIONS.md diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md new file mode 100644 index 0000000..8c7ae00 --- /dev/null +++ b/docs/DECISIONS.md @@ -0,0 +1,372 @@ +# MinerOps Architecture & Product Decisions + +This document records long-lived engineering and product decisions for +MinerOps. Each record explains the context, the chosen approach, and its +consequences so future work can preserve intent rather than infer it from code. + +Decisions may evolve as operational evidence changes. Replacing or reversing a +decision should be deliberate and documented in a later record. Existing +records should remain available as history rather than being silently rewritten. + +--- + +# ADR-0001 + +**Title:** MinerOps is self-hosted first. + +## Context + +Mining operations depend on local equipment, segmented networks, and +operational records that may need to remain under direct organizational control. +Requiring a hosted service would make availability, data access, and subscription +terms dependencies of core operations. + +External services can still provide useful integrations. The question is +whether they are optional participants or mandatory owners of the operational +record. + +## Decision + +MinerOps is self-hosted first. Operators control the deployment and retain +ownership of their operational data. Core use must not require a mandatory SaaS +subscription or transfer the authoritative record to a hosted provider. + +Remote access and integrations are allowed when the operator chooses them. They +must not change the self-hosted deployment into a secondary cache of a required +external service. + +## Consequences + +**Benefits:** Operators can place MinerOps near local mining networks, retain +control of data and availability, and use it in restricted environments. + +**Tradeoffs:** Operators are responsible for deployment, updates, backups, and +recovery. Optional hosted integrations must be designed so loss of the +integration does not remove ownership of the core record. + +--- + +# ADR-0002 + +**Title:** Assets use durable internal identity. + +## Context + +A miner's observable properties change during normal operations. IP addresses +change, network interfaces and control boards are replaced, equipment moves, +and operator-facing labels may be corrected. None of those changes should make +the asset appear to be a different historical object by default. + +Operators also need a practical label that can be printed, scanned, and used in +conversation without exposing an internal database key. + +## Decision + +Every miner asset has an immutable internal UUID. That UUID is the durable +identity used for relationships and history. + +The Asset ID is the operator-facing identifier. It is unique within a MinerOps +installation and can be managed independently of mutable network values. IP +addresses, MAC addresses, hardware serials, and location are attributes or +associations of the asset, not substitutes for its internal identity. + +Hardware replacement does not automatically create a new asset identity. The +correct outcome depends on whether the operation represents repair of the same +asset or introduction of a genuinely different asset, and that distinction must +be explicit. + +## Consequences + +**Benefits:** Records can remain connected through network changes, movement, +and component replacement. Internal relationships do not depend on a mutable or +human-entered value. + +**Tradeoffs:** Imports, discovery, and repair workflows must resolve observations +to an existing UUID or deliberately create a new asset. Duplicate resolution +cannot safely rely on IP or MAC alone. + +--- + +# ADR-0003 + +**Title:** Network identity is not asset identity. + +## Context + +Discovery observes devices through IP addresses, MAC addresses, hostnames, and +protocol responses. These values are useful for finding and communicating with +a miner, but they can change because of DHCP, network reconfiguration, control +board replacement, or data correction. + +Treating the latest network observation as the asset identity loses continuity +and can attach history to the wrong equipment. + +## Decision + +Network identities are associated with durable assets. Current IP and MAC values +represent the latest known network state, while meaningful prior associations +should remain available as history. + +Discovery proposes or updates associations; it does not redefine the asset +solely because an address changed. Ambiguous matches require a deliberate +identity workflow rather than silent merging or replacement. + +## Consequences + +**Benefits:** Discovery can remain useful without erasing asset continuity. +Operators can understand address changes and component replacement in historical +context. + +**Tradeoffs:** Matching requires more information and explicit conflict handling. +Some observations cannot be attached automatically, and network history adds +records that must be maintained and presented clearly. + +--- + +# ADR-0004 + +**Title:** Business logic belongs in services. + +## Context + +When business rules are implemented in HTTP handlers, they become coupled to a +transport and are difficult to reuse or test. When they are placed in database +code, persistence concerns become mixed with product decisions. + +MinerOps has existing integrated routes that predate the current domain +boundaries. Copying that structure would continue the coupling. + +## Decision + +Domain services own normalization, business validation, decisions, state-change +rules, and use-case orchestration. Routers handle HTTP concerns and call +services. Repositories persist the outcomes requested by services. + +Services raise domain errors and return domain results. They do not depend on +FastAPI requests, responses, decorators, or status codes. The Inventory service +is the current reference for this separation. + +## Consequences + +**Benefits:** Business behavior can be tested without HTTP or a real database, +used by more than one adapter, and maintained in one explicit location. + +**Tradeoffs:** Features require an additional boundary and clear input and output +contracts. Poorly chosen service responsibilities can become overly broad, so +service ownership must follow domain use cases rather than convenience. + +--- + +# ADR-0005 + +**Title:** Persistence is isolated behind repositories. + +## Context + +SQL embedded in routes or services couples product behavior to schema details, +connection handling, and a specific database driver. Repeated queries also make +ownership unclear and allow filtering or transaction behavior to diverge. + +Tests need a boundary where service behavior can substitute persistence and +where database behavior can be verified independently. + +## Decision + +Each domain isolates its database access behind repositories. Repositories own +SQL, database-facing filtering and ordering, connection and transaction +mechanics, and persistence mapping. + +Routers and services do not issue SQL. A domain owns persistence for its records, +and another domain does not bypass that ownership by importing its repository +to perform unrelated writes. + +## Consequences + +**Benefits:** SQL has explicit ownership, service tests can use substitutes, +repository tests can target real database behavior, and persistence changes have +a defined boundary. + +**Tradeoffs:** Repository interfaces must be maintained, and cross-domain read +requirements need deliberate query ownership. A repository is not an excuse to +hide business rules in database code. + +--- + +# ADR-0006 + +**Title:** Database schema changes use Alembic. + +## Context + +Persistent schema must be reproducible across new installations, existing +deployments, tests, and recovery environments. Runtime table creation makes +schema state depend on which application paths have executed and is difficult +to review or reverse. + +The existing application contains legacy runtime schema creation for +compatibility, but the repository now has a versioned Alembic migration chain +and focused migration tests. + +## Decision + +New persistent schema changes are made through explicit, versioned Alembic +migrations. A migration documents upgrade behavior, treatment of existing data, +constraints and indexes, and a downgrade path where it is safe and meaningful. + +New code must not create or alter persistent tables at application runtime. +Legacy runtime schema behavior is an existing compatibility condition, not a +pattern for new work. + +## Consequences + +**Benefits:** Schema state is reviewable, reproducible, testable, and ordered. +Deployments and disposable tests can reach the same known schema from an empty +or existing database. + +**Tradeoffs:** Schema work requires migration design and validation before the +application can use it. Some destructive downgrades cannot preserve all data and +must be documented explicitly. + +--- + +# ADR-0007 + +**Title:** Operational history is preserved. + +## Context + +The current value of an asset does not explain how it arrived there. Repairs, +movement, lifecycle changes, network identity changes, component replacement, +and operator actions all affect operational understanding. + +Overwriting important changes may simplify the current record but removes the +context technicians and managers need to diagnose problems and trust the +system. + +## Decision + +MinerOps preserves meaningful operational history. Current state remains easy +to identify, while important repairs, movement, lifecycle events, identity +associations, and audited actions remain traceable with time and context. + +Corrections must not silently destroy history that remains operationally +relevant. Retention policy may summarize high-volume observations, but durable +asset, repair, movement, lifecycle, and audit meaning is preserved. + +## Consequences + +**Benefits:** Operators can understand an asset across its lifecycle, technicians +can review prior work, and changes can be audited and explained. + +**Tradeoffs:** Historical data requires storage, retention policy, and interfaces +that distinguish current state from prior state. Corrections and privacy or +retention requirements need deliberate handling. + +--- + +# ADR-0008 + +**Title:** Safety takes precedence over convenience. + +## Context + +MinerOps can coordinate actions that interrupt individual miners or affect a +large part of a fleet. A fast or convenient action can create substantial +operational impact when its target, scope, timing, or authorization is wrong. + +Bulk operations and automation increase this risk because one request may affect +many devices without individual review. + +## Decision + +Potentially disruptive actions favor safety over minimum interaction. Product +workflows enforce permissions, communicate target and scope, require clear +confirmation where appropriate, and leave an audit trail. + +Broad actions should support safeguards such as preview or dry-run behavior, +staggering, limits, expiry, and awareness of maintenance or intentionally +offline state when those safeguards apply. Development and new installations +use safe defaults. + +## Consequences + +**Benefits:** Operators receive clearer intent and accountability, accidental +fleet-wide disruption is less likely, and actions can be investigated after the +fact. + +**Tradeoffs:** Some operations require more steps and may complete more slowly. +Safety behavior adds product and test complexity and must be maintained rather +than bypassed for convenience. + +--- + +# ADR-0009 + +**Title:** Progressive complexity. + +## Context + +Mining operations vary from small fleets with simple inventory needs to +multi-site organizations with detailed infrastructure, automation, and role +requirements. Requiring every installation to configure the largest possible +model would make basic workflows difficult to adopt and maintain. + +At the same time, limiting the product to the smallest deployment would prevent +larger operators from representing their real work. + +## Decision + +MinerOps exposes useful basic workflows without requiring every advanced +capability. Operators can begin with the records and structure they need, then +adopt additional location depth, monitoring, automation, integrations, and +organizational controls as their operation requires them. + +Advanced features remain coherent extensions of the same operational record. +They do not create a separate product mode or make basic asset and repair work +dependent on unrelated configuration. + +## Consequences + +**Benefits:** Small deployments can gain value with less setup, while larger +deployments have room to model additional complexity without abandoning the +same system of record. + +**Tradeoffs:** Defaults and optional states must be designed carefully. Features +must work when advanced context is absent, which increases the number of valid +configurations that testing must cover. + +--- + +# ADR-0010 + +**Title:** Architecture evolves incrementally. + +## Context + +MinerOps contains working early-stage software alongside newer domain +boundaries. Replacing the application in one rewrite would put existing +workflows, data compatibility, and validation at unnecessary risk. + +Leaving all existing responsibilities in integrated modules would also make new +features harder to test and maintain. + +## Decision + +Architecture improves incrementally. New domain code follows the established +router, service, and repository boundaries. Existing behavior moves behind +those boundaries in small, reviewable changes that preserve working software +and include compatibility validation. + +A new boundary is introduced when it clarifies ownership or testability, not +merely to rename or relocate code. Existing integrated code is context to +preserve, not a template to duplicate. + +## Consequences + +**Benefits:** Architectural quality improves while the application remains +usable. Smaller changes are easier to review, test, diagnose, and reverse. + +**Tradeoffs:** The repository will contain transitional patterns for a period of +time. Contributors must understand which code represents current rules and +which code remains for compatibility, and some temporary duplication may need +careful removal after migration.