feat: extend operational investigation workflows
Generic Container CI/CD / test-build-publish (push) Successful in 3m53s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 3m52s

This commit is contained in:
2026-10-30 17:30:19 +08:00
parent 63af998045
commit 05183aff93
82 changed files with 4644 additions and 330 deletions
+15 -21
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Synchronize the explicitly synthetic peripheral work orders into task projections."""
"""Synchronize peripheral work orders as project-owned system data."""
from __future__ import annotations
import argparse
@@ -15,7 +15,6 @@ import httpx
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from samples.peripheral.seed_identity import SEED_ACTOR_ID
from app.domain.schemas.workbench_events import WorkbenchEvent
try:
@@ -42,23 +41,15 @@ def peripheral_order_id(external_id: str | None) -> str | None:
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)
)
"""Project every active work order returned by the peripheral system."""
return True
def work_order_snapshot(order: dict) -> dict:
"""Preserve the flat order and its recorded activity without inventing stages."""
required = (
"work_order_id", "revision", "title", "summary", "status", "priority",
"origin", "updated_at",
"updated_at",
)
snapshot = {key: order[key] for key in required}
snapshot.update({key: order.get(key) for key in (
@@ -67,6 +58,7 @@ def work_order_snapshot(order: dict) -> dict:
snapshot["feedback_requirements"] = order.get("feedback_requirements") or []
snapshot["activity"] = order.get("activity") or []
snapshot["work_order_type"] = order.get("work_order_type", "general")
snapshot["origin"] = "system_data"
return snapshot
@@ -148,8 +140,9 @@ async def sync_once(client: httpx.AsyncClient, settings: WorkerSettings, periphe
work_order_ids, deleted_ids,
):
for order in page["items"]:
if order["project_id"] != settings.project_id or order["origin"] != "synthetic":
if order["project_id"] != settings.project_id or order["origin"] != "system_data":
raise ValueError("peripheral work order scope or origin mismatch")
source_label = "外围工单"
seen_order_ids.add(order["work_order_id"])
if not should_project_work_order(order, linked_order_ids):
continue
@@ -165,12 +158,13 @@ async def sync_once(client: httpx.AsyncClient, settings: WorkerSettings, periphe
event_request_id = str(uuid5(NAMESPACE_URL, f"{settings.project_id}:{external_id}:investigation"))
event = await client.post(tasks_url, headers=headers, json={
"request_id": event_request_id, "task_type": "event_investigation", "workflow": event_kind,
"title": "水质投诉调查" if event_kind == "water_quality_complaint" else "爆管事件调查", "summary": f"合成外围事件:{order['summary']}",
"title": "水质投诉调查" if event_kind == "water_quality_complaint" else "爆管事件调查",
"summary": f"外围事件:{order['summary']}",
"priority": "urgent" if order["priority"] in {"high", "urgent"} else "normal",
"source": {"kind": "external_system", "external_id": order["work_order_id"],
"external_revision": order["revision"], "event_kind": event_kind},
"trigger": {"kind": "event", "occurred_at": order.get("scheduled_at") or order["created_at"],
"detail": f"外围样板事件上报 · {order.get('location') or '位置待确认'}"},
"detail": f"外围事件上报 · {order.get('location') or '位置待确认'}"},
})
event.raise_for_status()
event_tasks[order["work_order_id"]] = event.json()
@@ -179,12 +173,12 @@ async def sync_once(client: httpx.AsyncClient, settings: WorkerSettings, periphe
request_id = str(uuid5(NAMESPACE_URL, f"{settings.project_id}:{external_id}:create"))
result = await client.post(tasks_url, headers=headers, json={
"request_id": request_id, "task_type": "external_work_order", "workflow": "external-work-order",
"title": order["title"], "summary": f"合成外围工单:{order['summary']}",
"title": order["title"], "summary": f"{source_label}:{order['summary']}",
"priority": "urgent" if order["priority"] in {"high", "urgent"} else "normal",
"source": {"kind": "external_system", "external_id": external_id,
"event_kind": order.get("work_order_type", "general")},
"trigger": {"kind": "external_sync", "occurred_at": order["created_at"],
"detail": "外围样板工单同步,进度以外部系统反馈为准"},
"detail": "外围工单同步,进度以外部系统反馈为准"},
"scheduled_for": order["scheduled_at"],
})
result.raise_for_status()
@@ -225,9 +219,9 @@ async def sync_once(client: httpx.AsyncClient, settings: WorkerSettings, periphe
"request_id": str(uuid5(NAMESPACE_URL, event_id)), "source_event_id": external_id,
"source_revision": order["revision"], "status": STATUS[order["status"]],
"occurred_at": order["updated_at"],
"detail": f"合成外围工单 {order['work_order_id']}:{order['status']}",
"evidence": {"evidence_id": event_id, "kind": "synthetic", "summary": evidence_summary,
"source_label": "外围样板合成工单", "source_ref": external_id,
"detail": f"{source_label} {order['work_order_id']}:{order['status']}",
"evidence": {"evidence_id": event_id, "kind": "external_feedback", "summary": evidence_summary,
"source_label": source_label, "source_ref": external_id,
"observed_at": order["updated_at"]},
}
# A child order's creation is already represented by its dispatch