feat: add repair timeline read APIs
This commit is contained in:
1 parent
f6a2512e23
commit
36a0caecd8
16 files changed
+1562
-9
No files matched your search
+6
-3
@@ -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
|
||||
|
||||
@@ -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.
|
||||
Reference in new issue
Block a user