# MinerOps API Style Guide ## Purpose Keep MinerOps APIs explicit, consistent, auditable, and aligned with the domain architecture. Implemented conventions and approved task specifications take precedence. ## Principles 1. Prefer domain commands over generic CRUD. 2. Use nouns for resources and explicit action routes for operational commands. 3. Keep writes focused and atomic. 4. Return truthful domain representations. 5. Separate authentication, permission, validation, domain logic, and persistence. 6. Preserve static-route compatibility. 7. Do not expose database structure as the public API. ## Current and Proposed Examples Implemented modular repair routes: ```http POST /api/repairs GET /api/repairs/{repair_id} GET /api/repairs/{repair_id}/events POST /api/repairs/{repair_id}/complete ``` Relevant legacy compatibility routes include: ```http GET /api/repairs/queue GET /api/repairs/parts-summary POST /api/miners/{miner_id}/change-mac ``` These integrated routes predate the modular domain conventions and are not models for new code. Proposed by Task 004, not implemented: ```http POST /api/miners/{miner_id}/replace-control-board ``` Good: ```http POST /api/repairs/{repair_id}/complete ``` Avoid: ```http PATCH /api/repairs/{repair_id} {"status":"completed"} ``` ## Methods - GET is read-only. - POST creates a resource or invokes an explicit command. - PATCH is limited to non-operational metadata when partial update semantics are appropriate. - Meaningful operational changes use explicit commands rather than generic PUT, PATCH, or DELETE routes. - Historical records are corrected with explicit append-only or void workflows, not physical deletion. ## Status Codes - 200: successful read or command with response - 201: created resource - 204: success with no useful response - 401: unauthenticated - 403: lacks permission - 404: resource missing - 409: valid request conflicts with domain state - 422: request validation failure ## Identifiers Use typed UUIDs for authoritative entity identifiers. Do not expose sequential database IDs as public identity. ## Time and Actors Use timezone-aware ISO 8601 timestamps. Authoritative timestamps and actor IDs are server controlled. Never accept client-supplied event actor, event timestamp, completion timestamp, or sequence. ## Permissions Implemented modular repair capabilities are: - `repairs.read` - `repairs.create` - `repairs.complete` Task 004 proposes `miners.replace_control_board`; it is not registered today. Do not duplicate role logic in routers. ## Request Models Use constrained types, normalize whitespace, reject unknown values, enforce length limits, avoid persistence-only fields, and never accept arbitrary client event payloads. ## Response Models The modular Inventory and Repairs APIs use typed success envelopes containing `data`, `meta`, and `error`. Expose useful domain state, not secrets or unrelated nested data. Preserve null when historical truth is unknown. ## Errors The application does not yet have one uniform typed error envelope. Modular routes currently use FastAPI validation responses and `HTTPException` detail responses while translating domain exceptions to 404, 409, or 422 as appropriate. New routes must follow the established behavior of their domain and must not leak SQL or driver errors. Repositories do not raise HTTP exceptions. Services do not import FastAPI. ## Pagination Potentially large collections require a bounded pagination design. The current Inventory collection uses bounded `limit` and `offset`; do not claim cursor pagination until a domain adopts it. The implemented repair timeline returns all events for one repair by explicit Task 002 design. Any later change to that contract requires compatibility review. ## Filtering Use explicit allowlisted filters and sort fields. Never pass arbitrary column names into queries. ## Static Routes Register static routes before overlapping UUID routes: ```text /api/repairs/queue /api/repairs/parts-summary /api/repairs/{repair_id} ``` Add route-precedence tests. ## Idempotency and Concurrency Use database invariants, row locks, affected-row checks, and narrow operation identifiers where demonstrated need exists. Do not add a generalized idempotency platform speculatively. The implemented repair workflows prevent duplicate active repairs, duplicate completion, duplicate event sequences, and partial state. Task 004 proposes the additional invariant that concurrent requests cannot assign one normalized MAC to two miners. ## Events Clients request domain actions, not raw events. The service constructs immutable events. ## Versioning MinerOps does not currently expose versioned API prefixes. Any incompatible API versioning scheme requires a separate compatibility decision; this guide does not reserve a future path. ## Route Specification Checklist Every new route should define: - method and path - authentication and permission - request and response - status codes - domain rules - transaction boundary - concurrency behavior - events - tests - out-of-scope items ## Review Checklist Confirm explicit action choice, status codes, permission, actor and timestamp authority, UUID typing, limits, transaction, concurrency, event construction, route precedence, architecture boundaries, and regressions.