An internal Applicant Tracking System built for Stackular. Two portals — Recruitment and Interviewer — covering the full hiring pipeline from job description creation to candidate selection.
Stackular ATS streamlines the recruiting workflow: recruiters create AI-generated job descriptions, upload resume folders, and manage candidates through a Kanban pipeline with automated ATS match scoring. Interviewers get a separate portal to view assigned JDs, schedule interviews, and submit feedback.
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript (strict), Vite, Tailwind CSS 4 |
| Routing | TanStack Router |
| Data Fetching | TanStack Query v5 |
| UI | Lucide icons, Sora font |
| Backend | .NET 10, SQL Server (Azure) |
| AI / Scoring | Python 3, FastAPI (localhost:8000) |
| Storage | Azure Blob Storage |
- JD Creation — AI-generated job descriptions with live field-summary panel (Live Summary), edit, assign, and finalize flow
- Resume Upload — Bulk upload with folder drag-and-drop, duplicate detection via file hashing
- ATS Scoring — Queue-based background scoring pipeline; real-time score updates via SSE stream
- Candidate Pipeline — 10-stage Kanban board (
under_review→selected/rejected) with virtualized list view - Job Folder → Candidate navigation — "View full profile" preserves stage context; back button restores the exact kanban column; prev/next arrows iterate candidates within the same stage
- Dashboard — Pipeline funnel, attention items, application volume chart, recent job folders
- Interviewer Assignment — Assign interviewers to candidates directly from the candidate detail page
- Dashboard — Upcoming interviews, personal stats, recent activity, prep tips
- JD View — Read assigned job descriptions and fill out role descriptions
- Interview Feedback — Submit ratings, recommendations, and notes per interview round
ATS-Tool-Stackular/
├── Front-End/ # React + Vite app
│ └── src/
│ ├── features/
│ │ ├── recruiter/ # candidates, dashboard, jd-creation, job-folders
│ │ └── interviewer/ # dashboard, jd-creation
│ └── shared/ # components, hooks, context, types, api client
├── Back-End/
│ └── ATStool/ # .NET 10 Web API
│ ├── Controllers/
│ ├── Services/
│ ├── Models/
│ ├── DTOs/
│ └── Migrations/
└── AI_Models/ # Python FastAPI service
├── ats_scoring/
├── jd_creation/
└── resume_extraction/
- Node.js 20+
- .NET 10 SDK
- Python 3.11+
- SQL Server (local or Azure)
- Azure Storage account (for resume blobs)
cd Front-End
npm install
npm run devRuns at http://localhost:5173.
cd Back-End/ATStool
dotnet restore
dotnet runRuns at http://localhost:5122.
cd AI_Models
pip install -r requirements.txt
python api_server.pyRuns at http://localhost:8000.
Scoring runs asynchronously via a Channel<AtsScoreJob> queue processed by AtsScoreWorker (a .NET BackgroundService). Results are pushed to the frontend in real time over a persistent SSE connection at GET /api/candidates/stream?jobId=.
Score sentinels:
null— unscored-1— pending (shown as...)- negative (other) — failed
0–100— match percentage
| Role | Route |
|---|---|
| Recruiter | /recruitment/... |
| Interviewer | /interviewer/... |
Authentication is JWT-based. Roles: Recruiter, Interviewer.
- Theme: Dark (
#0c0c0cbackground), Sora font throughout - Card pattern: Double-bezel — outer frosted shell + inner
#161719panel - Color language: Green = active/success · Amber = pending · Blue = selected/AI · Purple = filtered · Red = error/rejected
- Sidebar: 240px desktop · 64px icon-only tablet · hidden mobile