JobGoblin is a private, self-hosted job-search workspace for one owner and a few invited users. It stores resumes, resume versions, jobs, discovered roles, contacts, applications, analyses, cover-letter drafts, and outreach drafts while keeping the workflow local and review-driven.
It is not an auto-apply or spam tool. External actions such as sending email, contacting recruiters, or applying to jobs must remain human-reviewed. AI output must stay grounded in user-provided facts and never invent experience, skills, education, or credentials.
The core private job-search workflow is implemented across resumes, discovery, saved jobs, application materials, tracking, follow-ups, outreach, and interview prep.
Phase status:
- Phase 2 core resource modules are implemented: jobs, contacts, applications, dashboard, cover-letter drafts, and outreach drafts.
- Phase 3 resume-to-job analysis uses deterministic, requirement-normalized scoring and grounded guidance.
- Phase 4 runtime tooling and the optional Cloudflare Tunnel profile are implemented; OAuth and tunnel validation remain operator-specific.
- Phase 5 includes the profile builder, follow-up reminders, resume versions, job discovery, tailored resume drafts, email export, interview prep, and LLM observability.
Implemented:
- Docker Compose stack with Caddy as the same-origin entry point.
- Optional Cloudflare Tunnel compose profile, disabled by default.
- FastAPI backend, PostgreSQL, Alembic migrations, SQLModel models, liveness health, and DB readiness endpoint.
- Email/password auth, admin-created invite tokens, invite-only signup, Google OAuth plumbing, email allowlist, TOTP MFA, and environment-aware auth cookies.
- Resume upload, text extraction, AI parse, edit/list/detail/delete, version management, and PDF export.
- Jobs CRUD API and jobs list/create/detail/edit/delete UI.
- Job discovery preferences, mock/Adzuna provider plumbing, run/result storage, dedupe, dismiss/save states,
/discoverUI, save-to-job behavior, and AI-assisted ranking with profile/resume/saved-job context. - Contacts, applications, dashboard data, resume-to-job analysis with application guidance, cover-letter draft, profile builder, follow-up reminder, and review-only outreach APIs.
- Next.js app shell, auth guard, login/MFA/signup flow, resume, jobs, discovery, contacts, applications, dashboard, job-detail analysis guidance/cover-letter, outreach, and profile screens.
- Runtime operator checks for Ollama, DB readiness, local smoke testing, Adzuna smoke guidance, Cloudflare Tunnel/OAuth setup, backups, migrations, rollback, secrets, and release promotion.
- CI for backend ruff/pytest, frontend lint/build, and the merged E2E harness.
Remaining validation and future work:
- Integrated post-merge smoke pass across the browser workflow.
- Real local AI verification with
AI_PROVIDER=ollama. - Google OAuth, allowlist, HTTPS tunnel, and secure-cookie validation with real credentials.
- Richer discovery providers, tailored resume drafts, email draft/export integration, interview prep, and LLM observability.
- Any external sending remains out of scope unless it is explicit, user-reviewed, and approval-gated.
Copy the environment template:
cp .env.example .envFor fast local iteration, set mock AI and seed the demo admin in .env:
AI_PROVIDER=mock
ADMIN_EMAIL=admin@jobgoblin.local
ADMIN_PASSWORD=goblin-demo-pass-123Start the stack:
docker compose up -d --buildOpen:
- App through Caddy: http://localhost:8080
- Backend Swagger UI: http://localhost:18000/docs
Demo login, when the seed admin values above are configured:
- Email:
admin@jobgoblin.local - Password:
goblin-demo-pass-123
The Docker/Caddy path is the intended integration path. Caddy routes / to the frontend and /api/* to the backend so browser traffic is same-origin and auth can use HTTP-only cookies without CORS workarounds.
Ollama is included in the Compose stack, but model download is a one-time host action. For the intended local AI runtime, pull the default model after the stack is up:
docker compose exec ollama ollama pull qwen2.5:7b-instructUse AI_PROVIDER=mock in .env for fast local iteration without a model. Use AI_PROVIDER=ollama plus the default OLLAMA_BASE_URL=http://ollama:11434 when smoke-testing real local parsing/generation.
Use curl http://localhost:8080/api/health for liveness and curl http://localhost:8080/api/health/ready for database readiness. Cloudflare Quick Tunnel is optional and disabled by default. It needs no Cloudflare login and prints a fresh shareable trycloudflare.com URL in the tunnel logs:
docker compose --profile tunnel up -d cloudflared
docker compose --profile tunnel logs --tail=80 cloudflaredSet COMPOSE_PROFILES=tunnel in local .env when every normal docker compose up -d --build should also start the quick tunnel. Token-based named tunnels are still available through the named-tunnel profile when a fixed Cloudflare hostname is needed.
Signup is invite-only by default. Set PUBLIC_SIGNUP_ENABLED=true only for intentionally shared sessions where anyone with the app link may create an account.
jobgoblin/
|-- backend/ # FastAPI service, models, migrations, tests
|-- frontend/ # Next.js app shell and UI
|-- docs/ # architecture, design, roadmap
|-- infra/ # Caddy config
|-- docker-compose.yml # local/self-hosted stack
`-- .env.example # committed environment template
Backend:
cd backend
TEST_DATABASE_URL=postgresql+psycopg://test:test@localhost:5433/test ./.venv/Scripts/python.exe -m pytest -q
./.venv/Scripts/ruff.exe check .Frontend:
cd frontend
npm run lint
npm run buildGitHub Actions runs the same backend and frontend checks for pull requests.
- Architecture
- Detailed design
- Roadmap
- Post-merge remediation plan
- PR #45 detailed remediation and merge-readiness plan
- Frontend notes
Branch flow: main -> dev -> feature/*. Keep main release-ready, integrate through dev, and use focused PRs for feature work. See Runtime operator runbook for operator-run Ollama, Cloudflare/OAuth, Adzuna, backup/restore, migration/rollback, secrets, and dev-to-main release checks.