The full estate audit. The Finance Shadow narrative. The Snowflake ODS finding.
Three tracks. One programme. Approval-ready.
Prepared for the OfficeMax leadership team
~85
Ribbon apps in scope
744K
Lines of VBA catalogued
1
Shared credential across the estate
0 / 106
Snowflake ODS consumers
3
Hidden Oracle-ODS dependents
EXECUTIVE SUMMARY
What we found, what we're asking for.
A code-and-file audit of the Excel Ribbons estate, extended to the Snowflake ODS layer. One page. Everything else is evidence.
THE RISK
Finance runs on a shadow estate
85 workbooks. One shared credential. Cleartext auth. Live-Pronto reads and writes. When any of the people who wrote them leaves, they still hold the key.
THE HIDDEN LAYER
Snowflake ODS has zero consumers
106 tables audited. 181 dashboards, 875 widgets, 400 SQL, 85 ribbons, 744K VBA lines - not one binds to Snowflake ODS. The 287 "ODS" ribbon hits target Oracle, not Snowflake.
THE PATHWAY
Three tracks, one programme
Ribbons migrate onto Excel4Data + Power BI + MuleSoft. Snowflake ODS retires by tiers. Finance stabilises the shadow into a governed rebuild - owned by Finance, not IT.
THE ASKApprove the four-week discovery mandate. Authorise the "no ODS in Snowflake" rule. Kill live-Pronto reads immediately. Detail on page 12.
CHAPTER I
01
The Excel Ribbons estate.
What was scanned. What was found. Where the security exposure sits, and how the Finance function became a shadow-IT organisation without meaning to.
METHODOLOGY
How the review was done.
Seven stages. Static-analysis only - no runtime probing of Pronto. Every finding is evidenced from the code and the file share, not from interview.
01
Isolation & transfer
969 files pulled from the O:\ share into a controlled workspace. SHA hashed. Duplicates and archives removed.
02
VBA extraction
744,093 lines of VBA across 170 modules dumped for review. 50 apps carry meaningful automation.
03
Connection catalogue
Every connection string, every SELECT / INSERT / UPDATE / DELETE across the estate identified and grouped.
04
Snowflake ODS inventory
82 tables mapped, 4,238 columns catalogued, 31 identified as direct replicas of a LANDING source.
05
Usage aggregation
77 of 118 ribbons are self-logging, 3 workbooks do real business writes, the rest read and export.
06
Sisense cross-check
181 dashboards, 875 widgets, 400 repaired SQL, 15 elasticubes, 203 datasources all searched for ODS bindings.
07
ETL evidence
Every LANDING external-table stage mapped to its blob container. Direct-from-Pronto vs from-Oracle-ODS resolved by container path.
WHAT THIS REVIEW DOES NOT DO
No live queries against Pronto Prod or Oracle DW.
No changes to production systems, no data movement.
No interview-only claims - every finding traces back to a file, a table, a query or a log.
Sisense coverage: full production tenant metadata.
IDENTIFICATION · WHAT WE FOUND
The Excel Ribbons estate in numbers.
The scale that makes this a strategic issue, not a housekeeping one. Numbers below are from the static scan, all reproducible.
FILES
969
Files scanned on the O:\ share - Excel workbooks, shortcuts and orphans.
APPLICATIONS
~85
Distinct applications once duplicates and archives are removed. 50 carry meaningful automation.
RIBBONS / ENTRY POINTS
118
Auto-open handlers, ribbon buttons, custom menus. Each one a live entry point into the estate.
VBA LINES
744,093
Across 170 modules. Larger than most in-house apps, unversioned, unowned.
SELF-LOGGING RIBBONS
77
Of 118. Write their own usage log back to ODS. Not business writes - diagnostics that stayed on.
REAL BUSINESS WRITES
3
Workbooks that push data into Pronto Prod. Pricing and business-case flows. The concentration risk.
IDENTIFICATION · THE SECURITY CASE
Three concerns, in order of severity.
Every one is a rotation-and-migration problem, not a firefight. But it is a rotation-and-migration problem that has not been solved for years.
SEVERITY 1
Live Pronto reads from user workbooks
A subset of ribbons connect direct to Pronto Prod. Some carry write credentials. Any workbook, any user, no ceremony. Highest blast radius.
SEVERITY 2
Cleartext credentials in VBA
One shared username / password, embedded across 85 workbooks. Reads and writes on Oracle DW. Rotating it is a co-ordinated release, and until we do, anyone who has ever seen the workbook still holds the key.
SEVERITY 3
Unattended file-drop into Pronto load
Several ribbons write CSV to an O:\ staging folder. An 8pm overnight job picks whatever is there up and loads it into Pronto Prod. Controls around what actually gets loaded need review.
WHY IT STAYS UNSOLVED
The credential rotation is a coordinated release across 85 workbooks. Every workbook needs a code change. Every user needs to pick up the new build. The estate has no owner, no version control, no rollout pipeline. So it doesn't get done.
WHAT MOVES IT
Rotate under a migration plan, not as a standalone. Every workbook that moves onto Excel4Data or Power BI drops the cleartext credential in the same change. Sequence the estate: the migration IS the rotation.
THE FINANCE SHADOW
Finance is running a shadow IT function. It didn't set out to.
The ribbons weren't a project. They were the way Finance got its work done when official tooling didn't. Fifteen years later, they run the reporting stack - and the risk sits with the individuals who wrote them.
WHAT SHIFTS
Ownership: Finance keeps the model. Analytics builds the Snowflake layer. IT provides the platform. No one hands the whole thing to IT and hopes.
WHAT DOESN'T SHIFT
Speed: the ribbons exist because Finance needs fast turnaround. Excel4Data + Power BI preserve that. This is not slower - it is safer and centrally maintained.
CHAPTER II
02
The Snowflake ODS finding.
The programme extended into the data layer. Zero Snowflake ODS consumers - which was expected. Three hidden Oracle-ODS dependencies in LANDING - which was not.
HEADLINE FINDING
Zero consumers. Anywhere.
Every scanned surface came back the same. Not one Sisense dashboard, ribbon or repaired SQL binds to OMX_PRD.ODS.
SNOWFLAKE ODS CONSUMERS
0 / 106
tables in scope are referenced by any scanned system. The schema is a duplicate landing zone that shadows Pronto's Oracle ODS. It has no downstream reader.
How we tested: 181 dashboards, 875 widgets, 400 repaired SQL, 15 elasticubes, 203 datasources, 85 ribbon workbooks, 744,093 lines of VBA - every one searched for the 106 ODS-scope names. Zero matches.
85 workbooks, 744,093 lines of VBA. Zero references to OMX_PRD. Zero references to snowflake.
REPAIRED SQL · 0 HITS
243 hit PRESENTED, 74 hit DW, 3 hit LANDING. Zero hit ODS.
THE TRAP WE ALMOST FELL INTO
Oracle and Snowflake share the names. They are different databases.
287 ribbon "ODS" references exist - but every one targets Oracle prontoods.*, not Snowflake OMX_PRD.ODS. Same names, different physical objects.
EVIDENCE · SNOWFLAKE EXTERNAL TABLE STAGES
Where the data actually comes from.
Every LANDING external table points at a blob container. The container name tells us the source system. Three tables land from an Oracle ODS export container - and were previously invisible.
CHAPTER III
03
Pathways forward.
One target state. Three parallel tracks. A four-week discovery mandate to lock the sequencing plan and start the migration.
TARGET STATE
Where we are heading.
One source. One warehouse. Governed reads via Excel4Data and Power BI. Governed writes via MuleSoft and the overnight loader.
PATHWAYS FORWARD
Three parallel tracks. One programme sponsor.
Each track has its own owner, its own cadence, its own exit criteria. They share a single steering group so dependencies stay visible.
TRACK A · RIBBONS MIGRATION
85 apps into 7 lanes
Owner: Finance + Commercial (lead), Analytics + IT (support).
Pattern: Reads via Excel4Data on Snowflake. Writes via Power BI + overnight loader OR MuleSoft canonical API.
Exit: zero live-Pronto reads from user workbooks. Zero embedded credentials.
TRACK B · ODS RETIREMENT
106 tables in three tiers
Owner: Analytics (lead), FDL (Donovan) walk-list, IT quarantine.
Exit:OMX_PRD.ODS schema dropped. FDL Gold Standard forbids re-creation.
TRACK C · FINANCE STABILISATION
Shadow to steward
Owner: Finance (lead), IT (platform), Analytics (model).
Change: Finance keeps the reporting model, moves off scattered VBA. Business rules land in Power BI + O:\ drive.
Exit: credential rotation is a role revoke, not a coordinated 85-workbook release.
Reports20 appsExcel4Data on Snowflake. Commercial rebuilds its own; Analytics supplies model + reference report.TRACK A
Pricing uploads7 appsPower BI -> governed table -> overnight loader -> Pronto. Highest single risk, first to move.TRACK A
Customer orders / quotes4 appsMuleSoft canonical API for writes. Reads via Snowflake.TRACK A
Master data3 appsMuleSoft canonical API for writes. Reads via Snowflake.TRACK A
Discount recalc (ops close)1 appMigrate calculation into dbt on Snowflake. Ops close routine.TRACK A
Retire outright3 appsBusiness Case Template, Sales Targets DB, ods_table_log self-logging - all retire.TRACK A
THE ASK · APPROVE TODAY
Approve the four-week discovery mandate. Authorise the "no ODS in Snowflake" rule. Kill live-Pronto reads immediately.
WEEK 1
Kill live-Pronto reads
Rotate the shared DW credential inside the migration change. Formalise the "no ODS in Snowflake" rule as a written policy. Enable Snowflake query-history alerting on any read of OMX_PRD.ODS.*.
WEEK 2
Finance + Commercial start Power BI
Business rules for pricing and reporting lanes move out of VBA and into Power BI + O:\ drive. Analytics stands up the Snowflake model behind them. Weekly readout starts.
WEEK 3
Pilot the write-back
Pricing lane: Power BI outputs wire into the overnight loader. Excel4Data pilot on a reference report. Per-ribbon ODS-to-DW mapping in flight. Walk 6 VERIFY + 3 RETIRE-WITH-ORACLE tables with Donovan / FDL.
WEEK 4
Verdict per ribbon, lock sequencing
Each of the ~85 apps gets a verdict: swap, land-then-swap, or retire. Dependency map locked. Single owner per lane. Programme cadence hands over from discovery to migration.
PHASE 2
Freeze then retire ODS
Revoke INSERT / UPDATE / MERGE from ADF into OMX_PRD.ODS.*. 30 days of read alerting. Drop DROP-READY 79 in batches by prefix. Retire the schema.
PHASE 3
Close the door
Update FDL Gold Standard v2.0 to forbid ODS in Snowflake. Migrate Excel Ribbons off Oracle prontoods.* onto Snowflake LANDING.EXT_*. Rewire or retire the 3 Oracle-ODS dependents.
SPONSOR
Jeff Sutton
OWNERS
Finance · Commercial · Analytics · IT · FDL
NEXT DOCUMENT
Lane-by-lane workstream plan
CHAPTER IV
04
The plan.
Colin PM's Finance to Power BI and Excel4Data. IT owns the non-pricing solution design and every Pronto-to-Snowflake data gap. Derek and Jeff map the non-pricing pathway. Nothing lands on a table with ODS in the name.
GOVERNANCE · OWNERSHIP
Two workstreams, four owners.
Colin runs the pricing lane end-to-end with Finance. IT owns the investigation, solution design, and data-gap remediation for everything non-pricing. Derek and Jeff sit alongside Colin on the non-pricing pathway calls once the requester is understood.
COLINPricing lane - PM and delivery
Colin is programme manager for the pricing migration and is responsible for delivering it. Works alongside Finance while they build the capability - he does not build or migrate for them.
Set up Finance to run Power BI + Excel4Data themselves
Run early data-mapping so gaps surface while Finance is skilling up
Weekly cadence with Finance leads; escalate blockers to Jeff / Kate
Own the pricing decommission cutover date
ITNon-pricing - investigation and solution design
IT picks up every non-pricing ribbon: investigation, understanding, and solution design. IT also owns any Pronto-to-Snowflake data gap - sort and document.
Walk each non-pricing file with its requester (Colin brokers introductions)
Design target-state - Snowflake source, MuleSoft write-back where needed
Fill data gaps in Snowflake (Pronto-direct, NEVER ODS-name tables)
Publish per-ribbon target-state architecture for Derek and Jeff review
FINANCEPricing - capability owner
Finance owns the destination. Colin helps them stand up capability - Finance builds their own Power BI reports and Excel4Data data marts. This is a learn-by-doing handover, not a migration-by-vendor.
Nominate a pricing analyst lead to own the migration on their side
Build first Power BI report on Snowflake source (with Colin coaching)
Publish pricing rules to Excel4Data - out of VBA
Sign off when each ribbon is retired
JEFF + DEREKNon-pricing pathway - triage
Once Colin has met with each non-pricing requester and captured the ask, the three of us map the pathway - move to Lens / Power BI, rebuild on MuleSoft, retire, or park as low-value.
Weekly triage on non-pricing intake once Colin has walked with each requester
Decide the target platform per ribbon (Lens / Power BI / MuleSoft / retire)
Assign IT delivery slot in the technical backlog
Approve or reject cases where an ODS-name table looks unavoidable
RACI MATRIX · WHO DOES WHAT
RACI across the eight workstreams.
R = Responsible (does the work). A = Accountable (single owner). C = Consulted. I = Informed. Each row has exactly one A.
Workstream
Colin
Finance
IT
Derek
Jeff
FDL / Donovan
Pricing migration to Power BI + Excel4DataSet up Finance capability; no build-for-them
R
A
C
I
C
I
Early data-mapping - pricingSurface Pronto-Snowflake gaps before Finance needs them
A
C
R
I
I
C
Non-pricing intake and understandingWalk each ribbon with the requester who said they need it
A
I
C
I
I
I
Non-pricing pathway triageDecide the target platform per ribbon
R
I
C
R
A
I
Non-pricing solution designTarget-state architecture per ribbon
C
I
A
C
I
C
Pronto to Snowflake data gapsRewire and document - Pronto-direct only, NO ODS-name tables
I
I
A
I
I
R
ODS decommission (Snowflake)Drop 79 zero-consumer tables; walk 3 Oracle-fed replicas
I
I
R
I
A
R
Cutover, comms, sign-offRetire each ribbon after user acceptance
R
R
R
C
A
I
MILESTONES · TIMELINE
Four discovery weeks, then a phased migration.
Weeks 1-4 lock the scope. Phase 2 (M2-M4) migrates pricing and rewires the Oracle-ODS dependents. Phase 3 (M5-M9) retires the non-pricing ribbons behind Lens / Power BI on Snowflake.
Week 1
Discovery start
Colin briefed as PM; Finance names pricing lead
IT stands up the non-pricing intake queue
NEVER-ODS-in-name rule signed off in writing
Snowflake alerting on any read of OMX_PRD.ODS.* enabled
Week 2
Data mapping - pricing
Colin + Finance walk every pricing file
IT / FDL: map pricing reads to Pronto-direct Snowflake sources
Gap list published to Derek
Power BI workspace provisioned for pricing
Week 3
Non-pricing intake
Colin walks non-pricing files with each requester
Colin + Derek + Jeff map pathway per ribbon
Data-gap tickets opened for IT / FDL
First Power BI report - pricing pilot
Week 4
Sequencing locked
Every ribbon has a tier + owner + target date
Snowflake ODS-decom drop batch 1 (dev)
Excel4Data pilot on pricing reference report
Phase 2 kick-off approved
Phase 2 - M2-M4
Pricing cut over
Finance owns Power BI + Excel4Data pricing suite
3 Oracle-ODS-fed replicas rewired to Pronto-direct
Snowflake ODS 79-table drop in prod (batched by prefix)
Sisense pricing decommission
Phase 3 - M5-M9
Non-pricing behind Lens
Non-pricing readers migrated to Lens or Power BI
Non-pricing writers rebuilt on MuleSoft
REVIEW-MANUAL ribbons retired or documented as local
FDL Gold Standard v2.1: forbid ODS in Snowflake
DATA GAP PROGRAMME · IT-OWNED
Pronto to Snowflake, direct - no ODS in the name.
IT owns every gap between Pronto and Snowflake. Six governing rules the pathway must follow. Any ribbon that today reads an ODS-name table gets rewired or retired - never renamed.
1
Never use a table with ODS in the name. Not in Snowflake, not in Power BI, not in Excel4Data. If it exists, treat it as Oracle-legacy - rewire to a Pronto-direct source before consuming.
2
Every new consumer reads from Pronto-direct only. LANDING.EXT_* fed by /prod/010_pronto/ blob container. Anything else is a design smell.
3
Data-map before you migrate. Colin surfaces the pricing gaps early. IT / FDL close them in Snowflake while Finance builds capability - not after.
4
Every gap is a Snowflake ticket, not an Oracle patch. If the field is missing, IT extends the LANDING model - do not tap Oracle to bridge.
5
Writes go through MuleSoft. The 6 writer ribbons rebuild on MuleSoft-canonical Pronto endpoints. No direct Pronto writes from Excel or Power BI ever.
6
Document the mapping. Every rewired ribbon leaves a written source-to-target map in the FDL repo. If it is not documented, it is not migrated.
TECHNICAL PLAN · LANE A · PRICING
Pricing lane - Colin PM, Finance builds.
Four steps. Data mapping before capability. Power BI on Snowflake reads, Excel4Data for the write-back where pricing rules must land in Pronto. Finance builds their own; Colin coaches and unblocks.
LANE A - PRICING
From VBA-in-Excel to Power BI + Excel4Data on Snowflake / MuleSoft
STEP 1
Data mapping
Colin + Finance walk every pricing ribbon. Every field read or written gets a Snowflake target. Gaps opened as tickets to IT / FDL.
STEP 2
Gap fill in Snowflake
IT / FDL extend LANDING.EXT_* from Pronto-direct blob. Any table today read from Oracle prontoods.ODS_* is rewired now, not later.
STEP 3
Power BI + Excel4Data
Finance builds their own reports. Excel4Data writes pricing rules back via MuleSoft canonical to Pronto. VBA connections removed.
STEP 4
Retire and sign off
Each pricing ribbon replaced, Finance sign-off. VBA workbook archived; connection string, uid, pwd revoked at the DW.
LANE A - CONSTRAINTS
Non-negotiables that shape the build
1.Finance builds - Colin coaches. No hand-over-the-wall migration. Finance leaves the programme with the capability to run the tools themselves.
2.Never use an ODS-name table. Not in a Power BI dataset, not in an Excel4Data source. If today's ribbon reads one, IT rewires the source before the new build reads it.
3.Writes go through MuleSoft. Excel4Data writes call MuleSoft canonical - Pronto is called via the API layer, never directly from a client.
4.Credentials at rest, always. No connection strings in Power BI files. Managed Identity to Snowflake; MuleSoft brokered to Pronto.
TECHNICAL PLAN · LANE B · NON-PRICING
Non-pricing lane - IT investigates and designs.
IT owns the intake, understanding, and solution design for every non-pricing ribbon. Colin brokers the walk with the requester. Derek + Jeff sit on the triage call so the pathway is agreed before IT commits build time.
LANE B - NON-PRICING
Understand, then design - then build (or retire)
STEP 1
Requester walk
Colin brokers the meeting. The person who said they need the ribbon shows what they use, why, and how often. Screenshots, sample outputs, downstream Excel.
STEP 2
Pathway triage
Colin + Derek + Jeff decide the tier. Migrate to Lens or Power BI (read-only). Rebuild on MuleSoft (writer). Retire (no downstream). Park (low value).
STEP 3
IT solution design
IT publishes the target-state design - Snowflake source (Pronto-direct only), tool (Lens / Power BI / MuleSoft), auth, cadence, sign-off criteria.
STEP 4
Build, cutover, retire
IT delivers, requester signs off, Colin retires the VBA workbook. DW credential rotated in the same change.
LANE B - IT DELIVERABLES PER RIBBON
What "solution design" produces
a.Source-to-target map. Every table today (Oracle NZBIPROD, prontoods.*, prontodm.*) mapped to its Snowflake equivalent (LANDING.EXT_* / DW.D_* / DW.F_*). ODS-name targets are rejected.
b.Data gap ticket list. Fields missing from Snowflake go on the FDL backlog. Colin tracks them to closure.
c.Target-tool decision. Lens for enterprise BI reads; Power BI for department-scoped; MuleSoft canonical for writers; retire otherwise.
d.Cutover checklist. Written UAT. Requester sign-off email. VBA archive. DW credential rotation in the same PR.
CHAPTER V
05
Appendix.
Every file. Every table read. Every table written. Every stored proc invoked. Every file flagged that references a table with ODS in the name. Read from the VBA parser output on 84 workbooks.
APPENDIX · OVERVIEW
84 workbooks classified.
Tier assigned from VBA-parser output. RETIRE-WITH-ORACLE means the file reads or writes a table with ODS in its Oracle name - dies when Oracle ODS is decommissioned unless rewired to Pronto-direct in Snowflake first.
50
RETIRE-WITH-ORACLE
writer
1
RETIRE-WITH-ORACLE
reader
1
REBUILD-ON-SNOWFLAKE
MuleSoft write-back
4
READ-ONLY
migrate to Lens / Power BI
28
REVIEW-MANUAL
no SQL detected - UI/manual
A
How to read a card. Name and file path. Tier badge (RETIRE / REBUILD / READ / MANUAL). Counter chips for SELECT/INSERT/UPDATE/DELETE/EXEC. Security flags. Distinct tables read, tables written, stored procs. Any table with ODS in its name is highlighted in red.
B
Verification note. Counters come from 03-analysis/file_summary.csv. Distinct table lists come from 03-analysis/findings.csv - the raw VBA-parser findings.
C
Governance rule. Any NEW consumer that reads or writes an ODS-name Snowflake table is rejected at code-review. IT rewires the source to Pronto-direct first.
APPENDIX · RETIRE-WITH-ORACLE · files 1-4 of 50
RETIRE-WITH-ORACLE tier - RETIRE-WITH-ORACLE tier · 1-4 of 50
3 Year on Year Usage Report
3 Year on Year Usage Report.xlsb
TIER · RETIRE-WITH-ORACLE · writer
SELECT 2INSERT 1EXEC 26
ODS-NAMECONN-STR 15UID/PWDexcelinfoPronto refs
READS (1)
PRONTOODS.ODS_TBL_LOOKUP
WRITES (1)
PRONTOODS.ODS_TBL_EXCEL_LOG
EXEC (11)
CENTRE · CREATECCP_REPLACEMENT · CREATESIMPLECHART · GET3YEARSUSAGE · GET3YEARSUSAGE2 · GET3YEARSUSAGE6OCT2025 + 5 more
Verdict: writes to Oracle ODS-name table - dies with Oracle ODS; if kept, MUST rewire to Pronto-direct Snowflake