Implementation Roadmap¶
Status (2026-04-28): Phases 1–2 and a slice of Phase 5 + Phase 8 have shipped. The job-search vertical slice covers Adzuna (primary) + Seek + LinkedIn adapters, the FastAPI server (
/api/v1/), the CLI, and a React frontend with the documented filter UI. Phase 6 Indeed is deferred (Cloudflare ban risk — Adzuna API covers the same listings). Phases 3, 4, 6 (apply/track), 7 are still planned.
Phase Overview¶
gantt
title Kairos Implementation Phases
dateFormat YYYY-MM-DD
axisFormat %b %d
section Phase 1 Skeleton + API
Project setup + Docker Compose :p1a, 2026-04-01, 2d
Domain entities + interfaces (core) :p1b, after p1a, 2d
PostgreSQL models + migrations :p1c, after p1b, 1d
FastAPI server + core routes :p1d, after p1b, 2d
kairos.client library :p1e, after p1d, 1d
section Phase 2 Seek Search
SeekClient + parser :p2a, after p1e, 3d
PostgreSQL job repository :p2b, after p1c, 1d
Job search + list API endpoints :p2c, after p2a, 1d
section Phase 3 LLM Analysis
Claude client setup (anthropic SDK) :p3a, after p2c, 2d
JD analysis + match scoring :p3b, after p3a, 2d
Analysis API endpoints :p3c, after p3b, 1d
section Phase 4 Resume Tailoring
LaTeX parser :p4a, after p3c, 2d
Tailoring prompts + validation :p4b, after p4a, 3d
Resume API endpoints + WebSocket :p4c, after p4b, 1d
section Phase 5 CLI
Typer commands + kairos.client :p5a, after p1e, 3d
Rich output formatting :p5b, after p5a, 1d
section Phase 6 Apply + Track
Apply workflow + browser open :p6a, after p4c, 1d
Application tracking :p6b, after p6a, 2d
Indeed + LinkedIn adapters :p6c, after p6a, 3d
section Phase 7 Polish
Error handling + edge cases :p7a, after p6c, 2d
CLI UX polish :p7b, after p7a, 2d
section Phase 8 Web Frontend
React project setup :p8a, after p7b, 2d
Core views (search + jobs + resume) :p8b, after p8a, 5d
Dashboard + application tracking :p8c, after p8b, 3d
Phase Details¶
Phase 1: Skeleton + API¶
Goal: Working project with a running FastAPI server, PostgreSQL, and shared client library.
- Init Python project with
uv init, configurepyproject.toml - Docker Compose: PostgreSQL 18 + FastAPI (hot reload)
- Define all entities in
kairos.core(Pydantic models) - Define all interfaces (ABCs for Repository + Service)
- Define exception hierarchy per module
- Config loading via
pydantic-settings(TOML + env vars) - PostgreSQL setup + Alembic migrations (001 initial, 002 cursor index, 003 owner_id)
- FastAPI server with health check, RFC 9457 problem+json errors (no envelope), middleware stack
kairos.clientlibrary with typed async methods
Verify: docker compose up -d succeeds. curl localhost:8880/api/v1/health/ returns 200.
Phase 2: Job Search ✅ Shipped¶
Goal: Search jobs across multiple platforms via API.
- AdzunaSearchService (HTTP API, primary source — free, structured JSON, no scraping)
- SeekClient + LinkedInClient with httpx + beautifulsoup4 (fallback)
- Rate limiter with randomized delays for scrapers
- PostgreSQL job repository (SQLAlchemy, owner-scoped)
- API endpoints:
POST /api/v1/jobs/search,GET /api/v1/jobs(cursor-paginated),GET /api/v1/jobs/{id},POST /api/v1/jobs/{id}/fetch-details,DELETE /api/v1/jobs/{id} - 22 backend pytest cases lock the contract
Verify: curl -X POST localhost:8880/api/v1/jobs/search -d '{"keywords":"rust","country":"AU","location":"Perth"}' returns results.
Phase 3: LLM Analysis¶
Goal: Analyze JDs with Claude via API.
- anthropic SDK async client setup
- JD analysis prompt templates
- Analyzer implementation with Pydantic structured output
- API endpoints:
POST /api/jobs/:id/analyze,GET /api/jobs/:id/analysis - Match score computation
Verify: POST /api/jobs/:id/analyze returns analysis with match score.
Phase 4: Resume Tailoring¶
Goal: Import resume, tailor per JD via API, with WebSocket streaming.
- LaTeX section parser
- Resume import flow
- PostgreSQL resume repository
- Tailoring prompts with anti-hallucination
- Validation step
- API endpoints: resume CRUD,
POST /api/resumes/:id/tailor - WebSocket streaming for tailoring progress
Verify: Full resume flow works via API: import → tailor → approve.
Phase 5: CLI¶
Goal: Lightweight command-line client for scripting and daily use.
- Typer-based command structure
- Uses kairos.client for all API calls
- Commands:
jobs search,jobs list,resume import,resume tailor,applications list - Rich output: tables (default) and JSON (
--jsonflag) - Auto-spawn local server if not running
- Interactive approve/reject flow for resume tailoring
Verify: kairos jobs search "rust" --location perth returns results.
Phase 6: Apply + Track¶
Goal: Complete semi-automatic workflow.
- Apply action (open browser with application URL)
- Application tracking API endpoints
- ~~Indeed adapter (playwright)~~ — deferred, Cloudflare ban risk
- ~~LinkedIn adapter~~ ✅ shipped in Phase 2 (public guest API, httpx + bs4)
Verify: Full flow: search → analyze → tailor → apply → track.
Phase 7: Polish¶
Goal: Production-quality UX.
- Graceful error handling across API and CLI
- CLI: colorized output, progress spinners, help text
- Resume export (PDF/LaTeX)
- API rate limits, retries, and edge case handling
Phase 8: Web Frontend (React) ◐ Search slice shipped¶
Goal: Browser-based access to all Kairos features.
- ✅ React 19 + Vite+ + TypeScript scaffold with token-based design system (Phase 8a)
- ✅ Core search view: filter panel matching all CLI flags, cursor pagination, per-platform error surfacing (Phase 8b)
- Job detail view + JD analysis surface (planned)
- Resume tailor diff viewer (planned)
- LLM streaming via WebSocket (real-time analysis/tailoring progress) (planned)
- Application tracker board (planned)
- Responsive design polish for mobile access (planned)
Verify: Open browser → search → analyze → tailor → track — full workflow.
Definition of Done¶
- All tests pass with
pytest ruff checkandruff formatpass with no issues- Core workflow works end-to-end (search → analyze → tailor → apply → track)
- At least Seek adapter is fully functional
- Resume tailoring produces valid LaTeX output
- API server handles all core operations via REST + WebSocket
- CLI can perform the full workflow via API
- All frontends produce consistent behavior through the unified API
- API keys and JWT secrets handled securely (env var or config, never logged)
docker compose up -dbrings up the full stack