docs(localdb): verify lib assumptions against source (CreateConnection open+UDF, ReplicationOptions binding)

Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
This commit is contained in:
Joseph Doherty
2026-07-19 02:02:42 -04:00
parent b0d4e2edac
commit 84170b63ec
@@ -184,7 +184,7 @@ services.AddZbLocalDb(config, SiteLocalDbSetup.OnReady);
- Modify: wherever `AddSiteRuntime` registers the store (follow `services.AddSiteRuntime` from `SiteServiceRegistration.cs:51` into the SiteRuntime SCE)
- Test: `tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/Tracking/` (existing store tests)
**Step 1:** Constructor gains `ILocalDb localDb`; `_writeConnection = localDb.CreateConnection()` replaces `new SqliteConnection(_connectionString)` + `Open()` (CreateConnection hands back an **open, UDF-registered** connection — verify against the lib and adjust if it returns closed). Reader paths that open ad-hoc connections from `_connectionString` switch to `localDb.CreateConnection()` too (reads don't fire triggers, but one connection source is one less config knob). `OperationTrackingOptions.ConnectionString` becomes unused by the store — keep the options class but drop the store's dependency; leave a validator relaxation only if the DI-graph test demands it.
**Step 1:** Constructor gains `ILocalDb localDb`; `_writeConnection = localDb.CreateConnection()` replaces `new SqliteConnection(_connectionString)` + `Open()` (verified in the lib, `SqliteLocalDb.cs:83-98`: CreateConnection returns an **open** connection with per-connection pragmas — `synchronous`, `busy_timeout`, `foreign_keys=ON` — and the `zb_hlc_next` UDF registered; do NOT call `Open()` on it again). Reader paths that open ad-hoc connections from `_connectionString` switch to `localDb.CreateConnection()` too (reads don't fire triggers, but one connection source is one less config knob). `OperationTrackingOptions.ConnectionString` becomes unused by the store — keep the options class but drop the store's dependency; leave a validator relaxation only if the DI-graph test demands it.
**Step 2:** Update existing store tests to construct via a real `ILocalDb` over a temp file (the lib package is test-referenceable) instead of a raw connection string. Schema now comes from `OperationTrackingSchema.Apply` in setup.
@@ -280,8 +280,10 @@ The lib's passive service does not verify keys (documented). Fail-closed server
public sealed class LocalDbSyncAuthInterceptor : Interceptor
{
private const string ServicePrefix = "/localdb_sync.v1.LocalDbSync/";
// read LocalDb:Replication:ApiKey via IOptions<ReplicationOptions> (same key
// both nodes; ${secret:} refs resolve through the existing pre-host expander)
// read via IOptions<ReplicationOptions> — verified: AddZbLocalDbReplication binds
// section "LocalDb:Replication" with ValidateOnStart; ApiKey is string? (null =
// no key configured). Same key on both nodes; ${secret:} refs resolve through
// the existing pre-host expander.
// compare with CryptographicOperations.FixedTimeEquals over UTF8 bytes;
// non-sync methods pass through untouched.
}
@@ -385,5 +387,5 @@ Phase 2 (config tables + `sf_messages` into the consolidated DB; **delete** `Sit
## Execution notes
- Family conventions bind: TreatWarningsAsErrors, red-first tests, container-built DI-graph tests for all wiring, `dotnet test` offline-green.
- Verify each `ILocalDb.CreateConnection()` assumption (open vs closed, UDF present) against the lib source at `~/Desktop/scadaproj/ZB.MOM.WW.LocalDb/` on first use — the plan states behavior from its README + interface docs.
- Lib assumptions **verified against source 2026-07-19** (`~/Desktop/scadaproj/ZB.MOM.WW.LocalDb/`): `CreateConnection()` returns an open, pragma-configured, UDF-registered connection (`SqliteLocalDb.cs:83-98`); `ReplicationOptions` binds from `LocalDb:Replication` with `ValidateOnStart`, `ApiKey` nullable, and a passive node (empty `PeerAddress`) starts its `SyncBackgroundService` and immediately idles (`ReplicationServiceCollectionExtensions.cs`).
- If any task needs files beyond its `Files:` block, that is a plan defect — surface it rather than silently expanding scope.