Inspiration

Agencies run on retainers, but they get almost no warning before a client leaves. Existing churn tools (Gainsight, ChurnZero, Pendo) need product-usage data — agencies don't have that, because their "product" is a relationship, not software. Clients rarely leave over price; they leave because the relationship goes quiet — slower replies, cancelled meetings, late invoices — and by the time anyone notices, the decision's already made. We wanted to build the early-warning system agencies have never had.

What it does

ClientPulse watches communication and billing data an agency already has (Gmail, Calendar, invoices) and flags accounts drifting toward churn — weeks before renewal. Each account is scored against its own rolling history, not a portfolio average. Key screens:

  • Portfolio view — all accounts sorted by risk, with revenue-at-risk surfaced at the top.
  • Account detail — signal trend charts plus an AI-generated brief (Groq) explaining exactly which signals drove a flag, citing real data.
  • Alerts inbox — the working queue account managers triage.
  • Connections — Gmail/Calendar OAuth (metadata only, never content) and CSV invoice upload.

It never contacts clients directly — it only alerts internal staff. A human always decides what to do.

How we built it

FastAPI (Python) backend running scoring/ingestion as backend jobs; frontend rebuilt from Next.js to Vite + React + TypeScript with a custom flat "Modernist" design system; Supabase (Postgres) with real Auth and seeded demo data (15 accounts, 120 signal_snapshot rows); Groq (openai/gpt-oss-120b) generating briefs grounded in real signal contributions. Work was split by service boundary — ingestion (Gmail/Calendar + CSV data into signal_snapshot), scoring, LLM brief generation, and the frontend — so each piece could be built and verified independently. Deployed on Render (frontend) + Vercel (backend), after an initial deployment plan had to change (see Challenges).

Challenges we ran into

  • Had to re-route our deployment plan mid-build after Railway/Render's compute tiers required a card.
  • Missing SQL migrations caused alerts to silently fail to insert instead of throwing a clear error.
  • A stray second npm run dev (Vite auto-picks the next free port) looked exactly like a backend outage, since CORS only trusts explicitly listed origins.
  • Alert status started as one-directional; we reworked it so Acknowledge/Resolve/Reopen/Unacknowledge all work both ways, for real undo.
  • Redesigned the whole frontend off shadcn/ui onto a custom visual system mid-build.

Accomplishments that we're proud of

  • Fully live, not a mockup — backend and frontend both verified against a real Supabase project behind real Auth.
  • Gmail/Calendar ingestion and CSV import are live-verified against real data, not just implemented.
  • Groq briefs run in production and cite real signal contributions — no black box.

What we learned

Behavioral signals (reply time, cancellations, invoice lateness, contact turnover) carry real predictive weight when they're things an agency already understands, not new telemetry to instrument. Explainability isn't optional — an account manager only acts on a flag they can see the reasoning behind. And deployment constraints (cards-on-file, free-tier limits) can force real architecture decisions fast under hackathon time pressure.

What's next for ClientPulse

  • A real accounting integration (e.g. Xero) to replace CSV upload.
  • A client consent/data-scoping flow for email metadata.
  • A deeper signal set, and polish on the alerts workflow and charts.
Share this project:

Updates

Submission history