- Add per-listing notes (JobNotes component, notes column, auto-save) - Enforce hard score cap (≤15) when deal-breaker hits are present; add clearance/citizenship deal-breaker rules to scoring prompt - Cover letter prompt now uses full search profile (experience level, skills, work arrangement, location, salary, industries, deal-breakers) and produces longer, name-signed output - Include candidate name + location in sanitized scorer profile - Raise MAX_JOB_ACTION_BATCH_SIZE from 100 → 2500 (shared constant) - Update README with new features Made-with: Cursor
110 lines
5.6 KiB
Markdown
110 lines
5.6 KiB
Markdown
# JobOps
|
||
|
||
Self-hosted job search orchestration: discover roles from multiple sources, score fit with your profile, draft tailored resumes and cover letters, export PDFs, and track application email—**you still submit applications yourself**; JobOps prepares the work and keeps state organized.
|
||
|
||
Licensed under **AGPLv3 + Commons Clause** — see [LICENSE](LICENSE).
|
||
|
||

|
||
|
||
## What’s in this repo
|
||
|
||
| Area | Role |
|
||
|------|------|
|
||
| **`orchestrator/`** | Express API, SQLite + Drizzle, pipeline, React (Vite) UI, LLM integrations, Reactive Resume PDF flow |
|
||
| **`shared/`** | Shared TypeScript types and settings registry |
|
||
| **`docs-site/`** | Docusaurus user and developer documentation |
|
||
| **`extractors/`** | Per-source crawlers (Adzuna, Gradcracker, UK Visa Jobs, Hiring Café, Startup Jobs, JobSpy helpers, etc.) |
|
||
|
||
Root `package.json` is an npm **workspace** root; day-to-day app commands usually run under `orchestrator/`.
|
||
|
||
## Features (high level)
|
||
|
||
- **Sources**: Multiple boards and aggregators (exact list evolves; see docs and extractor packages).
|
||
- **Scoring & tailoring**: LLM compares jobs to your resume profile; optional drafts for summary, headline, skills, and project selection. The scorer enforces hard caps when deal-breakers fire (e.g. clearance/citizenship conflicts cap score to 0-15) and includes candidate name and location in the profile sent to the model.
|
||
- **Cover letters**: LLM-generated, profile-aware cover letters. The prompt uses the full job-search profile (experience level, target roles, must-have and nice-to-have skills, work arrangement, location, salary, industries, deal-breakers) and produces 4-5 paragraphs (~550 words) signed with the candidate's name.
|
||
- **Job notes**: Per-listing personal notes with debounced auto-save, available in Discovered, Ready, and detail panels.
|
||
- **PDFs**: Tailored exports via **Reactive Resume** (v4 or v5 API). Optional **local JSON resume** (`JOBOPS_LOCAL_RESUME_PATH` or Settings) as the base document for profile/tailoring; PDF export still uses RxResume when configured.
|
||
- **Pipeline**: Scheduled or manual runs (`POST /api/pipeline/run`, webhook trigger).
|
||
- **Post-application**: Optional Gmail-based inbox for interview/offer/rejection signals.
|
||
- **Job list filters** (orchestrator UI): Narrow the pipeline job list by **multiple sources** and **countries** (country is inferred from each listing’s location text). Filters sync to the URL (`source`, `sourceExclude`, `countries`, `countriesExclude`). Each source/country chip cycles **off → include → exclude** (exclude shows in red); listings marked **remote** still pass country include/exclude rules.
|
||
- **Bulk actions**: Select-all / batch actions support up to **2 500 jobs** per request (raised from 100).
|
||
- **Data**: SQLite and generated artifacts under `./data` (default in Docker).
|
||
|
||
## Requirements
|
||
|
||
- **Node.js 22** (see `package.json` / Volta pin) for local development.
|
||
- **Docker + Compose v2** for the recommended production-style run.
|
||
|
||
## Quick start (Docker)
|
||
|
||
```bash
|
||
git clone <your-repo-url>
|
||
cd Jobber
|
||
|
||
cp .env.example .env
|
||
# Edit .env: MODEL / LLM keys, Reactive Resume or local resume path, optional BASIC_AUTH, etc.
|
||
|
||
docker compose up -d --build
|
||
```
|
||
|
||
- **UI**: `http://localhost:3005` (host port mapped in `docker-compose.yml`; app listens on **3001** inside the container).
|
||
- **Health**: `GET /health` on the same origin.
|
||
|
||
Persist data by backing up the mounted **`./data`** directory.
|
||
|
||
## Local development
|
||
|
||
From the repository root:
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
Then use the orchestrator workspace (see **`orchestrator/README.md`** for API tables and scripts):
|
||
|
||
```bash
|
||
cd orchestrator
|
||
cp .env.example .env
|
||
npm run db:migrate
|
||
npm run dev
|
||
```
|
||
|
||
Typical dev URLs: API **http://localhost:3001**, Vite client **http://localhost:5173**.
|
||
|
||
## Configuration notes
|
||
|
||
- **LLM**: Configurable provider (OpenRouter default; also OpenAI, OpenAI-compatible endpoints, Gemini, Ollama, LM Studio, etc.). Keys can be set in `.env` or onboarding.
|
||
- **Reactive Resume**: v5 API key or v4 email/password; optional self-hosted `RXRESUME_URL`. Full behavior is documented in the docs site under **Reactive Resume**.
|
||
- **Local resume JSON**: Set `JOBOPS_LOCAL_RESUME_PATH` (or the Settings field) to a Reactive Resume–shaped export so you do not need a selected cloud “base resume” for profile and tailoring. PDF generation still performs a temporary import/print through RxResume when credentials are present.
|
||
|
||
## Documentation
|
||
|
||
| Resource | Contents |
|
||
|----------|----------|
|
||
| **`docs-site/`** | User-facing guides (build with `npm run docs:dev` from repo root) |
|
||
| **`orchestrator/README.md`** | Orchestrator layout, endpoints, dev commands |
|
||
| **`DEPLOY_GITEA_VM_CRON_TELEGRAM.md`** | VM/container deploy, cron, optional Telegram |
|
||
| **`AGENTS.md`** | API/logging/SSE conventions for contributors and automation |
|
||
|
||
## Deploy, cron, Telegram
|
||
|
||
See **[DEPLOY_GITEA_VM_CRON_TELEGRAM.md](./DEPLOY_GITEA_VM_CRON_TELEGRAM.md)** for production deploy, scheduling `POST /api/pipeline/run`, and optional notifications.
|
||
|
||
## Verification (CI parity)
|
||
|
||
From the repo root, before merging substantial changes:
|
||
|
||
```bash
|
||
./orchestrator/node_modules/.bin/biome ci .
|
||
npm run check:types:shared
|
||
npm --workspace orchestrator run check:types
|
||
npm --workspace orchestrator run build:client
|
||
npm --workspace orchestrator run test:run
|
||
```
|
||
|
||
(Additional workspace typechecks apply in CI; see **`AGENTS.md`**.)
|
||
|
||
## License
|
||
|
||
**AGPLv3 + Commons Clause** — you may self-host, use, and modify; you may not sell the software or offer paid hosting or support whose value substantially comes from this codebase. See [LICENSE](LICENSE).
|