# Job Ops Orchestrator A unified orchestrator for the job application pipeline. Discovers jobs, scores them for suitability, generates tailored resumes, and provides a UI to manage applications. ## Architecture ``` orchestrator/ ├── src/ │ ├── server/ # Express backend │ │ ├── api/ # REST API routes │ │ ├── db/ # SQLite + Drizzle ORM │ │ ├── pipeline/ # Orchestration logic │ │ ├── repositories/ # Data access layer │ │ └── services/ # Integrations (crawler, AI, PDF) │ ├── client/ # React frontend │ │ ├── api/ # API client │ │ ├── components/ # UI components │ │ └── styles/ # CSS design system │ └── shared/ # Shared types ├── data/ # SQLite DB + generated PDFs (gitignored) └── public/ # Static assets ``` ## Setup 1. **Install dependencies:** ```bash cd orchestrator npm install ``` 2. **Set up environment:** ```bash cp .env.example .env # The app is self-configuring. You can add keys via the UI Onboarding. ``` After the server starts, use the onboarding modal to connect your LLM provider, configure Reactive Resume (`v5` or `v4`), and select a template resume. `v5` (API key) is recommended for self-hosted/latest Reactive Resume. Use `v4` when connecting to the legacy email/password flow. OpenRouter is the default LLM provider, but LM Studio, Ollama, OpenAI, and Gemini are also supported. Use `LLM_API_KEY` / `llmApiKey` to configure providers that require an API key. 3. **Initialize database:** ```bash npm run db:migrate ``` 4. **Start development server:** ```bash npm run dev ``` This starts: - Backend API at `http://localhost:3001` - Frontend at `http://localhost:5173` ## API Endpoints ### Jobs | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/jobs` | List all jobs (filter with `?status=ready,discovered`) | | GET | `/api/jobs/:id` | Get single job | | PATCH | `/api/jobs/:id` | Update job | | POST | `/api/jobs/actions` | Run job actions (`move_to_ready`, `rescore`, `skip`) for one or many jobs | | POST | `/api/jobs/actions/stream` | Stream job action progress/events for one or many jobs | | POST | `/api/jobs/:id/apply` | Mark as applied | ### Pipeline | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/pipeline/status` | Get pipeline status | | GET | `/api/pipeline/runs` | Get recent pipeline runs | | POST | `/api/pipeline/run` | Trigger pipeline manually | | POST | `/api/webhook/trigger` | Webhook for n8n (use `WEBHOOK_SECRET`) | ### Post-Application Tracking | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/post-application/inbox` | List pending messages for review | | POST | `/api/post-application/inbox/:id/approve` | Approve and link to job | | POST | `/api/post-application/inbox/:id/deny` | Ignore message | | GET | `/api/post-application/runs` | List sync run history | | GET | `/api/post-application/providers/gmail/oauth/start` | Initiate Gmail OAuth flow | | POST | `/api/post-application/providers/gmail/oauth/exchange` | Exchange OAuth code | ## Daily Flow 1. **17:00 - n8n triggers pipeline:** - Calls `POST /api/webhook/trigger` - Pipeline crawls Gradcracker - Scores jobs with AI - Generates tailored resumes for top 10 2. **You review in the UI:** - See jobs at `http://localhost:5173` - "Ready" tab shows jobs with generated PDFs - Use command bar search (`Cmd/Ctrl+K`) to quickly find and open jobs - Click "View Job" to open application - Download PDF and apply manually - Click "Mark Applied" to mark application status 3. **Track responses (optional):** - Connect Gmail in Tracking Inbox settings - Automatic email monitoring for interview invites, offers, rejections - Review and approve/ignore matched emails in the Inbox ## n8n Setup Create a workflow with: 1. **Schedule Trigger** - Every day at 17:00 2. **HTTP Request:** - Method: POST - URL: `http://localhost:3001/api/webhook/trigger` - Headers: `Authorization: Bearer YOUR_WEBHOOK_SECRET` ## Development ```bash # Run just the server npm run dev:server # Run just the client npm run dev:client # Run the pipeline manually npm run pipeline:run # Build for production npm run build npm start ``` ## Tech Stack - **Backend:** Express, TypeScript, Drizzle ORM, SQLite - **Frontend:** React, Vite, CSS (custom design system) - **AI:** Configurable LLM provider (OpenRouter default; also supports OpenAI/Gemini/LM Studio/Ollama) - **PDF Generation:** Reactive Resume v4/v5 API export (configured via Settings) - **Job Crawling:** Wraps existing TypeScript Crawlee crawler