fix: enforce SCADA chart device coverage

This commit is contained in:
2026-11-12 10:38:55 +08:00
parent b853b61a0b
commit 2e8fe86f3f
17 changed files with 1220 additions and 13 deletions
+31 -3
View File
@@ -164,7 +164,7 @@ class OperationalTaskRepository:
ORDER BY generation DESC LIMIT %s OFFSET %s""",
(self.project_id, task_id, limit, offset),
)
return [{key: value for key, value in row.items() if key != "project_id"}
return [{key: value for key, value in row.items() if key not in {"project_id", "artifact_manifest"}}
for row in await cursor.fetchall()]
async def get_latest_run(self, task_id: str) -> dict | None:
@@ -371,6 +371,34 @@ class OperationalTaskRepository:
)
return [dict(row) for row in await cursor.fetchall()]
async def get_scada_presentation(self, task_id: str, run_id: str) -> dict | None:
cursor = await self.connection.execute(
"""SELECT EXISTS (SELECT 1 FROM pg_attribute
WHERE attrelid=to_regclass('workbench.operational_task_runs')
AND attname='artifact_manifest' AND NOT attisdropped) AS available"""
)
if not (await cursor.fetchone())["available"]:
raise DomainError("DEPENDENCY_UNAVAILABLE",
"SCADA display coverage requires resources/sql/035_scada_presentation_coverage.sql in this project database",
status=503)
cursor = await self.connection.execute(
"""SELECT artifact_manifest->'scada_presentation' AS document FROM workbench.operational_task_runs
WHERE project_id=%s AND task_id=%s AND run_id=%s""",
(self.project_id, task_id, run_id),
)
row = await cursor.fetchone()
return row["document"] if row else None
async def save_scada_presentation(self, task_id: str, run_id: str, document: dict, now: datetime) -> None:
cursor = await self.connection.execute(
"""UPDATE workbench.operational_task_runs
SET artifact_manifest=jsonb_set(artifact_manifest,'{scada_presentation}',%s::jsonb,true)
WHERE project_id=%s AND task_id=%s AND run_id=%s""",
(Jsonb({**document, "updated_at": now.isoformat()}), self.project_id, task_id, run_id),
)
if cursor.rowcount != 1:
raise DomainError("RUN_NOT_FOUND", "SCADA display coverage targets an unknown run", status=409)
async def get_task_by_create_request(self, request_id: str) -> dict | None:
cursor = await self.connection.execute(
"""SELECT document FROM workbench.operational_tasks
@@ -405,9 +433,9 @@ class OperationalTaskRepository:
cursor = await self.connection.execute(
"""SELECT task.document,
CASE WHEN active_run.run_id IS NULL THEN NULL
ELSE to_jsonb(active_run) - 'project_id' END AS active_run,
ELSE to_jsonb(active_run) - 'project_id' - 'artifact_manifest' END AS active_run,
CASE WHEN latest_run.run_id IS NULL THEN NULL
ELSE to_jsonb(latest_run) - 'project_id' END AS latest_run
ELSE to_jsonb(latest_run) - 'project_id' - 'artifact_manifest' END AS latest_run
FROM workbench.operational_tasks AS task
LEFT JOIN LATERAL (
SELECT run.* FROM workbench.operational_task_runs AS run
+1 -1
View File
@@ -404,7 +404,7 @@ async def task_context_page(
where = " ORDER BY revision DESC LIMIT 1"
stored = f"SELECT jsonb_build_object('section',%s::text,'data',document) AS snapshot FROM {relation} WHERE project_id=%s AND task_id=%s{where}"
elif section == "run":
stored = """SELECT jsonb_build_object('section','run','data',to_jsonb(r)-'project_id') AS snapshot
stored = """SELECT jsonb_build_object('section','run','data',to_jsonb(r)-'project_id'-'artifact_manifest') AS snapshot
FROM workbench.operational_task_runs r WHERE project_id=%s AND task_id=%s ORDER BY generation DESC LIMIT 1"""
params = (project_id, task_id)
elif section == "progress":