jobs-monorepo/shared/repo/job-description.go
Elshimy Ziad Magdy Taha 0ab6954231 feat: add job analysis infrastructure and Glassdoor support
- Added new job analysis result repository and database migration system
- Expanded job creation to support Glassdoor as a new provider alongside LinkedIn
- Added CV analysis service launch configuration in VS Code
- Updated Makefile with new commands for scraper service and migrations
- Improved environment loading in cron analyzer to support local development
- Added error handling for unsupported job providers
- Integrated job analysis results
2025-10-24 15:10:20 +05:00

87 lines
2.3 KiB
Go

package repo
import (
"database/sql"
"encoding/json"
"fmt"
"strings"
"github.com/jobs-scraper/shared/domain"
)
type JobDescriptionRepository struct {
db *sql.DB
}
type JobDescriptionData struct {
JobID int
Description string
Criteria map[string]string
}
func NewJobDescriptionRepository(db *sql.DB) *JobDescriptionRepository {
return &JobDescriptionRepository{db: db}
}
func (r *JobDescriptionRepository) SaveJobDescriptions(jobDescriptions []domain.JobDescription) error {
if len(jobDescriptions) == 0 {
return nil
}
// Build the VALUES clause dynamically
valueStrings := make([]string, 0, len(jobDescriptions))
valueArgs := make([]interface{}, 0, len(jobDescriptions)*3)
for i, jd := range jobDescriptions {
// Convert criteria map to JSONB
criteriaByte, err := json.Marshal(jd.Criteria)
if err != nil {
return fmt.Errorf("error marshaling job criteria for job %d: %v", jd.JobID, err)
}
valueStrings = append(valueStrings, fmt.Sprintf("($%d, $%d, $%d)", i*3+1, i*3+2, i*3+3))
valueArgs = append(valueArgs, jd.JobID, jd.Description, criteriaByte)
}
sqlStatement := fmt.Sprintf(`
INSERT INTO job_descriptions (job_id, description, job_criteria)
VALUES %s
ON CONFLICT (job_id) DO UPDATE SET
description = EXCLUDED.description,
job_criteria = EXCLUDED.job_criteria,
updated_at = CURRENT_TIMESTAMP
`, strings.Join(valueStrings, ","))
_, err := r.db.Exec(sqlStatement, valueArgs...)
if err != nil {
return fmt.Errorf("error saving job descriptions: %v", err)
}
return nil
}
func (r *JobDescriptionRepository) GetJobDescriptionByJobID(jobID int64) (string, map[string]string, error) {
var (
description string
criteriaByte []byte
criteria map[string]string
)
sqlStatement := `SELECT description, job_criteria FROM job_descriptions WHERE job_id = $1`
err := r.db.QueryRow(sqlStatement, jobID).Scan(&description, &criteriaByte)
if err != nil {
if err == sql.ErrNoRows {
return "", nil, nil // No description found
}
return "", nil, fmt.Errorf("error fetching job description: %v", err)
}
// Unmarshal the JSON criteria
if criteriaByte != nil {
if err := json.Unmarshal(criteriaByte, &criteria); err != nil {
return "", nil, fmt.Errorf("error unmarshaling job criteria: %v", err)
}
}
return description, criteria, nil
}