feat: add Repair Center operations view
This commit is contained in:
1 parent
786a1ab910
commit
4a1959ecd6
14 files changed
+1963
-338
No files matched your search
@@ -0,0 +1,96 @@
|
||||
"""Application service for the consolidated Repair Center read model."""
|
||||
|
||||
from app.repairs.center_repository import RepairCenterRepository
|
||||
from app.repairs.models import (
|
||||
RepairCenterAccess,
|
||||
RepairCenterCapabilities,
|
||||
RepairCenterFilters,
|
||||
RepairCenterItem,
|
||||
RepairCenterList,
|
||||
RepairCenterLocationOptions,
|
||||
RepairCenterMeta,
|
||||
RepairCenterResponse,
|
||||
RepairCenterSummary,
|
||||
)
|
||||
|
||||
|
||||
class RepairCenterService:
|
||||
"""Build typed, permission-aware Repair Center projections."""
|
||||
|
||||
def __init__(self, repository: RepairCenterRepository):
|
||||
self.repository = repository
|
||||
|
||||
@staticmethod
|
||||
def _capabilities(
|
||||
item: RepairCenterItem,
|
||||
access: RepairCenterAccess,
|
||||
) -> RepairCenterCapabilities:
|
||||
modular = item.source == "modular" and item.repair_id is not None
|
||||
legacy = item.source == "legacy"
|
||||
placed = bool(item.site_id and item.room_id and item.position_id)
|
||||
return RepairCenterCapabilities(
|
||||
can_open_miner=access.can_view_miners,
|
||||
can_open_map=access.can_view_locations and placed,
|
||||
can_read_modular_timeline=modular and access.can_read_repairs,
|
||||
can_read_modular_parts=modular and access.can_read_repairs,
|
||||
can_manage_modular_parts=(
|
||||
modular and item.active and access.can_read_repairs
|
||||
and access.can_manage_parts
|
||||
),
|
||||
can_complete_modular_repair=(
|
||||
modular and item.active and access.can_complete_repairs
|
||||
),
|
||||
can_read_legacy_history=legacy and access.can_read_repairs,
|
||||
can_manage_legacy=legacy and access.can_manage_legacy,
|
||||
can_mark_legacy_repaired=legacy and access.can_manage_legacy,
|
||||
can_decommission_legacy=legacy and access.can_manage_legacy,
|
||||
)
|
||||
|
||||
def list_repair_center(
|
||||
self,
|
||||
filters: RepairCenterFilters,
|
||||
access: RepairCenterAccess,
|
||||
) -> RepairCenterResponse:
|
||||
query = filters.query.strip() if filters.query else None
|
||||
model = filters.model.strip() if filters.model else None
|
||||
status = filters.status.strip() if filters.status else None
|
||||
repository_filters = filters.model_dump()
|
||||
repository_filters.update(query=query or None, model=model or None,
|
||||
status=status or None)
|
||||
projection = self.repository.list_repair_center(
|
||||
repository_filters,
|
||||
include_miner_details=access.can_view_miners,
|
||||
include_location_details=access.can_view_locations,
|
||||
)
|
||||
items: list[RepairCenterItem] = []
|
||||
for row in projection["items"]:
|
||||
row = {
|
||||
**row,
|
||||
"miner_status": row.get("runtime_status"),
|
||||
"latest_event_status": row.get("legacy_event_status"),
|
||||
"latest_event_description": row.get("latest_context"),
|
||||
"latest_event_at": row.get("latest_context_at"),
|
||||
"asset_state": row.get("legacy_asset_state"),
|
||||
"state_notes": row.get("latest_context"),
|
||||
"reported_error": row.get("reported_problem"),
|
||||
}
|
||||
item = RepairCenterItem.model_validate(
|
||||
{**row, "capabilities": RepairCenterCapabilities()}
|
||||
)
|
||||
item.capabilities = self._capabilities(item, access)
|
||||
items.append(item)
|
||||
|
||||
summary = RepairCenterSummary.model_validate(projection["summary"])
|
||||
location_options = RepairCenterLocationOptions.model_validate(
|
||||
projection.get("location_options") or {}
|
||||
)
|
||||
return RepairCenterResponse(
|
||||
data=RepairCenterList(items=items, summary=summary),
|
||||
meta=RepairCenterMeta(
|
||||
limit=filters.limit,
|
||||
offset=filters.offset,
|
||||
returned=len(items),
|
||||
total=summary.total,
|
||||
location_options=location_options,
|
||||
),
|
||||
)
|
||||
Reference in new issue
Block a user