perf(templateengine): alarm-override, folder-delete and template-delete checks read lean template projections (review 2026-10-21 04/P6, 08/P1)

InstanceService.SetAlarmOverrideAsync and TemplateDeletionService move to the
no-tracking, body-free GetAllTemplatesForAnalysisAsync; TemplateFolderService
counts folder contents from GetTemplateStubsAsync.
This commit is contained in:
Joseph Doherty
2026-10-22 06:25:16 -04:00
parent 7d11a1db8d
commit c7774b7ec2
7 changed files with 54 additions and 29 deletions
@@ -211,7 +211,15 @@ The design-time checks — acyclicity (`CycleDetector`), naming collisions
(`CollisionDetector`) and canonical-name resolution (`TemplateResolver`) — read the
whole template graph but write through none of it and read no script bodies. They
use `GetAllTemplatesForAnalysisAsync`: `AsNoTracking`, with `TemplateScript.Code`
projected away.
projected away. The same projection serves the non-analysis lookups that need only
names, locks and edges: `InstanceService.SetAlarmOverrideAsync` (resolving one alarm
name) and `TemplateDeletionService.CanDeleteTemplateAsync` (inheritor / derived /
composer checks). `TemplateFolderService.DeleteFolderAsync`, which only counts
templates per `FolderId`, reads the lighter `GetTemplateStubsAsync` identity projection
(review 2026-10-21 04/P6, 08/P1). Template member add/update paths still load the whole
analysis projection for collision detection; narrowing that to the edited template's
chain + composition closure needs a closure-scoped repository read that does not exist
yet.
The tracked, body-bearing `GetAllTemplatesAsync` remains the read for the two paths
that genuinely need it — the inheritance reconciler (which compares and copies