Enterprise-grade automated job application system (Bun + TypeScript, Express, Prisma, Redis Streams + Pub/Sub, Next.js).
- Runtime:
bun - API:
express+ws - Queue:
redis streams(jobs) +redis pub/sub(events) - Database:
postgres+prisma - Frontend:
next.js(App Router)
apps/apiAPI serverapps/workerQueue workerapps/webDashboard UIpackages/sharedShared typesprismaPrisma schema and migrations
buninstalleddockerrunning
- Start dependencies
docker compose up -d- Install deps
bun install- Configure environment
cp .env.example .env- Generate Prisma client and migrate
bun run db:generate
bun run db:migrate- Install Playwright browsers (first time only)
bunx playwright install chromium- Run the stack
bun run devBuild and run everything (API + worker + web + Postgres + Redis):
docker compose up --buildThe API container will automatically run prisma migrate deploy on startup.
Stop all services:
docker compose downbun run devstart API + worker + webbun run dev:apistart API onlybun run dev:workerstart worker onlybun run dev:webstart web onlybun run db:generategenerate Prisma clientbun run db:migraterun Prisma migrations
Single env file at repo root: .env
- WebSocket endpoint:
ws://localhost:3001/ws?token=dev-token - API endpoint:
http://localhost:3001 HEADLESS=falseopens a visible browser for automation.BROWSER_CHANNEL=chromeuses your installed Chrome (optional).AUTO_SUBMIT=falsestops at final review so you can submit manually.- First run requires login in the opened browser (LinkedIn/Indeed).
MANUAL_HOLD_MScontrols how long the review window stays open.AI_SCORING=trueenables Gemini scoring (limit withAI_SCORE_LIMIT).AI_ANSWER_ENABLED=trueenables AI answers for application questions.AI_ANSWER_LIMIT=3caps AI answers per form step.COVER_LETTER_ENABLED=truegenerates a cover letter per application.RESUME_TAILOR_ENABLED=truesaves a tailored resume snapshot per application.AI_PROVIDER=autochooses the LLM provider (openai,gemini,auto).OPENAI_API_KEYenables OpenAI usage (server-side only).OPENAI_MODELsets the OpenAI model (default:gpt-4o-mini).
- Discovery runs every 24h by default (
DISCOVERY_INTERVAL_MS). - Scheduled sources: Remotive + Arbeitnow (public APIs).
- Automation sources: LinkedIn + Indeed (via Playwright, requires login).
- Configure preferences in the dashboard:
/dashboard/settings. - API endpoints:
POST /users,GET /users?email=...,POST /preferences,GET /preferences/:userId,POST /automation/start.
Start applyingtriggers browser automation for LinkedIn + Indeed.AUTO_SUBMIT=falsestops at final review so you can submit manually.- First run requires login in the opened browser; session is reused.
- Add
GEMINI_API_KEYto.env. - (Optional) Add
OPENAI_API_KEYand setAI_PROVIDER=openaior choose OpenAI in the dashboard. - Open
/dashboard/settings, upload a resume PDF, click Upload & parse.
- The worker derives keywords/roles from your parsed resume if preferences are empty.
- AI scoring uses Gemini (if enabled) for up to
AI_SCORE_LIMITjobs per run. - Cover letters are generated per application and saved in the database.
- Tailored resumes are saved per application in
artifacts/resumes/. - AI answers autofill short text, dropdown, and radio/checkbox questions.
- Download tailored resumes and cover letters as PDF from
/dashboard/resume-viewer. - Generate interview prep per application and view it in the same panel.
Quick setup (example):
curl -X POST http://localhost:3001/users -H 'Content-Type: application/json' \\
-d '{"email":"you@example.com","fullName":"Your Name"}'
curl -X POST http://localhost:3001/preferences -H 'Content-Type: application/json' \\
-d '{"userId":"<USER_ID>","roles":["software engineer"],"keywords":["react","typescript"],"locations":["remote"],"remote":true}'- Monorepo scaffold with Bun workspaces
- Express API with WebSocket event streaming
- Redis Streams job queue + Redis Pub/Sub for events
- Prisma schema (core + resume/cover letter/import/notifications)
- Worker consumer loop for stream jobs
- Discovery scheduler (daily) with Remotive + Arbeitnow sources
- Next.js dashboard shell (Overview, Jobs, Queue, Logs, Settings)
- Discovery UI (create user + preferences)
- Discovery results UI (matches + jobs + runs)
- Start applying button (automation trigger)
- Playwright automation (LinkedIn + Indeed, stops at final review)
- Resume upload + Gemini parsing (profile extraction)
- AI scoring + cover letter generation
- Resume & cover letter viewer UI
- PDF export for tailored resume and cover letter
- Interview prep generation (AI)
- Auto-fill common form fields from resume profile
- Tailored resume snapshots per application
- AI answers for text + dropdown/radio/checkbox questions
- Live overview metrics + WebSocket log stream
- Queue status view backed by live application data
- Bulk job import endpoint + UI (paste multiple URLs)
- Email notifications on status updates (SMTP)
- Analytics dashboard (conversion + platform breakdown)
- Chrome extension (one-click save/apply)
- More platform adapters (Lever, Greenhouse, Wellfound)
- Resume PDF rendering (LaTeX or HTML/PDF)
Location: apps/extension
Load it in Chrome:
- Open
chrome://extensions - Enable Developer mode
- Click Load unpacked
- Select
apps/extension
Configure the API URL + User ID (Options page), then click Save & apply to queue a job.
Dashboard: /dashboard/analytics
API: GET /analytics/summary?userId=...