Files
minerops/docs/design/API_STYLE_GUIDE.md

5.2 KiB

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:

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:

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:

POST /api/miners/{miner_id}/replace-control-board

Good:

POST /api/repairs/{repair_id}/complete

Avoid:

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:

/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.