Skip to content

Gmail Job Tracker · Case study

Gmail Job Tracker

Reads your Gmail, finds every application email, and puts each company on a board by stage.

1 day

from brief to working app

5

agent sessions I directed

4

status columns

Design EngineeringAI ProductAgent Orchestration
Role
Product design · Design engineering · Agent orchestration
Type
Full stack product
Timeline
1 day · September 2026
Stack
Next.js 16 · Gmail API · Claude Haiku · SQLite · Motion
The Interviewing column with three frosted-glass cards.
One application card: Acme Corp, Design Technologist, 2 emails.

The problem

One application, six emails, four senders

Confirmations come from Greenhouse, invites from a recruiter, rejections from no-reply. Nothing says which company or stage.

The board

One card per company, four columns

Cards lift on hover.

Cards sort by the latest email.

Keeping up

New mail lands on the board

Sundial arrives, then Halcyon moves to Interviewing.

Gmail is polled every 2 minutes, or on Sync now. A new confirmation becomes a card.

Reading the email

A small model reads each email once

How the classifier reads an emailAn email (subject, sender, snippet, and the first 2,000 characters of the body) goes to Claude Haiku, which answers with a fixed-schema tool call: is_job_related, company, role, status and confidence. That becomes one card per company. If there is no API key or the model is down, a keyword heuristic produces the same answer.An emailSubject, from, snippetBody, first 2,000 charactersClaude HaikuOne tool call:record_classificationCompany is the onenamed in the email,not the sender.KeywordheuristicNo API key,or modeldownFixed schemais_job_related · companyrole · statusconfidenceOne card per companySorted by the latest email

Claude Haiku reads the subject, sender, snippet and first 2,000 characters, then answers through one fixed-schema tool call. A keyword heuristic takes over if the model is down.

  • Applied · Confirms an application was received.
  • Interviewing · Invites or confirms an interview or call.
  • Offer · Extends a job offer.
  • Rejected · Says the company is moving on.

Correcting it

Drag it, edit it, it stays

Drag between columns.
Open a card, fix the role, see it save.
One click hides a non-job email for good.

Once you edit a card, sync never overwrites your version.

What's stored

Only card data is stored

The data-model contract from PROJECT.md: the SQL that defines the tables.
The data-model contract from PROJECT.md.

The database holds subject, sender, date, a 200-character snippet, the classifier’s decision and a Gmail link. Bodies are read once, in memory.

The design system

Calm glass, with colour for status

The full board: pale blue canvas, blurred orbs, four frosted-glass columns, a glass header.
Canvas, orbs, glass.
The header bar with a sync toast, Show ignored toggle, Sync now and Sign out buttons.
The header.
The Interviewing column with a yellow status dot and three cards.
A column.
The Acme Corp side sheet: editable company, role, status, notes and two emails.
The detail sheet.

Pale blue canvas, frosted-glass cards. Status carries the only colour: yellow interviewing, green offer, red rejected.

Radii run 10, 14, 20, 28 and pill. Springs come from one file.

How I built it

I ran the build as five sessions

The session network behind the build and the redesignBuild: my brief goes to a planner on Fable that writes the PROJECT.md contract; a backend session and a frontend session, both on Sonnet, build in parallel; a Sonnet integration session runs a Playwright smoke test; an Opus reviewer does a security pass. Redesign: a DESIGN.md doc with tokens and component contracts goes to a primitives session; a board session and a detail sheet session work in parallel; a screenshot review follows, and it ships.BUILDBriefGoal and constraintsMePlannerWrites the contract, PROJECT.mdFableBackendData, API, mockSonnetFrontendBoard, componentsSonnetIntegrationPlaywright smoke test, READMESonnetSecurity reviewAuth, input checksOpusREDESIGNDesign docDESIGN.md: tokens, components, motionPrimitivesTokens, glass, motion, one sessionBoard sessionColumns and cardsDetail sheetPanel, sign-inScreenshotreview, then fixesShippedSame day
  • I wrote the brief; a planner froze stack, data model and API.
  • Two coders built backend and frontend in parallel, each owning set files.
  • An integration session ran both halves and fixed the seams with Playwright.
  • A reviewer did a security pass, and the redesign reused the shape.