Skip to content

Repository files navigation


β–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•
β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•‘   
β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•  β•šβ•β•β•β•β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   
β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   
 β•šβ•β•β•β•β•β• β•šβ•β•  β•šβ•β•β•β•β•šβ•β•β•šβ•β•  β•šβ•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•   β•šβ•β•   

Campus Recruitment Operating System

From application to offer β€” fully orchestrated.


Next.js Express Prisma PostgreSQL TypeScript Gemini License: MIT


Overview Β· Architecture Β· Features Β· Getting Started Β· API Reference Β· Database Schema Β· AI & ATS Β· Environment Variables Β· Contributing



πŸ“Œ Overview

UniNest is a full-stack campus recruitment operating system that connects students and companies through a structured, end-to-end placement workflow. It handles everything from drive discovery and resume verification to interview scheduling, ATS scoring, and offer management β€” in a single cohesive platform.

Role Core Capabilities
Student Browse drives, apply with verified resumes, track applications, manage interviews, accept/counter offers
Company Post drives, review applications with AI-powered ATS analysis, schedule interviews, extend and manage offers

UniNest is a monorepo. The frontend/ folder is a Next.js 15 App Router application. The backend/ folder is an Express + Prisma API server. They communicate over a versioned REST API (/api/v1).


πŸ— Architecture

High-Level System Diagram

Repository Structure

uninest/
β”œβ”€β”€ frontend/                   # Next.js 15 App Router
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ (auth)/             # login Β· register
β”‚   β”‚   β”œβ”€β”€ student/            # dashboard Β· drives Β· applications Β· offers Β· resumes Β· profile
β”‚   β”‚   β”œβ”€β”€ company/            # dashboard Β· drives Β· applications Β· offers Β· profile Β· statistics
β”‚   β”‚   β”œβ”€β”€ unauthorized/
β”‚   β”‚   └── page.tsx            # landing / root redirect
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ auth/               # LoginForm Β· RegisterForm Β· ProtectedRoute
β”‚   β”‚   β”œβ”€β”€ common/             # Alerts
β”‚   β”‚   β”œβ”€β”€ layout/             # Navbar
β”‚   β”‚   └── ui/                 # Button Β· Badge Β· Card Β· FormField Β· ResumeUploader
β”‚   β”œβ”€β”€ context/
β”‚   β”‚   └── AuthContext.tsx     # global auth state Β· localStorage Β· role-based redirect
β”‚   └── lib/
β”‚       └── api.ts              # Axios client Β· auto-attach Bearer Β· 401 redirect
β”‚
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ prisma/
β”‚   β”‚   └── schema.prisma       # canonical data model
β”‚   └── src/
β”‚       β”œβ”€β”€ server.ts           # entrypoint
β”‚       β”œβ”€β”€ controllers/        # request/response handlers
β”‚       β”œβ”€β”€ services/           # business logic Β· ATS Β· match
β”‚       β”œβ”€β”€ repositories/       # DB access via Prisma
β”‚       β”œβ”€β”€ routes/             # Express route definitions
β”‚       β”œβ”€β”€ middleware/         # authMiddleware Β· resumeUpload Β· errorHandler
β”‚       β”œβ”€β”€ config/
β”‚       β”œβ”€β”€ utils/
β”‚       └── scripts/            # seed and setup scripts
β”‚
β”œβ”€β”€ MD Files/                   # Postman guides Β· testing docs
β”œβ”€β”€ package.json                # root scripts
└── LICENSE

✨ Features

πŸŽ“ Student Portal
  • Dashboard β€” placement stats, upcoming drives, recent activity
  • Drive Discovery β€” browse and filter active placement drives
  • Applications β€” view status, stage history, interview timeline
  • Resume Management β€” upload PDFs (≀ 5 MB), request verification, track verification status
  • Offers β€” view, accept, reject, or counter salary offers
  • Profile β€” manage academic info and personal details
🏒 Company Portal
  • Dashboard β€” overview of posted drives, application volume, hire stats
  • Drive Management β€” create, update, and close placement drives with eligibility criteria
  • Application Review β€” view applicants, shortlist, update status, advance pipeline stages
  • ATS Analysis β€” AI-powered resume scoring per drive using Gemini 1.5 Flash
  • Interview Scheduling β€” create slots, confirm/reschedule with applicants
  • Offer Management β€” extend offers, respond to counter-offers, audit trail
  • Statistics β€” company-wide and per-drive placement analytics
πŸ€– AI / ATS Engine
  • Resume vs. drive JD matching via Gemini 1.5 Flash
  • Returns: score, verdict, summary, strengths, gaps, matched/missing keywords, score breakdown, confidence, rejection reason, recommendation
  • Graceful fallback to heuristic scoring (keyword overlap + resume length + education signals) when GEMINI_API_KEY is absent or the API call fails
  • Local keyword matching service (matchService) for lightweight analysis
  • Resume preview generation with Gemini fallback to text truncation
πŸ” Auth & Security
  • JWT-based authentication, bcryptjs password hashing
  • authMiddleware verifies Bearer tokens and sets req.userId on all protected routes
  • Role enum: STUDENT, COMPANY, ADMIN
  • CORS restricted to FRONTEND_URL (default: http://localhost:3000)
  • PDF-only resume upload enforced in middleware, 5 MB file size cap
  • Frontend 401 auto-logout: clears token + user from localStorage, redirects to /login
  • window.__TEST_INJECT_AUTH hook in AuthContext for browser-based integration testing

πŸš€ Getting Started

Prerequisites

Tool Version
Node.js β‰₯ 18.x
PostgreSQL β‰₯ 14
npm β‰₯ 9

1. Clone the repository

git clone https://github.com/ChiragVasava/uninest.git
cd uninest

2. Configure environment variables

Backend β€” create backend/.env:

DATABASE_URL="postgresql://USER:PASSWORD@localhost:5432/uninest"
PORT=8000
NODE_ENV=development
JWT_SECRET=your_jwt_secret
JWT_EXPIRE=7d
FRONTEND_URL=http://localhost:3000
GEMINI_API_KEY=your_gemini_api_key   # optional β€” falls back to heuristic scoring
UPLOAD_DIR=uploads/resumes           # see backend/.env.example
MAX_FILE_SIZE=5242880                # see backend/.env.example

Frontend β€” create frontend/.env.local:

NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1

3. Install dependencies

# root (runs both workspaces if configured)
npm install

# or independently:
cd backend && npm install
cd ../frontend && npm install

4. Set up the database

cd backend
npm run prisma:generate   # generate Prisma client
npm run prisma:migrate    # run all migrations
npm run prisma:seed       # seed initial data (optional)

5. Start development servers

# From repo root
npm run dev:frontend   # starts Next.js on http://localhost:3000
npm run dev:backend    # starts Express on http://localhost:8000

Or from each folder individually:

cd backend  && npm run dev
cd frontend && npm run dev

6. Production build

npm run build:backend    # compiles TypeScript β†’ dist/
npm run build:frontend   # Next.js production build

# Start
cd backend  && npm run start
cd frontend && npm run start

Deployment platform: Not Found in Codebase β€” no Docker, Vercel, or CI configuration files exist in the repository.


πŸ“‘ API Reference

All routes are prefixed with /api/v1. Protected routes require Authorization: Bearer <token>.

Auth /api/v1/auth
Method Path Description
POST /register Register new user (student or company)
POST /login Authenticate and receive JWT
GET /me Get current authenticated user
Students /api/v1/students
Method Path Description
GET / List all students
GET /statistics Placement statistics
GET /eligible/:department Students eligible by department
POST / Create student profile
GET /me/profile Get own profile
GET /:id Get student by ID
PUT /:id Update student
DELETE /:id Delete student
Companies /api/v1/companies
Method Path Description
GET / List all companies
GET /statistics Global company statistics
GET /by-sector/:sector Filter companies by sector
GET /me/profile Get own company profile
GET /me/statistics Own company's placement statistics
GET /:id Get company by ID
POST / Create company profile
PUT /:id Update company
DELETE /:id Delete company
Drives /api/v1/drives
Method Path Description
GET / List all drives
GET /statistics Drive statistics
GET /eligible/list Drives the authenticated student is eligible for
GET /me/company Drives posted by own company
GET /:id Get drive by ID
POST / Create drive
PUT /:id Update drive
DELETE /:id Delete drive
Applications /api/v1/applications
Method Path Description
GET /statistics Application statistics
GET /me/list Own applications list
GET /drive/:driveId All applications for a drive
GET /drive/:driveId/ats ATS scores for all drive applicants
GET /drive/:driveId/shortlisted Shortlisted applicants
GET /:id Get application by ID
GET /:id/timeline Full stage history
POST / Submit application
PUT /:id/status Update application status
POST /:id/stage Advance pipeline stage
POST /:id/interviews Create interview slot
PUT /interviews/:interviewId Update interview
POST /interviews/:interviewId/confirm Confirm interview
POST /interviews/:interviewId/reschedule Reschedule interview
DELETE /:id Delete application
Resumes /api/v1/resumes
Method Path Description
GET /statistics Resume statistics
GET /pending Resumes pending verification
GET /me/list Own resumes
GET /me/verified Own verified resumes
GET / All resumes
GET /:id Get resume by ID
POST / Upload resume (PDF, ≀ 5 MB)
PUT /:id Update resume metadata
POST /:id/match Run ATS match against a drive
POST /:id/verify Mark resume as verified
POST /:id/reject Reject resume
DELETE /:id Delete resume
Offers /api/v1/offers
Method Path Description
GET /statistics Offer statistics
GET /accepted All accepted offers
GET /me/list Own offers
GET /me/accepted Own accepted offers
GET /drive/:driveId Offers for a specific drive
GET / All offers
GET /:id Get offer by ID
GET /:id/audit Full offer audit log
POST / Extend offer
POST /:id/accept Accept offer
POST /:id/reject Reject offer
POST /:id/counter Submit counter-offer
POST /:id/counter/respond Respond to counter-offer
Health
Method Path Description
GET /api/v1/health Server health check

πŸ—ƒ Database Schema

The canonical schema lives at backend/prisma/schema.prisma.

erDiagram
    User {
        string id PK
        string email
        string password
        UserRole role
        datetime createdAt
        datetime updatedAt
    }
    Student {
        string id PK
        string userId FK
        string profile
        string academicInfo
        bool verified
    }
    Company {
        string id PK
        string userId FK
        string profile
        bool approved
    }
    Resume {
        string id PK
        string studentId FK
        string fileMetadata
        string extractedText
        VerificationStatus verificationStatus
    }
    Drive {
        string id PK
        string companyId FK
        string eligibilityFields
        string interviewFormat
    }
    DriveApplication {
        string id PK
        string studentId FK
        string driveId FK
        DriveApplicationStatus status
        string rejectionReason
    }
    Offer {
        string id PK
        string studentId FK
        string driveId FK
        float salary
        datetime joinDate
        json offerDetails
        OfferStatus status
        string counterOfferText
        datetime expiresAt
    }
    InterviewSchedule {
        string id PK
        string applicationId FK
        string driveId FK
        string companyId FK
        string studentId FK
        datetime scheduledTime
        InterviewMode mode
        string meetingLink
        InterviewConfirmationStatus confirmationStatus
    }
    ApplicationTimeline {
        string id PK
        string applicationId FK
        ApplicationStage stage
        string note
        json metadata
        string createdByUserId
    }
    OfferAudit {
        string id PK
        string offerId FK
        OfferAuditAction action
    }

    User ||--o| Student : "has"
    User ||--o| Company : "has"
    Student ||--o{ Resume : "uploads"
    Student ||--o{ DriveApplication : "submits"
    Student ||--o{ Offer : "receives"
    Student ||--o{ InterviewSchedule : "has"
    Company ||--o{ Drive : "posts"
    Company ||--o{ InterviewSchedule : "conducts"
    Drive ||--o{ DriveApplication : "receives"
    Drive ||--o{ Offer : "generates"
    Drive ||--o{ InterviewSchedule : "has"
    DriveApplication ||--o{ ApplicationTimeline : "tracks"
    DriveApplication ||--o{ InterviewSchedule : "linked"
    Offer ||--o{ OfferAudit : "logs"
Loading

Enums

Enum Values
UserRole STUDENT, COMPANY, ADMIN
DriveApplicationStatus Application pipeline statuses
OfferStatus Offer lifecycle statuses
ApplicationStage Interview pipeline stages
InterviewMode ONLINE, OFFLINE (or equivalent)
InterviewConfirmationStatus Confirmation states
OfferAuditAction Offer action log types
VerificationStatus Resume verification states

πŸ€– AI / ATS Engine

UniNest integrates Google's Gemini 1.5 Flash model for resume-to-JD matching via backend/src/services/atsService.ts.

ATS Response Shape

{
  score: number;             // 0–100
  verdict: string;           // e.g. "Strong Match"
  summary: string;
  strengths: string[];
  gaps: string[];
  matchedKeywords: string[];
  missingKeywords: string[];
  scoreBreakdown: object;
  confidence: number;
  whyRejected: string | null;
  recommendation: string;
  source: "gemini" | "heuristic";
}

Fallback Behavior

GEMINI_API_KEY present?
β”œβ”€β”€ YES β†’ call Gemini 1.5 Flash
β”‚         β”œβ”€β”€ Success β†’ return AI analysis (source: "gemini")
β”‚         └── Failure β†’ fall through to heuristic
└── NO  β†’ heuristic scoring
          (keyword overlap + resume length + education signals)
          returns source: "heuristic"

A separate matchService.ts provides local, synchronous keyword matching without any external API dependency.


🌐 Environment Variables

Backend (backend/.env)

Variable Required Description
DATABASE_URL βœ… PostgreSQL connection string
PORT βœ… Server port (default: 8000)
NODE_ENV βœ… development or production
JWT_SECRET βœ… Secret key for JWT signing
JWT_EXPIRE βœ… Token expiry (e.g. 7d)
FRONTEND_URL βœ… CORS allowed origin
GEMINI_API_KEY ⚠️ optional Gemini API key β€” falls back to heuristic ATS if absent
UPLOAD_DIR ⚠️ optional Upload directory path (see backend/.env.example)
MAX_FILE_SIZE ⚠️ optional Max file size in bytes (see backend/.env.example)

Frontend (frontend/.env.local)

Variable Required Description
NEXT_PUBLIC_API_URL βœ… Backend API base URL (default: http://localhost:8000/api/v1)

πŸ§ͺ Testing

Automated test runner: Not Found in Codebase β€” no test scripts were found in package.json.

Manual testing documentation is available in:

  • backend/README.md
  • backend/STUDENT_MODULE_API.md
  • MD Files/POSTMAN_TESTING_GUIDE.md
  • MD Files/START_TESTING_NOW.md

The frontend AuthContext exposes window.__TEST_INJECT_AUTH for browser-based integration testing without going through the login flow.


πŸ“œ Available Scripts

Root

Script Command
dev:frontend Start Next.js dev server
dev:backend Start Express dev server
build:frontend Build frontend for production
build:backend Compile backend TypeScript

Backend (cd backend)

Script Command
dev Nodemon + ts-node dev server
build TypeScript compile
start Run compiled production server
prisma:generate Generate Prisma client
prisma:migrate Run DB migrations
prisma:seed Seed database
lint ESLint

Frontend (cd frontend)

Script Command
dev Next.js dev server
build Next.js production build
start Start production server
lint ESLint

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/your-feature
  3. Commit your changes: git commit -m "feat: add your feature"
  4. Push to your fork: git push origin feat/your-feature
  5. Open a Pull Request

Please keep PRs focused and reference any related issues.


πŸ“„ License

MIT License
Copyright (c) 2026 Chirag Vasava

See LICENSE for the full text.


Built by Chirag Vasava

About

Intelligent Campus Recruitment Operating System

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages