Back to work
RE

Workflow / outreach ops

ReachLog - Outreach workflow and dedupe proof

Single-owner outreach system for tracking targets, messages, replies, bounces, forms, follow-ups, and dedupe protection.

Best for

  • private GTM workflow proof
  • dedupe-heavy target tracking
  • reply and follow-up operations
  • small internal tools that need auditability

Built to keep high-volume outreach auditable, searchable, and hard to duplicate.

What it does

Useful proof without the full internal dump.

  • stores targets, contacts, source, status, and dedupe keys
  • imports canonical CSV outreach data with dedupe preview
  • tracks emails, forms, replies, bounces, skips, and follow-up state
  • syncs mailbox activity through worker scripts
  • links inbound replies to existing threads where possible
  • exports targets, messages, events, forms, and follow-ups

Build notes

Implementation choices that matter.

Dedupe first
The schema treats duplicate prevention as a database concern, not just a UI warning.
Mailbox sync
Worker scripts connect outbound, inbound, bounce, and follow-up state to one target record.
Review queue
Replies and due follow-ups stay visible so execution does not depend on memory.

Workflow summary

Reply and follow-up control

ops UI

Reply triage

Action queue

Follow-ups

Due / overdue / upcoming

Dedupe

Import and send guard

Reply needs action today
Follow-up due open
Dedupe key hit skip
Next.js TypeScript React Tailwind CSS Drizzle ORM SQLite IMAP SMTP Node Workers CSV Import

UI screenshots

ReachLog in use

Private UI excerpts from the outreach workflow. Names, emails, and mailbox data are masked where needed.

ReachLog dashboard showing replies needing action, follow-up state, sent no-reply count, and recent mailbox activity.
Dashboard: reply triage, follow-up state, sent/no-reply count, and recent mailbox activity.
ReachLog import screen showing canonical CSV intake and dedupe preview.
Import/dedupe: canonical CSV intake before records are created or updated.
ReachLog target detail view showing contact fields, timeline, thread, notes, and follow-up state.
Target record: contact, timeline, thread, form events, notes, and next action in one place.

Dedupe schema / unique-index logic

typescript
export const targets = sqliteTable(
  "targets",
  {
    id: text("id").primaryKey(),
    dedupeKey: text("dedupe_key").notNull(),
    doNotResend: integer("do_not_resend", { mode: "boolean" }).notNull(),
  },
  (table) => ({
    dedupeKeyUnique: uniqueIndex("targets_dedupe_key_unique").on(table.dedupeKey),
  })
);
Purpose
Resolve each target to one canonical dedupe key.
Guardrail
Stops duplicate imports and sends when the same company appears through email, form, or CSV.
Tradeoff
Requires normalization before insert; the database becomes the final protection layer.

Fit

Relevant when workflow state, dedupe protection, and private operator UX matter more than a generic CRM.

Demo available on request.