# ScadaLink → ZB.MOM.WW.ScadaBridge Rename — Design **Date:** 2026-05-28 **Status:** Approved, in implementation **Scope:** Repo-wide rename of the product from "ScadaLink" to "ScadaBridge" and addition of the `ZB.MOM.WW` company prefix to every .NET project. Code, runtime artifacts (containers, network, databases), docs, and CLI config. ## Decisions | # | Decision | Selected option | |---|----------|-----------------| | 1 | Project / namespace format | `ZB.MOM.WW.ScadaBridge.` (both csproj filename and default namespace) | | 2 | Runtime artifact rename | Full — containers `scadabridge-*`, network `scadabridge-net`, DBs `ScadaBridge*`, CLI config `~/.scadabridge/` | | 3 | Git rollout | Staged commits on `main` (3 commits: code → runtime → docs) | | 4 | MS SQL DB migration | In-place `ALTER DATABASE … MODIFY NAME` (preserves data) | | 5 | Site SQLite | Wipe on cutover (`rm -rf docker/site-*/data` per existing reset pattern) | | 6 | Infra container `scadalink-mssql` | Rename to `scadabridge-mssql` + drop volume + re-seed (no `cp` between volumes) | ## Section 1 — Naming Map | Surface | Old | New | |---|---|---| | Solution file | `ScadaLink.slnx` | `ZB.MOM.WW.ScadaBridge.slnx` | | Source projects (23) | `src/ScadaLink./ScadaLink..csproj` | `src/ZB.MOM.WW.ScadaBridge./ZB.MOM.WW.ScadaBridge..csproj` | | Test projects (26) | `tests/ScadaLink..Tests/…` | `tests/ZB.MOM.WW.ScadaBridge..Tests/…` | | Special tests | `ScadaLink.IntegrationTests`, `ScadaLink.PerformanceTests`, `ScadaLink.Transport.IntegrationTests`, `ScadaLink.CentralUI.PlaywrightTests` | gain `ZB.MOM.WW.ScadaBridge.` prefix; no component infix | | Namespaces | `namespace ScadaLink.…` | `namespace ZB.MOM.WW.ScadaBridge.…` | | Assembly names | (default = csproj name) | (default = csproj name) | | DbContext | `ScadaLinkDbContext` | `ScadaBridgeDbContext` | | MS SQL databases | `ScadaLinkConfig`, `ScadaLinkMachineData`, `ScadaLinkConfig2`, `ScadaLinkMachineData2` | `ScadaBridgeConfig`, `ScadaBridgeMachineData`, `ScadaBridgeConfig2`, `ScadaBridgeMachineData2` | | Container names | `scadalink-central-a`, `scadalink-env2-site-x-a`, `scadalink-mssql`, … | `scadabridge-central-a`, `scadabridge-env2-site-x-a`, `scadabridge-mssql`, … | | Docker network | `scadalink-net` | `scadabridge-net` | | Docker image tag | `scadalink:latest` | `scadabridge:latest` | | CLI config dir | `~/.scadalink/config.json` | `~/.scadabridge/config.json` | | Top-level docs | `CLAUDE.md`, `README.md`, `docs/**`, `deployments/**` | rewritten in place | **Explicitly NOT renamed:** - `Transport.SourceEnvironment` values (`docker-cluster`, `docker-cluster-env2`) — deployment IDs, not product names. Stable per `deployments/`. - SQLite filenames (`site_events.db`, `audit.db`, S&F buffer) — already generic. - Sister repos `~/Desktop/MxAccessGateway`, `~/Desktop/OtOpcUa` — out of scope. - Repo folder `~/Desktop/scadalink-design` — renaming it breaks Claude Code memory paths and the user's shell context. Folder name is allowed to diverge from product name. ## Section 2 — Execution Mechanics A scripted multi-pass substitution, committed to the repo at `tools/rename-to-scadabridge.sh`. Substitution order is most-specific-first to avoid double-replacement: ``` 1. ScadaLinkDbContext → ScadaBridgeDbContext 2. ScadaLinkMachineData → ScadaBridgeMachineData 3. ScadaLinkConfig → ScadaBridgeConfig 4. ScadaLink. → ZB.MOM.WW.ScadaBridge. 5. ScadaLink → ScadaBridge 6. scadalink- → scadabridge- 7. scadalink: → scadabridge: 8. .scadalink/ → .scadabridge/ ``` Each pass operates on `git ls-files -z | xargs -0 sed -i ''` so the `.git/` directory and untracked artifacts are skipped. **Phases:** | # | Phase | What runs | |---|-------|-----------| | A | Generate | Write `tools/rename-to-scadabridge.sh`. Dry-run prints affected files. | | B | Text pass | Steps 1–8. Content edits only; csproj filenames + folder names not yet moved. Build will fail at this point — expected. | | C | Move files | `git mv` 23 src project folders + 26 test project folders, then each `.csproj` inside, then `git mv ScadaLink.slnx ZB.MOM.WW.ScadaBridge.slnx`. | | D | Build & test | `dotnet restore` → `dotnet build ZB.MOM.WW.ScadaBridge.slnx` → unit-test pass. Fix stragglers (generated proto code, JSON identifiers with unexpected casing). | | E | Runtime rename | `docker/docker-compose.yml`, `docker-env2/docker-compose.yml`, `infra/docker-compose.yml`, `Dockerfile`, all deploy/teardown/seed/build shell scripts, all appsettings.json connection strings. SQL rename script. | | F | Redeploy & verify | `bash docker/deploy.sh` → `bash docker-env2/deploy.sh` → integration tests → CLI smoke (`template list`). | | G | Docs & memory | `CLAUDE.md`, `README.md`, `deployments/*.md`, `docs/plans/*.md`, MEMORY.md references. | **Completeness gate** (end of phase D): ```bash git grep -nE "ScadaLink|scadalink" -- ':!*.md' ':!CLAUDE.md' | grep -v "docs/plans/2026-05-28-scadabridge-rename" ``` Must return zero hits in code/config. Docs and this design doc are allowed to mention the old name for historical context. **Commit sequence:** 1. `refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)` — phases B+C+D 2. `refactor: rename runtime artifacts to scadabridge (containers, network, DBs, image tag)` — phases E+F 3. `docs: rename ScadaLink → ScadaBridge across CLAUDE.md, README, deployments, plans` — phase G `git diff` review between each commit. ## Section 3 — Database Migration **MS SQL — in-place rename, no data loss:** ```sql USE master; ALTER DATABASE ScadaLinkConfig MODIFY NAME = ScadaBridgeConfig; ALTER DATABASE ScadaLinkMachineData MODIFY NAME = ScadaBridgeMachineData; ALTER DATABASE ScadaLinkConfig2 MODIFY NAME = ScadaBridgeConfig2; ALTER DATABASE ScadaLinkMachineData2 MODIFY NAME = ScadaBridgeMachineData2; ``` Wrapped in `docker/rename-databases.sh`; `docker-env2/init-db.sh` updated to create the new names going forward. EF Core doesn't store the database name in the model snapshot, so no migration is required. **Site SQLite — wipe on cutover:** ```bash rm -rf docker/site-*/data docker/central-*/data rm -rf docker-env2/site-*/data docker-env2/central-*/data ``` Run before redeploy in phase F. The seed-sites scripts re-create site rows; S&F buffers and event logs start empty. Matches the existing reset pattern documented in `docker/README.md`. **Infra container `scadalink-mssql`:** Drop volume + re-seed. `docker compose -f infra/docker-compose.yml down -v` then `up -d`. Test data is dev-only and seed scripts are fast — preferred over copying volume data. Same approach for LDAP (config-file driven), SMTP (ephemeral by design), OPC UA (config-file driven), REST API (stateless). ## Out of Scope - Sister repos `~/Desktop/MxAccessGateway`, `~/Desktop/OtOpcUa` — independent codebases, independent timelines. - Repo folder `~/Desktop/scadalink-design` — left as-is to preserve Claude Code memory paths and user shell context. - Existing Transport bundle manifests with `SourceEnvironment = "docker-cluster"` — those values are deployment IDs and stay stable. If the user later wants to rename the deployment IDs themselves, that's a separate design. ## Verification After all three commits: - `dotnet build ZB.MOM.WW.ScadaBridge.slnx` clean - `dotnet test` — unit + integration suites green (pre-existing flakes documented in earlier code-review remediation sessions remain accepted) - `curl -s http://localhost:9000/health/ready` and `http://localhost:9100/health/ready` both report healthy on the renamed primary + env2 stacks - CLI smoke: `dotnet run --project src/ZB.MOM.WW.ScadaBridge.CLI -- --username multi-role --password password template list` against both stacks - `git grep -nE "ScadaLink|scadalink"` returns only this design doc and intentional historical references in committed plans