Phase 1 Migration Dry-Run — Execution & Report#
Phase 1 is additive-only per ADR 0004: no writes to legacy tables, and every new Cube-2.0-owned artifact ships as an idempotent CREATE IF NOT EXISTS. The dry-run therefore boils down to three things:
- Read-only audit against staging to confirm the legacy schema still matches what the entity models assume
- Idempotent apply of the two new tables against staging
- Diff of the result to prove nothing legacy was touched
This doc is the reviewer’s execution guide and the report template. Fill in § 4 with actual results before signing off.
1. What ships#
Three SQL files under deploy/sql/:
| File | Purpose | Idempotent? |
|---|---|---|
phase-1-schema-audit.sql | Read-only — 9 SELECTs that verify legacy shape | N/A |
phase-1-add-mnxuserauth.sql | CREATE TABLE MnxUserAuth for Cube-2.0-owned password rehash (ADR 0006) | Yes — guarded by IF NOT EXISTS |
phase-1-add-mnxloginactivity.sql | CREATE TABLE MnxLoginActivity for login audit trail | Yes — guarded by IF NOT EXISTS |
No ALTER statements. No inserts into legacy tables. Nothing to roll back except dropping the two new tables.
2. Prerequisites#
- Read +
db_ddladminaccess to a copy ofBcomMX_01_04(not the live cluster; staging DB restored from prod backup) sqlcmdor Azure Data Studio with the connection string handed off separately- Backup taken immediately before § 3.2 (in case § 3.2 is somehow non-idempotent — belt and braces)
3. Execution order#
3.1 Audit (read-only)#
sqlcmd -S <staging-host> -d BcomMX_01_04 \
-U <reviewer-account> -P '<pw>' \
-i deploy/sql/phase-1-schema-audit.sql \
-o dry-run-audit.txtCapture dry-run-audit.txt. Redact any UserName / Email / password column values — the query already returns only lengths, but scan the output before pasting into § 4.
3.2 Apply new tables (idempotent)#
sqlcmd -S <staging-host> -d BcomMX_01_04 \
-U <reviewer-account> -P '<pw>' \
-i deploy/sql/phase-1-add-mnxuserauth.sql
sqlcmd -S <staging-host> -d BcomMX_01_04 \
-U <reviewer-account> -P '<pw>' \
-i deploy/sql/phase-1-add-mnxloginactivity.sqlRun the same command a second time. Second run should be a no-op (silent — the IF NOT EXISTS guard skips the CREATE). If the second run raises “table already exists”, the guard is broken — file as a blocker on this ticket.
3.3 Verify no legacy tables were altered#
SELECT name, modify_date
FROM sys.tables
WHERE schema_id = SCHEMA_ID('dbo')
AND modify_date > '<start-timestamp-of-3.2>'
ORDER BY modify_date DESC;Pass if this returns exactly two rows: MnxUserAuth and MnxLoginActivity. Any additional legacy table with a fresh modify_date is a critical bug — halt and file a blocker.
4. Report — reviewer fills in#
4.1 Environment#
| Item | Value |
|---|---|
| Staging host | <host> |
| DB name | BcomMX_01_04 |
| DB size (pre-run) | <GB> |
| Backup taken? | <yes, snapshot ID> |
| Executor | <name> |
| Date/time run | <ISO 8601> |
4.2 Audit results (from § 3.1)#
Query 1 — Password format distribution:
| PasswordFormat | row_count | Interpretation |
|---|---|---|
| 2 | <n> | Encrypted (expected — ADR 0001 assumption) |
| 1 | <n> | Hashed — if > 0, SHA1 verification path must be reactivated (currently stubbed) |
| 0 | <n> | Cleartext — CRITICAL if > 0, security follow-up ticket required |
Query 2 — Sample column lengths: paste the 3-row output verbatim.
Query 5 — Row counts: paste the union output verbatim.
Query 6 — Max roles per user: highest role_count = <n>. If > 100, revisit the “flat role array in JWT” decision (would push us to a reference token + role-fetch endpoint).
Query 7 — Admin flag distribution: paste the output. Note company_admin count — those are the users whose JWT will include every module in mod_admin.
Query 9 — MnxModule.IsPermission distribution: paste the output. This confirms the split between navigation and permission modules that the Menu API (BFC-25) filters on.
4.3 Apply results (from § 3.2)#
| Run | MnxUserAuth created? | MnxLoginActivity created? | Errors |
|---|---|---|---|
| First | <yes/no> | <yes/no> | <none/paste> |
| Second (should be no-op) | <already exists — silent> | <already exists — silent> | <none/paste> |
4.4 No-legacy-touched proof (from § 3.3)#
Paste the sys.tables diff output. Expected: exactly MnxUserAuth + MnxLoginActivity.
4.5 Rollback rehearsal (optional but recommended)#
DROP TABLE dbo.MnxLoginActivity;
DROP TABLE dbo.MnxUserAuth;Run this against staging after the report is signed off, then re-run § 3.2 to confirm the CREATE scripts still succeed after a drop. Documents that Phase 1 is fully reversible.
5. Sign-off#
- All § 4 queries executed and pasted
- Row counts within expected order-of-magnitude of production
- No
PasswordFormat=0rows - Max roles per user ≤ 100
- Only two new tables appeared in
sys.tablesdiff - Reviewer name + date:
_______
Once the checklist is complete, transition this ticket to DEPLOYED and merge Phase 1 branch to master.
6. Known limitations to document during sign-off#
- Audit does not validate
MnxModuleRelationshipshape — the entity is used only by the Navigation API (BFC-25). Add aSELECT TOP 10 * FROM MnxModuleRelationshipif the reviewer wants coverage. - No performance measurement — Phase 1 endpoints are all lightweight reads over already-indexed columns. Load test is deferred to Phase 2 when Sales/RMA hit larger row counts.