A one-page executive dashboard built as a dry run for the DSCubed × RAID "Forward: AI in Business" hackathon (10–14 Sep 2026).
Click Use your own data. The file is parsed in the browser and never uploaded anywhere — worth saying out loud when the data is a real sales ledger.
Column names are guessed from a list of aliases (Order Ref, invoice_no and
InvoiceNo all resolve to the same field) and every guess is shown with two
real values from the file underneath it, because a column name can lie and a
sample cannot. Change anything that looks wrong.
Before anything is computed you get a dry run — rows read, rows that will be
removed, rows that will be used, with the reason for each removal. Airtable's
importer shows updated / unchanged / new before it writes; this is the same
promise applied to cleaning.
Required: invoice, product, quantity, unit price. Optional: date, market, customer. Without a date column the trend panel says so instead of drawing an empty chart.
pip install pandas openpyxl
python prep.py # 541,909 raw rows -> data.json (5 KB)
Then serve the folder over HTTP — http://localhost:3200/exec-dash/.
Opening index.html directly will fail: the page fetches data.json.
UCI Online Retail — a real UK gift wholesaler, 1 Dec 2010 to 9 Dec 2011. 541,909 rows, genuinely dirty: 25% missing customer IDs, 9,251 cancelled invoices, 5,268 exact duplicates, negative quantities and zero prices.
data/ is gitignored — the source workbook is 24 MB. prep.py regenerates
everything from it.
Every excluded row is counted and given a reason, and those counts ship to
the page. The exclusion table reconciles — 5,268 + 9,251 + 1,336 + 1,176 =
17,031 = raw − kept — and prep.py asserts it, so a silent mis-drop fails the
build rather than quietly changing the revenue figure.
Every finding discloses what it rests on and where it is wrong. Confidence is a named level (high / medium), never a fabricated percentage — none of the AI products studied prints one, and Hex ships a named taxonomy instead.
It admits what it cannot tell you. One year of data, so seasonality cannot be separated from growth. Revenue is gross of returns. The final bar is a partial month. The product ranking mixes goods with postage and bank charges — £383,144, 3.6% of revenue — and the page says so, because the top "product" is a delivery fee.
Built from the vault rather than instinct: Dark Bento Pastel Dashboard for the
grid, "AI Assistant Website 6" (Variant community) for light pastel KPI tiles on
near-black, Linear's measured dark system (2% white lift, 7–10% alpha status
chips), Landing and Pricing Pages Measured for type (−0.032em on display,
14–15px body, pill-or-small radius), and Instruments Meters and Charts for the
bars — plain divs whose height is a percentage, no SVG and no chart library.
The invent-a-new-object rule deliberately does not apply: its own exemption covers tools and assessed work, and a judge reads this in fifteen seconds.
Bundled dataset: revenue/orders/markets match source · exclusions reconcile · 4 disclosures open · confidence named not numeric · 13 bars animate · no overflow at 1440 or 390 · 44px minimum tap target · zero console errors
Ingest, driven end-to-end in a real browser against a deliberately hostile CSV
(renamed headers, quoted fields containing commas, escaped quotes, a currency
symbol in the price, a duplicate, a cancellation, a zero quantity and a zero
price): all 7 columns auto-detected from renamed headers · dry run 10 read / 4 removed / 6 used · re-renders from the file · exclusions still reconcile · zero console errors