157 lines
5.2 KiB
Markdown
157 lines
5.2 KiB
Markdown
# 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.
|