Commit Graph

126 Commits

Author SHA1 Message Date
Joseph Doherty 9afcdc996e chore(plans): native alarms COMPLETE (28/28) + T28 live-integration notes 2026-05-31 03:29:37 -04:00
Joseph Doherty d24c00ec2c chore(plans): native alarms execution progress (27/28) + batch-8 notes 2026-05-31 02:55:36 -04:00
Joseph Doherty b03ab11d8a chore(plans): native alarms execution progress (24/28) + batch-7 notes 2026-05-31 02:41:45 -04:00
Joseph Doherty c4cea9eea5 chore(plans): native alarms execution progress (21/28) + batch-6 notes 2026-05-31 02:23:50 -04:00
Joseph Doherty 50176765fe chore(plans): native alarms execution progress (18/28) + batch-5 notes 2026-05-31 02:11:11 -04:00
Joseph Doherty 376dac4895 chore(plans): native alarms execution progress (15/28) + batch-4 notes 2026-05-31 01:50:30 -04:00
Joseph Doherty 3650a89fcd chore(plans): native alarms execution progress (12/28) + resume notes 2026-05-29 17:01:18 -04:00
Joseph Doherty 09e19db4e9 docs(plans): native alarms implementation plan (28 tasks, TDD)
Bite-sized task plan with exact file paths, code, and TDD steps for native
OPC UA A&C + MxAccess GW alarm ingestion. Phases: Commons contracts ->
config/flatten/migration -> DCL ingestion (actor + 2 adapters) -> site
runtime (NativeAlarmActor + SQLite) -> gRPC proto -> management/CLI -> UI ->
seed/docs/integration. Includes .tasks.json for executing-plans resume.
2026-05-29 15:27:43 -04:00
Joseph Doherty dadebbe227 docs(plans): native OPC UA & MxAccess GW alarms design
Read-only mirror of native alarm sources into a unified A&C-style state
model (severity + active/acked/shelved/suppressed). Instance-bound source
discovery, site-only SQLite state with live central query (no central
tables), DebugView enrichment. OPC UA A&C events + ConditionRefresh and
MxGateway session-less StreamAlarms via a new IAlarmSubscribableConnection
seam routed connection-level by source reference; new NativeAlarmActor peer
to computed AlarmActor.
2026-05-29 15:14:01 -04:00
Joseph Doherty 251407934b docs(plan): mark all MxGateway tasks complete in task persistence 2026-05-29 08:12:43 -04:00
Joseph Doherty 9b7916bb2e refactor(browse): rename BrowseOpcUaNode* to protocol-agnostic BrowseNode*
Renames BrowseOpcUaNodeCommand/Result -> BrowseNodeCommand/Result and
CommunicationService.BrowseOpcUaNodeAsync -> BrowseNodeAsync across Commons,
Communication, SiteRuntime, DCL actors, and CentralUI. Wire manifest name
follows (BrowseOpcUaNode -> BrowseNode). Browse regression tests green.
2026-05-29 07:57:36 -04:00
Joseph Doherty 2044023bdd docs(dcl): implementation plan for MxGateway data connection
19 bite-sized tasks across adapter (TDD), config serializer/validator,
browse generalization rename, Central UI protocol selector/editor, packaging,
and integration. Co-located task persistence for resumable execution.
2026-05-29 07:39:44 -04:00
Joseph Doherty 8730c6e30a docs(dcl): design for MxGateway data connection (2nd protocol)
Add design doc for a second data-connection protocol, MxGateway, alongside
the OPC UA client. New IDataConnection adapter behind the existing
DataConnectionFactory extension point; tag pipe (read/subscribe/write) plus
Galaxy hierarchy browse, optional 2nd endpoint for failover. Generalizes the
OPC-UA-named browse plumbing to protocol-agnostic browse via
IBrowsableDataConnection. No entity/schema changes.
2026-05-29 07:28:21 -04:00
Joseph Doherty 2aad9b533a plan: implementation plan for OPC UA tag browser popup (22 tasks)
Five phases, PR-shippable per phase: schema/contracts, DCL browse capability,
flattening uses override, Central UI popup + integration, docs. Per-task
classification, time estimates, and parallelism declared.
2026-05-28 11:43:04 -04:00
Joseph Doherty 8632c098b9 plan: design for OPC UA tag browser popup on instance config page
Per-instance address override + live ClusterClient-based browse via a new
IBrowsableDataConnection capability on RealOpcUaClient. Lazy-loaded tree
with manual-paste fallback; offline-safe.
2026-05-28 11:33:12 -04:00
Joseph Doherty 7b0b9c7365 refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)
Solution + 23 src projects + 26 test projects renamed; folders, csproj,
namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated.
ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated.
SQL roles/logins, LDAP domains, CLI command name, and CLI config dir
(~/.scadalink → ~/.scadabridge) also renamed.

Build green; 5 Host.Tests fail awaiting SQL login rename in next commit.
Pre-existing StaleTagMonitor timing flakes unchanged.

Rename script committed at tools/rename-to-scadabridge.sh.
2026-05-28 09:37:45 -04:00
Joseph Doherty d8eda2f508 plan: design for ScadaLink → ZB.MOM.WW.ScadaBridge rename
Decisions: full prefix in csproj names + namespaces, full runtime
artifact rename (containers/network/DBs), staged commits on main,
in-place MS SQL DB rename, wipe site SQLite on cutover.
2026-05-28 09:27:31 -04:00
Joseph Doherty 80497d1332 chore(plans): mark env2 plan tasks completed 2026-05-24 07:26:20 -04:00
Joseph Doherty 4951e6f81b docs(plans): add env2 + Transport manual verification checklist 2026-05-24 07:17:44 -04:00
Joseph Doherty e66fee0d26 docs(plans): add second environment (env2) implementation plan
11-task plan (T0-T10) covering the sibling docker-env2/ directory:
SQL setup script + mount, Traefik config, central/site appsettings,
docker-compose, lifecycle scripts, .gitignore, READMEs and cross-refs,
verification checklist, and a manual smoke test. No application code
changes -- pure deploy tooling. Most tasks (T0-T9) are independent
and parallel-ready; T5 is gated on T0 + T4; T10 gates on all of T0-T9.
2026-05-24 07:08:46 -04:00
Joseph Doherty 2fd3426fc2 docs(plans): add second environment (env2) design
Brainstorming output for a sibling docker-env2/ tree that brings up a
minimal second cluster (2 central + 1 site x 2 nodes + Traefik) on the
same machine alongside the primary docker/ stack. Shares the existing
scadalink-net network and scadalink-mssql container but uses separate
logical databases (ScadaLinkConfig2 / ScadaLinkMachineData2) so the
Transport (#24) feature can be exercised end-to-end with real
cross-environment exports and imports.
2026-05-24 07:03:02 -04:00
Joseph Doherty 90baa4d6d5 docs(transport): manual cluster verification checklist 2026-05-24 04:52:59 -04:00
Joseph Doherty 1bc98e10a1 docs(plans): add Transport (Component #24) implementation plan
30-task plan covering ScadaLink.Transport project, AES-256-GCM bundle
encryption, IAuditCorrelationContext for BundleImportId threading,
TreeView checkbox-selection mode + TemplateFolderTree wrapper, two
Central UI wizard pages, EF migration, integration tests, README +
cross-reference updates. Single shipping slice, no feature flag.
2026-05-24 03:43:18 -04:00
Joseph Doherty 1b02f33829 docs(plans): add Transport (Component #24) brainstorming design
File-based, encrypted bundle export/import via the Central UI for
promoting templates, system artifacts, and central-only configuration
across environments. Site-scoped artifacts excluded. Per-artifact
conflict resolution; config-only import (user redeploys via existing
Deployments page). Per-entity audit rows correlated by BundleImportId.
2026-05-24 03:32:21 -04:00
Joseph Doherty 8fb9eb0ce7 chore(db): align SourceNode unicode metadata + document partition-aligned index recipe
Tidies flagged by code review on the T6/T7/T8 migration bundle:

- Add `.IsUnicode(false)` to the three SourceNode EF property mappings to
  match every other ASCII varchar column on the same entities. Physical
  column was already `varchar(64)` because `HasColumnType` wins, but the EF
  model metadata flag was inconsistent.
- Add `unicode: false` to the three AddColumn<string> calls in the migrations
  + their Designer snapshots so the historical snapshots match the model.
- Update the model snapshot to carry IsUnicode(false) on each SourceNode entry.
- Document the SELECT-list invariant on SiteCallAuditRepository.QueryAsync:
  EF Core's FromSqlInterpolated requires every entity-tracked column in the
  result set, so future SiteCall columns must extend the list too.
- Amend plan Task 6 Step 2 to document the partition-aligned raw-SQL index
  recipe and the staging-table sync requirement.
2026-05-23 16:45:19 -04:00
Joseph Doherty 9e5e32d0f2 docs(audit): add SourceNode column to AuditLog/Notifications/SiteCalls design + plan
- Adds SourceNode varchar(64) NULL to AuditLog, Notifications, and SiteCalls
  tables with role-name semantics: node-a/node-b for site rows (qualified by
  SourceSiteId), central-a/central-b for central direct-write rows.
- New IX_AuditLog_Node_Occurred (SourceNode, OccurredAtUtc) index.
- Reframes CLAUDE.md from documentation-only to implementation project.
- Adds docs/plans/2026-05-23-audit-source-node.md + tasks.json companion.
2026-05-23 15:34:44 -04:00
Joseph Doherty e567eb334c docs(audit): drop stale InboundAuthFailure exclusion from design doc
The design doc claimed (in two places) that InboundAuthFailure rows
were excluded from the inbound full-body carve-out — but the actual
implementation gates the carve-out on Channel == ApiInbound, NOT Kind.
Every audit row the InboundAPI middleware emits (whether
Kind = InboundRequest or Kind = InboundAuthFailure) carries
Channel = ApiInbound, so both Kinds receive the inbound ceiling. That
is the intended behaviour: an auth-failure row's request body is
exactly the body the operator wants to see in full when investigating
a rejected request.

Update both occurrences (Decision block + Not in Scope block) to say
the carve-out applies to all Channel = ApiInbound rows regardless of
Kind. Pure documentation change — no code drift.
2026-05-23 09:25:23 -04:00
Joseph Doherty 441ec087a7 docs(audit): implementation plan — full request/response capture for inbound API audit rows
Plan companion to the 2026-05-23 design doc. Seven tasks (#0 prep, #1-3
implementation TDD, #4-5 doc updates, #6 final sweep). Tracks via
.tasks.json for resumability.
2026-05-23 05:36:08 -04:00
Joseph Doherty 0670864160 docs(audit): design — full request/response capture for inbound API rows
Carve-out from Payload Capture Policy: ApiInbound rows capture
RequestSummary and ResponseSummary in full up to a configurable 1 MB
per-body ceiling (AuditLog:InboundMaxBytes), instead of the global 8 KB /
64 KB caps. No schema change; existing redaction (headers + per-target
body redactors) still applies before persistence.
2026-05-23 05:28:34 -04:00
Joseph Doherty d4a7344f89 docs(centralui): refresh stale test summaries + drop redundant modal-lg 2026-05-22 02:03:36 -04:00
Joseph Doherty fd07654c68 docs(centralui): execution-tree node modal implementation plan + task tracking 2026-05-22 01:15:53 -04:00
Joseph Doherty d5623e98bd docs(centralui): execution-tree node detail modal design 2026-05-22 01:13:11 -04:00
Joseph Doherty e4b37e2798 docs(auditlog): ParentExecutionId implementation plan + task tracking 2026-05-21 16:58:07 -04:00
Joseph Doherty 6be26e2813 docs(auditlog): ParentExecutionId cross-execution correlation design 2026-05-21 16:53:25 -04:00
Joseph Doherty 4002f4197b docs(plan): Audit Log ExecutionId implementation plan 2026-05-21 14:37:12 -04:00
Joseph Doherty 6ffa47f258 docs(design): Audit Log ExecutionId universal correlation 2026-05-21 14:34:12 -04:00
Joseph Doherty 40955bbca6 docs(plan): mark audit-log follow-up tasks complete 2026-05-21 06:41:53 -04:00
Joseph Doherty 7a386a80ce docs(auditlog): mark follow-ups complete in roadmap; refresh stale comments 2026-05-21 06:39:49 -04:00
Joseph Doherty 5fe08eaceb docs(plan): audit-log deferred follow-ups implementation plan 2026-05-21 03:17:59 -04:00
Joseph Doherty 5492c94e2f docs(audit): roadmap closeout — all 8 milestones complete (#23)
Audit Log #23 implementation complete. M1-M8 merged to main. Full
solution 2,993 tests green, 0 failures. Records final state, the
v1.x deferrals (hash chain, Parquet, per-channel retention), and the
follow-ups noted during implementation (real gRPC push client, mapper
consolidation, Site Calls UI, multi-value filters, grid drag UX).
2026-05-20 22:16:53 -04:00
Joseph Doherty 263884fa63 docs(audit): add M8 CLI implementation plan (#23)
3 bundles: CLI audit command group (scaffold/query/export/verify-chain),
ManagementService endpoints, formatters + audit-config rename + README.
verify-chain is a v1 no-op stub; hash chain deferred to v1.x.
2026-05-20 21:39:29 -04:00
Joseph Doherty 2d13886286 docs(audit): add M7 Central UI implementation plan (#23)
8 bundles: page scaffold + rename, filter bar + grid, drilldown drawer,
drill-ins, KPI tiles, CSV export, permissions, Playwright. UI memory
constraints locked: Blazor Server + Bootstrap, no third-party libs.
2026-05-20 19:43:30 -04:00
Joseph Doherty 8c2382c2bc docs(audit): roadmap corrections after M6
M7 head records M6 realities:
- IAuditCentralHealthSnapshot exists; M7 dashboard reads it.
- SiteHealthReport.SiteAuditBacklog ready for per-site tiles.
- IAuditLogRepository.QueryAsync is the page's data source.
- Pre-existing AuditLog.razor rename to ConfigurationAuditLog.razor
  needs verification.
- OperationalAudit + AuditExport permission strings need to exist.
- Real gRPC pull client still deferred; doesn't gate M7.
2026-05-20 19:42:54 -04:00
Joseph Doherty b0584f7a08 docs(audit): add M6 reconciliation+purge+partition+health plan (#23)
6 bundles: proto+site handler, reconciliation actor, purge actor with
drop-and-rebuild around UX index, partition maintenance, four health
metrics, integration tests. M5 realities baked in.
2026-05-20 17:44:12 -04:00
Joseph Doherty db05af897e docs(audit): roadmap corrections after M5
M6 head records M5 realities:
- IOptionsMonitor hot-reload pattern verified; M6 retention config can
  reuse.
- AuditRedactionFailure counter site-only in M5; M6 wires central side.
- Filter integration is at 3 writer entry points; purge actor doesn't
  emit so no filter integration needed.
- SwitchOutPartitionAsync drop-and-rebuild dance required (M1 reality
  + M6-T4 already documents it).
- M6 should land the real ISiteStreamAuditClient (Option A) so push
  telemetry leaves NoOp behind.
2026-05-20 17:43:44 -04:00
Joseph Doherty e7b40c1c50 docs(audit): add M5 payload+redaction implementation plan (#23)
4 bundles: filter+truncation, redactors (header/body/SQL-param), wire
into all emission paths + health metric, config+perf+safety-net.

Vocabulary translation locked: error-row cap (64 KB) on Status NOT IN
(Delivered, Submitted, Forwarded). Filter integration point in each
writer (FallbackAuditWriter, CentralAuditWriter, AuditLogIngestActor)
BEFORE storage call.
2026-05-20 16:56:56 -04:00
Joseph Doherty dae6de2c48 docs(audit): roadmap corrections after M4
M5 head records M4 realities:
- AuditingDbConnection/Command/DataReader decorators need filter plug-in
  at WriteAsync emission point.
- CentralAuditWriter + FallbackAuditWriter are both filter integration
  points for the direct-write + chained-write paths.
- InboundAPI middleware RequestSummary populated, ResponseSummary=null
  pending response-body buffering decision in M5.
- UseWhen(/api/) path-scoped middleware gives natural per-target
  redaction hook.
- Error-row cap raised on Status IN (Failed, Parked, Discarded,
  Attempted, Skipped) per M1 vocab reconciliation.
2026-05-20 16:56:18 -04:00
Joseph Doherty c410fc6d43 docs(audit): add M4 remaining-boundaries implementation plan (#23)
5 bundles: DB sync emissions, NotificationOutbox central, site Notify.Send,
Inbound API middleware, integration tests. M3-reality vocab baked in
(DbWrite/NotifyDeliver/NotifySend/InboundRequest/InboundAuthFailure).
2026-05-20 15:41:13 -04:00
Joseph Doherty f48efa7ca8 docs(audit): roadmap corrections after M3
M4 head now records M3 realities:
- Vocabulary translation table from pre-M1 spec strings to M1-aligned
  enum values (DbWrite vs SyncWrite/SyncRead; NotifyDeliver vs
  Notification.Attempt/Terminal; InboundRequest/InboundAuthFailure vs
  ApiInbound.Completed; Failed vs PermanentFailure).
- Mapper consolidation: 4 DTO mappers exist; extract single helper
  before M4 adds more channels.
- OnCachedTelemetryWithoutDualWriteAsync test-mode fallback may be
  deprecated in M4.
- Site SQLite drain for OperationTrackingStore: only dual-write
  transaction writes central today; plan drain if M4 needs in-flight
  tracking visibility.
- SiteCallAuditActor wired but unused on M3 hot path; M4/M6 natural
  first direct caller.
2026-05-20 15:40:33 -04:00
Joseph Doherty 4ca0b3ce2a docs(audit): add M3 cached-operations implementation plan (#23)
7 bundles, 18 tasks. Vocabulary alignment baked in (CachedSubmit /
ApiCallCached / DbWriteCached / CachedResolve, statuses Submitted /
Forwarded / Attempted / Delivered / Failed / Parked / Discarded).

Recommended defaults locked: new IngestCachedTelemetry RPC, separate
CachedCallTelemetryForwarder reusing the SiteAuditTelemetryActor drain
loop, ScriptRuntimeContext wrapper for provenance, component-level e2e
in AuditLog.Tests via the extracted DirectActorSiteStreamAuditClient
helper.
2026-05-20 13:43:46 -04:00