190 lines
6.0 KiB
Markdown
190 lines
6.0 KiB
Markdown
# Task 005: Repair Parts Tracking
|
|
|
|
## Status
|
|
Design specification. Not yet implemented.
|
|
|
|
## Objective
|
|
Allow authorized operators to record parts installed, removed, or consumed
|
|
during a repair while preserving immutable history and leaving room for a later
|
|
spare-parts inventory system.
|
|
|
|
## Product Intent
|
|
A technician should be able to determine what parts were installed, removed, or
|
|
consumed; their quantity and identifying serial number where relevant; any
|
|
concise notes; and the authoritative actor and timestamp.
|
|
|
|
## Scope
|
|
- proposed focused repair-part read and action APIs
|
|
- proposed capability-based permissions
|
|
- a deliberately small part type and action vocabulary
|
|
- part type, action, quantity, optional serial number, and notes
|
|
- serialized component identifiers where applicable
|
|
- explicit void/correction rather than physical deletion
|
|
- immutable repair events
|
|
- migration, constraints, tests, and documentation
|
|
|
|
## Out of Scope
|
|
Purchasing, suppliers, pricing, invoices, warehouse transfers, reorder automation, warranties, RMA, full inventory, generalized bill of materials, bulk import, automatic stock deduction, photos, work orders, and control-board identity replacement.
|
|
|
|
Task 004 remains authoritative for control-board identity and MAC changes.
|
|
Task 005 must not accept `control_board` as a generic part type or update
|
|
`miners.control_board_sn`, `miners.current_mac`, or
|
|
`miner_network_identities`.
|
|
|
|
## API
|
|
Proposed routes:
|
|
|
|
```http
|
|
GET /api/repairs/{repair_id}/parts
|
|
POST /api/repairs/{repair_id}/parts
|
|
POST /api/repairs/{repair_id}/parts/{repair_part_id}/void
|
|
```
|
|
|
|
Do not physically delete authoritative entries.
|
|
|
|
## Permissions
|
|
The proposed authorization model is:
|
|
|
|
- use implemented `repairs.read` for the read route
|
|
- introduce `repairs.parts.manage` for add and void actions
|
|
|
|
Grant the proposed write permission to Admin, Manager, and Technician. Do not
|
|
grant it to Read Only. `repairs.parts.manage` does not exist yet and must be
|
|
introduced by the Task 005 migration. The router checks capabilities rather than
|
|
role names.
|
|
|
|
## Add Request
|
|
```json
|
|
{
|
|
"part_type": "fan",
|
|
"action": "installed",
|
|
"quantity": 1,
|
|
"serial_number": null,
|
|
"notes": "Replacement fan installed."
|
|
}
|
|
```
|
|
|
|
## Initial Vocabulary
|
|
Proposed part types:
|
|
|
|
- `fan`
|
|
- `power_supply`
|
|
- `hashboard`
|
|
- `cable`
|
|
- `consumable`
|
|
- `other`
|
|
|
|
Proposed actions:
|
|
|
|
- `installed`
|
|
- `removed`
|
|
- `consumed`
|
|
|
|
Task 005 does not model source inventory, stock movement, return destination,
|
|
condition, or disposition. Those concepts require a later inventory decision
|
|
and must not be approximated with overlapping action/value combinations here.
|
|
Use notes for concise context that is not authoritative structured inventory
|
|
data.
|
|
|
|
## Quantity Rules
|
|
- quantity greater than zero
|
|
- integer quantities for this task
|
|
- serialized components normally quantity 1
|
|
- consumables may exceed 1
|
|
- voiding does not create a negative entry or reverse inventory; it marks the
|
|
original record void
|
|
|
|
## Repair State Rules
|
|
- add entries only while the repair is active
|
|
- void entries only while the repair is active
|
|
- read entries and void state after completion
|
|
- completed repairs remain read-only
|
|
- no unrestricted editing in any repair state
|
|
|
|
## Data Model
|
|
Proposed table: `repair_parts`. No such table currently exists. The legacy
|
|
`/api/repairs/parts-summary` route summarizes generic maintenance-event data and
|
|
is not an implementation of this model.
|
|
|
|
Potential fields:
|
|
- UUID
|
|
- repair UUID
|
|
- part type
|
|
- action
|
|
- quantity
|
|
- serial number
|
|
- notes
|
|
- recorded actor and timestamp
|
|
- void actor, timestamp, and reason
|
|
- related event UUID
|
|
|
|
Entries are never physically deleted. A void changes only the one-way void
|
|
metadata. It must not edit the original part type, action, quantity, serial
|
|
number, notes, recording actor, or recording timestamp. The void reason is
|
|
required; void actor and timestamp come from authentication and the server.
|
|
|
|
## Constraints
|
|
- quantity > 0
|
|
- void fields all-null or all-present
|
|
- void timestamp after recorded timestamp
|
|
- actor and recorded timestamp required
|
|
- valid constrained values and combinations
|
|
- serialized entries with a serial number have quantity 1
|
|
|
|
## Events
|
|
Proposed types:
|
|
- `REPAIR_PART_RECORDED`
|
|
- `REPAIR_PART_VOIDED`
|
|
|
|
The events are immutable history; the table is the queryable projection.
|
|
|
|
## Atomicity
|
|
Adding a part and appending its event occur in one transaction. Voiding and appending the void event occur in one transaction.
|
|
|
|
Voiding must lock the repair-part row and succeed only when its void fields are
|
|
still null. Concurrent void requests must produce one success and one conflict,
|
|
with exactly one `REPAIR_PART_VOIDED` event.
|
|
|
|
## Architecture
|
|
Preserve `Router -> Service -> Repository -> PostgreSQL`. No generic parts CRUD, router SQL, or physical deletion.
|
|
|
|
## Tests
|
|
Cover:
|
|
- authorization
|
|
- serialized and consumable entries
|
|
- removed part
|
|
- list chronology
|
|
- read after completion
|
|
- explicit void
|
|
- invalid quantities and combinations
|
|
- control-board part rejection
|
|
- add to completed repair
|
|
- already-voided conflict
|
|
- cross-repair entry conflict
|
|
- concurrent void
|
|
- rollback on event failure
|
|
- direct constraints
|
|
- Tasks 001-004 regressions
|
|
- migration lifecycle and full backend suite
|
|
|
|
## Migration
|
|
Create the focused table, add permissions and event constraints, add justified indexes, preserve legacy truth, and refuse destructive downgrade when authoritative Task 005 history exists.
|
|
|
|
## Acceptance Criteria
|
|
1. Parts can be recorded against an active repair.
|
|
2. Historical entries remain readable.
|
|
3. Entries are never physically deleted.
|
|
4. Voids are explicit and audited.
|
|
5. Actor and timestamps are authoritative.
|
|
6. Writes and events are atomic.
|
|
7. Values and quantities are constrained.
|
|
8. No warehouse or purchasing system is introduced.
|
|
9. Task 004 remains authoritative for control-board identity changes.
|
|
10. No commit or push is performed.
|
|
|
|
## Completion Report
|
|
Report files, migration, routes, permissions, schema, constraints, events, tests, migration lifecycle, architecture audit, limitations, and final status.
|
|
|
|
Do not commit.
|
|
Do not push.
|