A full-stack Applicant Tracking System (ATS) built for small-to-medium businesses. This workshop application demonstrates modern web development practices using Python FastAPI, MongoDB, and React.
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, TailwindCSS, React Router |
| Backend | Python FastAPI, Motor (async MongoDB driver) |
| Database | MongoDB (local) / AWS DocumentDB (production) |
| Auth | JWT (access + refresh tokens), bcrypt password hashing |
| File Storage | Local uploads / AWS S3 |
| AWS SES | |
| Messaging | AWS SQS + SNS |
| Cache | Redis / AWS ElastiCache |
| Deployment | Docker, AWS ECS Fargate, CloudFormation |
citi-workshop/
├── backend/ # FastAPI backend application
│ ├── app/
│ │ ├── api/v1/routes/ # API route handlers
│ │ ├── core/ # Config, security, database
│ │ ├── models/ # Data models
│ │ ├── schemas/ # Pydantic request/response schemas
│ │ ├── services/ # Business logic layer
│ │ ├── middleware/ # Logging, rate limiting
│ │ └── utils/ # Helpers, validators
│ └── tests/ # Unit and e2e tests
├── frontend/ # React frontend application
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Page components
│ │ ├── services/ # API service layer
│ │ ├── context/ # React context (auth)
│ │ ├── hooks/ # Custom hooks
│ │ └── utils/ # Constants, formatters
│ └── tests/ # Unit and e2e tests
├── docs/ # Design & architecture documentation
├── scripts/ # Database, deployment, setup scripts
├── infra/ # CloudFormation, Docker configs
│ ├── cloudformation/ # AWS infrastructure templates
│ └── docker/ # Dockerfiles, nginx config
└── docker-compose.yml # Local development environment
- Docker & Docker Compose
- Python 3.11+
- Node.js 20+
- MongoDB (or use Docker)
# 1. Clone and enter project
cd citi-workshop
# 2. Run the setup script
chmod +x scripts/setup-local.sh
./scripts/setup-local.sh
# OR manually:
# 3. Start infrastructure services
docker-compose up -d mongodb redis
# 4. Backend setup
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.sample .env # Edit as needed
# 5. Initialize database and seed data
cd ../scripts
pip install -r requirements.txt
python init_db.py
python seed_data.py
# 6. Start backend
cd ../backend
uvicorn app.main:app --reload --port 8000
# 7. Frontend setup (new terminal)
cd frontend
npm install
cp .env.sample .env
npm run dev- Frontend: http://localhost:5173
- Backend API: http://localhost:8000
- API Docs (Swagger): http://localhost:8000/docs
- API Docs (ReDoc): http://localhost:8000/redoc
The project includes a comprehensive demo dataset for live demonstrations. After running the setup, load it with:
cd scripts
source ../backend/.venv/bin/activate
echo "yes" | python3 seed_demo_data.pyThis replaces any existing data with a rich, interconnected dataset designed for walkthroughs.
| Resource | Detail | Value |
|---|---|---|
| DocumentDB | Endpoint | smarthire-dev.cluster-chueiwozbnfz.us-east-1.docdb.amazonaws.com:27017 |
| Username | smarthire_admin |
|
| Password | SmartHire2024 |
|
| Database | smarthire |
|
| Valkey (Redis) | Endpoint | stveo0ktmbgsn45.przn1r.ng.0001.use1.cache.amazonaws.com:6379 |
| ECR Repository | URI | 367484709954.dkr.ecr.us-east-1.amazonaws.com/smarthire-dev-backend |
| Service | URL |
|---|---|
| Frontend | https://smarthire.revaturelabs.com |
| Backend API | https://smarthire-api.revaturelabs.com/api/v1 |
| Swagger Docs | https://smarthire-api.revaturelabs.com/docs |
| Health Check | https://smarthire-api.revaturelabs.com/api/v1/health |
All accounts use the password: Password123!
| Role | Permissions | |
|---|---|---|
| Admin | admin@smarthire.com |
Full system access, user management |
| HR Manager | hr.manager@smarthire.com |
Job approval, offer management, hiring decisions |
| Recruiter 1 | recruiter1@smarthire.com |
Source candidates, manage pipeline, schedule interviews |
| Recruiter 2 | recruiter2@smarthire.com |
Source candidates, manage pipeline, schedule interviews |
| Interviewer 1 | interviewer1@smarthire.com |
Conduct interviews, submit feedback and ratings |
| Interviewer 2 | interviewer2@smarthire.com |
Conduct interviews, submit feedback and ratings |
| Interviewer 3 | interviewer3@smarthire.com |
Conduct interviews, submit feedback and ratings |
| Collection | Count | Breakdown |
|---|---|---|
| Users | 7 | 1 admin, 1 HR manager, 2 recruiters, 3 interviewers |
| Jobs | 8 | 4 open, 1 on_hold, 1 draft, 2 closed |
| Candidates | 15 | Engineering, Product, Design, Data, QA backgrounds |
| Applications | 22 | 6 applied, 4 screening, 5 interview, 2 offer, 1 hired, 4 rejected |
| Interviews | 14 | 9 completed (with feedback), 4 scheduled (upcoming), 1 cancelled |
Use these scenarios to walk students through the complete ATS workflow. Each scenario highlights different features and real-world hiring patterns.
Login as: hr.manager@smarthire.com
The dashboard shows a bird's-eye view of the entire hiring operation:
- Jobs by Status — 4 open positions actively hiring, 1 on hold (budget freeze), 1 draft (pending approval), 2 closed (filled or cancelled)
- Application Pipeline — 22 applications distributed across all 6 stages (applied, screening, interview, offer, hired, rejected), showing a healthy funnel
- Today's Interviews — Upcoming interviews scheduled for the near future
- Recent Applications — Latest candidates entering the pipeline
Teaching points: Real-time aggregation queries, MongoDB aggregation pipelines, dashboard as a decision-making tool for HR leadership.
Login as: recruiter1@smarthire.com
Navigate to Jobs > QA Automation Engineer (closed). Then view its applications.
Liam O'Connor completed the full pipeline for this role:
| Stage | What Happened |
|---|---|
| Applied | Applied via LinkedIn |
| Screening | Strong automation background (pytest + Playwright) |
| Interview | Live coding was impressive; solid CI/CD knowledge |
| Offer | $130K offered, accepted same day |
| Hired | Started March 1st, background check cleared |
His interview with Sarah Thompson (interviewer2) has detailed feedback: "Live-coded a Playwright test suite for our login flow. Clean, maintainable code with good error handling."
Teaching points: End-to-end hiring workflow, stage history tracking, how feedback flows from interviews to hiring decisions, the hired terminal status.
Login as: recruiter1@smarthire.com
Navigate to Jobs > Senior Backend Engineer (open). This role has the most active pipeline with 7 applicants at different stages:
| Candidate | Status | Story |
|---|---|---|
| Sofia Martinez (Netflix, 8 yrs) | Offer | Top candidate. Scored 5/5 on all interviews. Offer extended at $195K + equity. Awaiting response. |
| Raj Gupta (Google, 9 yrs) | Interview | Dream candidate. Technical interview tomorrow. Also cross-applied to PM role. |
| James Wilson (Stripe, 7 yrs) | Interview | Passed phone screen + technical. Hiring manager round scheduled in 3 days. |
| Michael Brown (Salesforce, 6 yrs) | Screening | Good Java/Spring background. Evaluating Python proficiency. |
| Olivia Taylor (Twilio, 4 yrs) | Applied | Just applied 3 days ago. Promising but junior. |
| Alex Rivera (Capital One, 6 yrs) | Applied | Cross-applied from Data Engineer role. Reviewing fit. |
| Jessica Kim (Snap, 3 yrs) | Rejected | Only 3 years experience, below the 5-year minimum. Encouraged to reapply later. |
Teaching points: Competitive hiring (multiple candidates for one role), pipeline management, rejection with constructive feedback, cross-applications (Raj applied to 2 roles), salary negotiation context in stage notes.
Login as: interviewer1@smarthire.com (Marcus Johnson)
Navigate to Interviews. Marcus has conducted several interviews with detailed feedback:
| Candidate | Role | Type | Rating | Key Feedback |
|---|---|---|---|---|
| James Wilson | Backend Engineer | Technical | 4/5 | "Solved system design (URL shortener at scale) thoroughly. Good caching/sharding knowledge. Minor gap: limited Go experience." |
| Raj Gupta | Backend Engineer | Phone | 5/5 | "9 yrs at Google. Incredible depth. Salary expectation $200K+ — within range for this caliber." |
| Chen Wei | Data Engineer | Technical | 4/5 | "SQL deep-dive excellent — optimized query from 30s to 0.5s live. Minor concern: no Airflow at scale." |
Upcoming interviews: Raj Gupta's technical interview (tomorrow), James Wilson's on-site (3 days out)
Teaching points: Structured interview feedback, rating systems, how interviewers see only their assigned interviews, the difference between phone/technical/onsite interview types.
Login as: recruiter2@smarthire.com
Several candidates applied to multiple roles, demonstrating real-world talent routing:
| Candidate | Applied To | Status |
|---|---|---|
| Raj Gupta | Senior Backend Engineer | Interview (technical tomorrow) |
| Product Manager - Growth | Applied (discussing fit with hiring manager) | |
| Olivia Taylor | Senior Backend Engineer | Applied (engineering fit) |
| Senior UX Designer | Applied (exploring design-engineering crossover) | |
| Michael Brown | Senior Backend Engineer | Screening |
| Frontend Engineer (on_hold) | Screening (paused due to job hold) | |
| Jessica Kim | Senior Backend Engineer | Rejected (too junior) |
| Frontend Engineer (on_hold) | Applied (paused) | |
| Sofia Martinez | Senior Backend Engineer | Offer ($195K) |
| QA Automation Engineer (closed) | Rejected (overqualified, redirected to Backend) |
Teaching points: Candidates aren't 1:1 with jobs, talent redirection (Sofia was redirected from QA to Backend), pipeline pausing when a job goes on hold, unique constraint on (job_id, candidate_id) preventing duplicate applications.
Login as: hr.manager@smarthire.com
Navigate to Jobs to see all 8 positions across every lifecycle stage:
| Status | Jobs | What It Means |
|---|---|---|
| Open (4) | Senior Backend Engineer, Product Manager - Growth, Senior UX Designer, Data Engineer | Actively accepting applications and interviewing |
| On Hold (1) | Frontend Engineer | Budget freeze — 2 candidates paused mid-pipeline, will resume when budget approved |
| Draft (1) | DevOps / Platform Engineer | Created by recruiter, pending VP Engineering headcount approval |
| Closed (2) | QA Automation Engineer (filled, Liam hired), Marketing Coordinator (cancelled, budget reallocation) |
Teaching points: Job status state machine (draft > open > on_hold/closed), why jobs get paused vs. closed, the difference between "closed-filled" and "closed-cancelled", draft as a review gate.
Login as: recruiter1@smarthire.com
Navigate to Applications and filter by rejected status. The demo data includes 4 rejections at different pipeline stages, each with constructive reasoning:
| Candidate | Role | Rejected At | Reason |
|---|---|---|---|
| Jessica Kim | Backend Engineer | Screening | Insufficient experience (3 yrs vs. 5 yr minimum) |
| Aisha Patel | PM - Growth | Interview | Lacked depth on growth metrics despite strong communication |
| Sofia Martinez | QA Engineer | Applied | Overqualified (Staff Engineer at Netflix for a QA role) — redirected to Backend |
| Aisha Patel | Marketing Coordinator | Screening | Position closed due to budget reallocation |
Teaching points: Rejections happen at every stage for different reasons, importance of documenting rejection reasons (legal compliance, candidate experience), talent redirection as a positive practice, how external factors (budget) can close positions.
Login as: admin@smarthire.com
Navigate to Candidates to see 15 candidates from varied sources:
| Source | Count | Examples |
|---|---|---|
| 5 | James Wilson (Stripe), Michael Brown (Salesforce), Raj Gupta (Google), Chen Wei (Uber), Liam O'Connor (Datadog) | |
| Referral | 3 | Sofia Martinez (referred by Marcus Johnson), Priya Sharma (referred by Hannah Roberts), Maria Rodriguez (referred by David Chen) |
| Career Page | 3 | Olivia Taylor, Emily Zhang, Daniel Lee |
| Job Board | 2 | Aisha Patel, Jessica Kim |
| Agency | 1 | Alex Rivera (TechRecruit agency, 20% placement fee) |
Candidates come from top tech companies: Google, Netflix, Stripe, Uber, Salesforce, Amazon, Meta, Airbnb, Spotify, Shopify, Twilio, Snap, Capital One, HubSpot, Datadog.
Teaching points: Multi-channel sourcing strategy, referral tracking (who referred whom), agency cost implications noted in stage history, candidate search across names/skills/companies.
Login as: hr.manager@smarthire.com
Two active offers in the system demonstrate different offer scenarios:
| Candidate | Role | Offer Details | Status |
|---|---|---|---|
| Sofia Martinez | Senior Backend Engineer | $195K base + 15% bonus + equity | Awaiting response (deadline Friday) |
| Priya Sharma | Product Manager - Growth | $160K base | Verbally accepted, start date April 14th |
Compare with the completed hire: Liam O'Connor accepted $130K for QA Engineer and started March 1st.
Teaching points: Offer negotiation context captured in stage notes, time-sensitive decisions (response deadlines), the gap between verbal acceptance and official start, compensation benchmarking across roles.
Open Swagger UI at https://smarthire-api.revaturelabs.com/docs (or http://localhost:8000/docs for local dev)
Walk through these API calls to show the backend powering the UI:
- Authenticate:
POST /api/v1/auth/loginwith{"email": "admin@smarthire.com", "password": "Password123!"}— copy theaccess_token - Dashboard stats:
GET /api/v1/dashboard/stats— see aggregated pipeline metrics - List jobs with filter:
GET /api/v1/jobs?status=open— only open positions - View a candidate:
GET /api/v1/candidates/{id}— full profile with skills array - Application pipeline:
GET /api/v1/applications?job_id={id}— all applicants for a job - Update status:
PATCH /api/v1/applications/{id}/status— move a candidate through the pipeline - Schedule interview:
POST /api/v1/interviews— create a new interview - Submit feedback:
POST /api/v1/interviews/{id}/feedback— rate and review
Teaching points: RESTful API design, JWT bearer authentication, query parameter filtering, PATCH for partial updates, Swagger/OpenAPI as self-documenting API contracts.
# Backend tests
cd backend
pytest tests/ -v --cov=app
# Frontend tests
cd frontend
npm test
# All tests
chmod +x scripts/run-tests.sh
./scripts/run-tests.sh# First-time deploy (creates all infrastructure + seeds database)
./scripts/deploy.sh -e dev -d
# Backend-only update
./scripts/deploy.sh -e dev -s -f
# Frontend-only update
./scripts/deploy.sh -e dev -s -bSee DEPLOY.md for the complete deployment guide.
All design and architecture documentation is in the docs/ folder. PDF versions with Revature branding are available in docs/pdf/.
| # | Document | Description |
|---|---|---|
| 01 | Requirement Document | Functional & non-functional requirements |
| 02 | System Design | Architecture overview, monolith vs microservices |
| 03 | Application Design | Layered architecture, component design |
| 04 | Database Design | MongoDB schema, collections, indexes |
| 05 | Security Design | Defense-in-depth, auth, RBAC |
| 06 | Coding Standards | Python PEP 8, React/JS conventions |
| 07 | Performance Design | Performance targets, caching, optimization |
| 08 | Network & Deployment | AWS infrastructure, VPC, networking |
| 09 | API Documentation | RESTful API endpoints, request/response |
| 10 | Design Patterns | Repository, service layer, middleware |
| 11 | Auth Implementation | JWT dual-token strategy |
| 12 | Development Plan | 6-phase development timeline |
| - | AWS Architecture Diagram | Visual deployment architecture (PDF) |
| - | Deployment Guide | Step-by-step AWS deployment |
To regenerate all branded PDFs:
python3 scripts/generate_docs_pdf.py
python3 scripts/generate_arch_diagram.py| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/auth/register | Register new user |
| POST | /api/v1/auth/login | Login |
| POST | /api/v1/auth/refresh | Refresh token |
| GET | /api/v1/auth/me | Current user profile |
| GET/POST | /api/v1/jobs | List/Create jobs |
| GET/PUT/DELETE | /api/v1/jobs/:id | Get/Update/Delete job |
| GET | /api/v1/jobs/:id/applications | Job applications |
| GET/POST | /api/v1/candidates | List/Create candidates |
| GET/PUT/DELETE | /api/v1/candidates/:id | Get/Update/Delete candidate |
| POST | /api/v1/candidates/:id/upload-resume | Upload resume |
| GET/POST | /api/v1/applications | List/Create applications |
| PATCH | /api/v1/applications/:id/status | Update status |
| GET/POST | /api/v1/interviews | List/Create interviews |
| PATCH | /api/v1/interviews/:id/feedback | Submit feedback |
| GET | /api/v1/dashboard/stats | Dashboard statistics |
| GET | /api/v1/health | Health check |
This project is for educational/workshop purposes.