feat: add repair parts tracking

This commit is contained in:
lussierj committed 2026-08-02 21:26:15 +00:00
1 parent 6e550c1c13
commit eab9646960
23 files changed
+2386 -4

No files matched your search

+111
View File
@@ -15,6 +15,10 @@ from app.repairs.exceptions import (
RepairConflict,
RepairMinerNotFound,
RepairNotFound,
RepairPartActorRequired,
RepairPartComponentNotFound,
RepairPartNotFound,
RepairPartValidationError,
)
from app.repairs.models import (
BeginRepairRequest,
@@ -24,6 +28,10 @@ from app.repairs.models import (
RepairCompleteRequest,
RepairDetailResponse,
RepairTimelineResponse,
RepairPartListResponse,
RepairPartRecordRequest,
RepairPartResponse,
RepairPartVoidRequest,
)
from app.repairs.service import RepairService
@@ -33,6 +41,7 @@ control_board_router = APIRouter(prefix="/api/miners", tags=["miners"])
require_repair_create = require_permission("repairs.create")
require_repair_read = require_permission("repairs.read")
require_repair_complete = require_permission("repairs.complete")
require_repair_parts_manage = require_permission("repairs.parts.manage")
require_control_board_replace = require_permission("miners.replace_control_board")
RepairServiceDependency = Annotated[
@@ -42,6 +51,7 @@ RepairServiceDependency = Annotated[
RepairCreateUser = Annotated[dict, Depends(require_repair_create)]
RepairReadUser = Annotated[dict, Depends(require_repair_read)]
RepairCompleteUser = Annotated[dict, Depends(require_repair_complete)]
RepairPartsManageUser = Annotated[dict, Depends(require_repair_parts_manage)]
ControlBoardReplaceUser = Annotated[dict, Depends(require_control_board_replace)]
@@ -149,6 +159,107 @@ def complete_repair(
return RepairDetailResponse(data=repair)
@router.get(
"/{repair_id}/parts",
response_model=RepairPartListResponse,
)
def list_repair_parts(
repair_id: UUID,
service: RepairServiceDependency,
current_user: RepairReadUser,
) -> RepairPartListResponse:
del current_user
try:
parts = service.list_repair_parts(repair_id)
except RepairNotFound as exc:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Repair not found",
) from exc
return RepairPartListResponse(data=parts)
@router.post(
"/{repair_id}/parts",
response_model=RepairPartResponse,
status_code=status.HTTP_201_CREATED,
)
def record_repair_part(
repair_id: UUID,
request: RepairPartRecordRequest,
service: RepairServiceDependency,
current_user: RepairPartsManageUser,
) -> RepairPartResponse:
try:
part = service.record_repair_part(
repair_id,
request,
actor_user_id=UUID(str(current_user["id"])),
)
except (RepairNotFound, RepairPartComponentNotFound) as exc:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=str(exc),
) from exc
except RepairMinerNotFound as exc:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Repair miner no longer exists",
) from exc
except RepairConflict as exc:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail=str(exc),
) from exc
except (RepairPartActorRequired, RepairPartValidationError) as exc:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=str(exc),
) from exc
return RepairPartResponse(data=part)
@router.post(
"/{repair_id}/parts/{repair_part_id}/void",
response_model=RepairPartResponse,
)
def void_repair_part(
repair_id: UUID,
repair_part_id: UUID,
request: RepairPartVoidRequest,
service: RepairServiceDependency,
current_user: RepairPartsManageUser,
) -> RepairPartResponse:
try:
part = service.void_repair_part(
repair_id,
repair_part_id,
request,
actor_user_id=UUID(str(current_user["id"])),
)
except (RepairNotFound, RepairPartNotFound) as exc:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=str(exc),
) from exc
except RepairMinerNotFound as exc:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Repair miner no longer exists",
) from exc
except RepairConflict as exc:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail=str(exc),
) from exc
except (RepairPartActorRequired, RepairPartValidationError) as exc:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=str(exc),
) from exc
return RepairPartResponse(data=part)
@router.get(
"/{repair_id}",
response_model=RepairDetailResponse,