kairos/
+-- Cargo.toml # Workspace root
+-- config.example.toml
+-- docs/ # mdbook documentation
|
+-- crates/
+-- kairos-client/ # Library: shared HTTP client
| +-- Cargo.toml
| +-- src/
| +-- lib.rs
| +-- error.rs # Client errors
| +-- client.rs # KairosClient (reqwest-based)
| +-- jobs.rs # Job endpoints
| +-- resumes.rs # Resume endpoints
| +-- applications.rs # Application endpoints
| +-- ws.rs # WebSocket client for streaming
|
+-- kairos-core/ # Domain layer (no external deps)
| +-- Cargo.toml
| +-- src/
| +-- lib.rs
| +-- error.rs # DomainError (thiserror)
| +-- entity/
| | +-- mod.rs
| | +-- job.rs # Job, JdAnalysis, Platform
| | +-- resume.rs # Resume, ResumeSection, TailoredResume
| | +-- application.rs # Application, ApplicationStatus
| | +-- user_profile.rs # UserProfile, Country
| | +-- search_criteria.rs
| +-- repository/
| | +-- mod.rs
| | +-- job_repository.rs
| | +-- resume_repository.rs
| | +-- application_repository.rs
| +-- service/
| +-- mod.rs
| +-- job_search_service.rs
| +-- jd_analysis_service.rs
| +-- resume_tailor_service.rs
| +-- application_service.rs
|
+-- kairos-platform/ # Platform adapters
| +-- Cargo.toml
| +-- src/
| +-- lib.rs
| +-- error.rs
| +-- rate_limiter.rs
| +-- http_client.rs
| +-- seek/
| | +-- mod.rs
| | +-- client.rs # impl JobSearchService
| | +-- parser.rs
| | +-- types.rs
| +-- indeed/
| | +-- mod.rs, client.rs, parser.rs, types.rs
| +-- linkedin/
| +-- mod.rs, client.rs, parser.rs, types.rs
|
+-- kairos-llm/ # LLM integration
| +-- Cargo.toml
| +-- src/
| +-- lib.rs
| +-- error.rs
| +-- analyzer.rs # impl JdAnalysisService
| +-- tailor.rs # impl ResumeTailorService
| +-- prompt/
| +-- mod.rs
| +-- jd_analysis.rs
| +-- resume_tailoring.rs
|
+-- kairos-db/ # Persistence layer
| +-- Cargo.toml
| +-- migrations/
| | +-- V1__initial.sql
| +-- src/
| +-- lib.rs
| +-- error.rs
| +-- repository/
| +-- mod.rs
| +-- sqlite_job_repo.rs
| +-- sqlite_resume_repo.rs
| +-- sqlite_application_repo.rs
|
+-- kairos-api/ # HTTP API server
| +-- Cargo.toml
| +-- src/
| +-- main.rs # Entry point, server startup
| +-- config.rs # API server config
| +-- error.rs # HTTP error mapping
| +-- middleware/
| | +-- mod.rs
| | +-- auth.rs # API key / JWT auth
| | +-- envelope.rs # Response envelope wrapper
| +-- routes/
| | +-- mod.rs
| | +-- jobs.rs # Job search, list, analyze
| | +-- resumes.rs # Resume import, tailor, export
| | +-- applications.rs # Application CRUD
| | +-- profile.rs # User profile + config
| | +-- health.rs # Health check
| +-- ws/
| +-- mod.rs
| +-- handler.rs # WebSocket for LLM streaming
|
+-- kairos-cli/ # Command-line HTTP client (binary: `kairos`)
+-- Cargo.toml
+-- src/
+-- main.rs # Entry point, clap setup
+-- commands/
| +-- mod.rs
| +-- jobs.rs # search, list, analyze
| +-- resumes.rs # import, tailor, export
| +-- applications.rs # list, update status
| +-- server.rs # start/stop server
+-- output.rs # Table/JSON output formatting
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
kairos-core has zero infrastructure dependencies — only thiserror, chrono, uuid, serde, async-trait
- One concept per file — each file owns one struct/trait
- Traits in core, implementations in infrastructure — ports-and-adapters pattern
- All I/O is async — via tokio
- Error types per crate — each crate has its own
error.rs with thiserror