Commit Graph

650 Commits

Author SHA1 Message Date
Joseph Doherty
435c853dce docs(plans): track SMTP-helper deduplication follow-up 2026-05-19 01:33:21 -04:00
Joseph Doherty
04e00d56c6 test(notification-outbox): cover Email adapter permanent/cancellation arms, align error casing 2026-05-19 01:32:54 -04:00
Joseph Doherty
b8dece0e70 feat(notification-outbox): add Email notification delivery adapter 2026-05-19 01:26:33 -04:00
Joseph Doherty
8d52890245 feat(notification-outbox): add NotificationOutboxOptions and delivery adapter abstraction 2026-05-19 01:20:49 -04:00
Joseph Doherty
fb589bf1da feat(notification-outbox): scaffold ScadaLink.NotificationOutbox project 2026-05-19 01:16:58 -04:00
Joseph Doherty
c547f82957 feat(notification-outbox): add notification message and outbox query contracts 2026-05-19 01:13:36 -04:00
Joseph Doherty
6056ad58b0 fix(notification-outbox): backfill NotificationLists.Type with a valid enum value in migration 2026-05-19 01:10:15 -04:00
Joseph Doherty
5696a8af9f feat(notification-outbox): add Notifications table migration 2026-05-19 01:07:30 -04:00
Joseph Doherty
07cd185368 refactor(notification-outbox): align outbox repository with cancellationToken convention 2026-05-19 01:05:52 -04:00
Joseph Doherty
2c59d59b61 feat(notification-outbox): add NotificationOutbox repository 2026-05-19 01:02:06 -04:00
Joseph Doherty
3022aa8379 style(notification-outbox): align NotificationOutboxConfiguration with sibling config style 2026-05-19 00:58:50 -04:00
Joseph Doherty
761595309b feat(notification-outbox): add Notification EF configuration and DbSet 2026-05-19 00:55:58 -04:00
Joseph Doherty
87ac9b8a4d feat(notification-outbox): add Type field to NotificationList 2026-05-19 00:52:23 -04:00
Joseph Doherty
ed7fddb0b5 test(notification-outbox): cover all Notification constructor null guards 2026-05-19 00:50:52 -04:00
Joseph Doherty
397a62677f feat(notification-outbox): add Notification entity 2026-05-19 00:48:48 -04:00
Joseph Doherty
926ca902bd test(notification-outbox): fold notification enum tests into EnumTests convention 2026-05-19 00:47:23 -04:00
Joseph Doherty
f9b942bb94 feat(notification-outbox): add NotificationType and NotificationStatus enums 2026-05-19 00:45:05 -04:00
Joseph Doherty
dff9e0aa76 docs(plans): code implementation plan for the notification outbox
26 TDD tasks across six phases — data layer, message contracts, the new
ScadaLink.NotificationOutbox project (actor, dispatcher, Email adapter),
site S&F retarget and central wiring, Central UI, and verification.
2026-05-19 00:39:10 -04:00
Joseph Doherty
f2513a4ef4 docs(notification-outbox): fix stale message-pattern count and tree alignment 2026-05-18 23:52:10 -04:00
Joseph Doherty
c8b8cd9150 docs(notification-outbox): merge duplicate S&F dependency bullet, standardize cross-ref 2026-05-18 23:48:59 -04:00
Joseph Doherty
bb35453d58 docs(notification-outbox): fix stale cross-references after outbox addition 2026-05-18 23:45:43 -04:00
Joseph Doherty
ba166bf503 docs(notification-outbox): split UI bullet, fix outbox-vs-S&F wording in CLAUDE.md 2026-05-18 23:41:32 -04:00
Joseph Doherty
7585612347 docs(notification-outbox): split overstuffed CLAUDE.md design-decision bullet 2026-05-18 23:40:01 -04:00
Joseph Doherty
b9e0ef4650 docs(notification-outbox): update component list and design decisions in CLAUDE.md 2026-05-18 23:38:28 -04:00
Joseph Doherty
aac3ee9bb3 docs(notification-outbox): add Notification Outbox to README component index 2026-05-18 23:35:38 -04:00
Joseph Doherty
097bb3361e docs(notification-outbox): polish Task 8 docs — purge basis, message-contract naming, density 2026-05-18 23:34:40 -04:00
Joseph Doherty
ef4614d710 docs(notification-outbox): clarify purge is a repository operation, not job ownership 2026-05-18 23:32:07 -04:00
Joseph Doherty
bb5519f6f2 docs(notification-outbox): add Notifications table, entity, and message contracts 2026-05-18 23:30:16 -04:00
Joseph Doherty
d7a16084b5 docs(notification-outbox): add Notification Outbox page to Central UI 2026-05-18 23:25:41 -04:00
Joseph Doherty
f2d710a9dc docs(notification-outbox): add Notification Submission communication pattern 2026-05-18 23:22:33 -04:00
Joseph Doherty
0dd3be0bd8 docs(notification-outbox): trim Site Event Logging notification row, de-duplicate rationale 2026-05-18 23:21:23 -04:00
Joseph Doherty
a59f5ec1ff docs(notification-outbox): add Notification category to Site Event Logging 2026-05-18 23:19:27 -04:00
Joseph Doherty
6ccf3766dc docs(notification-outbox): add central-computed outbox KPIs to Health Monitoring 2026-05-18 23:17:07 -04:00
Joseph Doherty
0b56c809e1 docs(notification-outbox): polish S&F naming consistency and prose 2026-05-18 23:15:59 -04:00
Joseph Doherty
b83d16364a docs(notification-outbox): retarget S&F notification category to central 2026-05-18 23:13:17 -04:00
Joseph Doherty
2a7e7289b3 docs(notification-outbox): polish Notification Service prose and heading scope 2026-05-18 23:12:02 -04:00
Joseph Doherty
0f96562bfd docs(notification-outbox): central-only Notification Service, typed lists, async API 2026-05-18 23:09:29 -04:00
Joseph Doherty
a4ba2dfe01 docs(notification-outbox): fix naming consistency and status-lifecycle clarity 2026-05-18 23:07:17 -04:00
Joseph Doherty
0388720390 docs(notification-outbox): add Component-NotificationOutbox design doc 2026-05-18 23:04:17 -04:00
Joseph Doherty
f177b58699 docs(plans): implementation plan for the notification outbox
11 bite-sized documentation tasks covering the new component doc and
revisions across the affected component docs, README, and CLAUDE.md,
with a final cross-reference consistency sweep.
2026-05-18 23:01:30 -04:00
Joseph Doherty
bbfa0c515e docs(plans): fold refinement decisions into notification outbox design
Resolves the six open questions: host-level forward-retry config,
Notify.Status returns a status record, 10-min stuck threshold, a
site-local Forwarding state, site-side logging of forward failures
only, and point-in-time KPIs computed from the Notifications table.
2026-05-18 22:57:45 -04:00
Joseph Doherty
d4e86c1b1d docs(plans): design for central notification outbox
Captures the basic design for a reliable notification outbox: sites
store-and-forward notifications to the central cluster, which logs
them to a type-agnostic Notifications table (single audit source) and
delivers them via per-type adapters with retry, parking, and KPIs.
2026-05-18 22:54:17 -04:00
Joseph Doherty
381eea63b1 refactor(central-ui): drop redundant Parent Template field from Template Properties
The Template Properties card repeated the parent template, which the page
header already shows — the "inherits X" line for base templates and the
"Derived from X — composed inside Y" line for derived ones. The card now
carries only Name and Description.
2026-05-18 19:14:09 -04:00
Joseph Doherty
06462a0100 feat(template-engine): contained names for composition-derived templates
A composition-derived template now stores its contained name — the
composition slot's InstanceName (e.g. "Pump"), unique only within its
owner — instead of the dotted global path ("Motor Controller.Pump").
The qualified hierarchical name is computed on read.

- TemplateNaming.QualifiedName: walks the OwnerCompositionId chain to
  build the dotted path; null-safe, cycle-guarded.
- TemplateConfiguration: the unique index on Template.Name becomes
  filtered (WHERE IsDerived = 0) — base templates stay globally unique;
  derived templates' uniqueness is the existing (TemplateId,
  InstanceName) index on TemplateComposition.
- Migration ContainedDerivedTemplateNames: rewrites derived rows to the
  contained name; Down rebuilds the dotted names via a recursive CTE
  before restoring the global index.
- TemplateService: composition create/rename store the contained name;
  the dotted-name collision pre-checks and cascade-rename are removed
  (a slot rename no longer touches nested derived templates).
- TemplateEdit: title shows the contained name; the qualified path is a
  breadcrumb subtitle; "composed inside" uses the owner's qualified name.

TDD: 4 TemplateNaming tests + updated composition tests. TemplateEngine
293, ConfigurationDatabase 114, CentralUI 316 green. Migration applied to
the dev cluster and verified in the browser (Motor Controller.Pump now
titled "Pump"; nested Motor Controller.Pump.TempSensor resolves).

Design: docs/plans/2026-05-18-contained-template-names-design.md
2026-05-18 17:50:30 -04:00
Joseph Doherty
2d4b287ab2 docs(plans): design for contained names on composition-derived templates 2026-05-18 17:37:43 -04:00
Joseph Doherty
36c6036060 feat(central-ui): enlarge script modal; tab the Shared Script form
Script editor modal (TemplateEdit): the tabbed Trigger/Code/Parameters/
Return content is substantial, so the dialog now fills most of the
viewport — a .script-editor-modal class (96vw wide, ~full height) replaces
modal-xl, paired with modal-dialog-scrollable so the body scrolls.

Shared Script create/edit form (SharedScriptForm): Code, Parameters, and
Return type move from stacked sections into a tab strip, matching the
template script modal. Panels toggle via display:none so the Monaco editor
and JSONJoy island stay mounted across tab switches; Code is the default
tab. Name stays above the tabs.

Markup/CSS only — no logic change. CentralUI suite 316 green; both
verified in the browser.
2026-05-18 17:06:28 -04:00
Joseph Doherty
e1a4ce4de8 refactor(central-ui): move script Trigger section into the tabbed panel
The Add/Edit Script modal's Trigger configuration (trigger editor + Min
time between runs) moves out of the always-visible header area and into
the tab strip as a new first tab: Trigger | Code | Parameters | Return
type. Trigger is the default selected tab.

Name and Locked remain above the tabs. The Trigger panel toggles via
display:none like the others, so the trigger expression's Monaco editor
stays mounted across tab switches. Markup-only — no logic change; verified
in the browser. CentralUI suite 316 green.
2026-05-18 16:51:58 -04:00
Joseph Doherty
01509a045f feat(central-ui): add Min time between runs field to the script form
The template script editor had no input for MinTimeBetweenRuns, so a
WhileTrue trigger configured through the UI always saved a null interval
and degraded to a single edge fire. The Add/Edit Script modal now has a
"Min time between runs" number+unit (ms/sec/min) field.

- Visible only for ValueChange / Conditional / Expression triggers — the
  auto-firing triggers MinTimeBetweenRuns throttles. Hidden for Interval
  (its own period is the cadence), Call (invoked explicitly, never
  throttled), and None.
- For a WhileTrue Conditional/Expression trigger the field is labelled as
  the re-fire interval and shows a warning while it is blank.
- Wired through the new-script and edit-script save paths (edit previously
  only preserved the existing value, never let the user change it).

New DurationInput helper does the TimeSpan <-> number+unit conversion;
ScriptTriggerConfigCodec.SupportsMinTimeBetweenRuns classifies trigger
types. Both TDD'd — 21 new tests. CentralUI suite 316 green; verified
end-to-end in the browser (visibility per trigger type, WhileTrue warning,
save/reload round-trip).
2026-05-18 16:44:15 -04:00
Joseph Doherty
437fe154e7 feat(triggers): add WhileTrue fire mode for Conditional/Expression script triggers
Conditional and Expression script triggers gain an optional `mode` field
in their TriggerConfiguration JSON:

- OnTrue (default): unchanged edge/per-change firing. An absent mode field
  parses as OnTrue, so every existing trigger config behaves identically.
- WhileTrue: fires on the false->true edge, then re-fires on a periodic
  timer while the condition holds; stops on the true->false edge. The
  re-fire cadence is the script's MinTimeBetweenRuns; with none configured
  the trigger degrades to a single edge fire and logs a warning.

ScriptActor tracks condition truth state and manages a dedicated
"whiletrue-trigger" timer. ScriptTriggerConfigCodec and ScriptTriggerEditor
round-trip the mode and expose an OnTrue/WhileTrue selector for the two
trigger kinds. Design: docs/plans/2026-05-18-whiletrue-trigger-mode-design.md

Tests: 7 ScriptActor runtime tests (edge fire, timer re-fire, stop,
re-arm, no-MinTimeBetweenRuns degrade, OnTrue regressions) + 14 codec /
editor tests. SiteRuntime suite 206 green, CentralUI suite 295 green.
2026-05-18 10:44:11 -04:00
Joseph Doherty
19870d1f8f docs(plans): design for WhileTrue conditional/expression trigger mode 2026-05-18 10:30:22 -04:00