barts.work
jobhunt — app screenshot
Work in progress web

jobhunt

A local-first job-search tracker that git-branches a tailored, PDF-built CV for every single application.

jobhunt exists because my wife and I were both job hunting at once and every spreadsheet we tried collapsed under its own weight within a week. Company, role, which CV version we’d actually sent, whether we’d heard back, when to follow up — none of that survives a spreadsheet tab past application twenty. So I built the tracker I actually wanted: two profiles, one shared local instance, zero accounts, zero cloud.

Status

Status-wise, this one’s actually done and running on a homelab, not a demo — full architecture built to spec, seven screens, ~70 source files, every route verified end to end, unit and E2E suites green.

How it was built

The part I’m proudest of is the resume pipeline. Every application gets its own git branch — offer/<id> — cut from your AwesomeCV LaTeX repo. Claude Code runs locally against the job description and tailors cv.tex on that branch; a sibling TeXLive service in Docker Compose compiles it to a PDF on demand. Nothing auto-merges, nothing auto-applies — the app owns the build, I own the tailoring and the send. Every PDF you’ve generated stays retrievable, because the build history is append-only: git is the source of truth, PDFs are just derived artifacts you can always regenerate.

It’s Next.js 16 and Prisma 7 over SQLite, one Docker Compose stack with two services — the app itself, and an isolated TeXLive image so the ~4GB LaTeX toolchain never touches the web container. Board capture is deterministic: parsers for JustJoin.it, NoFluffJobs, Bulldogjob, theProtocol.it, and Pracuj.pl pull structured JD data off a pasted URL. AI is a pluggable, opt-in provider defaulting to none — keyword extraction and gap analysis run on plain string matching against a per-profile keyword library, so the loop works with zero API keys and zero recurring cost.

Lessons learned

I nearly shipped a sign error in the dashboard’s weekly-activity sparkline, caught while porting the design prototype into the real app — the kind of bug that quietly lies about momentum for months. Splitting the builder into its own service instead of shelling out to pdflatex from the main app was the right call early: the web image stays small, and the flaky LaTeX toolchain can fail without taking the tracker down with it.