fix(workbench): remove synthetic check projections

This commit is contained in:
2026-09-24 12:01:01 +08:00
parent 1a6ff64bbe
commit e374b5b3cb
25 changed files with 953 additions and 935 deletions
+29 -5
View File
@@ -10,6 +10,8 @@ from uuid import NAMESPACE_URL, uuid5
import httpx
from samples.peripheral.seed_identity import SEED_ACTOR_ID
try:
from scripts.run_operational_worker import CredentialProvider, WorkerSettings
except ModuleNotFoundError:
@@ -19,18 +21,34 @@ except ModuleNotFoundError:
logger = logging.getLogger("peripheral-task-sync")
STATUS = {"draft": "scheduled", "open": "assigned", "in_progress": "in_progress",
"awaiting_reply": "awaiting_feedback", "completed": "completed", "cancelled": "cancelled"}
EVENT_WORK_ORDER_TYPES = frozenset({"water_quality_complaint", "burst_report"})
def should_project_work_order(order: dict, linked_order_ids: set[str]) -> bool:
"""Exclude retired seed checks while preserving user and workflow orders."""
work_order_id = order["work_order_id"]
work_order_type = order.get("work_order_type", "general")
if work_order_type in EVENT_WORK_ORDER_TYPES or work_order_id in linked_order_ids:
return True
return not (
work_order_type == "general"
and order.get("origin") == "synthetic"
and order.get("created_by") == str(SEED_ACTOR_ID)
)
def work_order_snapshot(order: dict) -> dict:
"""Preserve external process facts without deriving stages from total status."""
"""Preserve the flat order and its recorded activity without inventing stages."""
required = (
"work_order_id", "revision", "title", "summary", "status", "priority",
"origin", "updated_at",
)
snapshot = {key: order[key] for key in required}
snapshot.update({key: order.get(key) for key in (
"assignee", "scheduled_at", "location", "scenario_code", "subtasks",
"assignee", "scheduled_at", "location", "scenario_code",
)})
snapshot["feedback_requirements"] = order.get("feedback_requirements") or []
snapshot["activity"] = order.get("activity") or []
snapshot["work_order_type"] = order.get("work_order_type", "general")
return snapshot
@@ -39,7 +57,10 @@ async def sync_once(client: httpx.AsyncClient, settings: WorkerSettings, periphe
credentials: CredentialProvider) -> int:
headers = await credentials.headers(client)
tasks_url = f"{settings.server_url.rstrip('/')}/api/v1/operational-tasks"
existing, event_tasks, investigations, offset = {}, {}, [], 0
existing: dict[str, dict] = {}
event_tasks: dict[str | None, dict] = {}
investigations: list[dict] = []
offset = 0
while True:
response = await client.get(tasks_url, headers=headers, params={"limit": 100, "offset": offset})
response.raise_for_status()
@@ -63,6 +84,7 @@ async def sync_once(client: httpx.AsyncClient, settings: WorkerSettings, periphe
receipt = action.get("receipt")
if action["kind"] == "create_work_order" and receipt and receipt["adapter"] == "peripheral_sample":
linked.setdefault(receipt["receipt_id"], []).append(task["task_id"])
linked_order_ids = set(linked)
cursor, synchronized = None, 0
while True:
@@ -76,14 +98,16 @@ async def sync_once(client: httpx.AsyncClient, settings: WorkerSettings, periphe
for order in page["items"]:
if order["project_id"] != settings.project_id or order["origin"] != "synthetic":
raise ValueError("peripheral work order scope or origin mismatch")
if not should_project_work_order(order, linked_order_ids):
continue
external_id = f"peripheral_sample:{order['work_order_id']}"
# Complaint intake is an event even if no browser was open when the
# external system created it. Use the same source key as the UI.
event_kind = order.get("work_order_type")
if (
event_kind in {"water_quality_complaint", "burst_report"}
event_kind in EVENT_WORK_ORDER_TYPES
and order["work_order_id"] not in event_tasks
and order["work_order_id"] not in linked
and order["work_order_id"] not in linked_order_ids
):
event_request_id = str(uuid5(NAMESPACE_URL, f"{settings.project_id}:{external_id}:investigation"))
event = await client.post(tasks_url, headers=headers, json={