# 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.<Component>` (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.<C>/ScadaLink.<C>.csproj` | `src/ZB.MOM.WW.ScadaBridge.<C>/ZB.MOM.WW.ScadaBridge.<C>.csproj` |
| Test projects (26) | `tests/ScadaLink.<C>.Tests/…` | `tests/ZB.MOM.WW.ScadaBridge.<C>.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.<C>…` | `namespace ZB.MOM.WW.ScadaBridge.<C>…` |
| 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
