Overview
End-to-end B2B sales-acquisition automation for a German company. Built to research, score, email, call, and close prospect companies from a single data model and a single benchmark score, running one funnel end-to-end: Research → Campaign assignment → Outreach → Connect → Closing.
Guiding principle
Build the glue. Buy the commodities.
Dialers, email transport and inbox-warmup infrastructure, Maps data, crawling, e-signature and payment rails are solved, mature products. Rebuilding them is a multi-year arms race with no payoff. What doesn't exist as a single product — and what makes this platform worth building — is the connective tissue:
- Funnel orchestration — one automated pipeline from research to close, with humans only where quality matters.
- Research + benchmark engine — target discovery (Serper.dev Maps by postal code + industry, enriched from several sources) plus a single 0–100 benchmark computed once and flowing through all stages.
- Sender management — the VirtualCompany / VirtualEmployee layer that owns synthetic sender identities, warmup orchestration, and the bandit that picks the best content variant.
- Call-center workforce orchestration (shifts, gatekeeper KPIs, per-agent commissions, benchmark-driven call packages).
- A unified target lifecycle that ties Outreach → Connect → Closing into one state machine and one data model, plus cross-stage controlling.
Everything else, we integrate. This decision is the difference between a short MVP and a 12+ month rebuild.
The funnel
Research → Campaign assignment → Outreach (email) → Connect (calls) → Closing
│ │ │ │ │
└────────────────┴──────── one benchmark score ────────────┴─────────────────┘
└──────────────────── one target lifecycle state machine ────────────────────┘
Who it's for (personas)
- Supervisor / admin (the product owner): defines campaigns (postal codes + industry + budget), sets assignment rules, schedules call-center shifts and releases, watches cross-team controlling.
- Connect-Agent: works a focused cockpit — the current target's full context (research data + benchmark + email history), the script, a disposition form; CloudTalk's power dialer auto-advances to the next call. Sees only released campaigns.
- Closing-Agent: works a drag-drop pipeline of interested targets → appointments → contracts. Sees only their round-robin-assigned targets.
- Owner / domain experts: want the cross-stage overview — cost per stage, yield per source, per-agent performance, budget health.
Scope
Core system — what we build
- Target research pipeline — queue-driven, budget-governed discovery (Serper.dev Maps) + enrichment (Firecrawl website crawl, Meta ads, Wayback web-archive age, job-portal signal), with per-fact provenance.
- Benchmark scoring engine — versioned, pluggable, one 0–100 score across 5 weighted dimensions, with a stored breakdown.
- Campaigns & target lifecycle — campaign CRUD, targets belonging to 0..1 campaign (re-assignable), per-target lifecycle state machine.
- Outreach — VirtualCompany/VirtualEmployee sender identities, Microsoft Graph / Exchange Online transport, Trulyinbox warmup, a 3-mail sequence, bandit variant selection, reply processing.
- Connect / call center — Connect-Agents, shifts, benchmark-driven call packages, call cockpit, gatekeeper/interest KPIs, per-agent commissions. The biggest market gap — worth extra polish.
- Closing — drag-drop pipeline, appointments, notes, contracts (SignRequest), payment collection (GoCardless), no-show tracking, closing commissions.
- Controlling — cross-team read-model dashboards + budget allocation optimization.
Non-goals (explicitly out, at least for now)
- Building our own email transport or telephony stack (Exchange Online / Microsoft Graph and CloudTalk are fixed).
- Running our own crawler against Google Maps (use Serper.dev; Firecrawl for site crawl).
- Reputation monitoring for virtual employees.
- A full GDPR / spam / UWG compliance layer (design consideration only in v1).
- General-purpose CRM for arbitrary industries; AI presentation generation; closing QA.
Build vs. integrate — component matrix
| Component | Decision | Why |
|---|---|---|
| Funnel orchestration engine | BUILD | Core IP. No product runs this Research→Closing flow. |
| Research pipeline (Serper.dev Maps + enrichment) | BUILD (thin adapters to sources) | Local-business discovery + provenance is the front-end differentiator. |
| Benchmark scoring engine | BUILD | Core IP. Single score across all stages is the differentiator. |
| Target lifecycle state machine | BUILD | Ties the whole flow together; must be ours. |
| VirtualCompany/VirtualEmployee sender management | BUILD | Owning synthetic senders + warmup orchestration is the outreach differentiator. |
| Bandit (variant selection) | BUILD | Thompson-Sampling variant picker that learns from reply outcomes — core IP. |
| Call-center workforce layer (shifts, KPIs, commissions) | BUILD | The single biggest market gap. |
| Sales pipeline / closing tool | BUILD | Tightly coupled to the rest; a drag-drop Kanban is cheap to build well. |
| Cross-stage controlling / analytics | BUILD | Derives from our own data model. |
| Email transport | INTEGRATE (Microsoft Graph / Exchange Online) | Mail send/receive is a commodity; we build the sender layer on top. |
| Inbox warmup | INTEGRATE (Trulyinbox) | Continuous background warmup is a mature commodity. |
| Power dialer / telephony | INTEGRATE (CloudTalk — client already chose it) | Solved. Native power dialer, recording, listen-in, webhooks. |
| Google Maps / Places data | INTEGRATE (Serper.dev) | Primary ID source; don't run our own crawler against Google. |
| Website crawling | INTEGRATE (Firecrawl.dev) | On-demand site crawl is a commodity. |
| Meta paid-ads check | INTEGRATE (Meta Ad Library API — official, free) | Official API exists. |
| Website-age check | INTEGRATE (Wayback Machine / Internet Archive API) | Official API exists. |
| Job-portal signal | INTEGRATE (jobsuche.api.bund.dev primary, SerpAPI Google Jobs fallback) | Official/free source available. |
| Company register / hiring-manager ID | INTEGRATE (handelsregister.ai, TheirStack) | Only on demand, budget-pre-checked. |
| E-signature / payments | INTEGRATE (SignRequest, GoCardless) | Solved rails; no reason to build. |
Locked product decisions
| Decision | Choice | Status |
|---|---|---|
| Overall strategy | Build the glue, integrate the commodities | Locked |
| Email transport | Microsoft Graph / Exchange Online for send/receive; the platform builds the VirtualCompany/VirtualEmployee sender layer on top. Not Smartlead/Instantly. | Locked |
| Inbox warmup | Trulyinbox (continuous background warmup) | Locked |
| Power dialer | CloudTalk (native power dialer, recording, webhooks) | Locked (client chose) |
| Maps access | Serper.dev (Google Maps/Places — primary ID source, parallel) | Locked |
| Website crawling | Firecrawl.dev (on demand) | Locked |
| E-signature / payments | SignRequest (contracts) + GoCardless (payment collection) | Locked |
| Architecture | TypeScript monorepo — NestJS API (apps/api) + Next.js 16 / React 19 (apps/web) + shared packages/; pnpm workspaces + Turborepo |
Locked |
| Database | PostgreSQL (JSON enrichment payloads + analytical queries) | Recommended — [open] |
| ORM | Prisma (or Drizzle) | Recommended — [open] |
| Queue/cache | Redis + BullMQ (the research pipeline is queue-driven) | Recommended — [open] |
| Frontend | Next.js App Router + React 19 + shadcn/ui + Tailwind 4 | Locked |
| Benchmark | Single, versioned 0–100 score computed once per target, drives sorting in all stages | Locked |
| Tenancy | Single-tenant build now; multi-tenancy achieved by forking the instance | ⚠️ Needs client sign-off |
| Integration boundaries | Every integration behind an interface (mockable, retried, timed-out, cost-tracked) so providers are swappable | Locked |
| State machine | Explicit state machine in the domain layer (enums + guarded transitions) for the target lifecycle | Locked |
| Permissions | Role/permission layer (e.g. CASL) — Admin, Supervisor, Connect-Agent, Closing-Agent | Locked |
| Audit | Append-only immutable audit_logs — every transition logged, feeds KPI dashboards; never UPDATE/DELETE |
Locked |
The layer that used to be a scope risk is now core: rather than integrating a third-party deliverability/persona product, this platform owns the sender layer — VirtualCompany / VirtualEmployee identities, Trulyinbox warmup, vacation/sick-day randomization, and the bandit that optimizes content. Transport is delegated to Exchange Online / Microsoft Graph, so the heavy lifting is mail content and orchestration, which is exactly the differentiator.
Glossary
- Target — a prospect company (the word "Lead" is never used). A Target carries the lifecycle state, the benchmark score, and its research data. A Target belongs to 0..1 Campaign (it may be "unassigned"; re-assignment is supported). There is no separate deduplicated "Company" master reused across many campaigns — the Target is the company.
- Contact — a contact person at a Target (1:n).
- Benchmark — a normalized, versioned 0–100 score (with a stored breakdown) computed once per target from research signals across 5 weighted dimensions; the single sort key for outreach ordering, call prioritization, and shift assignment.
- Research data point — a fact gathered about a Target (paid Meta ads, website age, hiring
activity, industry, size proxy), stored in
research_data_pointswith provenance (source, retrieved_at, confidence) and feeding the benchmark. - Campaign — a run definition: postal codes + industry + budget + assignment rule + product, bundling OutreachVariants and ConnectVariants.
- Assignment rule — the per-campaign rule that decides which researched targets attach to the campaign: a threshold rule (numeric benchmark cutoff) or an LLM prompt rule (natural-language matching).
- VirtualCompany / VirtualEmployee — synthetic sender identities (1 company → 1..3 employees) the platform manages to send Outreach mail via Exchange Online.
- Bandit — a multi-armed bandit (Thompson Sampling default, epsilon-greedy alternative) that
selects the best
StepVersionat send time and learns from reply outcomes. - Budget guard — a counter checked before every paid external call; pre-checks against the campaign budget, warns at 80%, and auto-pauses the campaign at 100%.
- Shift — an assignment of agent × campaign × datetime × target-count that falls inside a ConnectVariant's weekday/time window; on activation the system locks the top-N unworked targets by benchmark into call Packages for the shift.
- Gatekeeper quote — call-center KPI: rate at which agents get past the gatekeeper to a decision-maker.
- Provision — per-agent commission derived from call/close outcomes.
- Warm handoff — a non-cold follow-up handed from the call team back for closing; a distinct job type from cold-call shifts.
Legal & compliance
Not optional throat-clearing — it shapes the architecture. Raise before Phase 2 (Outreach). Note: a full GDPR/spam/telemarketing compliance layer is explicitly out of scope for v1 — the items below are design considerations, and the deliverable is a written legal opinion, not a built compliance module.
- GDPR (EU/German). Researching business contact data, storing named contact persons, and cold-emailing them all touch GDPR. Need a lawful basis, retention limits, deletion handling, and a record of processing. Bake right to erasure into the data model from day one.
- UWG (German unfair-competition law). Unsolicited B2B cold email generally requires prior consent; unsolicited cold calling of businesses has its own constraints. Directly affects how Outreach and Connect flows may legally operate.
- Sender-identity design. Fabricated VirtualEmployee personas carry legal exposure — keep this in view when designing the sender layer.
- Provider ToS. Google Maps and Meta both restrict scraping; use the official/licensed APIs (Serper.dev, Meta Ad Library) rather than raw crawling.
Recommendation: get a short written opinion from a German data-protection/UWG lawyer on the Outreach + Connect design before building those modules. Cheaper than rebuilding after launch.
Open questions for the client / domain experts
- Sender layer scope: confirm the depth of the VirtualCompany/VirtualEmployee simulation (vacation/sick-day randomization, per-employee send caps) for v1. ⚠️ Needs client sign-off.
- Maps access route: Serper.dev as the primary ID source is locked — confirm budget ceilings for paid, on-demand sources (Firecrawl, TheirStack, handelsregister.ai).
- Closing CRM: confirm we build it (recommended) vs. bolt on an external pipeline tool.
- Multi-tenancy: one internal tool, or will it serve multiple client organizations later? Current design: fork the instance per tenant. ⚠️ Needs client sign-off.
- Legal sign-off: who owns getting the GDPR/UWG opinion, and by when?
- Benchmark definition: which signals matter most? Domain experts' 15+ years of experience should seed the initial 5-dimension scoring weights.
See also: 01-architecture · 02-roadmap · 03-data-model · modules/