Turn job-related Gmail emails into a clean application pipeline, and generate follow-up drafts when you’re due.
Built for the early pipeline: applying consistently, tracking status, and following up on time.
- ✅ Parse job application emails → normalized
JobEmailrows - ✅ Seed “ToDo” follow-ups when
APPLIEDis older than X days - ✅ One-click draft generation (OpenAI Agent SDK-ready)
- ✅ Minimal UI: ToDo list + Sheet draft viewer + Copy button
Goal: reduce the “did I follow up?” mental overhead and help you keep momentum during the apply phase.
Dashboard
- “Sync ToDo’s” button
- List of due follow-ups (company / role / applied date)
- “View draft email” → opens a Sheet with subject/body and Copy
A Gmail poller searches for job-related messages (ex: LinkedIn application confirmations), parses the message, and stores:
status(NEW,APPLIED,INTERVIEW, …)appliedDatecompanyName,roleTitle,location- links (
applicationLink,externalUrl, etc.)
A “seed” action finds JobEmail rows that are:
status = APPLIEDappliedDate <= now - X days- no existing
FollowUpDraft(DRAFT, EMAIL)row
It inserts placeholder drafts:
subject = null,body = nullisGenerated = false
When the user clicks “view draft email”:
- server action loads the
JobEmail - calls
runFollowUpDraftAgent(...)(currently deterministic template, later OpenAI Agent SDK) - updates
FollowUpDraftwithsubject/body, marksisGenerated = true - UI opens a Sheet with Copy button
- Next.js (App Router)
- TypeScript
- Prisma (Postgres)
- Prisma Accelerate (optional extension)
- Gmail API (OAuth refresh token)
- OpenAI (agent/draft generation)
UI:
- shadcn/ui + Radix primitives (Sheet, Button, Input, Textarea)
JobEmail— canonical “application email” recordFollowUpDraft— draft outreach for aJobEmail(unique perjobEmailId + channel + status)
app/
(pages)/
dashboard/
page.tsx # server page: loads todos
FollowUpsList.tsx # client: renders list + opens Sheet
FollowUpDraftSheet.tsx # client: Sheet + Copy
sync-button.tsx # client: seed todos + router.refresh
actions/
followup/
seed.ts # seeds FollowUpDraft placeholders
followups.ts # getOrGenerateFollowUpEmailDraft
agents/
followup.agent.ts # agent entrypoint (SDK-ready)
generateFollowUpEmailDraft.ts # current deterministic template
followup.types.ts
followup.policy.ts
followup.tools.ts
services/
gmail.ts # poll + parse Gmail emails
followupDrafts.ts # seed + query todos + upsert drafts
lib/
prisma.ts # Prisma singleton (+ Accelerate)
validation/
JobEmail/...
FollowUpDraft/...

