Commit Graph

70 Commits

Author SHA1 Message Date
Joseph Doherty
84a696b0e4 fix(security): resolve Security-009,010,011 — LDAP connection timeout, design-doc correction, security-path test coverage; Security-008 deferred 2026-05-16 22:24:03 -04:00
Joseph Doherty
7d1cc5cbb4 fix(configuration-database): resolve ConfigurationDatabase-005,006,008,009,010,011 — bounded gRPC columns, split queries, CSV-parse logging, null guards, coverage 2026-05-16 22:14:23 -04:00
Joseph Doherty
c07f524ca4 fix(commons): resolve Commons-005..007,009..012 — OPC UA parse status, TryConvert correctness, Result null guard, invariant formatting, doc refresh 2026-05-16 22:04:21 -04:00
Joseph Doherty
738e67acc5 fix(cli): resolve CLI-002..007 — robust response rendering, URL/JSON arg validation, credential env-vars, doc refresh 2026-05-16 20:58:03 -04:00
Joseph Doherty
cac8aebe9f docs(cluster-infrastructure): resolve ClusterInfrastructure-001 — document that the Host owns the Akka bootstrap 2026-05-16 20:12:24 -04:00
Joseph Doherty
8050a1996f docs(plans): implementation plan for expression triggers 2026-05-16 05:25:10 -04:00
Joseph Doherty
c94d3b7570 docs(plans): design for expression-based script & alarm triggers
Captures the brainstormed design for a new Expression trigger: a read-only
boolean C# expression evaluated on attribute updates, edge-triggered for
scripts and level-based for alarms, compiled against a restricted read-only
globals type.
2026-05-16 05:21:57 -04:00
Joseph Doherty
7044791a55 docs(plans): scrub LmxProxy references from design plans
Remove the LmxProxy work package (WP-8) from phase-3b, the CD-DCL-1..6
protocol details, Q9/Q-P3B-2 from the questions log, the LmxProxy
component-design rows in requirements-traceability, and the inline
mentions across phase-0, phase-4, the gRPC streaming plans, and the
primary/backup data-connection plans.
2026-05-13 13:30:07 -04:00
Joseph Doherty
751248feb6 feat(alarms): HiLo trigger type with per-band level, hysteresis, messages, overrides
Adds a new HiLo alarm trigger type with four configurable setpoints
(LoLo / Lo / Hi / HiHi). Each setpoint carries an optional priority,
deadband (for hysteresis), and operator message. The site runtime emits
AlarmStateChanged with an AlarmLevel field so consumers can differentiate
warning vs critical bands.

Plumbing:
  - new AlarmLevel enum + AlarmStateChanged.Level/Message init properties
  - AlarmTriggerEditor (Blazor) gets a HiLo render with severity tinting
  - AlarmTriggerConfigCodec extracted from the editor for testability
  - sitestream.proto carries level + message over gRPC
  - SemanticValidator enforces numeric attribute, setpoint ordering,
    non-negative deadband
  - on-trigger scripts get an Alarm global (Name/Level/Priority/Message)
    so notification routing can branch by severity
  - per-instance InstanceAlarmOverride entity + EF migration + flattening
    step + CLI commands; HiLo overrides merge setpoint-by-setpoint, binary
    types whole-replace
  - DebugView shows a Level badge + per-band message tooltip
  - App.razor auto-reloads on permanent Blazor circuit failure
  - docker/regen-proto.sh automates the proto regen workflow (the linux/arm64
    protoc segfault means generated files are checked in for now)
2026-05-13 03:23:32 -04:00
Joseph Doherty
783da8e21a feat(ui): structured editors for script schemas and alarm triggers
Replace raw-JSON text inputs with rich UI: script parameter/return types use
a JSON Schema builder (SchemaBuilder + JsonSchemaShapeParser, with a migration
to convert existing definitions); alarm trigger config uses a type-aware
editor with a flattened attribute picker (AlarmTriggerEditor). AlarmActor
gains optional direction (rising/falling/either) on RateOfChange triggers.
2026-05-13 00:33:00 -04:00
Joseph Doherty
552c9e4065 docs(templates): record phase 4-9 completion + verification TODOs
All nine derive-on-compose phases are now implemented. The status doc
captures what shipped per phase, what was deferred (LockedInDerived
override warning toast, SCADA008 base-Parent hint), and the live-DB /
UI smoke checks worth running before merge.
2026-05-12 08:59:19 -04:00
Joseph Doherty
8b8b85c839 docs(templates): record phase 2+3 completion in status doc
Phase 1 → 3 marked done; remaining work is phases 4-9. Sanity script now
targets the post-Phase-3 commit (03a8c4a) and notes the pre-existing
NU1608 build error in IntegrationTests / Host.Tests so future sessions
don't chase a phantom regression.
2026-05-12 08:31:20 -04:00
Joseph Doherty
91b786eb1c docs(templates): derive-on-compose phase status + resume plan
Companion to the design doc — captures current state, the four
decisions already made, what's done (phase 1, commit 5615f3d),
and a full play-by-play for phases 2 through 9 with exact files,
methods, and tests to touch. Written so a future session after
context compaction can pick up cleanly.
2026-05-12 08:18:43 -04:00
Joseph Doherty
a968cefbc2 docs(templates): record derive-on-compose decisions (naming, migration, tree UX) 2026-05-12 08:13:11 -04:00
Joseph Doherty
68548432b3 docs(templates): design for derive-on-compose specialization
Aveva-style composition: composing $Sensor into $Pump creates a
derived template Pump.TempSensor that inherits from $Sensor and can
override values, override script bodies, add new fields, with
LockedInDerived on the base preventing specific overrides.

Schema sketch: Template gains IsDerived + OwnerCompositionId;
TemplateAttribute/Script gain IsInherited + LockedInDerived.
TemplateComposition.ComposedTemplateId pivots to point at the
derived template (the base is reachable via derived.ParentTemplateId).

Phased rollout (9 phases), starting from additive schema, then
flow change for new compositions, then EF Core migration of
existing data, then resolution, lock semantics, tree UI, derived
template edit UI, base template lock-toggle UI, editor metadata
simplification (multi-parent picker becomes mostly obsolete —
derived templates always have a single owner).

Open questions captured at the end for review before phase 1.
2026-05-12 08:12:12 -04:00
Joseph Doherty
3ed05f0595 docs(scripts): design for template-script scope access
Self / Children / Parent accessors with sync-indexer + async-method
shape. Flattening pipeline emits ScriptScope per resolved script;
ScriptCompilationService seeds the accessors at execution time with
no new actor messages or lookup paths.

Phased: (1) runtime accessors + Scope on ResolvedScript, (2)
flattening + deploy round-trip, (3) editor metadata fetch for child
+ parent shapes, (4) Monaco completion / hover / diagnostics
(SCADA006 unknown attribute, SCADA007 unknown composition).

Out of scope: per-template Roslyn-generated typed accessors,
locking-aware writes (covered by lock-enforcement pass), and
sibling-of-sibling chained navigation.
2026-05-12 05:38:58 -04:00
Joseph Doherty
ff5f5a10ef docs(ui): UI audit findings (2026-05-12)
Audit of every page in CentralUI against the Sites.razor card-grid
pattern, the no-third-party-UI-libs constraint, and accessibility
basics. Findings + per-page severity + suggested implementation
order live in docs/plans/. Implementation follows in subsequent commits.
2026-05-12 03:31:54 -04:00
Joseph Doherty
a9c4c2c655 docs(plans): implementation plan for OPC UA config model refactor
14 bite-sized tasks (TDD pattern) covering:
- Commons foundation: POCOs, serializer, validator
- Runtime adoption: OpcUaDataConnection + DeploymentManagerActor swap
- UI build: <OpcUaEndpointEditor> + DataConnectionForm rewrite
- Verification: build/test green + Docker browser smoke + push

Tasks #45-#58 created with blocking dependencies; companion
.tasks.json sidecar persists the plan for executing-plans skill.
2026-05-12 00:33:51 -04:00
Joseph Doherty
c906e73441 docs(plans): OPC UA endpoint config model & form refactor design
Captures the design decisions from the brainstorming session:
- OpcUaEndpointConfig POCO + validator + serializer in Commons
- Single source of truth: both UI and site runtime consume the model
- Typed nested JSON storage (camelCase), legacy flat-dict fallback
- Shared <OpcUaEndpointEditor> Blazor component used twice
- Custom protocol removed from dropdown; Protocol field hidden
- Validation timing on Save only; per-field red text via ValidationEntry
2026-05-12 00:27:35 -04:00
Joseph Doherty
da5fdf0e63 feat(ui/admin): Topology-style refresh of Data Connections page
Brings the Data Connections admin page up to the same UX standard as the
Topology page:
- Search box with dim non-matches (opacity 0.4, shape preserved)
- Toolbar: + Connection (disabled until a site is selected), Refresh,
  Expand, Collapse
- Site context menu gains "Add Connection here" that navigates with
  ?siteId= so the form preselects + locks the Site field
- Form gains "Primary Endpoint" / "Backup Endpoint" h6 subsection
  headers matching the SiteForm convention; Failover Retry Count moved
  inside the Backup subsection
- URL renamed: /admin/connections (primary) + /admin/data-connections
  (legacy secondary @page). Same dual-route treatment on the form
- Nav label: "Data Connections" -> "Connections"
- Adds DataConnectionsPageTests bUnit suite (6 tests)
2026-05-11 22:42:48 -04:00
Joseph Doherty
f3386d0278 feat(ui/deployment): consolidate sites/areas/instances into Topology page
Single /deployment/topology page replaces /deployment/instances (legacy URL
preserved as a secondary @page directive) and the /admin/areas* CRUD pages.
TreeView with Site → Area → Instance, V1–V7 visual guide (bi-building /
bi-diagram-3 / bi-box), always-visible empty containers, search dim, F2
inline area rename, and right-click context menus per node kind (Add Area,
Move to Area…, lifecycle actions, etc.).

Adds AreaService.MoveAreaAsync with cycle prevention, same-site enforcement,
and name-collision check at the new parent. Instance rename intentionally
out of scope — UniqueName is the site-side actor identity, requires its own
design pass.
2026-05-11 22:03:55 -04:00
Joseph Doherty
b2eddd9713 feat(ui/templates): derived-template action and slimmer composition row
Right-click a template now offers "New Derived Template" — opens
TemplateCreate with the parent pre-selected via a new ?parentId query
parameter. Composition rows in the tree drop the trailing
"→ TargetName" muted text; the kind glyph plus the instance name carry
enough meaning, and the composed template is one click away from the
row's right-click menu.
2026-05-11 21:29:32 -04:00
Joseph Doherty
8e388a89c5 feat(ui/templates): adopt TreeView design guide; split editor to /design/templates/{id}
Templates page is now a tree-only browser; editing happens on a dedicated
TemplateEdit page. Drag-drop is replaced by context-menu Move-to-Folder.
TreeView gains Bootstrap Icons (chevron + per-kind glyphs), ancestor guide
lines, defined hover/selected/focus tokens, and Escape-dismisses-menu per
the new Visual Design Guide (V1-V7) in Component-TreeView.md.
2026-05-11 20:52:34 -04:00
Joseph Doherty
8155dbc411 docs(templates): describe folder hierarchy and management commands 2026-05-11 11:28:09 -04:00
Joseph Doherty
18387df8cb plan(templates-page): use ScadaLink.slnx (repo uses slnx, not sln) 2026-05-11 10:30:15 -04:00
Joseph Doherty
892204ea3a plan(templates-page): implementation plan for folder hierarchy 2026-05-11 10:27:39 -04:00
Joseph Doherty
daa01261f3 design(templates-page): folder hierarchy and split-pane tree layout
Replaces the current /design/templates list view with a Wonderware-style
template toolbox: nested TemplateFolder entity, FolderId on Template,
composition children as inline tree leaves, persistent split-pane with
editor on the right, context menus + drag-drop reorg.
2026-05-11 10:20:50 -04:00
Joseph Doherty
9dccf8e72f deprecate(lmxproxy): move all LmxProxy code, tests, and docs to deprecated/
LmxProxy is no longer needed. Moved the entire lmxproxy/ workspace, DCL
adapter files, and related docs to deprecated/. Removed LmxProxy registration
from DataConnectionFactory, project reference from DCL, protocol option from
UI, and cleaned up all requirement docs.
2026-04-08 15:56:23 -04:00
Joseph Doherty
addbb6ffeb fix(ui): move treeview-storage.js to Host wwwroot where static files are served 2026-03-24 16:19:39 -04:00
Joseph Doherty
161dc406ed feat(scripts): add typed Parameters.Get<T>() helpers for script API
Replace raw dictionary casting with ScriptParameters wrapper that provides
Get<T>, Get<T?>, Get<T[]>, and Get<List<T>> with clear error messages,
numeric conversion, and JsonElement support for Inbound API parameters.
2026-03-22 15:47:18 -04:00
Joseph Doherty
af7335f9e2 docs(dcl): update protocol and type mapping docs to reflect v2 TypedValue and SDK integration 2026-03-22 15:11:58 -04:00
Joseph Doherty
5de6c8d052 docs(dcl): document primary/backup endpoint redundancy across requirements and test infra 2026-03-22 08:43:59 -04:00
Joseph Doherty
5ca1be328c docs(dcl): add primary/backup data connections implementation plan
8 tasks with TDD steps, exact file paths, and code samples.
Covers entity model, failover state machine, health reporting,
UI, CLI, management API, deployment, and documentation.
2026-03-22 08:13:23 -04:00
Joseph Doherty
6267ff882c docs(dcl): add primary/backup data connection endpoints design
Covers entity model, failover state machine, health reporting,
UI/CLI changes, and deployment flow for optional backup endpoints
with automatic failover after configurable retry count.
2026-03-22 08:09:25 -04:00
Joseph Doherty
abb7579227 chore(infra): remove LmxFakeProxy — replaced by real LmxProxy v2 instances on windev
LmxFakeProxy is no longer needed now that two real LmxProxy v2 instances
are available for testing. Added remote test infra section to test_infra.md
documenting the windev instances. Removed tagsim (never committed).
2026-03-22 07:42:13 -04:00
Joseph Doherty
efed8352c3 feat(infra): add second OPC UA server instance (opcua2) on port 50010
Enables multi-server testing with independent state. Both instances
share the same nodes.json tag config. Updated all infra documentation.
2026-03-22 07:31:56 -04:00
Joseph Doherty
d3194e3634 feat: separate create/edit form pages, Playwright test infrastructure, /auth/token endpoint
Move all CRUD create/edit forms from inline on list pages to dedicated form pages
with back-button navigation and post-save redirect. Add Playwright Docker container
(browser server on port 3000) with 25 passing E2E tests covering login, navigation,
and site CRUD workflows. Add POST /auth/token endpoint for clean JWT retrieval.
2026-03-21 15:17:24 -04:00
Joseph Doherty
b3f8850711 docs: document script hot-reload mechanisms for all script types 2026-03-21 13:42:06 -04:00
Joseph Doherty
416a03b782 feat: complete gRPC streaming channel — site host, docker config, docs, integration tests
Switch site host to WebApplicationBuilder with Kestrel HTTP/2 gRPC server,
add GrpcPort/keepalive config, wire SiteStreamManager as ISiteStreamSubscriber,
expose gRPC ports in docker-compose, add site seed script, update all 10
requirement docs + CLAUDE.md + README.md for the new dual-transport architecture.
2026-03-21 12:38:33 -04:00
Joseph Doherty
b76ce09221 docs: add gRPC streaming channel implementation plan with task tracking 2026-03-21 11:32:24 -04:00
Joseph Doherty
3efec91386 fix: route debug stream events through ClusterClient site→central path
ClusterClient Sender refs are temporary proxies — valid for immediate reply
but not durable for future Tells. Events now flow as DebugStreamEvent through
SiteCommunicationActor → ClusterClient → CentralCommunicationActor → bridge
actor (same pattern as health reports). Also fix DebugStreamHub to use
IHubContext for long-lived callbacks instead of transient hub instance.
2026-03-21 11:32:17 -04:00
Joseph Doherty
41aff339b2 docs: add gRPC streaming channel design plan for site→central real-time data
Replaces ClusterClient-based event streaming with dedicated gRPC server-streaming
channels. Covers proto definition, server/client patterns, Channel<T> bridging,
keepalive/orphan prevention, failover scenarios, port/address configuration,
extensibility guide for new event types, testing strategy, and implementation guardrails.
2026-03-21 11:26:09 -04:00
Joseph Doherty
fd2e96fea2 feat: replace debug view polling with real-time SignalR streaming
The debug view polled every 2s by re-subscribing for full snapshots. Now a
persistent DebugStreamBridgeActor on central subscribes once and receives
incremental Akka stream events from the site, forwarding them to the Blazor
component via callbacks and to the CLI via a new SignalR hub at
/hubs/debug-stream. Adds `debug stream` CLI command with auto-reconnect.
2026-03-21 01:34:53 -04:00
Joseph Doherty
d91aa83665 refactor(docs): move requirements and test infra docs into docs/ subdirectories
Organize documentation by moving requirements (HighLevelReqs, Component-*,
lmxproxy_protocol) to docs/requirements/ and test infrastructure docs to
docs/test_infra/. Updates all cross-references in README, CLAUDE.md,
infra/README, component docs, and 23 plan files.
2026-03-21 01:11:35 -04:00
Joseph Doherty
3e93a0d8c3 docs: add LmxFakeProxy implementation plan with 10 tasks
Detailed task-by-task plan covering scaffolding, TagMapper, SessionManager,
OpcUaBridge, ScadaServiceImpl, Program.cs, Docker, docs, and integration test.
2026-03-19 11:13:51 -04:00
Joseph Doherty
e19a568b9b docs: add LmxFakeProxy design — OPC UA-backed test proxy for LmxProxy protocol
Defines a gRPC server implementing the scada.ScadaService proto that bridges
to the existing OPC UA test server. Enables end-to-end testing of
RealLmxProxyClient without a Windows LmxProxy deployment.
2026-03-19 11:08:47 -04:00
Joseph Doherty
c36de676f3 Add implementation plan: Management Service + CLI 2026-03-17 14:35:52 -04:00
Joseph Doherty
54c03a3139 Add implementation plan: deploy artifacts, remove config DB dependency 2026-03-17 13:35:54 -04:00
Joseph Doherty
75ccd4b1c0 Add design doc: deploy artifacts to sites, remove config DB dependency 2026-03-17 13:30:23 -04:00
Joseph Doherty
2b2cc0a151 All phases complete: execution checklists for Phases 3C through 8
All 11 phases (0, 1, 2, 3A, 3B, 3C, 4, 5, 6, 7, 8) implemented.
781 tests passing across 20 test projects. Zero build warnings.
2026-03-16 22:19:29 -04:00