Reporting Boards

Sales-ops tooling

Internal · Sales Operations

Reporting the book
as it actually stood.

Three self-hosted tools that answer questions a BI dashboard stopped answering: what the numbers looked like on any past day, what a rep will actually be paid, and whether last night's data pipeline ran.

PHP 8.3 SQLite No frameworks No build step Server-rendered
01 / HISTORICALS

Point-in-time attainment

Live
The problem

When the team's BI tool was discontinued, every team fell back on its own historical archive. Those archives didn't reconcile with each other, they stored only final numbers rather than the underlying data, and answering "how did we look at this point last quarter?" mid-quarter was close to impossible.

The approach

One daily archive of the whole book, stored at rep grain, viewable exactly as it stood on any past date — no retroactive revenue. A two-handle timeline slider makes any two snapshots comparable, so a delta is whatever pair you point at rather than a fixed window.

What it does
  • Today — the everyday management view, locked to latest vs the same day last week.
  • Historicals — the full slider, quick-compare presets, and a daily delivery-vs-quota chart.
  • Meta — week-over-week change as it stood 1wk / 1mo / 1q / 1yr ago, so you can see momentum building or fading.
  • Pipeline — open-stage funnel, win rate, and weighted pipeline at rep grain.
  • Goals resolve up a hierarchy — Rep › Pod › Function › Directorate › Program — to the most specific quota and pacing curve that matches your filters.
Point-in-time Hand-rolled SVG charts Magic-link auth HMAC push ingest
Open Historicals →
COMPARE VIEW 98 DAILY SNAPSHOTS REP GRAIN

Any two snapshots, any delta.

02 / BONUS CALCULATOR

Compensation, modelled

Live
The problem

Reps couldn't easily answer "what do I earn at 112%?", and the plan mechanics — a stepped threshold, a ramp to full base, then marginal accelerator bands — live in a document rather than anywhere you can actually run a number through. Managers, meanwhile, had no structured way to flag a value that looked wrong.

The approach

One shared compensation engine that every page includes, so the schedules exist in exactly one place and can't drift between the rep-facing calculator and the manager review. Around it, a self-serve front end and an approval queue that keeps edits auditable rather than silent.

What it does
  • Calculator — enter an attainment, see the quarterly bonus resolve through threshold, ramp, and accelerator bands.
  • Team review — managers see their own team, edit a value inline with a required note, and that edit becomes a pending change request.
  • Approval queue — an admin approves or rejects; approved changes apply and the bonus recomputes.
  • My details — a rep enters their email and the governed roster mails their settings to the address on file, never to whatever was typed, so one person's data can't leak to another.
Single source of truth Change-request queue Governed roster SQLite
Open Calculator → Team review
85% 100% ACCELERATOR $

Threshold → ramp → marginal bands.

03 / REPORT TRACKER

Did last night's job run?

Live
The problem

Automated reports fail quietly. You find out when someone opens a dashboard and the numbers look wrong — and because dashboards feed each other, one broken upstream job silently poisons everything downstream of it.

The approach

Every script posts a signed receipt when it finishes. The tracker holds those receipts and, crucially, holds a dependency graph between dashboards — so when an upstream report fails, everything downstream is automatically marked blocked instead of quietly serving stale numbers.

What it does
  • Receipt API — a bearer-token JSON endpoint any script can POST to: report ID, timestamp, success, message.
  • Dashboard — password-gated status board of every registered report.
  • Dependency graph — dashboards as nodes, "depends on" as directed edges, with cycle detection when you add one.
  • Blocked propagation — upstream failure cascades a BLOCKED state to everything downstream, computed per page load.
  • Flat JSON storage — no database, no Composer, no npm.
Bearer-token API Cycle detection Flat JSON Zero dependencies
Open Tracker →
RPT001 OK RPT002 FAIL BLOCKED BLOCKED BLOCKED

One failure, cascaded downstream.