feat: add repair timeline read APIs

This commit is contained in:
lussierj committed 2026-07-29 16:28:44 +00:00
1 parent f6a2512e23
commit 36a0caecd8
16 files changed
+1562 -9

No files matched your search

+6 -3
View File
@@ -99,9 +99,11 @@ durable asset record. Repairs, maintenance, work orders, parts usage, equipment
movement, testing, and return-to-service history become coherent operational
records rather than disconnected actions.
The Begin Repair workflow is complete. An authorized actor can open a repair
against a durable miner UUID, record sequenced starting events, and move the
miner into repair atomically. Later repair lifecycle workflows remain planned.
The Begin Repair and read-only Repair Timeline workflows are complete. An
authorized actor can open a repair against a durable miner UUID, record
sequenced starting events, and move the miner into repair atomically. Authorized
readers can inspect the repair and its ordered immutable events. Later repair
lifecycle workflows remain planned.
Technician experience is a priority. Responsive and QR-assisted workflows may
reduce lookup and data-entry effort where they reinforce the same asset record.
@@ -214,6 +216,7 @@ Major completed foundations include:
- Manual Inventory schema and backend domain foundation
- Focused Inventory and migration test foundations
- Begin Repair operational workflow
- Read-only Repair Timeline API
- MinerOps branding package and project README
- Architecture guide
- Product guide
+183
View File
@@ -0,0 +1,183 @@
# Task 002: Repair Timeline
## Objective
Add read-only APIs for viewing one repair and its immutable timeline.
## Scope
Add exactly these two endpoints:
```http
GET /api/repairs/{repair_id}
GET /api/repairs/{repair_id}/events
```
Do not add any other repair endpoints.
## Permissions
Add:
```text
repairs.read
```
Grant it to Admin, Manager, Technician, and Read Only. Existing `repairs.create` access remains unchanged.
## Architecture
Preserve:
```text
Router -> Service -> Repository -> PostgreSQL
```
Routers contain no SQL or transaction logic. Services contain no FastAPI dependencies. Repositories contain no FastAPI imports. Reads must not modify data.
## GET /api/repairs/{repair_id}
Return:
```json
{
"repair_id": "uuid",
"miner_id": "uuid",
"miner_asset_id": "string",
"status": "OPEN",
"reason": "INSPECTION",
"opened_at": "timestamp",
"opened_by": {
"user_id": "uuid",
"display_name": "string"
},
"closed_at": null,
"closed_by": null,
"miner_lifecycle": "in_repair",
"latest_event_sequence": 2
}
```
Requirements:
- Return 404 when the repair does not exist.
- Return the current miner lifecycle.
- Resolve actor identity using existing user conventions.
- Obtain `latest_event_sequence` from authoritative event data.
- Do not infer missing history or expose internal-only fields.
## GET /api/repairs/{repair_id}/events
Return:
```json
{
"repair_id": "uuid",
"events": [
{
"event_id": "uuid",
"sequence": 1,
"event_type": "REPAIR_STARTED",
"actor": {
"user_id": "uuid",
"display_name": "string"
},
"occurred_at": "timestamp",
"payload": {
"reason": "INSPECTION",
"from_lifecycle": "active",
"to_lifecycle": "in_repair"
}
}
]
}
```
Requirements:
- Return 404 when the repair does not exist.
- Return all events ordered strictly by database sequence ascending.
- Do not order only by timestamp.
- Preserve payload as structured JSON.
- Avoid N+1 actor lookups.
## Timeline Invariants
Events are immutable. This task must not add support for editing, deleting, replacing, or reordering timeline events. Corrections must be represented by new events.
## Models and Validation
- Use UUID types for identifiers.
- Use timezone-aware datetime types.
- Reuse existing constrained status, reason, lifecycle, and event types where practical.
- Represent payloads as structured JSON, not serialized strings.
- Avoid exposing unexpected internal fields.
## Repository Requirements
Add focused read methods for repair detail and ordered repair events. Queries should include miner asset ID, current lifecycle, actor display data, and latest event sequence. Do not add broad list or search methods.
## Service Requirements
The service must validate existence, coordinate repository reads, map missing repairs to the domain-standard not-found exception, and contain no SQL or FastAPI dependencies.
## Router Requirements
Expose exactly the two routes in this specification, require `repairs.read`, follow existing exception patterns, and contain no SQL, commits, or transaction management.
## Migration
Create the next Alembic revision only if required to add `repairs.read` and role assignments. Preserve existing permissions and provide a complete downgrade. Do not alter repair tables unless a material incompatibility is found; report that conflict before deviating.
## Tests
Cover at least:
- 401 unauthenticated
- 403 unauthorized
- Read Only can read detail and events
- Admin, Manager, and Technician can read
- `repairs.create` behavior remains unchanged
- existing repair detail
- missing repair 404
- asset ID, lifecycle, actor, nullable closed fields, and latest sequence
- sequence ordering even when timestamps are equal or non-monotonic
- structured JSON payload
- actor data
- explicit empty-timeline behavior
- Begin Repair regression
- Inventory regression
- migration upgrade, downgrade, re-upgrade, and empty database through head
- exactly two new routes
- architecture audits
## Validation
Run:
- Python compilation
- shell syntax validation
- focused timeline tests
- existing Begin Repair tests
- inventory regression tests
- migration validation
- disposable development baseline
- router SQL/driver/transaction audit
- service/repository FastAPI audit
- exact route-count audit
- `git diff --check`
## Documentation
Update `docs/ROADMAP.md` only after implementation and validation pass. Do not add an ADR unless a genuinely new architectural decision is required.
## Explicitly Out of Scope
Do not implement repair listing, search, pagination, adding or editing notes, deleting events, completion, return to service, cancellation, assignment, diagnostics, parts, photos, control-board replacement, generic CRUD, or UI changes.
## Completion Report
Report files created and modified, migration revision if any, routes, permission changes, tests and validation, and final `git status --short`.
Do not commit.
Do not push.