A local job search tracker built with NestJS, React, and PostgreSQL. Track applications, interviews, interviewers, and take live notes during interview calls.
- Node.js 20+
- pnpm
- PostgreSQL (running locally)
- Install dependencies
pnpm install- Create the database (one-time)
createdb jobtrackerIf your Postgres uses a username (Postgres.app uses your macOS username), update DATABASE_URL in .env and apps/api/.env:
DATABASE_URL=postgresql://yourusername@localhost:5432/jobtracker
- Run database migrations
pnpm db:generate
pnpm db:migrate- Start development servers
pnpm devThis starts:
- API at http://localhost:3001
- Web at http://localhost:5173
Open http://localhost:5173 in your browser.
job-tracker/
├── apps/
│ ├── api/ # NestJS REST API
│ └── web/ # React + Vite frontend
├── packages/
│ └── shared/ # Shared types, enums, Zod schemas
└── prisma/ # Database schema and migrations
- Dashboard — status counts, upcoming interviews, recent activity
- Applications — track every role with status, dates, rejection reasons
- Interviews — log rounds, formats, outcomes, and dates
- Interviewers — directory of people you've met
- Live Notes — full-screen note editor with autosave during interviews
- Google Calendar — connect your account; events refresh automatically when the app loads
- In Google Cloud Console, create OAuth 2.0 credentials (Web application).
- Add authorized redirect URI:
http://localhost:3001/api/auth/google/callback - Add your Google account as a test user (while the app is in testing mode).
- Copy Client ID and Client Secret into
apps/api/.env:
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:3001/api/auth/google/callback
WEB_APP_URL=http://localhost:5173
- Restart the API, then click Connect Google Calendar in the app header.
- On each app load, upcoming events (next 30 days) are fetched from your primary calendar. Use Refresh to sync again without reloading.
| Command | Description |
|---|---|
pnpm dev |
Start API + web dev servers |
pnpm db:migrate |
Run Prisma migrations |
pnpm db:studio |
Open Prisma Studio (DB browser) |
pnpm build |
Build all packages |
All routes are prefixed with /api:
GET /applications— list applications (optional?status=filter)POST /applications— create applicationGET /applications/:id— application detail with interviewsPATCH /applications/:id— update status, rejection infoPOST /applications/:id/interviews— add interviewGET /interviews/:id— interview detailPOST /interviews/:id/notes— add notePATCH /notes/:id— update note (autosave)GET /interviewers— list interviewersGET /dashboard/summary— dashboard statsGET /calendar/status— Google Calendar connection statusPOST /calendar/sync— fetch upcoming events from Google CalendarGET /auth/google— start Google OAuth flowDELETE /calendar/disconnect— disconnect Google Calendar