DealerBit
A ground-up rewrite of a decade-old BI/ETL data warehouse — consolidating business logic scattered across 3-4 systems into one clean, code-first engine that reproduces the legacy numbers cell-for-cell.
Stack
DealerBit — data-warehouse modernization
Rewriting a 10-year-old BI platform without breaking a single number.
What it is
DealerBit is a multi-tenant BI/reporting data warehouse for automotive dealer groups. It ingests operational data — service orders, invoices, parts inventory, sales CRM, accounting, HR/payroll — from many different dealer management systems into a central warehouse, then materializes per-organization, per-location reports.
The challenge
The legacy platform had grown for ~10 years and kept business logic in 3-4 different places at once: PHP application code, MySQL triggers/functions/views, stored procedures living on the client’s own DMS servers (computed remotely, in no repository), and scattered hardcodes — with report formulas evaluated through raw PHP eval() and yet more logic buried in JSON. It pulled from ~8 heterogeneous data sources (MS SQL, Firebird, MySQL, REST APIs, accounting systems) feeding ~44 dynamic reports and ~23 list reports. Nobody could fully account for how the numbers were produced.
What we built
- A greenfield Python engine that reads the same production database read-only and diffs its output against the legacy results cell-by-cell — exact parity (decimal 15,5 / HALF_UP) is the success criterion
- A hard architectural rule: all logic lives in code — no DB triggers, no
eval, no logic in JSON. The legacy system is reference for what to compute, not how - Scope discipline: rebuilt only what the live client actually uses, dropping years of multi-tenant dead weight and non-determinism
- A FastAPI + Jinja “coverage map” UI showing, report by report and cell by cell, exactly which figures are reproduced and matching (green/red/unimplemented)
Results / impact
- Proven cell-for-cell parity on the hardest reports: the flagship Service Department Analysis (spanning 6 DMS families) hit 296/296 cells (100%); another key report 361/361; a feared legacy stored function reimplemented in Python at 100/100
- Test suite green (110 passing); historical “mismatches” traced to legacy snapshot staleness, not logic errors
- Business logic consolidated from 3-4 places into one codebase, removing dead code and eliminating legacy non-determinism
- The AI-assisted rewrite ran ~1.6-3× cheaper than a purely human build, verified with timed probes showing the mechanical work compresses 10-50×
Stack
Rewrite: Python (FastAPI, Jinja, pytest), reading a MariaDB warehouse, orchestrated via controllable workers. Legacy (reference): PHP 8 custom framework + Symfony components, RabbitMQ, MariaDB (282 tables), Vue 2 SPA (~89k LOC), PowerShell dumpers.
Status: Migration in progress — parity proven on pilot reports; legacy system untouched while the rewrite is validated.