2026-04-07 12:26:22 -07:00

4.7 KiB

ResumeLens Development Skill

Use this skill when building or modifying features in the ResumeLens application.

Project at a glance

  • Stack: Go backend (chi router) + React 19 + TypeScript + Vite frontend.
  • Core purpose: accept a resume PDF and job description, call OpenAI, and return structured scoring + feedback.
  • Backend entrypoint: cmd/server/main.go.
  • Frontend entrypoint: web/src/main.tsx.
  • API endpoint: POST /api/analyze.

Repository map

  • cmd/server/main.go: starts HTTP server on :3000, mounts middleware and API routes.
  • internal/api/: CORS + rate-limit middleware and route mounting.
  • internal/handlers/analyze.go: multipart request validation + JSON response.
  • internal/services/analyzer.go: PDF text extraction + OpenAI call + JSON parsing.
  • internal/services/prompt.go: system prompt contract for LLM output.
  • internal/models/analysis.go: canonical backend response schema.
  • web/src/pages/: app routes (/, /upload, /demo, /results).
  • web/src/components/analysis/: reusable result UI sections.
  • web/src/types/resumeAnalysis.ts: frontend schema mirror of backend response.
  • docker-compose.yml: local multi-container runtime (backend + frontend at :3005).

Local development workflow

Backend

  • Run: go run ./cmd/server
  • Test: go test ./...
  • Backend listens on http://localhost:3000.

Frontend

  • Install deps: cd web && npm ci
  • Dev server: cd web && npm run dev
  • Build: cd web && npm run build
  • Lint: cd web && npm run lint

Full stack with Docker

  • Run: docker compose up --build
  • Frontend served at http://localhost:3005
  • Nginx proxies /api/* to backend service (web/nginx.conf).

Configuration and env vars

  • Backend requires OPENAI_API_KEY.
  • Frontend optionally uses VITE_API_BASE_URL.
    • If unset: dev defaults to http://localhost:3000.
    • If production build: defaults to relative path (/api/...) for nginx proxying.

Do not hardcode keys or expose secrets in client code.

API contract (critical)

POST /api/analyze expects multipart/form-data:

  • resume: uploaded file (backend expects a parseable PDF).
  • job_description: non-empty string.

Responses:

  • 200: JSON matching AnalysisResult / ResumeAnalysisResult.
  • 400: invalid form payload (missing file/job description).
  • 429: per-IP rate limit exceeded.
  • 500: analysis failure (PDF parse issue, OpenAI issue, JSON parse issue).

Keep backend model and frontend type definitions synchronized whenever fields change.

Existing behavior to preserve

  • Rate limiting is in-memory and per source IP: max 10 requests/hour.
  • CORS currently allows:
    • http://localhost:5173
    • http://localhost
    • http://localhost:80
  • Results page depends on router state; direct navigation to /results redirects to /.
  • Download JSON action exists on results page.
  • Prompt injection output fields are supported in both backend and frontend:
    • injection_detected
    • injection_details

LLM integration details

  • LLM call uses openai-go chat completions with model gpt-4o-mini.
  • System prompt in internal/services/prompt.go requires strict JSON-only output.
  • Parsing is strict JSON unmarshal into models.AnalysisResult.

When adding fields:

  1. Update internal/models/analysis.go.
  2. Update prompt JSON contract in internal/services/prompt.go.
  3. Update web/src/types/resumeAnalysis.ts.
  4. Update UI components in web/src/components/analysis/ and pages consuming the data.

Known implementation quirks

  • Upload UI currently accepts files with MIME image/* in handleFileSelect, but the file input element only allows .pdf, and backend parser expects PDF bytes.
  • PDF extraction buffers full file in memory before parsing (io.ReadAll), so large-file behavior should be considered when adding limits.
  • Current rate limiter is process-local; scaling to multiple backend replicas will need shared storage.

Feature development checklist

When implementing a new feature, follow this order:

  1. Define data contract impact first (backend model + frontend type).
  2. Update API handler/service behavior.
  3. Update UI and route behavior.
  4. Add or update tests (go test ./...; frontend lint/build).
  5. Validate end-to-end flow with one manual upload + analyze run.

Validation commands before shipping

  • Backend tests: go test ./...
  • Frontend checks: cd web && npm run lint && npm run build
  • Optional full-stack smoke test: docker compose up --build

Deployment notes

  • CI workflow (.github/workflows/deploy.yml) builds and pushes backend/frontend images on pushes to master.
  • Manual image commands are documented in DEPLOY.md.

If you add runtime dependencies or env vars, update:

  • Dockerfiles
  • docker-compose.yml
  • CI workflow
  • this skill file