Web Development case study
SEO Dashboard
Built for a client. A multi-project SEO platform that replaced a workbook, with an agency console, a read-only client portal and a parity check proving the numbers match.
The decision that shaped everything else
Two audiences, two applications, one database
The agency console holds everything: adding keywords and pages, recording monthly ranks, logging backlinks, assigning deliverables, tracking team performance. The client portal is read-only, scoped to that client's own project, written in plain language, with a message thread to their team. Same data, two completely different products, because an agency screen shown to a client is either overwhelming or has to be censored on the fly.
A parity check that reads the workbook independently
Every figure the app computes is compared against the workbook's own formulas, re-implemented separately: 16,855 checks across every field, every rank cell and every derived total, including the per-specialist table compared against the totals Excel itself had stored. That number is the argument for switching. It is not a claim that the migration went well, it is a check anyone can re-run.
The check that agreed with itself
An earlier version of that parity script reused the importer's own row filters. So it compared the importer's interpretation of the sheet against the importer's output, and agreed by construction. It reported 16,723 of 16,723 passing while fourteen real backlinks were missing from the database. A parity check that shares the importer's assumptions cannot detect the importer's mistakes, which is obvious in hindsight and was not obvious at the time.
Three places the app deliberately disagrees with the sheet
Excel's COUNTIFS ignores case, and the workbook depended on that: matching anchors exactly was silently dropping 491 links from keyword progress, so the app matches the way Excel does, with expression indexes keeping the join fast. The sheet counted a backlink twice when the same keyword sat in both anchor slots, and one link is one link. And its rank distribution pointed at a hard-coded column, so every figure now follows the selected month instead. Each difference is printed in the parity output rather than buried, because an unexplained discrepancy is what destroys confidence in a migration.
The numbers it holds
The workbook has a successor that two audiences use for different things, and the client can open their own numbers without waiting for someone to export them.
The part worth keeping is the parity check, and specifically the version of it that was wrong. It passed, it looked rigorous, and it was measuring the importer against itself. We now write verification against the original source rather than against our own interpretation of it, on every migration we take on. A check that cannot fail is not a check.
Replacing a spreadsheet that a business already trusts is a category of work we take on often. It sits under our Next.js web development service, where the scope, timeline and starting price are published before you talk to anyone.
Tell us what’s slowing you down.
Fixed scope, quoted before kickoff, four to eight weeks to production. You talk to the engineer who writes your code.
Start a project