# Copy to `.env` at the repo root for Compose variable substitution. # Secrets for the app itself still live in `backend/.env` (see backend/.env.example). # Never commit a filled `.env`. # --- Compose / production stack ---------------------------------------------------- # Used by docker-compose.yml for the container Postgres and frontend publish port. DB_USERNAME=postgres DB_PASSWORD=change-me-strong-password DB_NAME=hrms # Public SPA port only (production). Dev overlay defaults FRONTEND_PORT to 5173. FRONTEND_PORT=80 # API workers behind nginx (production backend-api command). UVICORN_WORKERS=2 # Schema sync on API startup (docker compose up -d --build). # true = upgrade (if any on-disk revisions) + apply model drift in-memory. # Revision .py files stay gitignored and are not written on the server. DB_AUTO_MIGRATE=true DB_AUTOGENERATE=true # Empty = same-origin fetches; frontend nginx proxies to backend-api. # Set only when the API is intentionally on another origin. VITE_API_BASE= # Optional: override mail service URL for containers (else host.docker.internal:5000). # EMAIL_URL=http://host.docker.internal:5000 # Optional: point containers at host Postgres instead of Compose postgres # (also set by docker-compose.dev.yml). # DB_HOST=host.docker.internal # --- Bulk ATS scoring engine (also read by ats-engine / backend) -------------------- OPENAI_API_KEY= # Must be a structured-outputs model family: gpt-5*, gpt-4.1*, o3*, o4*. # "-chat-latest" variants are rejected -- they track the ChatGPT product surface and # do not expose reasoning effort. # Note gpt-4.1 is allowed but is not a reasoning model, so OPENAI_EFFORT is ignored # for it (the adapter omits the parameter rather than sending a 400). OPENAI_MODEL=gpt-5.4-mini # Covers reasoning tokens AND the visible response on a reasoning model. Too low and # the JSON truncates mid-object, failing the candidate with MODEL_RESPONSE_INVALID. # Enforced floor is 2048. Do not lower this to save cost -- lower OPENAI_EFFORT. OPENAI_MAX_OUTPUT_TOKENS=4000 # none | minimal | low | medium | high | xhigh OPENAI_EFFORT=low OPENAI_MAX_RETRIES=3 OPENAI_TIMEOUT_SECONDS=120 # OpenAI prompt caching is automatic and cannot be turned off. This only controls # whether a prompt_cache_key routing hint is sent to raise the cache hit rate. OPENAI_ENABLE_PROMPT_CACHE=true SCORING_CONCURRENCY=5 MAX_RESUMES_PER_REQUEST=50 MAX_PDF_SIZE_MB=10 MAX_JD_CHARS=30000 MAX_RESUME_CHARS=60000 # text | json LOG_FORMAT=json LOG_LEVEL=INFO