A backend service that automates the initial screening of job applications using AI evaluation. The system evaluates candidate CV and project reports against job descriptions and case study briefs, producing structured evaluation reports through LLM driven analysis.
This service provides automated candidate evaluation by:
- Accepting candidate CV and project report submissions
- Evaluating documents against job requirements and scoring rubrics
- Using Retrieval Augmented Generation (RAG) for context evaluation
- Generating structured feedback with match scores and recommendations
- Processing evaluations asynchronously with a job queue system
The backend follows clean architecture principles with clear separation of concerns:
internal/
├── domain/ # entities and repository interfaces
├── repository/ # database access impl
├── usecase/ # business logic
├── service/ # external service integrations (LLM, PDF, embeddings)
└── handler/ # HTTP request handlers
- Echo (Web Framework Go)
- PostgreSQL (DB with pgvector extension)
- GORM (ORM)
- Gemini API (LLM Provider)
- PDF (PDF Processing)
- Viper (Configuration)
- Docker Compose (Containerization)
- Go 1.25 or higher
- PostgreSQL 16 with pgvector extension
- Google Gemini API key
- Make (optional)
Clone the repository:
git clone https://github.com/sawalreverr/cv-reviewer.git
cd cv-reviewerInstall dependencies:
go mod downloadSet up PostgreSQL with pgvector:
docker-compose up -dConfigure environment variables:
cp .env.example .envRun database migrations:
make migrate
# drop all tables
make migrate flag=-drop
# or run manually (if doesnt have make)
go run scripts/migration/ migrate.go # -drop, if neededPrepare system documents in /docs/ directory:
job_description.pdf- job descriptionscase_study_brief.pdf- case study brief documentcv_scoring_rubric.pdf- cv evaluation criteriaproject_scoring_rubric.pdf- project evaluation criteria
Ingest system documents into vector database:
make ingest
# or run manually (if doesnt have make)
go run scripts/ingestion/ingest_docs.goStart the server:
make run
# or run manually (if doesnt have make)
go run cmd/api/main.goThe API will be available at http://localhost:8080
Ensuring the API is running
GET /health
Response:
{
"success": true,
"data": {
"status": "ok",
"message": "api is running"
}
}POST /upload
Content-Type: multipart/form-data
Form fields:
cv(file): candidate CV in PDFproject_report(file): candidate project report in PDF
Response:
{
"success": true,
"message": "documents uploaded successfully",
"data": {
"cv_id": "uuid",
"project_report_id": "uuid"
}
}POST /evaluate
Content-Type: application/json
Request body:
{
"job_title": "Backend Developer",
"cv_id": "uuid",
"project_report_id": "uuid"
}Response:
{
"success": true,
"message": "evaluation job created",
"data": {
"id": "uuid",
"status": "queued"
}
}GET /result/{job_id}
Response (while processing):
{
"success": true,
"data": {
"id": "uuid",
"status": "processing"
}
}Response (completed):
{
"success": true,
"data": {
"id": "uuid",
"status": "completed",
"result": {
"cv_match_rate": 0.82,
"cv_feedback": "Strong in backend and cloud, limited AI integration experience...",
"project_score": 4.5,
"project_feedback": "Meets prompt chaining requirements, lacks error handling robustness...",
"overall_summary": "Good candidate fit, would benefit from deeper RAG knowledge..."
}
}
}The evaluation process consists of three main stages:
- Extracts text from candidate CV
- Retrieves relevant job description context using vector similarity search
- Retrieves CV scoring rubric criteria
- Uses LLM to generate match rate (0-1 scale) and feedback
- Extracts text from project report
- Retrieves relevant case study brief context
- Retrieves project scoring rubric criteria
- Uses LLM to generate score (1-5 scale) and feedback
- Synthesizes CV and project evaluations
- Generates holistic candidate assessment
- Provides hiring recommendation
Example workflow:
curl -X POST http://localhost:8080/upload \
-F "cv=@/path/to/cv.pdf" \
-F "project_report=@/path/to/report.pdf"curl -X POST http://localhost:8080/evaluate \
-H "Content-Type: application/json" \
-d '{
"job_title": "Backend Developer",
"cv_id": "cv-uuid",
"project_report_id": "report-uuid"
}'curl http://localhost:8080/result/{job_id}{
"success": false,
"message": "invalid file type, only pdf allowed",
"error": "invalid file type, only PDF allowed"
}{
"success": false,
"message": "cv or project report document not found",
"error": "resource not found"
}{
"success": false,
"message": "job queue is full, please try again later",
"error": "job queue is full"
}