This is the densest phase — where the field mapping, the wave plan, the migration architecture, the definition of "correct," the risk posture, and the adoption plan all get set. Get these right and the build is mechanical.
Scope baseline
In: ~1,200 objects and 250 rationalized reports across 8 functions; code conversion, data foundation, and reporting migration.
Out: retired reports, source systems, and net-new analytics.
Constraint: financial close windows are protected — no cutover during month-end.
Mobilize → Discover → Design & Map → Build & Convert → Test & Reconcile → Cutover → Adopt → Decommission. Each decomposes per wave into work packages with an owner and an exit gate.
The load-bearing artifact
The one document where the legacy schema, the new schema, and the business meaning are reconciled in a single row. Every cell closes a question — and each is a place the migration can go wrong.
| Source (SQL Server) | Type · grain | Transformation | Target (Snowflake) | Validation | Owner |
|---|---|---|---|---|---|
| FactOpportunity.CloseAmt | MONEY · per opp / snapshot | MONEY→NUMBER(19,4); FX to USD on close date; null rejected, not defaulted | FACT_OPPORTUNITY.CLOSE_AMOUNT_USD | Sum + row-count reconcile; FK to DIM_ACCOUNT resolves | Sales Finance SME |
| FactOpportunity.CloseDate | DATETIME · per opp | DATETIME→TIMESTAMP_NTZ; timezone normalized | FACT_OPPORTUNITY.CLOSE_DATE | Min/max date parity per period | Sales Finance SME |
| DimAccount.AcctId | IDENTITY · per account | IDENTITY→sequence; surrogate key re-seeded & remapped | DIM_ACCOUNT.ACCOUNT_KEY | Distinct-count parity; no orphan facts | Data Governance |
The interactive version — where each cell explains what it carries and what the TPM owns — is a companion artifact: open the mapping deep-dive →
Consumer plan
| Report | Consumers | Disposition | Rationale |
|---|---|---|---|
| Revenue by Segment | Sales Finance, Exec | Rebuild | High-value; re-model for Snowflake performance |
| Pipeline Snapshot | Sales Ops | Migrate | Re-point to new source; logic unchanged |
| Legacy Quota v3 (copy) | — none in 12 mo | Retire | Duplicate of active report; no recent access |
Schedule baseline
Functions migrate in dependency order — shared dimensions before the facts that depend on them — so no wave is blocked waiting on another. Cutover sits inside each wave, never during a financial close.
Migration strategy
Bulk history load
Full historical load per wave into Snowflake, validated before the incremental feed is switched on.
Incremental / CDC dual-run
Both platforms run in parallel, reconciled daily, so the target is proven current before anyone depends on it.
Code conversion
T-SQL stored procs rewritten as Snowflake Scripting — the bulk of the engineering effort, sized as its own workstream.
Definition of correct
"Migrated" isn't done; "reconciled" is done. Because Snowflake accepts but doesn't enforce PK/FK constraints, integrity checks move out of the schema and into the test suite.
| Test | What it proves | Tolerance |
|---|---|---|
| Row-count parity | No rows dropped or duplicated in transit | 0 |
| Sum / metric parity | Financial totals match — revenue to the penny | 0 on financials |
| Checksum / hash | Row-level values identical, not just aggregates | 0 |
| Referential integrity | No orphan facts — the check Snowflake won't do itself | 0 orphans |
| Report parity | Old dashboard vs. new, same inputs, same output | visual sign-off |
Risk management
Scored probability × impact, owned, and reviewed on cadence. These are the migration-specific risks that actually bite.
| # | Risk | Severity | Mitigation | Owner |
|---|---|---|---|---|
| R1 | Source data-quality gaps surface during load | High | Data profiling in discovery; cleansing rules agreed before build | Data Eng |
| R2 | Financial metric fails reconciliation post-load | High | Zero-tolerance sum parity; grain stated on both sides of every row | TPM / SME |
| R3 | T-SQL code conversion underestimated | Medium | Conversion sized as its own workstream; accelerator evaluated | Data Eng |
| R4 | SME availability during design & UAT | Medium | Named owners per domain in RACI; time booked in advance | TPM |
| R5 | Adoption resistance at go-live | Medium | Change management from day one; champions network per function | Change Lead |
| R6 | Dual-run sync drift between platforms | Low | Daily reconciliation during dual-run; drift alerts | Data Eng |
The third program
The amateur mistake is treating this as end-of-project training. It starts in mobilization and never stops — because ~4,500 people have to trust the new numbers, not just receive a login.
| Stage | When | Activity | Measured by |
|---|---|---|---|
| Awareness | Mobilize | Comms on the why; impact by function | Reach |
| Involvement | Design → UAT | SMEs in mapping and parity sign-off; champions recruited | SME participation |
| Training | Pre-cutover | Role-based training; office hours; quick-reference guides | Completion % |
| Adoption | Post go-live | Champions support; usage nudges; feedback loop | Active users vs. target |
Rhythm of business
| Forum | Cadence | Purpose |
|---|---|---|
| Steering committee | Bi-weekly | Health, escalations, gate approvals |
| Workstream standup | Daily | Blockers, dependencies, sprint progress |
| Risk / RAID review | Weekly | Score changes, new issues, mitigations |
| Design authority | As needed | Ambiguous-field rulings, model decisions |