Publish curated MobilityOps source snapshot
This commit is contained in:
commit
7adc072f5e
317 files changed
+48851
No files matched your search
@@ -0,0 +1,77 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date
|
||||
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.data_quality import DataQualityIssue
|
||||
from app.models.outbox import OutboxEvent
|
||||
from app.models.vehicle import Vehicle
|
||||
from app.schemas import DashboardMetrics
|
||||
|
||||
SEVERITY_ORDER = {"high": 0, "medium": 1, "low": 2}
|
||||
|
||||
|
||||
def compute_metrics(db: Session) -> DashboardMetrics:
|
||||
"""Shared operations-summary computation used by both the dashboard and the MCP
|
||||
provider API, so the two never drift out of sync with two copies of the same query."""
|
||||
status_counts: dict[str, int] = dict(
|
||||
db.execute(
|
||||
select(Vehicle.operational_status, func.count()).group_by(Vehicle.operational_status)
|
||||
).all() # type: ignore[arg-type]
|
||||
)
|
||||
open_issues = db.scalar(
|
||||
select(func.count()).select_from(DataQualityIssue).where(DataQualityIssue.status == "open")
|
||||
)
|
||||
pending_or_failed = db.scalar(
|
||||
select(func.count())
|
||||
.select_from(OutboxEvent)
|
||||
.where(OutboxEvent.delivery_status.in_(["pending", "failed"]))
|
||||
)
|
||||
return DashboardMetrics(
|
||||
available=status_counts.get("available", 0),
|
||||
rented=status_counts.get("rented", 0),
|
||||
cleaning=status_counts.get("cleaning", 0),
|
||||
maintenance=status_counts.get("maintenance", 0),
|
||||
blocked=status_counts.get("blocked", 0),
|
||||
open_quality_issues=open_issues or 0,
|
||||
pending_or_failed_workflows=pending_or_failed or 0,
|
||||
)
|
||||
|
||||
|
||||
def list_attention_vehicles(
|
||||
db: Session, minimum_severity: str = "medium", on_or_before: date | None = None, limit: int = 20
|
||||
) -> list[dict]:
|
||||
max_rank = SEVERITY_ORDER.get(minimum_severity, 1)
|
||||
stmt = (
|
||||
select(DataQualityIssue)
|
||||
.where(DataQualityIssue.entity_type == "vehicle", DataQualityIssue.status == "open")
|
||||
.order_by(DataQualityIssue.detected_at.asc())
|
||||
)
|
||||
if on_or_before is not None:
|
||||
stmt = stmt.where(func.date(DataQualityIssue.detected_at) <= on_or_before)
|
||||
issues = db.scalars(stmt).all()
|
||||
filtered = [i for i in issues if SEVERITY_ORDER.get(i.severity, 3) <= max_rank]
|
||||
filtered.sort(key=lambda i: SEVERITY_ORDER.get(i.severity, 3))
|
||||
|
||||
vehicle_ids = {i.entity_id for i in filtered}
|
||||
vehicles_by_id = {
|
||||
v.id: v for v in db.scalars(select(Vehicle).where(Vehicle.id.in_(vehicle_ids))).all()
|
||||
}
|
||||
|
||||
results = []
|
||||
for issue in filtered[:limit]:
|
||||
vehicle = vehicles_by_id.get(issue.entity_id)
|
||||
if vehicle is None:
|
||||
continue
|
||||
results.append(
|
||||
{
|
||||
"vehicle_ref": vehicle.public_ref,
|
||||
"severity": issue.severity,
|
||||
"rule_type": issue.rule_type,
|
||||
"summary": issue.evidence_json.get("summary", ""),
|
||||
"detected_at": issue.detected_at,
|
||||
}
|
||||
)
|
||||
return results
|
||||
Reference in new issue
Block a user