Skip to content
Pipeline CRM
Contact
CRMSaaS applicationIn production

Pipeline CRM

A focused B2B CRM with AI lead scoring and deal forecasting.

Client
B2B services firm (NDA)
Role
Full-stack engineer and product designer
Year
2025
Industry
B2B services
Built withReactTypeScripttRPCPostgreSQLPrismaPythonTailwind CSS

Problem

Every rep had their own version of the pipeline

Deals lived in personal spreadsheets, notes lived in inboxes, and the weekly pipeline meeting was spent reconciling versions. Managers couldn't trust the forecast, and follow-ups slipped whenever a deal changed hands.

BeforeEmail, sheets and chat
  • Pipeline Q3 (final) (2).xlsxSales team, via spreadsheet
  • Can everyone update the forecast sheet before Friday?Sales manager, via chat
  • Re: Proposal — did anyone follow up?Account executive, via email
  • My deals (please don't edit).xlsxAccount executive, via spreadsheet
Representative examples, reconstructed from discovery interviews.
  • Personal spreadsheets

    Each rep kept their own sheet with their own columns, so there was no single pipeline to look at.

  • Context scattered

    Emails, call notes and meeting outcomes lived in separate tools, and none of it was attached to the account.

  • Forecast by chasing

    Managers assembled the forecast by messaging reps for updates before every review.

  • Missed follow-ups

    Nothing flagged a proposal that had gone unanswered, or a deal that had quietly stopped moving.

Research

Designing around how the team actually sells

Before choosing between an off-the-shelf CRM and a custom build, I sat in on pipeline reviews and mapped the sales motion stage by stage. The heavy CRMs the team had trialled failed on setup and adoption, not on features.

  • Pipeline review shadowing

    Observed pipeline reviews to learn which questions managers actually ask, and which data they needed to answer them.

  • Rep interviews

    What reps track, what they skip, and why the spreadsheet kept winning over every tool they'd tried.

  • Spreadsheet archaeology

    Merged the column sets from every rep's sheet into one data model, keeping the fields people really used.

  • Signal audit

    Listed the buying signals the strongest reps look for. These later became the features behind lead scoring.

What we learned

  • Reps would only keep a CRM up to date if it took fewer clicks than their spreadsheet.
  • Managers cared less about a score than about why a deal was hot or stalled.
  • Most deal context already existed in email and calendars; it just wasn't linked to the account.
  • Stages needed exit criteria, or the pipeline would drift back into opinion.

User journey

A rep's day, before and after

A composite persona built from rep interviews, following one working day.

BeforeWith the product

  1. 1

    Plan the day

    Before: Scanned the inbox and a spreadsheet to decide who to call first.

    Now: Opens a Today view ranked by lead score, with the reason behind each score.

  2. 2

    Log a call

    Before: Wrote notes in a doc nobody else could find.

    Now: Adds notes to the account timeline, where the email thread already sits.

  3. 3

    Move a deal forward

    Before: Updated a cell, then told the manager in chat.

    Now: Drags the deal to the next stage; stage rules ask only for what that stage needs.

  4. 4

    Follow up

    Before: Relied on memory to chase deals that had gone quiet.

    Now: Gets a nudge when a proposal goes unanswered or a deal stops moving.

  5. 5

    Forecast review

    Before: Spent the meeting reconciling spreadsheet versions.

    Now: Walks through one shared pipeline the manager has already reviewed.

Solution

A CRM shaped around one sales motion

Contacts, companies, deals and activities in one fast interface. The pipeline enforces lightweight stage rules, every account has a single timeline, and lead scoring shows the signals behind each score instead of a bare number.

  • Drag-and-drop pipeline

    Stages with exit criteria: moving a deal asks for the fields that stage needs, and nothing more.

  • Unified timeline

    Emails, meetings, calls and notes on one chronological feed per account, synced from Gmail and Calendar.

  • Explainable scoring

    Every score is shown with the signals behind it, so reps can act on it or disagree with it.

  • Saved views and bulk actions

    Filters, saved views and bulk edits that make the CRM faster than the spreadsheet it replaced.

How the work flows

Switch between the old process and the one the product runs.

  1. 1

    Lead captured with context

    Forms and webhooks create the lead with its company attached.

    AutomatedOwner: Zapier webhook
  2. 2

    Activity attaches itself

    Gmail and Calendar sync onto the account timeline.

    AutomatedOwner: Sync worker
  3. 3

    Move the deal

    Drag to the next stage; stage rules prompt for required fields.

    Person, in productOwner: Rep
  4. 4

    Score updates with reasons

    Scoring re-runs on new activity and explains what changed.

    AutomatedOwner: Scoring service
  5. 5

    Alerts where the team works

    Slack alerts for stalled and won deals.

    AutomatedOwner: Sync worker
  6. 6

    Review one forecast

    Managers review the shared pipeline in the product.

    Person, in productOwner: Manager
Reps move deals and log calls. Capture, sync, scoring and alerts happen on their own.

Architecture

One typed path from database to pixel

A React front end calls a tRPC API with types generated from the Prisma schema, so a renamed field breaks the build rather than production. Scoring runs in a separate Python service, and integration workers handle everything that talks to the outside world.

  • Interface
  • Service
  • AI
  • Data and queues
  • External system

Interface

API

Data and jobs

External

Sync workers

TypeScriptService

Background workers that sync Gmail and Calendar, receive webhooks and post alerts to Slack.

Why it's built this way

All third-party traffic lives here, so an outage elsewhere never slows the app down.

Connections

UI

Faster than the spreadsheet it replaced

Adoption was the whole game. Every screen was measured against one question: is this quicker than updating a cell? Inline editing, keyboard shortcuts and saved views made the answer yes.

Contacts with inline editing, saved views and bulk actions, built on the same table component as every other list.
The manager's forecast view on desktop, next to the rep's Today list on mobile.
  • Fewer clicks than a cell

    Inline editing, keyboard shortcuts and bulk actions, so updating a deal is quicker than updating a spreadsheet.

  • Reasons next to scores

    Scores never appear alone; the strongest signals sit right beside them.

  • One timeline per account

    Emails, meetings, calls and notes in a single chronological feed, so a handover never loses context.

Development

Shipped weekly, behind flags

The team used the CRM while it was being built. Features shipped behind flags, were demoed to the sales team each week, and were switched on once the reps agreed they were faster than the old way.

  • End-to-end types

    Types flow from the Prisma schema through tRPC procedures to React components, so breaking changes fail at build time.

  • Components before screens

    A small set of tables, boards and property panels was built first, so every view behaves the same way.

  • Feature flags

    New views and rules shipped dark, were demoed to the team, then enabled per team when they were ready.

  • Careful data migration

    Every rep's spreadsheet was imported through a mapping step that de-duplicated companies and contacts.

Stack

Frontend
ReactTypeScriptTailwind CSS
API
tRPC
Data
PostgreSQLPrisma
Scoring
Python
Integrations
GmailGoogle CalendarSlackStripeZapier

AI

Lead scoring that shows its work

The scoring service turns account activity into features (how recently a prospect replied, meetings held, stakeholders involved, fit with the ideal customer profile) and produces a score with its strongest signals. Reps see the reasons next to the score, so they can act on it or push back.

Deal moves, score explains itself

Sample data
Qualified2
Northwind TradersDR
$24kWarm
Acme CorporationSO
$12kCold
Proposal1
GlobexDR
$40kWarm
Negotiation1
InitechPN
$18kHot
Waiting for the repA rep drags a deal to Proposal. The stage rule asks for one field, and the score updates with the signals behind it.
  1. 1

    Collect signals

    Email replies, meetings, stage history and firmographics are turned into features per deal.

  2. 2

    Score with an interpretable model

    Trained on the team's own won and lost deals, and chosen so that each feature's contribution can be read.

  3. 3

    Explain the score

    The largest contributions become plain-language reasons, like a reply within a day or a confirmed budget.

  4. 4

    Learn from outcomes

    Closed deals feed periodic retraining, and reps can flag a score that looks wrong.

Guardrails

  • Scores suggest priority. They never move deals or change ownership on their own.
  • Every score is shown with its reasons, so nobody acts on an unexplained number.
  • Free-text personal notes are excluded from the features the model sees.

Integration

Context flows in, alerts flow out

The CRM is only as good as the context attached to each account. Integrations bring that context in automatically and push the important changes to where the team already works.

  • Google Workspace

    Gmail and Calendar APIs

    Emails and meetings attach to the right account by domain; meetings booked from the CRM land on the rep's calendar.

    Two-way
  • Slack

    Slack API

    Stalled and won deal alerts in team channels, with a link back to the deal.

    Outbound
  • Stripe

    Webhooks

    Subscription and invoice events update the customer record for expansion and renewal deals.

    Inbound
  • Zapier

    Webhooks

    Web forms and marketing tools create leads through one documented, de-duplicating endpoint.

    Inbound

Performance

Instant on the surface, incremental underneath

A CRM that feels slow doesn't get updated. The interface responds immediately, and everything expensive happens incrementally in the background.

  • Optimistic updates

    Moving a deal or editing a field updates immediately and reconciles with the server, rolling back cleanly on error.

  • Server-side pagination

    Views page, sort and filter in PostgreSQL through tRPC procedures rather than in the browser.

  • Indexes for real queries

    Indexes on owner, stage and last activity, which are what nearly every saved view filters on.

  • Incremental sync

    Gmail and Calendar sync with history IDs and sync tokens, fetching only what changed since the last run.

  • Scoring off the request path

    Scores are computed in the background and stored on the deal, so the pipeline never waits for the model.

  • Code-split views

    Board, table and reports load as separate chunks, so opening the pipeline doesn't download the charting library.

Outcome

One pipeline the whole team trusts

The spreadsheets were retired. Reps update deals as part of their work rather than as a separate chore, managers review the forecast inside the product, and every account carries its own history, so a handover no longer loses context.

What's next

Next: forecast categories and a weekly digest that summarises pipeline changes for managers.

What changed

  • One shared pipeline replaced personal spreadsheets
  • Managers review the forecast from the product instead of chasing updates
  • Every account has a single timeline of what happened and what's next

Outcomes are described qualitatively. Client figures stay with the client.

Have a similar project?

Whether it's a workflow that still runs on email and spreadsheets or a system you need to integrate with, tell me what you're building. I reply within one business day with questions and a suggested first step.