Production-ready AI-powered job aggregator with:
- Django REST backend (JWT auth, ingestion workers, assistant APIs)
- Next.js App Router frontend (jobs listing/detail/dashboard/auth)
Frontend (Next.js + TypeScript + Tailwind + Framer Motion)
|
v
Backend API (Django REST + JWT)
|
v
Service Layer (ingestion, ranking, assistant)
|
+--> MySQL (core data)
+--> Redis (Celery broker/result + optional cache)
+--> Meilisearch (optional search index)
Ingestion flow:
Celery Beat -> Redis Queue -> Celery Workers -> Normalize/Dedupe -> MySQL -> Meilisearch
- JWT auth with refresh tokens
- User profile support (
GET/PATCH /api/auth/me) - Job listing, detail, and search APIs
- Save job and application tracking APIs
- Hybrid ranking: Meilisearch + lexical + recency fallback
- AI assistant endpoints (job discovery, resume help, eligibility guidance)
- Compliant ingestion pipeline:
- API sources
- company/scraper sources (with
robots.txtchecks) - configurable request delays
- source attribution + dedupe (
title+company+location)
- Landing page
- Job listing page with filters, pagination, loading skeletons
- Job detail page with save/apply actions
- Dashboard with:
- saved jobs
- AI recommendations
- profile editor (headline/skills/bio/full name/resume URL)
- Auth pages (login/register)
- Protected dashboard redirect (
/dashboard-> login when unauthenticated)
POST /api/auth/registerPOST /api/auth/loginPOST /api/auth/refreshGET /api/auth/mePATCH /api/auth/me
GET /api/jobsGET /api/jobs/{id}GET /api/jobs/search
POST /api/jobs/savePOST /api/jobs/applyGET /api/user/saved
POST /api/assistant/chatGET /api/assistant/recommendations
career_aggregator/ Django settings + celery
api/ REST API serializers/views/urls
jobs/ Models, tasks, migrations, admin, seed command
services/ ingestion/search/assistant services
frontend/ Next.js App Router app
From project root:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
python manage.py migrate
python manage.py createsuperuser
python manage.py seed_sourcesRun backend:
python manage.py runserverRun workers (separate terminals):
celery -A career_aggregator worker -l info
celery -A career_aggregator beat -l infocd frontend
cp .env.local.example .env.local
npm install
npm run clean
npm run devOpen:
- Frontend:
http://127.0.0.1:3000 - Backend API:
http://127.0.0.1:8000/api
- DB:
DB_NAME,DB_USER,DB_PASSWORD,DB_HOST,DB_PORT - Redis/Celery:
REDIS_URL,CELERY_BROKER_URL,CELERY_RESULT_BACKEND - JWT:
JWT_ACCESS_MINUTES,JWT_REFRESH_DAYS - CORS/CSRF:
CORS_ALLOWED_ORIGINSCSRF_TRUSTED_ORIGINS
- Optional integrations:
MEILISEARCH_URL,MEILISEARCH_API_KEYOPENAI_API_KEY,OPENAI_MODEL
NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8000/api
After seed_sources, run one-shot API ingestion:
python manage.py shell -c "from jobs.models import Source, SourceType; from services.ingestion_service import ingest_api_source; [print(ingest_api_source(s)) for s in Source.objects.filter(type=SourceType.API, is_active=True)]"Then verify:
http://127.0.0.1:8000/api/jobshttp://127.0.0.1:8000/api/jobs/search?q=dev
- Ensure backend is running on
127.0.0.1:8000. - Check API directly in browser:
http://127.0.0.1:8000/api/jobs/search?q=dev. - Verify CORS vars in
.env:CORS_ALLOWED_ORIGINS=http://127.0.0.1:3000,http://localhost:3000CSRF_TRUSTED_ORIGINS=http://127.0.0.1:3000,http://localhost:3000
- Restart backend + frontend.
- Recommended Node runtime: 20.x.
frontend/package.jsonincludes engine constraints (>=20 <23).- If
nvmis unavailable, install/use Node 20 via your preferred version manager/package tool. - Clean and reinstall frontend deps:
cd frontend
rm -rf node_modules package-lock.json .next
npm install
npm run dev- No login-protected scraping
robots.txtchecks for company/scraper sources- Rate limiting between ingestion requests
- Source attribution always stored (
source,source_url) - Description stored as snippet (not full copied pages)
- Legacy Django template pages still exist from earlier iteration.
- Current product frontend is the
frontend/Next.js app. - Assistant uses OpenAI only when configured; otherwise uses deterministic fallback responses.