Skip to content
← All systems

Cold-email engine · find → write → send → book

Shipped

OutreachEngine

Optimises one number: positive replies per week. Everything else is diagnostic.

A single-operator outreach system. It finds and stores prospects, researches them, writes a personalised first touch, sends from a real Gmail mailbox on a warm-up schedule, detects and classifies replies, books the meeting, and reports the conversion.

53.5K
TypeScript LOC
1,017
Test cases
17
Migrations
11 / 11
Phases shipped

The hard part

Twenty send jobs fire at once against a daily cap of five. How many emails go out?


Exactly five, and there is an integration test that proves it. One atomic INSERT … ON CONFLICT DO UPDATE … WHERE sent_count < limit reserves the slot, so the database decides rather than a read-then-write in the worker. The same file proves the kill switch halts the next send, and that a suppressed address is never mailed even when the suppression landed after the message was queued.

Design decisions

01

The AI is not allowed to make things up about anyone

Two files hold everything an email may say. One holds what is true about the sender, where every claim carries its evidence and anything embargoed or unbuilt is marked unlinkable — a guard fails the prompt seed rather than let a dead link reach a stranger. The other holds what is true about the recipient, tiered so that the generic facts every bought list carries cannot on their own open the send gate. A lead with nothing specific about it produces a blocked draft, not a worse email.

02

Tenancy proven by test, not by convention

Every read and write goes through a scoped data handle that applies the workspace filter itself — a caller's where clause is ANDed with the scope and cannot replace it, and the insert type has no workspace field to get wrong. An integration test enumerates all 22 tenant tables and every read method; removing the scope filter fails 28 of its 37 assertions.

03

Replies are read as decisions

A reply stops every sequence for that lead across all campaigns, cancelling steps already rendered. An out-of-office does not — it is caught from RFC 3834 headers before any model runs, and pushes the follow-up to the date the responder named. A hard bounce suppresses the address permanently; a soft bounce does not, because a full mailbox is not a dead one.

04

Credentials sealed to their row

Gmail tokens are AES-256-GCM encrypted and sealed under the mailbox id and the column name, so a ciphertext copied into another row or column fails to open rather than quietly authorising the wrong account. Google grants are incremental: sign-in asks for identity, and Gmail and Calendar scopes are requested only when those features are connected.

05

Deliverability treated as a constraint

Warm-up is a function of the mailbox's start date — day one is ten sends, +5/day to the cap — so it cannot be raised by editing a number. Sends are spaced by 45–240 seconds of jitter applied as a deferral, never an in-process sleep, so a worker restart cannot burn a slot on a message that was not sent. Every email carries a postal address and an HMAC-signed RFC 8058 one-click unsubscribe, and sending is blocked outright until that address is set.

06

Idempotent where the network is not

Cal.com sends no delivery id, so a booking webhook is keyed on a hash of its own body and enforced by a unique index — a replayed delivery creates exactly one meeting. Bookings sync both ways with Google Calendar, with loops prevented by comparing Google's updated timestamp against the last local write.

Stack

  • Next.js 16
  • TypeScript (strict)
  • Drizzle ORM
  • PostgreSQL 16
  • Zod
  • Vitest
  • Playwright
  • Gmail API
  • Google Calendar
  • Cal.com

My part in it

Sole architect and engineer, across all eleven phases.


What is not done

Built for one operator — me — and run that way. It is not a multi-customer SaaS and was never scoped as one.