Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase
Joseph Doherty 297ae56b85 refactor(config-db): GetTraceEventsAsync and GetExecutionTreeAsync share one chain walker (arch-review F9)
GetTraceEventsAsync re-implemented GetExecutionTreeAsync's execution-chain walk
as a second copy: the upward ParentExecutionId climb, the root MIN(OccurredAtUtc)
window, and the recursive Edges/Chain CTE with its DISTINCT-edges trick and
MAXRECURSION cap. Two walkers that had to stay in step on window slack, depth and
the edge distillation.

Extracted into three shared members:
- ChainAnchor (root execution id + root's first event timestamp, with the
  Edges window predicate derived from it)
- ResolveChainAnchorAsync — phase 1 up-walk plus the root window read
- ChainCtePrefix / AddChainParameters — the Edges/Chain CTE prefix and its
  @root/@winStart/@winEnd binding

Each walker appends its own projection to the prefix: GetExecutionTreeAsync the
ChainIds CTE plus the per-execution aggregate, GetTraceEventsAsync the bare id
union. Both keep OPTION (MAXRECURSION 32).

Pure refactor. The tree walker's generated SQL is byte-identical (verified by
diffing the composed command text against the pre-change literal); the trace
walker's differs only by the SQL comment lines it now inherits from the shared
prefix. Behaviour is pinned by the existing MSSQL-backed tests
(GetExecutionTree_MultiLevelChain / _StubParentNode / _RespectsMaxRecursion,
ExecutionTree_Bounds_EdgeScan_To_Root_Window, and both
AuditLogRepositoryTraceEventsTests) — 410 passed / 0 skipped before and after.

Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
2026-09-06 14:12:47 -04:00
..