Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 136 additions & 118 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,83 +30,105 @@
- [Contributing](#contributing)
- [License](#license)


## Overview

InterXAI is an AI-powered interview automation platform designed to make technical hiring smarter, faster, and more scalable. It simulates real interview experiences by dynamically generating follow-up questions based on candidate responses, evaluating answers in real time using large language models, and maintaining a natural conversational flow throughout the entire interview process.

Organizations create fully customized interviews with domain-specific questions and DSA challenges. Candidates apply by submitting their resumes, which are automatically evaluated and scored by an LLM agent against the job requirements - all without manual intervention. To ensure interview integrity, the platform integrates proctoring features including tab-switch detection, page-refresh monitoring, and OpenCV-based malpractice detection.

## Quick Start

```bash
# Clone repository
git clone https://github.com/your-username/InterXAI.git

# Backend setup
cd backend
uv sync --dev
uv run alembic upgrade head
uv run uvicorn app.main:app --reload
```

## Frontend setup

```bash
cd frontend
npm install
npm run dev
```
Comment on lines +41 to +58

## Features
Comment on lines +39 to 60

### For Organizations

- **Custom Interview Builder** - Create structured interviews with tailored questions, DSA topics, and evaluation criteria
- **Automated Resume Screening** - LLM-powered analysis that scores and shortlists candidates automatically
- **AI-Driven Evaluations** - Real-time answer evaluation with structured, unbiased scoring
- **Candidate Dashboard** - Track all applications, review scores, and access AI-generated feedback reports

### For Candidates

- **Seamless Application Flow** - Upload your resume and let the AI evaluate your fit for the role
- **Conversational Interviews** - Experience dynamic, follow-up-rich interviews that adapt to your responses
- **Instant Feedback** - Receive structured feedback on your performance after each session
- **Multi-Round Sessions** - Navigate through Q&A, DSA, and resume-based rounds in a single interview

### Platform Intelligence

- **Dynamic Question Generation** - LLMs generate context-aware follow-up questions based on candidate answers
- **Resume Intelligence** - Extracts, standardizes, and evaluates resume content against job requirements
- **Interview Proctoring** - Tab-switch detection, page-refresh monitoring, and OpenCV-based malpractice detection ensure integrity
- **Event-Driven Processing** - Asynchronous background jobs via TaskIQ + Redis ensure interviews scale without bottlenecks


## Tech Stack

| Layer | Technology |
|---|---|
| **Backend API** | FastAPI, Python 3.12+ |
| **Frontend** | React 19, TypeScript, Vite, TailwindCSS 4 |
| **Database** | PostgreSQL via Neon (production) / SQLite (development) |
| **ORM & Migrations** | SQLAlchemy 2.0 (async), Alembic |
| **Background Jobs** | TaskIQ + Redis |
| **AI / LLM** | LangChain, LiteLLM, Groq |
| **File Storage** | Supabase Storage |
| **Auth** | JWT (PyJWT), bcrypt |
| **State Management** | Zustand, React Query |
| **Package Manager** | `uv` (backend), `npm` (frontend) |
| **Containerization** | Docker, Docker Compose |

| Layer | Technology |
| -------------------- | ------------------------------------------------------- |
| **Backend API** | FastAPI, Python 3.12+ |
| **Frontend** | React 19, TypeScript, Vite, TailwindCSS 4 |
| **Database** | PostgreSQL via Neon (production) / SQLite (development) |
| **ORM & Migrations** | SQLAlchemy 2.0 (async), Alembic |
| **Background Jobs** | TaskIQ + Redis |
| **AI / LLM** | LangChain, LiteLLM, Groq |
| **File Storage** | Supabase Storage |
| **Auth** | JWT (PyJWT), bcrypt |
| **State Management** | Zustand, React Query |
| **Package Manager** | `uv` (backend), `npm` (frontend) |
| **Containerization** | Docker, Docker Compose |

## Architecture

```

┌─────────────────────────────────────────────────────────────────┐
Client (React)
React Query · Zustand · React Hook Form · Zod
│ Client (React) │
│ React Query · Zustand · React Hook Form · Zod │
└───────────────────────────┬─────────────────────────────────────┘
│ REST / JSON
│ REST / JSON
┌───────────────────────────▼─────────────────────────────────────┐
FastAPI Backend
/users /organizations /interviews /applications /health
┌────────────────┐ ┌──────────────────┐ ┌────────────────┐
Auth (JWT + │ │ Routers / │ │ Exception
bcrypt) │ │ Business Logic │ │ Handlers
└────────────────┘ └────────┬─────────┘ └────────────────┘
│ FastAPI Backend │
│ /users /organizations /interviews /applications /health │
│ │
│ ┌────────────────┐ ┌──────────────────┐ ┌────────────────┐ │
Auth (JWT + │ │ Routers / │ │ Exception
bcrypt) │ │ Business Logic │ │ Handlers
│ └────────────────┘ └────────┬─────────┘ └────────────────┘ │
└────────────────────────────────┼────────────────────────────────┘
┌─────────────────┼──────────────────┐
│ │ │
┌──────────▼───────┐ ┌───────▼──────────┐ ┌────▼────────────┐
│ PostgreSQL / │ │ TaskIQ + Redis │ │ Supabase Storage│
│ SQLite │ │ Worker │ │ (Resume PDFs) │
│ (SQLAlchemy ORM) │ └───────┬──────────┘ └─────────────────┘
└──────────────────┘ │
┌────────▼────────┐
│ LLM Pipeline │
│ LiteLLM/Groq │
│ LangChain │
│ ResumeEvaluator│
└─────────────────┘
┌─────────────────┼──────────────────┐
│ │ │
┌──────────▼───────┐ ┌───────▼──────────┐ ┌────▼────────────┐
│ PostgreSQL / │ │ TaskIQ + Redis │ │ Supabase Storage│
│ SQLite │ │ Worker │ │ (Resume PDFs) │
│ (SQLAlchemy ORM) │ └───────┬──────────┘ └─────────────────┘
└──────────────────┘ │
┌────────▼────────┐
│ LLM Pipeline │
│ LiteLLM/Groq │
│ LangChain │
│ ResumeEvaluator│
└─────────────────┘

```

### Request Lifecycle
Expand All @@ -120,61 +142,63 @@ Organizations create fully customized interviews with domain-specific questions
### Resume Processing Pipeline

```

POST /applications/{interview_id}
├── Create Application record (status: pending)
└── Return 202 to client immediately
├── Create Application record (status: pending)
└── Return 202 to client immediately

TaskIQ Worker (async):
├── Decode base64 PDF
├── Upload PDF → Supabase Storage
├── Extract text (PyPDF2)
├── ResumeEvaluator.evaluate()
│ ├── Build ChatPromptTemplate
│ ├── Call LiteLLM/Groq
│ └── Parse structured JSON response
│ score · shortlisting_decision · feedback
└── Update Application record with evaluation results
(Delete Application on failure)
```
├── Decode base64 PDF
├── Upload PDF → Supabase Storage
├── Extract text (PyPDF2)
├── ResumeEvaluator.evaluate()
│ ├── Build ChatPromptTemplate
│ ├── Call LiteLLM/Groq
│ └── Parse structured JSON response
│ score · shortlisting_decision · feedback
└── Update Application record with evaluation results
(Delete Application on failure)

```

## Project Structure

```

InterXAI-re/
├── backend/ # FastAPI application
├── app/
├── ai/ # LLM agents and prompt templates
├── background/
│ │ ├── taskiq/ # TaskIQ broker & resume task
│ │ └── celery/ # Legacy (deprecated)
├── exceptions/ # Custom exception hierarchy
├── interfaces/ # Abstract base classes
├── models/ # SQLAlchemy ORM models
├── routers/ # API route handlers
├── schemas/ # Pydantic request/response schemas
├── utils/ # Concrete implementations
├── config.py # Pydantic settings (env-driven)
├── database.py # Async DB session factory
└── main.py # App factory, lifespan, middleware
├── alembic/ # Database migrations
├── Dockerfile # API server image
├── Dockerfile.taskiq # Worker image
└── pyproject.toml
├── frontend/ # React + TypeScript SPA
├── src/
├── app/ # App routing and layout shells
├── components/ # Shared, reusable UI components
├── features/ # Feature-scoped modules
└── services/ # Axios-based API client layer
└── package.json
├── docker-compose.yml # Multi-service orchestration
├── backend/ # FastAPI application
│ ├── app/
├── ai/ # LLM agents and prompt templates
├── background/
│ │ ├── taskiq/ # TaskIQ broker & resume task
│ │ └── celery/ # Legacy (deprecated)
├── exceptions/ # Custom exception hierarchy
├── interfaces/ # Abstract base classes
├── models/ # SQLAlchemy ORM models
├── routers/ # API route handlers
├── schemas/ # Pydantic request/response schemas
├── utils/ # Concrete implementations
├── config.py # Pydantic settings (env-driven)
├── database.py # Async DB session factory
└── main.py # App factory, lifespan, middleware
│ ├── alembic/ # Database migrations
│ ├── Dockerfile # API server image
│ ├── Dockerfile.taskiq # Worker image
│ └── pyproject.toml
├── frontend/ # React + TypeScript SPA
│ ├── src/
├── app/ # App routing and layout shells
├── components/ # Shared, reusable UI components
├── features/ # Feature-scoped modules
└── services/ # Axios-based API client layer
│ └── package.json
├── docker-compose.yml # Multi-service orchestration
├── LICENSE
└── tools/
└── backend_lint # One-shot ruff + mypy quality check
```
└── backend_lint # One-shot ruff + mypy quality check

```

## Getting Started

Expand All @@ -193,18 +217,18 @@ Create a `.env` file inside the `backend/` directory:
cp backend/.env.example backend/.env
```

| Variable | Default | Description |
|---|---|---|
| `DATABASE_URL` | `sqlite+aiosqlite:///./dev.db` | PostgreSQL URL for production |
| `REDIS_URL` | `redis://localhost:6379/0` | TaskIQ broker + result backend |
| `SECRET_KEY` | `secret` | JWT signing key - **change in production** |
| `ALGORITHM` | `HS256` | JWT signing algorithm |
| `ACCESS_TOKEN_EXPIRE_MINUTES` | `30000` | Token lifetime |
| `GROQ_API_KEY` | - | Required for LLM inference |
| `SUPABASE_URL` | - | Supabase project URL |
| `SUPABASE_KEY` | - | Supabase service role key |
| `SUPABASE_BUCKET_NAME` | `resumes` | Storage bucket for resume PDFs |
| `LLM_MODEL_NAME` | `groq/openai/gpt-oss-120b` | LiteLLM model string |
| Variable | Default | Description |
| ----------------------------- | ------------------------------ | ------------------------------------------ |
| `DATABASE_URL` | `sqlite+aiosqlite:///./dev.db` | PostgreSQL URL for production |
| `REDIS_URL` | `redis://localhost:6379/0` | TaskIQ broker + result backend |
| `SECRET_KEY` | `secret` | JWT signing key - **change in production** |
| `ALGORITHM` | `HS256` | JWT signing algorithm |
| `ACCESS_TOKEN_EXPIRE_MINUTES` | `30000` | Token lifetime |
| `GROQ_API_KEY` | - | Required for LLM inference |
| `SUPABASE_URL` | - | Supabase project URL |
| `SUPABASE_KEY` | - | Supabase service role key |
| `SUPABASE_BUCKET_NAME` | `resumes` | Storage bucket for resume PDFs |
| `LLM_MODEL_NAME` | `groq/openai/gpt-oss-120b` | LiteLLM model string |

### Option A - Docker (Recommended)

Expand Down Expand Up @@ -250,7 +274,6 @@ npm run dev

The frontend dev server runs at `http://localhost:5173`.


## API Reference

FastAPI auto-generates interactive documentation:
Expand All @@ -260,24 +283,23 @@ FastAPI auto-generates interactive documentation:

### Endpoints Summary

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| `GET` | `/health` | - | Health check |
| `POST` | `/users/signup` | - | Register a candidate account |
| `POST` | `/users/login` | - | Authenticate and receive JWT |
| `GET` | `/users/{user_id}` | User | Get user profile |
| `PUT` | `/users/{user_id}` | User | Update user profile |
| `DELETE` | `/users/{user_id}` | User | Delete user account |
| `POST` | `/organizations/signup` | - | Register an organization |
| `GET` | `/organizations/{org_id}` | Org | Get organization details |
| `PUT` | `/organizations/{org_id}` | Org | Update organization |
| `POST` | `/interviews/` | Org | Create a new interview |
| `GET` | `/interviews/` | Any | List interviews |
| `GET` | `/interviews/applied` | User | Get applied interviews |
| `GET` | `/interviews/{interview_id}` | Org | Get full interview details |
| `POST` | `/applications/{interview_id}` | User | Apply with resume (PDF) |
| `GET` | `/applications/{interview_id}` | Org | Get all applications |

| Method | Endpoint | Auth | Description |
| -------- | ------------------------------ | ---- | ---------------------------- |
| `GET` | `/health` | - | Health check |
| `POST` | `/users/signup` | - | Register a candidate account |
| `POST` | `/users/login` | - | Authenticate and receive JWT |
| `GET` | `/users/{user_id}` | User | Get user profile |
| `PUT` | `/users/{user_id}` | User | Update user profile |
| `DELETE` | `/users/{user_id}` | User | Delete user account |
| `POST` | `/organizations/signup` | - | Register an organization |
| `GET` | `/organizations/{org_id}` | Org | Get organization details |
| `PUT` | `/organizations/{org_id}` | Org | Update organization |
| `POST` | `/interviews/` | Org | Create a new interview |
| `GET` | `/interviews/` | Any | List interviews |
| `GET` | `/interviews/applied` | User | Get applied interviews |
| `GET` | `/interviews/{interview_id}` | Org | Get full interview details |
| `POST` | `/applications/{interview_id}` | User | Apply with resume (PDF) |
| `GET` | `/applications/{interview_id}` | Org | Get all applications |

## Data Models

Expand All @@ -303,7 +325,6 @@ InterviewSession

**Round Types:** `QUESTIONS` · `DSA` · `RESUME`


## Development

### Running Code Quality Checks
Expand Down Expand Up @@ -332,7 +353,6 @@ uv run alembic upgrade head
uv run alembic revision --autogenerate -m "add column to applications"
```


## Contributing

Contributions are welcome. Please follow these steps:
Expand All @@ -351,12 +371,10 @@ Contributions are welcome. Please follow these steps:
- Type annotations are mandatory - `mypy --strict` must pass without errors
- Line length: 100 characters (enforced by Ruff)


## License

This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.


<div align="center">
Built with FastAPI, React, and LangChain
</div>
Loading
Loading