Skip to content

Project Structure

This is the target architecture. Not every module below exists today — items marked (planned) are scoped but not implemented. The currently-shipped surface is the search vertical slice (core entities + Adzuna/Seek/LinkedIn adapters + jobs API + CLI + React frontend). LLM, resume, and application modules are stubs (__init__.py only) and will fill in as features land.

Repository Layout

kairos/
+-- pyproject.toml                      # Project config (uv)
+-- uv.lock                            # Lockfile
+-- docker-compose.yml                  # PostgreSQL + FastAPI
+-- Dockerfile                          # FastAPI container
+-- alembic.ini                         # Migration config
+-- docs/                               # mdbook documentation
|
+-- alembic/
|   +-- env.py
|   +-- versions/
|       +-- 001_initial.py
|
+-- src/
|   +-- kairos/
|       +-- __init__.py
|       +-- core/                       # Domain layer (no infra deps)
|       |   +-- __init__.py
|       |   +-- errors.py              # DomainError hierarchy
|       |   +-- entities/
|       |   |   +-- __init__.py
|       |   |   +-- job.py             # Job, JdAnalysis, Platform
|       |   |   +-- resume.py          # Resume, ResumeSection, TailoredResume
|       |   |   +-- application.py     # Application, ApplicationStatus
|       |   |   +-- user_profile.py    # UserProfile, Country
|       |   |   +-- search_criteria.py
|       |   |   +-- skill.py           # SkillEntry, SkillCategory
|       |   +-- interfaces/
|       |   |   +-- __init__.py
|       |   |   +-- job_repository.py
|       |   |   +-- resume_repository.py
|       |   |   +-- application_repository.py
|       |   |   +-- job_search_service.py
|       |   |   +-- jd_analysis_service.py
|       |   |   +-- resume_tailor_service.py
|       |   |   +-- application_service.py
|       |
|       +-- api/                        # FastAPI application
|       |   +-- __init__.py
|       |   +-- main.py                # App factory, lifespan
|       |   +-- config.py              # Settings (pydantic-settings)
|       |   +-- deps.py                # Dependency injection
|       |   +-- middleware/
|       |   |   +-- __init__.py
|       |   |   +-- auth.py            # API key / JWT auth
|       |   |   +-- envelope.py        # Response envelope wrapper
|       |   +-- routes/
|       |   |   +-- __init__.py
|       |   |   +-- jobs.py            # Job search, list, analyze
|       |   |   +-- resumes.py         # Resume import, tailor, export
|       |   |   +-- applications.py    # Application CRUD
|       |   |   +-- profile.py         # User profile + config
|       |   |   +-- health.py          # Health check
|       |   +-- ws/
|       |       +-- __init__.py
|       |       +-- handler.py         # WebSocket for LLM streaming
|       |
|       +-- platform/                   # Platform adapters
|       |   +-- __init__.py
|       |   +-- rate_limiter.py
|       |   +-- http_client.py
|       |   +-- seek/
|       |   |   +-- __init__.py
|       |   |   +-- client.py          # impl JobSearchService
|       |   |   +-- parser.py
|       |   +-- indeed/
|       |   |   +-- __init__.py
|       |   |   +-- client.py, parser.py
|       |   +-- linkedin/
|       |       +-- __init__.py
|       |       +-- client.py, parser.py
|       |
|       +-- llm/                        # LLM integration
|       |   +-- __init__.py
|       |   +-- analyzer.py            # impl JdAnalysisService
|       |   +-- tailor.py              # impl ResumeTailorService
|       |   +-- extractor.py           # impl SkillExtractorService
|       |   +-- prompts/
|       |       +-- __init__.py
|       |       +-- jd_analysis.py
|       |       +-- resume_tailoring.py
|       |       +-- skill_extraction.py
|       |
|       +-- db/                         # Persistence layer
|       |   +-- __init__.py
|       |   +-- models.py              # SQLAlchemy ORM models
|       |   +-- session.py             # Async session factory
|       |   +-- repositories/
|       |       +-- __init__.py
|       |       +-- job_repo.py
|       |       +-- resume_repo.py
|       |       +-- application_repo.py
|       |
|       +-- client/                     # Shared HTTP client library
|       |   +-- __init__.py
|       |   +-- client.py              # KairosClient (httpx-based)
|       |   +-- jobs.py
|       |   +-- resumes.py
|       |   +-- applications.py
|       |
|       +-- cli/                        # CLI (entry point: `kairos`)
|           +-- __init__.py
|           +-- main.py                # Typer app setup
|           +-- commands/
|           |   +-- __init__.py
|           |   +-- jobs.py            # search, list, analyze
|           |   +-- resumes.py         # import, tailor, export
|           |   +-- applications.py    # list, update status
|           |   +-- server.py          # start/stop server
|           +-- output.py              # Rich table/JSON formatting
|
+-- tests/
    +-- conftest.py                     # Fixtures (async DB session, test client)
    +-- test_core/
    +-- test_api/
    +-- test_platform/
    +-- test_llm/
    +-- test_db/
    +-- test_cli/

Module Dependency Graph

graph TD
    API[kairos.api] --> Core[kairos.core]
    API --> Platform[kairos.platform]
    API --> LLM[kairos.llm]
    API --> DB[kairos.db]

    Client[kairos.client] --> Core

    CLI[kairos.cli] --> Client
    CLI --> Core

    Platform --> Core
    LLM --> Core
    DB --> Core

    Client -.->|HTTP/WS| API

Design Principles

  1. kairos.core has zero infrastructure dependencies — only stdlib + Pydantic for entity definitions
  2. One concept per file — each file owns one class/ABC
  3. Interfaces in core, implementations in infrastructure — ports-and-adapters pattern
  4. All I/O is async — via asyncio (FastAPI, httpx, asyncpg, playwright)
  5. Error types per module — each module defines its own exception hierarchy

Entry Points

Defined in pyproject.toml:

[project.scripts]
kairos = "kairos.cli.main:app"
kairos-server = "kairos.api.main:run"