# Deployment record — wonder-app-vd03 — 2026-06-27

Point-in-time record of a ScadaBridge upgrade + live configuration changes on the
single-host install at **`wonder-app-vd03.zmr.zimmer.com`** (`E:\ApiInstall\ScadaBridge`,
three Windows services: `ScadaBridge-LDAP`, `ScadaBridge-Central` :8085, `ScadaBridge-Site`).

> Runtime config on this box (instance connection bindings, template compositions) is
> **config-as-data** held in the `ScadaBridge` SQL ConfigDb and applied via the management
> API — it is **not** source-controlled. This file is the durable record of those changes.
> Secrets (DB password, gateway API key, JWT/pepper) are intentionally omitted.

## 1. Binary + schema upgrade

| Item | Value |
|---|---|
| Build deployed | `main` @ **`06f2df4f`** (from `1f261263`; 40 commits) |
| Headline change | **notify-and-fetch deploy rework** — Central stages a `PendingDeployment` row + sends `RefreshDeploymentCommand`; the Site fetches config over HTTP from `GET {CentralFetchBaseUrl}/api/internal/deployments/{id}/config`. Retires the old cross-cluster `DeployInstanceCommand` config-push path. |
| EF migration applied | **`20260626161432_AddPendingDeployment`** (additive: new `PendingDeployments` table + FK + 3 indexes). Baseline was `20260619191520_SmsFromNumberOptional`. From→to script via `sqlcmd -C -b -I`. |
| New required config | **`ScadaBridge:Communication:CentralFetchBaseUrl = http://localhost:8085`** in `appsettings.Central.json` (empty → deploy fail-fast). Site needs nothing new — it receives the URL+token in the notify/reconcile message. |
| Not deployed | the new standalone `DelmiaNotifier` console tool (external client, not part of the Host service). |
| Preserved across swap | box `appsettings.json` + `appsettings.Site.json` + the entire `app\data\` (`inbound-api-keys.sqlite`, 53 KB). |
| DB backup | `E:\ApiInstall\ScadaBridge-backups\ScadaBridge_pre-AddPendingDeployment_20260627T001136.bak` |
| Binary backup | `E:\ApiInstall\ScadaBridge\app.bak.20260627T001254` (old `1f261263` binaries + appsettings + data) |

### Verification
- `/health/ready` = **200 Healthy** (database + akka-cluster Up + all 5 required singletons).
- DisableLogin active (mgmt API no-auth → 200); inbound auth intact (bogus `X-API-Key` → 401).
- New `SiteReconciliationActor` / `SiteReplicationActor` started; reconcile pass `0 fetched, 0 failed, 0 orphan(s)`.
- **Notify-and-fetch proven end-to-end**: deploying an instance staged a `PendingDeployment` → Site fetched config (`200`, ~118 KB) over `CentralFetchBaseUrl` → applied → re-subscribed.

## 2. Live ConfigDb changes (config-as-data, not in git)

### 2a. Instance connection-binding completeness fixes
Several CvdReactor instances failed *pre-deployment validation* (missing binding rows for
data-sourced attributes — every existing binding correctly pointed at the only site
connection, `MxGateway` id=1). Fixed by adding the missing bindings via
`SetConnectionBindings` (full-list replace), then redeploying. Galaxy object names were
read from the gateway snapshot hierarchy (`galaxy-snapshot.json`).

| Instance (id) | Reactor-level `DelmiaReceiver` object | LeakTest side objects | Result |
|---|---|---|---|
| Z28061 (1) | `DelmiaReceiver_038` | (already bound: `Left_002`/`Right_002`) | +10 bindings → **deploys**, 270 tags, DelmiaReceiver 10/10 Good |
| Z28062 (2) | `DelmiaReceiver_039` | `Left_003.LeakTest.*` / `Right_003.LeakTest.*` | +60 bindings → **deploys**, 270 tags, DelmiaReceiver 10/10 Good, LeakTest 28/50 Good (22 Bad = genuine idle-2nd-reactor source state) |
| Z28061Sim (8) | `DelmiaReceiver_037` | `Left_001`/`Right_001` | already complete (reference instance) |

### 2b. CvdReactor template rename: `DelmiaRecv` → `DelmiaReceiver`
The `CvdReactor` template (id 1) had a typo'd reactor-level composition `DelmiaRecv`
(built from a duplicate template named `DelmiaRecv`, byte-identical to the proper
`DelmiaReceiver` template id 12). Corrected:

- `DeleteTemplateComposition` (the `DelmiaRecv` composition) — this also auto-removed its
  composition-owned clone template (the old `DelmiaRecv` template id 25).
- `AddTemplateComposition` → `DelmiaReceiver` from template 12 (engine cloned 12 → new
  template id 26; composition uses the clone).
- Flattened attribute paths changed `DelmiaRecv.*` → `DelmiaReceiver.*`, so all three
  CvdReactor instances were rebound (binding prefix renamed; source `DelmiaReceiver_03x`
  objects unchanged) and redeployed.

Result: CvdReactor components are now `LeftMESReceiver, RightMESReceiver, LeftReactorSide,
RightReactorSide, LeftDelmiaReceiver, RightDelmiaReceiver, DelmiaReceiver`. No `DelmiaRecv`
template or component remains. Z28061 `DelmiaReceiver.*` reads 10/10 Good.

## 3. Instance deployability — final

| Instance | Template | Deploys? |
|---|---|---|
| Z28061 | CvdReactor | ✅ |
| Z28062 | CvdReactor | ✅ |
| Z28061Sim | CvdReactor | ✅ |
| ZIPSEN (id 7) | IpsenSim (18) | ❌ pre-existing `MESReceiver (26)` binding gap — unfinished/draft instance, not touched |

## 4. Rollback
- Schema: restore `ScadaBridge_pre-AddPendingDeployment_20260627T001136.bak` (the migration
  `Down` drops `PendingDeployments`).
- Binaries: restore `app.bak.20260627T001254` + restart Central then Site.
- Binding/template changes: pre-edit binding sets were captured at deploy time; the template
  composition swap is reversible via `DeleteTemplateComposition`/`AddTemplateComposition`.

## 5. Outstanding
- **ZIPSEN** is the only non-deployable instance — needs its full `MESReceiver` binding set
  authored (or to be retired). Deferred pending confirmation it is wanted.
