122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package cron
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"log"
|
|
"os"
|
|
|
|
"github.com/jobs-scraper/infrastructure/rabbitmq"
|
|
"github.com/jobs-scraper/internal/domain"
|
|
"github.com/jobs-scraper/internal/repo"
|
|
"github.com/jobs-scraper/internal/services"
|
|
)
|
|
|
|
type JobAnalyzer struct {
|
|
db *sql.DB
|
|
jobRepo *repo.JobRepository
|
|
jobDescriptionRepo *repo.JobDescriptionRepository
|
|
openRouterService services.OpenRouterService
|
|
rmq *rabbitmq.RabbitMQClient
|
|
}
|
|
|
|
func NewJobAnalyzer(db *sql.DB) *JobAnalyzer {
|
|
apiKey := os.Getenv("OPENROUTER_API_KEY")
|
|
model := os.Getenv("CV_AI_MODEL")
|
|
|
|
jobRepo := repo.NewJobRepository(db)
|
|
jobDescriptionRepo := repo.NewJobDescriptionRepository(db)
|
|
openRouterService := services.NewOpenRouterService(model, apiKey)
|
|
|
|
rmq, err := rabbitmq.NewRabbitMQClient()
|
|
if err != nil {
|
|
log.Printf("Warning: Failed to create RabbitMQ client: %v", err)
|
|
}
|
|
|
|
return &JobAnalyzer{
|
|
db: db,
|
|
jobRepo: jobRepo,
|
|
jobDescriptionRepo: jobDescriptionRepo,
|
|
openRouterService: openRouterService,
|
|
rmq: rmq,
|
|
}
|
|
}
|
|
|
|
func (ja *JobAnalyzer) AnalyzeJobs() error {
|
|
// Get jobs that need analysis (status = created)
|
|
jobs, err := ja.jobRepo.GetJobsByStatus(domain.JobStatusCreated)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("Found %d jobs to analyze", len(jobs))
|
|
|
|
// Read CV file
|
|
cv, err := os.ReadFile("cv.txt")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, job := range jobs {
|
|
if err := ja.analyzeJob(job, string(cv)); err != nil {
|
|
log.Printf("Error analyzing job %d: %v", job.ID, err)
|
|
// Update job status to error
|
|
if updateErr := ja.jobRepo.UpdateJobStatus(job.ID, domain.JobStatusError); updateErr != nil {
|
|
log.Printf("Error updating job status to error: %v", updateErr)
|
|
}
|
|
continue
|
|
}
|
|
|
|
// Update job status to analyzed
|
|
if err := ja.jobRepo.UpdateJobStatus(job.ID, domain.JobStatusAnalyzed); err != nil {
|
|
log.Printf("Error updating job status to analyzed: %v", err)
|
|
}
|
|
|
|
log.Printf("Successfully analyzed job %d", job.ID)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ja *JobAnalyzer) analyzeJob(job domain.Job, cv string) error {
|
|
// Get job description
|
|
jobDescription, jobCriteria, err := ja.jobDescriptionRepo.GetJobDescriptionByJobID(job.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Analyze job with CV
|
|
result, err := ja.openRouterService.AnalyzeJobDescription(cv, domain.JobDescription{
|
|
JobID: job.ID,
|
|
Description: jobDescription,
|
|
Criteria: jobCriteria,
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("Analysis result for job %d: Recommendation=%s, Score=%d", job.ID, result.Recommendation, result.ConfidenceScore)
|
|
|
|
// Publish CV analysis message to RabbitMQ if available
|
|
if ja.rmq != nil {
|
|
message := rabbitmq.CvAnalyzeMessage{
|
|
JobID: job.ID,
|
|
}
|
|
|
|
if err := ja.publishCvAnalysisMessage(message); err != nil {
|
|
log.Printf("Warning: Failed to publish CV analysis message: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ja *JobAnalyzer) publishCvAnalysisMessage(message rabbitmq.CvAnalyzeMessage) error {
|
|
data, err := json.Marshal(message)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return ja.rmq.Publish(rabbitmq.CvAnalyzeQueue, rabbitmq.CvAnalyzeExchange, data)
|
|
}
|