M18: implement operational workspaces

This commit is contained in:
NuklearRabbit
2026-08-10 12:41:28 +02:00
parent 8030753dbc
commit fe06ff75a1
33 changed files with 1082 additions and 95 deletions
+14 -10
View File
@@ -2,7 +2,7 @@ from __future__ import annotations
import uuid
from dataclasses import dataclass, field
from datetime import UTC, datetime
from datetime import UTC, datetime, timedelta
from difflib import SequenceMatcher
from sqlalchemy import select, update
@@ -28,6 +28,15 @@ REQUIRED_VEHICLE_FIELDS = ("registration_number", "make", "model", "location")
DUPLICATE_THRESHOLD = 70
def issue_due_at(detected_at: datetime, severity: str) -> datetime:
"""Return the local operational SLA deadline for a newly detected issue."""
return detected_at + {
"high": timedelta(hours=4),
"medium": timedelta(days=1),
"low": timedelta(days=3),
}.get(severity, timedelta(days=1))
@dataclass
class ScanResult:
created: dict[str, int] = field(default_factory=dict)
@@ -112,6 +121,7 @@ def _open_issue(
evidence_json=evidence,
proposed_action_json={},
detected_at=now,
due_at=issue_due_at(now, severity),
)
db.add(issue)
db.flush()
@@ -280,9 +290,7 @@ def _scan_odometer_regressions(db: Session, scan: ScanResult) -> None:
vehicles = {v.id: v for v in db.scalars(select(Vehicle)).all()}
bookings_by_vehicle: dict[uuid.UUID, list[Booking]] = {}
for booking in db.scalars(
select(Booking).where(
Booking.status == "returned", Booking.end_odometer_km.is_not(None)
)
select(Booking).where(Booking.status == "returned", Booking.end_odometer_km.is_not(None))
).all():
bookings_by_vehicle.setdefault(booking.vehicle_id, []).append(booking)
@@ -346,9 +354,7 @@ def run_scan(
def _load_open_issue(db: Session, public_ref: str) -> DataQualityIssue:
issue = db.scalar(
select(DataQualityIssue).where(DataQualityIssue.public_ref == public_ref)
)
issue = db.scalar(select(DataQualityIssue).where(DataQualityIssue.public_ref == public_ref))
if issue is None:
raise AppError("ISSUE_NOT_FOUND", "Data quality issue not found.", status_code=404)
if issue.status != "open":
@@ -750,9 +756,7 @@ def apply_recommended_status(
# recommendation alone for the post-condition.
post_facts = gather_vehicle_status_facts(db, vehicle, exclude_issue_id=issue.id)
post_check = evaluate_vehicle_status(vehicle, post_facts)
if post_check.recommendation_code not in (
RECOMMENDATION_CODE_NO_CONFLICT,
):
if post_check.recommendation_code not in (RECOMMENDATION_CODE_NO_CONFLICT,):
raise AppError(
"CONFLICT_STILL_PRESENT",
"Applying the recommended status did not resolve the conflict.",
+2 -1
View File
@@ -2,7 +2,7 @@ from __future__ import annotations
import uuid
from dataclasses import dataclass
from datetime import UTC, datetime
from datetime import UTC, datetime, timedelta
from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
@@ -255,6 +255,7 @@ def register_vehicle_return(
},
proposed_action_json={},
detected_at=now,
due_at=now + timedelta(days=1),
)
db.add(issue)
db.flush()