~/jessejaffe/work/crm
all work

AI research + sales operations / 2026

CRM

I built a CRM that turns names or social links into researched, scored leads with supporting evidence.

role
product, full-stack, AI systems
system
lead research, qualification + outreach
status
production / beta

Lead qualification is manual, and the evidence is scattered across the web.

Confirming a lead's current role, company, fit, and contact details requires laborious research across often-blocked sites.

The CRM combines searchable snippets and public pages into separate confidence and fit scores with supporting evidence.

From a social profile to a claimed lead and an informed next step.

One workflow connects research, qualification, ownership, and outreach.

  1. 01

    Let the team build one lead pool

    Links and uploaded lists enter a shared pool where one salesperson can claim each lead.

  2. 02

    Research the public web around a blocked profile

    Search snippets and selected public pages reconstruct role, company, and contact evidence without crawling blocked profiles.

    Lead research run showing evidence searches, models, token usage, cost, contact candidates, confidence, and fit score
    Lead research run and evidence audit
  3. 03

    Separate confidence from fit

    Confidence validates identity and current role; configurable fit scoring measures sales relevance.

    Admin lead fit criteria with editable weights and written criteria for current role, client audience, technology fit, and agency size
    Admin-controlled fit criteria and weights
  4. 04

    Give the salesperson evidence, not just a score

    Each record preserves the evidence, uncertainty, fit reasoning, and conversation hooks behind its scores.

    Research output with lead quality notes, salesperson notes, and category-by-category fit reasoning
    Research reasoning and salesperson context
  5. 05

    Recommend the next reachable move

    Reachable channels and activity history inform an optional, human-led next-step recommendation.

  6. 06

    Make every AI decision reviewable

    Admins can review each run's inputs, output, model, tokens, cost, and rationale.

    Admin outreach AI logs with usage, model, token and cost totals, plus the recommendation and rationale for a recent run
    AI output, usage, and cost audit trail

README.md

A production CRM built around a traceable evidence pipeline, explicit role boundaries, structured AI outputs, and a durable lead lifecycle.

01 / architecture

One evidence-backed lifecycle from intake to outreach

A lead begins as a LinkedIn profile URL or a row in an uploaded spreadsheet. Research produces a normalized person, agency, contact routes, confidence, fit evidence, and a decision about whether the lead should enter the pool. Claiming then attaches one salesperson to that durable record without erasing who originally created it.

01profile intakeone URL or uploaded list
02evidence banksnippets + selected public pages
03lead decisionidentity, current role + confidence
04fit scoringadmin criteria + weighted signals
05shared poolavailable until one rep claims
06outreachactivity history + AI next step

PostgreSQL holds the source of truth for users, agencies, leads, outreach activity, research evidence, AI runs, saved suggestions, and cost records. Prisma keeps those relationships explicit, while Next.js server actions perform authenticated mutations close to the interface.

02 / blocked-platform discovery

Use the searchable web around social platforms

LinkedIn, Instagram, Facebook, and other social sites may block crawlers or restrict discovery through their APIs. The pipeline therefore treats a social URL as an identity seed. It derives the person's name from the profile slug, queries search indexes, and uses the title, URL, and snippet text that search engines have already made public.

Exa LinkedIn snippets + broad public-web discovery

Finds exact-profile role signals and possible agency, bio, press, interview, team, and contact pages.

Serper Google-visible social snippets when evidence is thin

Supplies exact-person social-profile titles and bios without directly fetching the social pages.

direct fetcher Selected non-social evidence pages

Retrieves the most useful official or credible pages after AI ranks which URLs are worth the request.

evidence cache Reuse discovery instead of paying twice

Stores the collected bank so repeat analysis can revisit the same sources without repeating search and fetch work.

The system does not pretend a snippet is a full social profile. Source quality, recency, conflicting identities, and direct public-page corroboration all affect the confidence decision.

03 / AI decisions

Give each model one bounded decision

The pipeline uses structured JSON schemas. Each call has a distinct responsibility, and code validates the output before it can change the CRM.

page selection

GPT-5.4 Nano ranks non-social URLs for current-role evidence, agency context, contact routes, fit signals, and warm outreach hooks.

lead extraction

Nano resolves identity, current role, agency, location, contact details, salesperson notes, and lead-quality confidence.

fit scoring

A separate Nano pass applies the admin's weighted criteria only after the lead is considered valid.

bounded image evidence

Gemini 3.1 Flash Lite may add an approximate age bucket only when the image is clearly verified as the target person.

contact safety

Contact pages are classified so a general business form can be used while a prospective-client intake form is avoided.

quality gates

Same-name contamination, stale roles, unrelated agency contacts, and evidence below the confidence threshold cannot silently enter the pool.

confidence / 0–100 Is this the right person in a current role?

Measures identity certainty, evidence quality, recency, and whether the expected current role is supported.

fit / 0–100 How closely does this valid lead match the sales strategy?

Combines admin-weighted current-role, client-audience, technology-adjacency, and agency-scale sub-scores.

04 / roles + claiming

Separate team contribution from account ownership

Both salespeople and admins can create leads and claim unowned records. The creator remains recorded for provenance, while claimed ownership determines which salesperson sees and works the account. The claim update succeeds only while the database still shows no owner, so two people cannot take the same lead at once.

salesperson Create, claim, research, and work accounts

Salespeople see the shared pool, their claimed accounts, message library, outreach history, qualification controls, and their own AI suggestions.

admin Operate the system and tune its judgment

Admins can manage the team, inspect all leads, edit fit criteria, review research and outreach logs, and audit model usage and spend.

Authentication uses signed, expiring HTTP-only session cookies. Active-user checks and role guards run on the server before protected pages or mutations access CRM data.

05 / outreach advisor

Recommend a next step from channels and history

GPT-5.4 Mini receives the lead and agency context, whether a phone number, email, or website form is available, every logged activity and outcome, salesperson notes, and the shared message library. It returns a schema-validated action, timing, urgency, rationale, guardrail, channel, and optional message.

research-derived lead + reachable channels
activity history + outcomes + salesperson notes
shared message templates
                    ↓
             GPT-5.4 Mini
                    ↓
action + timing + channel + rationale
+ existing message or new draft

Generating a suggestion is optional. Successful outputs are saved, can be archived, and remain attributable to the lead and salesperson. The UI treats the result as advice rather than an autonomous send command.

06 / reliability + economics

Keep experimental AI inside a production audit trail

The CRM is in production and labeled beta because the automated research and recommendation policies are still being calibrated. The surrounding system is designed so those policies can improve without hiding what happened on an earlier run.

structured outputs

Strict schemas and normalization reject malformed provider responses before they touch lead or outreach state.

durable evidence

Queries, snippets, selected URLs, fetch decisions, contact candidates, confidence, fit, and errors stay with the research run.

cost by operation

Tokens and estimated spend are attributed to page selection, extraction, fit scoring, image analysis, and outreach advice.

lower-cost processing

OpenAI Flex processing and small task-specific models reduce cost where the workflow can accept slightly more latency.

provider fallback

Capacity-related Flex failures can retry on the default service tier instead of losing the salesperson's request.

deployment safety

Server releases install from a clean snapshot, apply Prisma migrations, build, restart the service, and verify its local health endpoint.

07 / stack

Built across the full product surface

language
TypeScript, SQL, JavaScript
frontend
Next.js 15, React 19, Tailwind CSS 4
server
Next.js App Router, server actions, Node.js
data
PostgreSQL, Prisma ORM, versioned migrations
authentication
JOSE JWT sessions, HTTP-only cookies, bcrypt
AI
OpenAI Responses API, GPT-5.4 Nano, GPT-5.4 Mini, Gemini 3.1 Flash Lite
search + evidence
Exa, Serper, HTTP fetch pipeline, cached evidence bank
file intake
XLSX, CSV, TSV, and text URL imports
operations
Linux, Nginx, systemd, Hetzner