Production-grade backend for Hotel GM resume matching with a minimal commercial UI for end-to-end operation.
- Backend API + worker (FastAPI + RQ)
- Resume ingestion pipeline (PDF/DOCX/TXT)
- Semantic matching + deterministic structured ranking
- Top-25 ranked shortlist output
- SaaS-style frontend (Next.js) for:
- workspace API-key entry
- ingestion uploads + status monitoring
- match execution + ranked results
- recent match history
app/: backend API, services, infrastructure adaptersworker/: asynchronous ingestion workermigrations/: Alembic schema migrationsfrontend/: Next.js TypeScript SaaS UIdocker/: Dockerfiles for API, worker, frontenddocker-compose.yml: full local stack orchestrationrender.yaml: Render deployment blueprint (free tier)
- Ensure Docker is running.
- Start all services:
docker compose up --build -d- Open:
- UI:
http://localhost:3000 - API:
http://localhost:8000
- In UI landing screen:
- API Base URL:
http://localhost:8000 - Workspace API Key:
change-me(or your configuredAPI_KEY)
GET /healthPOST /resumes:ingestGET /resumes/{resume_id}GET /ingestion/{ingestion_job_id}POST /matchGET /match/{job_id}GET /matches/recentGET /dashboard/summary
Protected endpoints use header:
X-API-Key: <API_KEY>
Backend (.env from .env.example):
API_KEYDATABASE_URLREDIS_URLEMBEDDINGS_PROVIDER=local|openaiOPENAI_API_KEY(optional)CORS_ALLOW_ORIGINS(comma-separated, include UI URL)
Frontend (frontend/.env.local):
NEXT_PUBLIC_API_BASE_URL(defaulthttp://localhost:8000)NEXT_PUBLIC_API_KEY(optional prefill only; prefer entering at runtime)
render.yaml includes:
- API web service (
docker/Dockerfile.api) - Worker service (
docker/Dockerfile.worker) - Frontend web service (
docker/Dockerfile.frontend) - Free Postgres + free Key Value
Required checks after deploy:
- Set API
CORS_ALLOW_ORIGINSto include frontend Render URL. - Set frontend
NEXT_PUBLIC_API_BASE_URLto API public URL. - Validate flow: upload resume -> status completes -> run match -> open result details.
docker compose psshows all servicesUp- UI dashboard loads stats from
/dashboard/summary - Ingestion page transitions statuses to
COMPLETED - Match page returns ranked candidates and result detail view