How I map a 1,200-object inventory, establish governance, and build the wave strategy — before a single line of conversion code gets written.
Setting up the wave plan & critical artifacts
Before I let anyone start building, I needed the mandate, the scope, and the decision rights nailed down. This is the unglamorous phase where a migration is either set up to succeed or quietly set up to fail six months out.
I write the charter myself and take it to Steering rather than waiting for someone to hand me one. It names the outcome in numbers I'll be held to: ~1,200 objects across 8 functions, zero-defect reconciliation on every financial metric, adoption by the reporting user base before I'll agree to decommission anything.
I put three options on the table, because I want the trade-offs on record before anyone can relitigate them mid-program.
| Approach | What it is | Why I rejected or kept it | Verdict |
|---|---|---|---|
| Lift & shift | Replicate the SQL Server schema as-is on Snowflake. | Fastest, but I'd be carrying every legacy flaw and un-tuned model into the new platform. I killed this one. | Rejected |
| Re-architect | Redesign the full data model for Snowflake from scratch. | Best end state on paper, but the timeline and risk ballooned past what the business would tolerate. I killed this one too. | Rejected |
| Hybrid | Migrate structure faithfully; selectively re-model high-value domains and retire dead objects. | Balanced speed and quality — and the rationalization I did up front paid for itself before we built anything. | What I recommended |
I build the RACI myself and get every workstream lead to sign off on it in the same room. Ambiguous decisions resolve once, in the forum I design for it — not repeatedly, at the keyboard, three weeks apart.
Without a written RACI, "who decides" defaults to whoever's loudest or most senior in the room — and that person changes by meeting. This is what lets me point to a document instead of re-arguing authority every time.
| Key decision / deliverable | Me (TPM) | Exec Sponsor | Data Eng Lead | Function SME | BI Lead | Change Lead |
|---|---|---|---|---|---|---|
| Field-mapping sign-off | A | I | C | R | C | I |
| Report disposition (migrate/retire) | R | I | I | A | C | I |
| UAT sign-off | A | I | C | R | C | I |
| Go / no-go decision | R | A | C | C | C | C |
| Legacy decommission | R | A | C | C | I | I |
I inventory every report and who actually uses it before I let anyone touch a migration plan. Nobody thanks the TPM who faithfully migrates 400 reports when 150 of them haven't been opened in a year — so I don't let that happen.
Golden thread
The Sales/Revenue close-amount report is one I confirmed as high-use and kept in scope. I named its owner — a Sales Finance SME — right here, and held them accountable for the field's meaning all the way through mapping, UAT, and cutover.
I sequence functions in dependency order — shared dimensions before the facts that depend on them — so no wave sits blocked waiting on another. I also protect the financial close calendar: no cutover ever gets scheduled during month-end, full stop.
A wave plan isn't a Gantt chart for show — it's the sequencing logic made checkable. Anyone can see why their function landed where it did, which is what lets me defend "you're Wave 3" without it sounding like an excuse.
The most important document
This is the one document I refuse to let go stale. Every object's wave assignment, and my reasoning for it, lives in one place — so nobody can argue sequencing on a hunch after the fact.
Sequencing lives in someone's head until it's written down — and heads leave the room, get pulled onto other fires, or just forget. This matrix is what lets a new engineer, three months in, understand why Wave 4 can't start early without asking me.
| Object / domain | Upstream dependency | Wave I assigned | Why it couldn't move earlier |
|---|---|---|---|
| DIM_ACCOUNT, DIM_DATE, DIM_PRODUCT | None — root objects | Wave 1 | Every downstream fact joins to these. Get them wrong and the error replicates across every wave that follows. |
| FACT_GL_TRANSACTIONS (Finance) | Shared dims + Chart of Accounts | Wave 2 | Finance's close calendar drove the earliest cutover-safe window — I sequenced it right after the shared dims, not before. |
| FACT_OPPORTUNITY (Sales/Marketing) | DIM_ACCOUNT, DIM_DATE | Wave 3 | Can't reconcile revenue against an account dimension that hasn't itself been validated yet. |
| FACT_SHIPMENT (Supply Chain) | DIM_PRODUCT, DIM_ACCOUNT | Wave 4 | Waits on the Wave 1 product-dimension rebuild landing clean. |
The judgment call
What I Decide Here
Decision: I override the domain-based migration order that Sales and Marketing both want, and hold the line on a strict dependency-first wave strategy instead.
Friction: Domain leads want their functions prioritized immediately — nobody wants to hear "you're Wave 3" when they think their number matters most. I hold the line on sequencing by upstream dependency, not by whoever asks loudest.
Outcome: It prevents upstream pipeline rework we would pay for twice, and means Wave 1 lays a foundation the other four waves can actually build on without replaying the same fixes.