125 lines
5.0 KiB
Python
125 lines
5.0 KiB
Python
"""Application service for the consolidated Repair Center read model."""
|
|
|
|
from app.repairs.center_repository import RepairCenterRepository
|
|
from app.repairs.models import (
|
|
ActiveRepairSummary,
|
|
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,
|
|
),
|
|
)
|
|
|
|
def list_miner_repairs(
|
|
self, miner_id, access: RepairCenterAccess
|
|
) -> list[RepairCenterItem]:
|
|
items = []
|
|
for row in self.repository.list_miner_repairs(miner_id):
|
|
mapped = {
|
|
**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(
|
|
{**mapped, "capabilities": RepairCenterCapabilities()}
|
|
)
|
|
item.capabilities = self._capabilities(item, access)
|
|
items.append(item)
|
|
return items
|
|
|
|
def summarize_active_repairs(self) -> ActiveRepairSummary:
|
|
return ActiveRepairSummary.model_validate(
|
|
self.repository.summarize_active_repairs()
|
|
)
|