docs: add repair domain design documents

This commit is contained in:
lussierj committed 2026-08-02 03:44:15 +00:00
1 parent f2b736b08e
commit 62c91a2c3e
4 files changed
+778

No files matched your search

+156
View File
@@ -0,0 +1,156 @@
# 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.