HR-ATS-Portal/backend/.env.example

128 lines
3.8 KiB
Bash

# Sole secrets / config file for the whole monorepo (app + backend + Compose).
# Copy to backend/.env and fill in. Never commit a filled .env.
#
# Compose: docker compose --env-file ./backend/.env up -d --build
# true → RDS over SSL (asyncpg). false → local Postgres over asyncpg (no SSH).
PROD_ENV=false
DB_USERNAME=postgres
DB_PASSWORD=
DB_HOST=localhost
DB_PORT=5432
DB_NAME=hrms
# Blank: require when PROD_ENV=true, off when local. Override only if needed.
DB_SSLMODE=
DB_AUTO_MIGRATE=true
DB_AUTOGENERATE=true
EMAIL_URL=
EMAIL_API_TOKEN=
# Optional overrides; blank falls back to EMAIL_URL / EMAIL_API_TOKEN.
CALENDAR_URL=
CALENDAR_API_TOKEN=
EMAIL_SYNC_FOLDER=inbox
EMAIL_SYNC_SINCE=
EMAIL_SYNC_CRON=* * * * *
JWT_SECRET_KEY=
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
JWT_RESET_TOKEN_EXPIRE_MINUTES=10
TEAMS_MAIL_API_URL=
TEAMS_API_TOKEN=
RESET_CODE_TTL_SECONDS=60
RESET_CODE_RESEND_SECONDS=30
RESET_CODE_MAX_ATTEMPTS=5
FRONTEND_URL=http://127.0.0.1:5173
CONFIRM_EMAIL_PATH=/auth/confirm-email
CONFIRM_TOKEN_TTL_SECONDS=86400
CONFIRM_TOKEN_RESEND_SECONDS=60
BUFFER_API=
BUFFER_API_URL=https://api.buffer.com
BUFFER_CHANNEL_ID=
# Talent sourcing via Apify (talent/). Token from console.apify.com → Settings →
# API & Integrations. APIFY_TOKEN is honoured as a fallback name for the token.
APIFY_API_TOKEN=
APIFY_API_BASE=https://api.apify.com/v2
APIFY_ACTOR_ID=harvestapi~linkedin-profile-search
# Hard per-run cap; client requests are clamped to it. "Full" mode costs
# $0.10 per search page + $0.004 per profile (~$0.20 for a 25-profile run).
APIFY_MAX_RESULTS=25
# Server-side spend ceiling per run (Apify maxTotalChargeUsd; minimum $0.10).
APIFY_MAX_COST_USD=1.0
# Own companies whose CURRENT employees must never appear in sourced results.
# Names feed the always-on server-side filter (case-insensitive substring);
# URLs feed the actor's excludeCurrentCompanies filter (full LinkedIn company
# URLs) so those profiles are not even scraped. Comma-separated.
APIFY_EXCLUDE_COMPANIES=Utopia Brands,Utopia Deals
APIFY_EXCLUDE_COMPANY_URLS=https://www.linkedin.com/company/utopiadeals,https://www.linkedin.com/company/utopia-brands-usa,https://www.linkedin.com/company/utopiabrands
# Short | Full | Full + email search
APIFY_PROFILE_MODE=Full
APIFY_TIMEOUT=30
OPENAI_API_KEY=
OPENAI_MODEL=gpt-5.4-mini
# Blank omits the parameter, for reasoning models that reject it.
OPENAI_TEMPERATURE=0
OPENAI_MAX_OUTPUT_TOKENS=4096
OPENAI_TIMEOUT=60
OPENAI_MAX_RETRIES=3
OPENAI_CONNECT_RETRIES=3
# Set only for Azure OpenAI or a gateway; blank uses api.openai.com.
OPENAI_BASE_URL=
OPENAI_ORGANIZATION=
OPENAI_PROJECT=
# ATS scoring (bulk-ats engine). Shared OPENAI_* names above.
OPENAI_EFFORT=low
OPENAI_ENABLE_PROMPT_CACHE=true
OPENAI_TIMEOUT_SECONDS=120
SCORING_CONCURRENCY=5
MAX_RESUMES_PER_REQUEST=50
MAX_PDF_SIZE_MB=10
MAX_JD_CHARS=30000
MAX_RESUME_CHARS=60000
# Inbox intake gate (inbox_classifier/).
INBOX_TRIAGE_ENABLED=true
INBOX_TRIAGE_FAIL_OPEN=true
INBOX_TRIAGE_CONCURRENCY=5
INBOX_TRIAGE_MAX_SUBJECT_CHARS=300
INBOX_TRIAGE_MAX_BODY_CHARS=4000
INBOX_TRIAGE_MIN_CONFIDENCE=0
# Compose overrides these on the network; keep docker DNS names for containers.
REDIS_URL=redis://redis:6379/0
BACKEND_URL=http://backend-api:8000
TASKIQ_QUEUE_NAME=inbox
TASKIQ_CV_QUEUE_NAME=cv_upload
TASKIQ_MAX_RETRIES=3
TASKIQ_RETRY_DELAY=5
TASKIQ_MAX_DELAY=120
TASKIQ_DLQ_STREAM=taskiq:dlq
TASKIQ_IDLE_TIMEOUT_MS=600000
MANUAL_UPLOAD_TO_ADDRESS=manual-cv-upload@hr-ats.local
APP_VERSION=dev
# Compose host ports (docker compose --env-file ./backend/.env …).
FRONTEND_PORT=5173
BACKEND_PORT=8000
ATS_PORT=8100
REDIS_PORT=6379
POSTGRES_PORT=5433
UVICORN_WORKERS=2
# Empty = same-origin via nginx on :5173. For Vite on the host, use
# VITE_API_BASE=http://127.0.0.1:8000 (backend is published on BACKEND_PORT).
VITE_API_BASE=
LOG_FORMAT=json
LOG_LEVEL=INFO