72 lines
3.9 KiB
Markdown
72 lines
3.9 KiB
Markdown
# Jobhunt Platform
|
|
|
|
An AI-assisted job-hunt platform where **you stay in control**. The system discovers jobs, scores them against your profile, drafts application material and prepares sends — but nothing external ever happens without your explicit approval.
|
|
|
|
Open source. Self-hosted. Single-user first, multi-user later.
|
|
|
|
## Core ideas
|
|
|
|
1. **Approval gate, architecturally enforced.** Every external action (send email, submit application) requires a server-side confirmed `Approval` referencing the exact artifact hash. No approval row, no send. This is a hard constraint, not a style guide.
|
|
2. **State machine owns the flow, LLM answers questions inside it.** Pipeline transitions live in a table. The LLM scores, extracts, critiques and suggests — it never picks the next step. Deterministic orchestration, probabilistic judgment.
|
|
3. **Per-task model routing with token budgets.** Cheap model for extraction/scoring, strong model for prose review, budgets enforced per task so the bill stays boring.
|
|
4. **The user drafts, the system reviews.** Measured reality: human-drafted prose outperforms full AI drafts. Default cover-letter flow is user-writes, AI-reviews with tracked suggestions.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
apps/web Vue 3 + Vite + Tailwind — tabs: CV editor, Research, Applications (kanban), Application detail
|
|
apps/api FastAPI + PostgreSQL — REST API, state machine, scheduler, approval enforcement
|
|
packages/
|
|
llm-gateway/ Model routing, per-task budgets, structured JSON IO, retry/fallback policy
|
|
connectors/ Job source adapters -> normalized JobPosting (LinkedIn read-focused, jobindex, paste-a-URL)
|
|
artifacts/ CV + cover-letter generation: Jinja templates -> PDF (fpdf2), versioning, hashing
|
|
docs/ ADRs, data model, API contract, worker task cards
|
|
```
|
|
|
|
## Pipeline
|
|
|
|
```
|
|
discovered -> scored -> approved -> drafting -> sent -> interviewing -> offer -> closed
|
|
\-> rejected (by user) \-> expired
|
|
```
|
|
|
|
External comms are only possible from `approved`/`drafting` states, and only with a matching confirmed `Approval`.
|
|
|
|
## Quick start (POC)
|
|
|
|
```bash
|
|
cp .env.example .env # add LLM provider keys (no key = mock mode, deterministic)
|
|
|
|
# Backend tests + live API (DinD-safe: everything runs inside the compose network)
|
|
docker compose run --rm api-test # 47 pytest tests
|
|
docker rm -f jobhunt-api-poc 2>/dev/null; \
|
|
docker compose run -d --name jobhunt-api-poc \
|
|
--entrypoint "uvicorn app.main:app --host 0.0.0.0 --port 8000" api-test
|
|
docker exec jobhunt-api-poc curl -s localhost:8000/api/health # {"status":"ok"}
|
|
|
|
# Frontend (host): Vue dev server proxies to the API
|
|
cd apps/web && npm install && VITE_API_BASE=http://localhost:8000/api npm run dev
|
|
|
|
# Packages (host, no DB needed): artifacts + llm-gateway unit tests
|
|
cd packages/artifacts && uv venv && . .venv/bin/activate && uv pip install -e ".[dev]" && pytest -q
|
|
cd packages/llm-gateway && uv venv && . .venv/bin/activate && uv pip install -e ".[dev]" && pytest -q
|
|
```
|
|
|
|
Note: in sandboxed Docker-in-Docker environments host port publishing may not work; run curl/docker exec against the `jobhunt-api-poc` container directly, as above.
|
|
|
|
## Status
|
|
|
|
POC scaffolding in progress. See `docs/` for the design.
|
|
|
|
## Screenshots
|
|
|
|
Screenshots will be added here as the UI stabilizes.
|
|
|
|
| View | Description | Screenshot |
|
|
|------|-------------|------------|
|
|
| Today | Daily digest with top matches, nudge cards, and cost summary | _placeholder_ |
|
|
| Onboarding Wizard | Welcome, CV import, postings fetch, done steps | _placeholder_ |
|
|
| CV Editor | Profile form, sections list, AI assist, PDF render | _placeholder_ |
|
|
| Research | Postings table with fetch form, scam column, and scoring | _placeholder_ |
|
|
| Applications Kanban | Drag-and-drop board with red-flag badges and nudge dots | _placeholder_ |
|
|
| Application Detail | Posting info, interview prep modal, cover letter, approval gate | _placeholder_ |
|