ISSUE 14
LIVENext.jsTypeScriptSQLiteHubSpot
CONTEXT
Freshpaint's events team tracks every conference, House Call, and field event in HubSpot, but the numbers they're judged on don't live on the event record.They're scattered across events, deals, pipelines, stages, and companies, and have to be re-derived every time someone asks.Every quarterly review turned into a manual export-and-reconcile exercise.
BUILD
A Next.js 15 app on a single Fly.io machine.An hourly sync pulls a full HubSpot snapshot into SQLite inside one all-or-nothing transaction, then four pipeline KPIs (open, influenced, influenced revenue, created) are computed in SQL at read time, so a definition change is a one-line edit with no resync.Stage semantics come from synced pipeline metadata rather than hardcoded IDs, so a HubSpot rename can't silently break a number.Events missing a location get one inferred by a cheap-first LLM pass, each card is auto-illustrated with a license-clean city photo chosen by a vision model, and every event plots onto a WebGL globe.Google sign-in is enforced server-side and restricted to @freshpaint.io.
RESULT
Live and used by the team on one always-on Fly.io machine.The quarterly 'what did events do for pipeline' reconciliation is now a page: pick a quarter and every event is there with its KPIs already deduped and attributed, each number drilling down to its source deals in HubSpot.
SCREENSHOTS