docs: record Galaxy library adoption (0.2.0) complete + caveats
Mark A2 handoff and stillpending §2 adopted; note the host-side design (GatewayBrowseScopeProvider, dashboard summary projector), the lib 0.2.0 upstream changes, and caveats (NSSM deploy config, pre-existing NU1903 + IntegrationTests EventStreamService breaks). Point CLAUDE.md at the package.
This commit is contained in:
@@ -1,5 +1,24 @@
|
||||
# A2 — Adopt the shared `ZB.MOM.WW.GalaxyRepository` library
|
||||
|
||||
> **✅ ADOPTED 2026-06-25 (branch `feat/galaxyrepository-adoption`).** mxaccessgw now consumes
|
||||
> `ZB.MOM.WW.GalaxyRepository` **0.2.0** and the inline Galaxy code is deleted (27 files, −2959 LOC).
|
||||
> What shipped:
|
||||
> - **Lib 0.2.0** (published to Gitea) closed the two real upstream gaps: **alarm-attribute discovery**
|
||||
> (`GalaxyAlarmAttributeRow` + `IGalaxyRepository.GetAlarmAttributesAsync` + `AlarmAttributesSql`) and an
|
||||
> injectable **`IGalaxyBrowseScopeProvider`** (default `NullGalaxyBrowseScopeProvider` = no scoping;
|
||||
> HistorianGateway @ 0.1.0 unaffected) wired into the lib's gRPC service. Lib test suite: 64 green.
|
||||
> - **mxaccessgw** registers `GatewayBrowseScopeProvider : IGalaxyBrowseScopeProvider` (reads the API key's
|
||||
> `EffectiveConstraints.BrowseSubtrees`) before `AddZbGalaxyRepository(config,"MxGateway:Galaxy")`, maps
|
||||
> `MapZbGalaxyRepository()`, and switched `GatewayGrpcScopeResolver` galaxy request types to the lib
|
||||
> `.Grpc` namespace (the global authz interceptor now intercepts the lib service). The **dashboard summary
|
||||
> stays host-side** (`DashboardGalaxySummaryProjector`, memoized by cache `Sequence`) since the lib entry
|
||||
> doesn't carry it. Server build zero-warning; 327 targeted tests green.
|
||||
> - The end-to-end host authz chain is covered (`GalaxyRepositoryHostWiringTests`), and the lib gained the
|
||||
> ported browse-projector / deploy-notifier / refresh-service (Server-005 timeout guard) tests.
|
||||
>
|
||||
> **Caveats / follow-ups** (see "Post-adoption notes" at the bottom).
|
||||
> Original handoff (now historical) follows.
|
||||
|
||||
> Handoff note. Written 2026-06-25 from the HistorianGateway side, where the shared lib is
|
||||
> already consumed in production. This is the mxaccessgw half of the cross-repo
|
||||
> "Galaxy-browse normalization" follow-on (HistorianGateway `pending.md` A2 /
|
||||
@@ -153,17 +172,39 @@ be **deleted**. **Keep** the mxaccessgw-specific ones that exercise behavior the
|
||||
`GalaxyAlarmAttributeMappingTests`, `GalaxyFilterInputSafetyTests`, `GalaxyRepositoryGrpcServiceTests`
|
||||
(unless their subjects move upstream too), and the live `IntegrationTests/Galaxy/**`.
|
||||
|
||||
## Suggested order
|
||||
## Suggested order — all DONE (2026-06-25)
|
||||
|
||||
1. ~~Verify the **gRPC-service authz parity** question~~ **DONE (2026-06-25):** wholesale swap is unsafe —
|
||||
per-key browse-subtree filtering is baked into the service body. The service must keep an mxaccessgw
|
||||
subtree-scoping hook (push the provider upstream, or wrap). See the ⚠️ block above.
|
||||
2. Decide alarm-attributes: **upstream into the lib (`0.2.0`)** vs keep inline on top of shared interfaces.
|
||||
3. If upstreaming: do that in `scadaproj/ZB.MOM.WW.GalaxyRepository` first, publish, bump the version.
|
||||
4. `nuget.config` + `csproj` + DI/endpoint wiring; delete the superseded inline files; rebind namespaces
|
||||
in dashboard/alarms/security consumers.
|
||||
5. Delete duplicated tests; build zero-warning; run the suite; live-validate browse + alarm watch-list.
|
||||
6. Propagate to the scadaproj umbrella index + HistorianGateway's `pending.md` A2 (mark adopted).
|
||||
1. ~~Verify the **gRPC-service authz parity** question~~ **DONE:** wholesale swap was unsafe — per-key
|
||||
browse-subtree filtering was baked into the service body. Resolved by pushing an injectable
|
||||
`IGalaxyBrowseScopeProvider` hook **upstream** into the lib (option preferred in the ⚠️ block).
|
||||
2. ~~Decide alarm-attributes~~ **DONE:** upstreamed into the lib as part of `0.2.0`.
|
||||
3. ~~Upstream + publish + bump~~ **DONE:** lib `0.1.0 → 0.2.0`, packed and pushed to the Gitea feed (verified live).
|
||||
4. ~~`nuget.config` + `csproj` + DI/endpoint wiring; delete inline; rebind~~ **DONE.**
|
||||
5. ~~Delete duplicated tests; build zero-warning; run the suite~~ **DONE** (lib 64 green; gateway 327 targeted green).
|
||||
Live-validate browse + alarm watch-list is the one remaining **manual** step (needs Galaxy SQL + a running
|
||||
gateway — opt-in `MXGATEWAY_RUN_LIVE_GALAXY_TESTS=1`); not runnable from the dev Mac.
|
||||
6. **Remaining:** propagate to the scadaproj umbrella index + HistorianGateway's `pending.md` §A2 (mark adopted)
|
||||
— cross-repo, do in those repos.
|
||||
|
||||
## Post-adoption notes / caveats
|
||||
|
||||
- **Deployment config (NSSM):** the deployed services (`MxAccessGw` on 10.100.0.48; the wonder host) read
|
||||
config from **NSSM environment variables, not `appsettings.json`**. The lib's `SnapshotCachePath` default
|
||||
is empty (persistence no-ops). `appsettings.json` sets `MxGateway:Galaxy:SnapshotCachePath` +
|
||||
`PersistSnapshot`, but the deployments must carry `MxGateway__Galaxy__SnapshotCachePath` and
|
||||
`MxGateway__Galaxy__PersistSnapshot` in their NSSM env on redeploy, or snapshot persistence silently
|
||||
no-ops in production.
|
||||
- **Pre-existing NU1903 (unrelated):** adding the package surfaced a transitive `SQLitePCLRaw.lib.e_sqlite3`
|
||||
2.1.11 advisory (GHSA-2m69-gcr7-jv3q, no upstream patch) that breaks the build under `TreatWarningsAsErrors`
|
||||
— already red on `main`. Resolved with a targeted `NuGetAuditSuppress` in `src/Directory.Build.props`
|
||||
(its own commit). Remove the suppression once a patched e_sqlite3 ships.
|
||||
- **Pre-existing IntegrationTests break (unrelated, NOT fixed here):** `IntegrationTests/WorkerLiveMxAccessSmokeTests.cs`
|
||||
constructs `EventStreamService` with 6 ctor args, but a prior event-stream refactor reduced that ctor — so
|
||||
the IntegrationTests project does not compile (already broken on `main`, independent of Galaxy). The Galaxy
|
||||
live tests there were rebound to the lib and compile in isolation, but the project won't build until that
|
||||
unrelated call site is fixed. Track separately.
|
||||
- **No republish needed for the lib test additions:** the browse-projector / deploy-notifier / refresh-service
|
||||
tests were added to the lib AFTER 0.2.0 was published; tests aren't shipped, so 0.2.0 is unchanged.
|
||||
|
||||
## Reference pointers
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
The architecture is a two-process design — read `gateway.md` before making structural changes:
|
||||
|
||||
- **Gateway** (`src/ZB.MOM.WW.MxGateway.Server`, .NET 10, x64): ASP.NET Core gRPC server. Owns the public API, sessions, auth, the Blazor dashboard, and the Galaxy Repository SQL browse RPCs. **Never instantiates MXAccess COM directly.**
|
||||
- **Gateway** (`src/ZB.MOM.WW.MxGateway.Server`, .NET 10, x64): ASP.NET Core gRPC server. Owns the public API, sessions, auth, the Blazor dashboard, and the Galaxy Repository SQL browse RPCs. The Galaxy-browse implementation comes from the shared **`ZB.MOM.WW.GalaxyRepository`** package (`AddZbGalaxyRepository`/`MapZbGalaxyRepository`), not inline code; mxaccessgw adds `GatewayBrowseScopeProvider` (per-key browse-subtree scoping) and a host-side dashboard summary projector. See `A2-galaxyrepository-adoption-handoff.md`. **Never instantiates MXAccess COM directly.**
|
||||
- **Worker** (`src/ZB.MOM.WW.MxGateway.Worker`, .NET Framework 4.8, **x86**): one process per session. Owns one MXAccess COM instance on a dedicated STA, pumps Windows messages, and converts COM events to protobuf.
|
||||
- **IPC**: gateway↔worker uses one bidirectional named pipe per worker (`mxaccess-gateway-{gatewayPid}-{sessionId}`) with length-prefixed `WorkerEnvelope` protobuf frames. Gateway hosts the pipe server and launches the worker. **gRPC is not used inside the worker** — .NET Framework 4.8 doesn't have a first-class gRPC stack.
|
||||
- **Contracts** (`src/ZB.MOM.WW.MxGateway.Contracts`): multi-targets `net10.0;net48` and owns the `.proto` files (`mxaccess_gateway.proto`, `mxaccess_worker.proto`, `galaxy_repository.proto`). All other projects consume the generated types from here. Do not hand-edit anything under `Generated/`.
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ These are documented, deliberate, and mostly enforced. Listed so the deferred su
|
||||
- 🔵 **No server-side / streaming browse search** — `docs/plans/2026-05-28-lazy-browse-design.md:208`.
|
||||
- 🔵 **Alarm command surface is ack + query only** — no Clear/Disable/Enable/Silence/Shelve/Inhibit; matches the MXAccess alarm-client set. `Worker/MxAccess/AlarmCommandHandler.cs`, shelve/suppress out of scope per `docs/AlarmClientDiscovery.md:60-66`.
|
||||
- 🟡 **Dashboard EventsHub has no per-session ACL — still true on `main`, planned (epic Phase 4, not started).** Any authenticated dashboard user may still subscribe to any session group (`Dashboard/Hubs/EventsHub.cs` `TODO(per-session-acl)`). The enabling foundation (session `OwnerKeyId`) already merged in epic Phase 1; epic Phase 4 (Tasks 16–19) adds the gRPC session-owner gate, a session tag + group-to-tag config, and EventsHub per-session ACL with a hub-token tag claim. `docs/plans/2026-06-15-session-resilience.md` Phase 4. (See also §8.)
|
||||
- 🔵 **Adopt the shared `ZB.MOM.WW.GalaxyRepository` library (cross-repo normalization) — not started.** The inline Galaxy-browse code under `src/ZB.MOM.WW.MxGateway.Server/Galaxy/**` (+ `Grpc/GalaxyRepositoryGrpcService.cs`/`GalaxyProtoMapper.cs`) is the source the shared lib was extracted from; HistorianGateway already consumes it as a `PackageReference @ 0.1.0`. Swapping to the package gives one Galaxy-browse implementation across both sidecars (same `galaxy_repository.v1` wire contract — no client change). Non-trivial: mxaccessgw has extra consumers the lib doesn't cover (alarm watch-list / `GetAlarmAttributesAsync`, dashboard projectors, constraint-authz). The gRPC-service authz-parity gate is **verified (2026-06-25): a wholesale swap to `MapZbGalaxyRepository()` is unsafe** — per-key browse-subtree filtering is baked into mxaccessgw's service body (`Grpc/GalaxyRepositoryGrpcService.cs`), so the service must keep a subtree-scoping hook (push the provider upstream, or wrap), not just rely on the interceptor. Full handoff: **`A2-galaxyrepository-adoption-handoff.md`** (repo root). Tracked cross-repo in HistorianGateway `pending.md` §A2 + scadaproj component normalization.
|
||||
- ✅ **Adopt the shared `ZB.MOM.WW.GalaxyRepository` library (cross-repo normalization) — RESOLVED (2026-06-25, branch `feat/galaxyrepository-adoption`).** The inline Galaxy-browse code (`src/ZB.MOM.WW.MxGateway.Server/Galaxy/**` + `Grpc/GalaxyRepositoryGrpcService.cs`/`GalaxyProtoMapper.cs`, 27 files / −2959 LOC) is deleted; mxaccessgw now consumes `ZB.MOM.WW.GalaxyRepository` **0.2.0** (published to Gitea), same `galaxy_repository.v1` wire (no client change). The authz-parity gate was resolved by pushing the per-key browse-subtree filter **upstream** as an injectable `IGalaxyBrowseScopeProvider` (default no-op; HistorianGateway @ 0.1.0 unaffected); mxaccessgw supplies `GatewayBrowseScopeProvider` and switched `GatewayGrpcScopeResolver` to the lib proto types. Alarm-attribute discovery (`GetAlarmAttributesAsync`) was upstreamed too; the dashboard summary stays host-side (`DashboardGalaxySummaryProjector`). Lib 64 tests green; gateway 327 targeted green. Full record + caveats (NSSM config, pre-existing NU1903 + IntegrationTests `EventStreamService` breaks): **`A2-galaxyrepository-adoption-handoff.md`**. Remaining: cross-repo propagation (HistorianGateway `pending.md` §A2, scadaproj index) + opt-in live Galaxy-SQL validation. Full handoff: **`A2-galaxyrepository-adoption-handoff.md`** (repo root). Tracked cross-repo in HistorianGateway `pending.md` §A2 + scadaproj component normalization.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user