A comprehensive web application that helps job seekers optimize their CVs using AI technology. Upload your CV, add job descriptions, and get AI-generated sections tailored to specific job requirements.
- CV Upload & Parsing: Upload PDF, DOC, or DOCX files and extract structured data using AI
- User Authentication: Clerk-based authentication with JWT token verification (legacy JWT also supported)
- CV Editing: Interactive editor with drag-and-drop reordering and inline editing
- Job Description Integration: Add job descriptions via text input or URL with browser automation support
- AI-Enhanced Sections: Generate tailored "Why I'm a Good Fit" sections using OpenAI
- Real-time Preview: Live preview of CV changes in PDF-style layout
- Auto-save: Automatic saving of changes with version history
- Backend: FastAPI with SQLAlchemy ORM
- Frontend: React 18 with TypeScript and Material-UI
- Database: SQLite (development) / PostgreSQL (production)
- AI Integration: OpenAI GPT-4o-mini for CV parsing and content generation
- File Processing: PDF, DOC, DOCX text extraction
- Testing: Comprehensive test suite with 90%+ coverage
- Docker: Containerized deployment with Docker Compose
- Python 3.11+
- Node.js 18+
- Docker & Docker Compose (optional)
- OpenAI API key
git clone <repository-url>
cd cv_latorcd backend
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
cp env.example .env
# Edit .env with your configuration
# Initialize database
python src/database.py
# Run tests
python tests/run_tests.py
# Start development server
uvicorn main:app --reload --host 0.0.0.0 --port 8000cd frontend
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Edit .env with your configuration
# Run tests
npm test
# Start development server
npm run devLocal stack (Compose project cvlator-local: frontend on http://localhost:3000, backend 8000, PDF service 8001; images aligned with Cloudflare container builds). Prepare .env.prod (see repo root), then:
docker compose up -d --buildProduction: frontend on Cloudflare; API on AWS (Docker Compose + Nginx). See Deployment below.
Create a .env file in the backend directory:
# Database Configuration
DATABASE_URL=sqlite:///./cv_optimizer.db
# Auth & Security
DEV_MODE=true
JWT_SECRET_KEY=your-secret-key-here-change-in-production
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# Clerk Backend API (used to enrich user info)
# Obtain from Clerk Dashboard β API Keys β Secret Key (starts with sk_)
# Required to call Clerk Backend API (e.g., fetch user email/metadata).
# If omitted in local dev, the app will skip API calls and use placeholders.
CLERK_SECRET_KEY=sk_test_your_secret_key_from_clerk_dashboard
# Clerk JWT Verification (required in staging/production)
CLERK_VERIFY_TOKENS=true
CLERK_JWKS_URL=https://YOUR-CLERK-DOMAIN/.well-known/jwks.json
CLERK_ISSUER=https://YOUR-CLERK-DOMAIN
CLERK_AUDIENCE=YOUR_BACKEND_AUDIENCE
# OpenAI Configuration
OPENAI_API_KEY=your-openai-key-here
# Application Configuration
DEBUG=true
MAX_FILE_SIZE=10485760
ALLOWED_FILE_TYPES=application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document
CV_PARSE_WORKERS=2Notes:
- Local development: you can leave
CLERK_SECRET_KEYunset and either:- set
CLERK_VERIFY_TOKENS=falseto allow insecure decode bypass, or - provide the JWKS config (
CLERK_JWKS_URL,CLERK_ISSUER,CLERK_AUDIENCE) to verify tokens properly.
- set
- Staging/Production: set
CLERK_VERIFY_TOKENS=trueand configure JWKS variables; do not rely on the dev bypass. - When
CLERK_SECRET_KEYis not set, backend will not call Clerkβs API, avoiding 401 errors during local dev.
Create a .env file in the frontend directory:
VITE_API_BASE_URL=http://localhost:8000cd backend
python tests/run_tests.pycd frontend
npm test- Backend: 90%+ code coverage
- Frontend: 85%+ code coverage
- Integration tests for all API endpoints
- Unit tests for all services and components
Once the backend is running, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
POST /auth/register- Legacy user registration (Clerk is primary)POST /auth/login- Legacy user login (Clerk is primary)POST /auth/refresh- Refresh JWT token (legacy)POST /auth/logout- User logoutGET /auth/me- Get current user info (works with both Clerk and legacy JWT)
POST /api/cvs/- Upload CV fileGET /api/cvs/- List user's CVsGET /api/cvs/{cv_id}- Get specific CVPUT /api/cvs/{cv_id}- Update CV dataDELETE /api/cvs/{cv_id}- Delete CV
POST /api/cvs/{cv_id}/job-descriptions- Add job descriptionGET /api/cvs/{cv_id}/job-descriptions- Get job descriptionsDELETE /api/job-descriptions/{jd_id}- Delete job description
POST /api/cvs/{cv_id}/generate-section- Generate AI sectionGET /api/cvs/{cv_id}/ai-sections- Get AI-generated sections
backend/
βββ src/
β βββ api/ # API endpoints
β βββ models/ # Database models
β βββ services/ # Business logic
β βββ database.py # Database configuration
βββ tests/ # Test suite
βββ uploads/ # File storage
βββ main.py # Application entry point
frontend/
βββ src/
β βββ components/ # Reusable components
β βββ contexts/ # React contexts
β βββ pages/ # Page components
β βββ services/ # API services
β βββ App.tsx # Main application
βββ tests/ # Test suite
βββ public/ # Static assets
- Frontend: Cloudflare (static / Pages +
wrangler deployinfrontend/as before). - Backend API: AWS (e.g. Lightsail EC2): repo root
.env.prod, thendocker compose up -d --buildforbackend+pdf-serviceonly (same images as local: slimbackend/Dockerfile.wranglerfor the API,backend/Dockerfile.pdf-servicefor PDF/LaTeX). Nginx on the host terminates 80/443 and proxies to 127.0.0.1:8000. Pointapi.<domain>in Cloudflare DNS to the instance public IP (proxied A record); SSL mode Full (or Full strict with a Cloudflare origin cert on Nginx). - Database: managed PostgreSQL (
DATABASE_URLin.env.prod), not SQLite.
SSH (production API host): ssh ec2-user@3.139.146.5 β then e.g. cd ~/cv_lator && sudo docker compose logs -f backend
CI deploy: .github/workflows/deploy-backend-aws.yml checks out the repo, SCPs backend/ + docker-compose.yml to /home/ec2-user/cv_lator on the instance, then runs docker compose. Triggers: push to master (paths backend/**, docker-compose.yml, or this workflow) and workflow_dispatch. Secrets: AWS_SSH_HOST, AWS_SSH_USER, AWS_SSH_PRIVATE_KEY. CI does not upload .env.prod β the VPS must already have one (bootstrap once), unless you overwrite it locally.
Laptop backend deploy: ./scripts/deploy-backend-ec2.sh (repo root) rsyncs backend/, docker-compose.yml, and ./.env.prod from this machine (DEPLOY_ENV_FILE overrides) to the VPS, then runs the same Compose target as CI β or ./scripts/deploy-backend-ec2.sh --env-only to rsync ./.env.prod alone and --force-recreate services. See .cursor/commands/deploy.md.
- Clerk authentication with JWT token verification (JWKS support)
- Legacy JWT authentication with refresh tokens (backward compatibility)
- Password hashing with bcrypt (legacy accounts)
- File type validation and size limits
- CORS configuration
- Input validation and sanitization
- SQL injection prevention via ORM
- XSS protection
- Admin impersonation with audit logging
- API response times: < 200ms (95th percentile)
- File upload: < 5 seconds for 10MB files
- AI generation: < 30 seconds
- Page load: < 2 seconds
- Supports 1000+ concurrent users
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For support and questions:
- Create an issue in the repository
- Check the API documentation
- Review the test cases for usage examples
- Initial release with full MVP functionality
- Complete CV upload and parsing
- AI-powered content generation
- Comprehensive test suite
- Docker support
- Production-ready deployment
- Multiple CV templates
- PDF export functionality
- CV analytics and insights
- Team collaboration features
- Advanced AI customization
- Multi-language support
- Caching layer (Redis)
- Message queue for AI processing
- CDN for static assets
- Database optimization
- Microservices architecture
Built with β€οΈ using FastAPI, React, and OpenAI