fix(transport): case-insensitive name lookups, batch preview lookups, correct flattener doc (ScadaBridge#93)

- ApplyTemplatesAsync/PreviewAsync template lookups use a case-insensitive,
  never-throwing comparer (SQL Server collation); base template wins over derived.
  Base names are already unique case-insensitively via the filtered unique index
  on Template.Name, derived templates are not covered by it.
- Preview reads database connections, notification lists and API methods with one
  GetAll query each instead of one by-name query per bundled row.
- Component-TemplateEngine.md: the flattener does not call GetAllTemplatesAsync;
  it loads chains via GetTemplateWithChildrenAsync.

Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
Joseph Doherty
2026-11-09 13:46:45 -05:00
parent bec07378cc
commit c7d868c52e
3 changed files with 223 additions and 10 deletions
@@ -239,7 +239,7 @@ falls back to `GetTemplateChainAsync` — the template's own inheritance chain,
one load per level — since resyncing a leaf reads only its chain (Gitea #89). The
read-only resolved-members query (`GetResolvedTemplateMembersCommand`, behind the
editor's inherited view and CLI `template resolved-members`) reads that chain alone,
untracked. The flattener keeps reading the whole tracked graph via `GetAllTemplatesAsync`.
untracked. The flattener does not call `GetAllTemplatesAsync` (verified against `FlatteningPipeline`/`FlatteningService`, Gitea #93): the pipeline loads each template chain the instance needs through `GetTemplateWithChildrenAsync` (tracked, fully included, memoised per `FlattenSession`) and each composition's chain the same way, so it still reads tracked, body-bearing rows — only the whole-library load is not part of it.
### Native Alarm Source Resolution