package handlers import ( "encoding/json" "io" "net/http" "git.gophernest.net/azpect/ResumeLens/internal/models" "git.gophernest.net/azpect/ResumeLens/internal/services" ) var analyzeResume = func(resume io.Reader, jobDescription string) (*models.AnalysisResult, error) { return services.AnalyzeResume(resume, jobDescription) } func SetAnalyzeResumeForTesting(fn func(io.Reader, string) (*models.AnalysisResult, error)) func() { prev := analyzeResume analyzeResume = fn return func() { analyzeResume = prev } } // Analyze handles POST /api/analyze. // It expects a multipart form with: // - "resume" — the uploaded resume file (PDF) // - "job_description" — the job description as plain text // // Trace: SDD_LLD_0005 - Provide HTTP handler and endpoint for multipart/form data uploads // Trace: SDD_HLD_0001 - Accept PDF resume input // Trace: SDD_HLD_0004 - Accept job description in textbox func Analyze(w http.ResponseWriter, r *http.Request) { r.Body = http.MaxBytesReader(w, r.Body, 10<<20) // Trace: SDD_LLD_0005 - Accept multipart/form data uploads from frontend if err := r.ParseMultipartForm(10 << 20); err != nil { http.Error(w, "failed to parse form", http.StatusBadRequest) return } // Trace: SDD_HLD_0001 - Accept PDF resume input file, _, err := r.FormFile("resume") if err != nil { http.Error(w, "missing resume file", http.StatusBadRequest) return } defer file.Close() // Trace: SDD_HLD_0004 - Read string of text from textbox // Trace: SDD_LLD_0021 - Accept textual job description input jobDescription := r.FormValue("job_description") if jobDescription == "" { http.Error(w, "missing job_description", http.StatusBadRequest) return } // Trace: SDD_HLD_0005 - Provide structured inputs to AI grader result, err := analyzeResume(file, jobDescription) if err != nil { // Trace: SDD_LLD_0013 - Handle API failures and error responses http.Error(w, "analysis failed: "+err.Error(), http.StatusInternalServerError) return } // Trace: SDD_LLD_0019 - Support JSON output w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(result) }