Finds exact-profile role signals and possible agency, bio, press, interview, team, and contact pages.
AI research + sales operations / 2026
CRM
I built a CRM that turns names or social links into researched, scored leads with supporting evidence.
the problem
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.
-
01
Let the team build one lead pool
Links and uploaded lists enter a shared pool where one salesperson can claim each lead.
Shared lead creation and claiming -
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 and evidence audit -
03
Separate confidence from fit
Confidence validates identity and current role; configurable fit scoring measures sales relevance.
Admin-controlled fit criteria and weights -
04
Give the salesperson evidence, not just a score
Each record preserves the evidence, uncertainty, fit reasoning, and conversation hooks behind its scores.
Research reasoning and salesperson context -
05
Recommend the next reachable move
Reachable channels and activity history inform an optional, human-led next-step recommendation.
Human-led outreach with an optional AI advisor -
06
Make every AI decision reviewable
Admins can review each run's inputs, output, model, tokens, cost, and rationale.
AI output, usage, and cost audit trail
technical brief
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.
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.
Supplies exact-person social-profile titles and bios without directly fetching the social pages.
Retrieves the most useful official or credible pages after AI ranks which URLs are worth the request.
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.
GPT-5.4 Nano ranks non-social URLs for current-role evidence, agency context, contact routes, fit signals, and warm outreach hooks.
Nano resolves identity, current role, agency, location, contact details, salesperson notes, and lead-quality confidence.
A separate Nano pass applies the admin's weighted criteria only after the lead is considered valid.
Gemini 3.1 Flash Lite may add an approximate age bucket only when the image is clearly verified as the target person.
Contact pages are classified so a general business form can be used while a prospective-client intake form is avoided.
Same-name contamination, stale roles, unrelated agency contacts, and evidence below the confidence threshold cannot silently enter the pool.
Measures identity certainty, evidence quality, recency, and whether the expected current role is supported.
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.
Salespeople see the shared pool, their claimed accounts, message library, outreach history, qualification controls, and their own AI suggestions.
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.
Strict schemas and normalization reject malformed provider responses before they touch lead or outreach state.
Queries, snippets, selected URLs, fetch decisions, contact candidates, confidence, fit, and errors stay with the research run.
Tokens and estimated spend are attributed to page selection, extraction, fit scoring, image analysis, and outreach advice.
OpenAI Flex processing and small task-specific models reduce cost where the workflow can accept slightly more latency.
Capacity-related Flex failures can retry on the default service tier instead of losing the salesperson's request.
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