FMCG · 2026–present
Bahlsen Group: Taking Over a Data & AI Estate Nobody Had Mapped
Inherited a data platform with no estate-level documentation. Mapped it, audited it in three lenses, sequenced the modernization, and shipped the two internal products that were missing.
Contents

A capable, hand-operated data platform built by other people, with no document anywhere explaining how it fits together.
A mapped estate, a severity-ranked audit, a sequenced modernization roadmap, and two internal products shipped.
- Strategy, architecture, DevEx
- Estate audit
- SSO-gated use-case portfolio
- AI Compass
- Tokens + web components
- Design system
Engagement
- Client
- Bahlsen Group
- Role
- Interim Head of Data & AI
- Timeframe
- 2026–present
- Industry
- FMCG
I took over as Interim Head of Data & AI in July 2026 and inherited a platform I had not built. Years of work by internal staff and external partners sat underneath me: a cloud landing zone, a warehouse on BigQuery, a transformation layer in dbt, a BI layer on top, a self-hosted runtime executing every scheduled job, and a drawer full of internal applications.
The engineering was mostly sound. What was missing was any document that explained how it fit together. The naming conventions were genuinely good and written down nowhere. Onboarding meant reverse-engineering the flow from source systems to dashboards out of individual repository READMEs.
So the first thing I shipped was not a feature. I pulled every repository in the estate into one read-only mirror and wrote the orientation document that did not exist: the layer map, the conventions, the deploy contract, the end-to-end data flow, and an honest inventory of which repositories were load-bearing versus stubs and duplicate copies.
I want to be exact about attribution. I did not build this platform. My job was to be able to hold it in one head, and then decide what to do with it.
I ran the estate through three separate reviews and ranked everything by severity: a strategy lens on bets and concentration risk, an architecture lens on failure modes and security, and a developer-experience lens on what it is actually like to ship a change here.
The findings clustered, which was the useful part.
- One keystone, mid-replacement. Every scheduled workload ran on a single self-hosted runtime, and the organisation was halfway through migrating it to a second deployment. A keystone you are partway through replacing is the highest strategic risk on the board.
- No cross-layer observability. Failure visibility was per-repository webhooks. Nothing enforced that ingestion had finished before transformation ran. Stale dashboards were discovered by an analyst, not by an alert.
- Uneven security and operational hygiene across the estate. The specifics stay internal; the severity ranking put the worst of them at the top of the remediation queue.
- No estate-level orientation document at all — the single cheapest, highest-leverage artefact the team was missing, and the one the audit itself produced.
One finding I pulled out of the roadmap entirely and handled as an incident. Some things do not get a quarter.
The modernization assessment covered the whole chain: ingestion, transformation, orchestration, serving. Every layer scored low, and the temptation with a scorecard like that is to propose a rebuild.
The platform did not need a rebuild. It needed an order of operations.
The ingestion pattern was full-load and append-only with no merge key, and most transformation models did not deduplicate on read. That meant re-runs quietly propagated duplicate rows into downstream metrics — wrong numbers on real dashboards, today, with no orchestrator involved. Test coverage across the model layer sat far below where a platform this load-bearing needs it.
So the sequencing call was: close idempotency and observability first, because neither needs new infrastructure. Build the orchestration backbone second. Modernize ingestion third. Do not let a multi-month orchestrator programme gate the deduplication fix that stops shipping wrong numbers this week.
Writing that down mattered more than the target architecture did. A roadmap that starts with the expensive thing is a roadmap that never reaches the cheap thing.
The AI use-case portfolio arrived the way these things always arrive: as a document. Every department had submitted candidates, every candidate had been scored across a dozen dimensions, and the whole thing was unusable in a steering call because answering "what is unowned" meant reading it end to end.
I built it into an internal web application, access-controlled end to end, because the underlying data is sensitive.
- A command centre with the two numbers a manager acts on — how many cases have nobody's name on them, and how many are quick wins — plus a feed of what actually moved in the last seven days.
- A delivery map, a sortable table, and an impact/effort matrix with configurable axes, all reading one filter state out of the URL. Drilling into a tile narrows the view you are already in instead of discarding your filters. Any filtered view is a link you can send to a colleague.
- A department scorecard — every team on one page, with demand, horizon split, evidence coverage, quick wins, ownership gaps and outstanding follow-ups, and every number clickable through to the cases behind it.
- An action board collecting every open follow-up across the portfolio into one list, so nobody opens hundreds of detail pages to find them.
- Shortlists, exports and presentation mode. Pick cases across screens, export the view or the selection as CSV at three levels of detail, or turn either into a slide deck or a one-page brief that prints straight to PDF.
The part I am most pleased with is the authorization model, because it is the part that will still be correct after I leave. Access and role are two different questions, and both are answered in reviewed code rather than inside the app: a membership change ships as a small merge request the app itself renders for you, the app writes nothing, and the merge is the authority. Permissions resolve per request, so a change takes effect immediately rather than whenever a session happens to expire.
The second gap was visual. Every internal application had grown its own palette, its own buttons, its own idea of what a chart should look like.
I built a framework-neutral design system as a monorepo: layered design tokens, accessible controls as native custom elements, and thin typed wrappers so the same components are comfortable in React, Svelte, and the e-learning framework the training courses use. One Storybook catalog, one fixed semantic version across every published package, changesets on every consumer-visible change.
The accessibility work is the substance rather than the trim. Tested colour pairings, contrast thresholds and chart-encoding metadata ship as data alongside the tokens, so a consumer can assert against them. Every series in a chart carries a shape as well as a colour, and the legend repeats the shape next to the name — which means the charts survive greyscale printing, colour-blindness, and forced-contrast mode. The one contrast pair I could not fix inside a design-system release, I wrote up as an open item with the measured ratios rather than shipping it quietly.
Three smaller pieces of work, all aimed at the same problem: institutional knowledge that existed but could not be queried.
I archived internal wikis into auditable, machine-readable form with per-document access lists attached, then built a conflict register that pairs contradictory statements from different sources side by side with their evidence, an accountable owner, a verification test and acceptance criteria — so a contradiction becomes a ticket instead of an argument.
And I built a knowledge graph over meeting transcripts as a navigation aid, with communities, cross-cutting hub nodes and the questions the graph is uniquely positioned to answer. It shipped with its own coverage warning at the top, because extraction was partial and a navigation aid that implies completeness is worse than no aid at all.
Infrastructure and application live in separate repositories with their own pipelines. Changes ship as reviewed pull requests, including my own. Findings get written down with a severity, a file path and a proposed fix, so somebody else can act on them without me in the room.
That last part is the whole point of an interim mandate. Everything I have built here — the estate map, the audit, the roadmap, the portfolio app, the design system — is an artefact somebody else can pick up and keep running.
Estate audit strategy, architecture, DevEx. AI Compass SSO-gated use-case portfolio. Design system tokens + web components.
