Add FAQ for IIT-ROPAR#89
Conversation
📌 OverviewThe Vicharanashala Support Portal is a production-grade, full-stack web platform built exclusively for interns at IIT Ropar's Vicharanashala Internship Program — a single intelligent hub where every question gets answered, every issue gets resolved, and every intern stays informed throughout their program cycle. At its core lives Yaksha — a 3D AI copilot powered by Google Gemini that understands Vicharanashala-specific context end-to-end: NOC validation, certificate workflows, Rosetta Journal requirements, and team formation. Around Yaksha is a complete ecosystem of 18 purpose-built features — a multi-language FAQ engine, a dedicated voice assistant, a threaded community forum, a smart bookmark system, a priority-based ticket system, coordinator-verified answers, and a full admin control center. Built with strict TypeScript, role-based JWT authentication, rate limiting, CSP headers, and a type-safe ORM — this is a production system designed to serve real students across real internship cycles, not a demo. ✦ Features
Yaksha AI Copilot Hub%%{init: {'theme':'base'}}%%
flowchart LR
subgraph HUB["AI Copilot Hub"]
A["How can Yaksha assist you?"]
subgraph CONTEXT["Supported Topics"]
B["NOC"]
C["Certificates"]
D["Rosetta Journal"]
E["Projects"]
end
Y["Yaksha AI<br/>Status: Active"]
end
A --> B
A --> C
A --> D
A --> E
B --> Y
C --> Y
D --> Y
E --> Y
classDef default fill:#1f1f1f,color:#ffffff,stroke:#666666,stroke-width:1px;
linkStyle default stroke:#999999,stroke-width:1.5px;
Yaksha is the intelligence layer of the entire portal. A conversational AI assistant embedded into the dashboard with a live 3D avatar, active status indicator, and deep FAQ integration. It understands Vicharanashala-specific context end-to-end.
🎙️ Voice AssistantA dedicated voice interface — its own section in the navbar, separate from the chat.
Intelligent FAQ SystemNot a static page. A fully intelligent, multi-layered knowledge base purpose-built for internship workflows. 📂 Browse & Discover
📖 Read & Save
💡 Ask & Clarify
Community Discussion Workflow%%{init: {'theme':'base'}}%%
flowchart TD
A["Student posts question"]
B["Discussion Thread"]
C["Peers and Coordinators respond"]
D["Coordinator reviews answers"]
E["Verified Answer"]
F["Promoted to Official FAQ"]
G["Knowledge loop closes"]
A --> B
C --> B
B --> D
D --> E
E --> F
F --> G
classDef default fill:#1f1f1f,color:#ffffff,stroke:#666666,stroke-width:1px;
linkStyle default stroke:#999999,stroke-width:1.5px;
Support Ticket Workflow%%{
init: {
"theme": "base",
"flowchart": {
"curve": "linear"
}
}
}%%
flowchart TD
A["Student raises ticket"]
B["Selects category"]
C["Sets priority"]
D["Describes issue"]
P["LOW"]
Q["MEDIUM"]
R["HIGH"]
E["Unique Ticket ID<br/>Assigned automatically"]
F["OPEN"]
G["IN PROGRESS"]
H["RESOLVED"]
I["Admin manages via Control Center"]
A --- B
A --- C
A --- D
C --- P
C --- Q
C --- R
B --- E
C --- E
D --- E
E --- F
F --- G
G --- H
H --- I
classDef default fill:#1f1f1f,color:#ffffff,stroke:#666666,stroke-width:1px;
linkStyle default stroke:#808080,stroke-width:2px;
🔔 Notification CenterStudents are never out of the loop.
🛡️ Admin Control CenterComplete operational visibility for program coordinators — all from one protected tab.
🗺️ Architecture & Data Flowflowchart TB
subgraph CLIENT["🖥️ Client Layer — React 19 + Vite 6"]
OVERVIEW["📊 Overview Dashboard"]
FAQ["❓ Intelligent FAQ"]
VOICE["🎙️ Voice Assistant"]
YAKSHA["🤖 Yaksha AI"]
COMMUNITY["💬 Community Forum"]
TICKETS["🎫 Support Tickets"]
NOTIFICATIONS["🔔 Notifications"]
ADMIN["🛡️ Admin Control Center"]
UI["Tailwind CSS v4<br/>Framer Motion<br/>React Router<br/>Axios"]
end
subgraph SERVER["⚙️ API Layer — Express.js + TypeScript"]
AUTH["/api/auth"]
FAQAPI["/api/faqs"]
CHAT["/api/chat"]
TICKETAPI["/api/tickets"]
COMMUNITYAPI["/api/community-answers"]
NOTIFYAPI["/api/notifications"]
ADMINAPI["/api/admin/logs"]
HEALTH["/api/health"]
SECURITY["🔐 JWT Auth<br/>Helmet<br/>CORS<br/>Rate Limiting<br/>Role Guards"]
end
subgraph AI["🧠 AI Layer"]
GEMINI["Google Gemini API"]
end
subgraph DATABASE["🗄️ Database Layer — Prisma ORM"]
USER["User"]
FAQDB["FAQ"]
TICKETDB["Ticket"]
ANSWER["CommunityAnswer"]
NOTIFICATION["Notification"]
STORAGE["SQLite (Dev)<br/>PostgreSQL Compatible (Prod)"]
end
OVERVIEW --> FAQAPI
FAQ --> FAQAPI
VOICE --> CHAT
YAKSHA --> CHAT
COMMUNITY --> COMMUNITYAPI
TICKETS --> TICKETAPI
NOTIFICATIONS --> NOTIFYAPI
ADMIN --> ADMINAPI
AUTH --> SECURITY
FAQAPI --> SECURITY
CHAT --> SECURITY
TICKETAPI --> SECURITY
COMMUNITYAPI --> SECURITY
NOTIFYAPI --> SECURITY
ADMINAPI --> SECURITY
CHAT --> GEMINI
SECURITY --> USER
SECURITY --> FAQDB
SECURITY --> TICKETDB
SECURITY --> ANSWER
SECURITY --> NOTIFICATION
USER --> STORAGE
FAQDB --> STORAGE
TICKETDB --> STORAGE
ANSWER --> STORAGE
NOTIFICATION --> STORAGE
🛠️ Tech Stack
📁 Project Structure🚀 Getting StartedPrerequisitesBefore you begin, ensure you have the following installed:
Step 1 · Clonegit clone https://github.com/tarun-1607/IIT-ROPAR.git
cd IIT-ROPARStep 2 · Installnpm installStep 3 · Configure environmentcp .env.example .env.local# ─────────────────────────────────────────────────────────────────
# Required
# ─────────────────────────────────────────────────────────────────
# Powers Yaksha AI — server-side only, NEVER sent to the browser
GEMINI_API_KEY="your_gemini_api_key_here"
# Base URL for the application
APP_URL="http://localhost:3000"
# ─────────────────────────────────────────────────────────────────
# Optional
# ─────────────────────────────────────────────────────────────────
NODE_ENV="development" # Set to "production" for prod builds
PORT=3000Step 4 · Initialize databasenpm run setup
Step 5 · Launchnpm run devOpen http://localhost:3000 and the full portal is live. ✦ 📜 Scripts
🔌 API ReferenceAll routes are prefixed Authorization: Bearer <your_jwt_token>🔑 Authentication ·
|
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/register |
Register a new student account |
POST |
/api/auth/login |
Authenticate and receive a signed JWT |
🎫 Tickets · /api/tickets · 🔐 JWT required
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/api/tickets |
Student / Admin | Own tickets (student) · Full queue (admin) |
POST |
/api/tickets |
Student | Raise ticket with category + priority |
GET |
/api/tickets/:id |
Student / Admin | Fetch by unique ticket ID |
PATCH |
/api/tickets/:id |
Admin | Update ticket status |
❓ FAQs · /api/faqs
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/api/faqs |
Public | All FAQs with categories and metadata |
POST |
/api/faqs |
🔐 Admin | Create a new FAQ entry |
PATCH |
/api/faqs/:id |
🔐 Admin | Update an existing entry |
🤖 Yaksha AI · /api/chat · 🔐 Rate limited: 15 req / min
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/chat |
Send a message → receive a Gemini-powered response |
💬 Community · /api/community-answers · 🔐 JWT required
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/community-answers |
List all discussion threads |
POST |
/api/community-answers |
Submit an answer (increments contributor score) |
🔔 Notifications · /api/notifications · 🔐 JWT required
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/notifications |
Fetch current user's notifications |
🛡️ Admin · /api/admin/logs · 🔐 Admin role only
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/admin/logs |
Full system stats + complete user roster |
{
"success": true,
"userCounts": 42,
"ticketCounts": 17,
"faqCounts": 8,
"answerCounts": 93,
"usersList": [
{
"name": "Ananya Sharma",
"email": "ananya@iitropar.ac.in",
"studentId": "2022CSB1234",
"college": "IIT Ropar",
"role": "student",
"isVerified": true,
"contributionScore": 12
}
]
}💚 Health · /api/health · Public
{ "status": "healthy", "timestamp": "2026-06-19T14:32:00.000Z" }🗄️ Data Models
model User {
id String @id @default(cuid())
name String
email String @unique
password String // bcrypt hashed; never stored in plaintext
studentId String?
college String?
role Role @default(student)
isVerified Boolean @default(false)
contributionScore Int @default(0)
tickets Ticket[]
answers CommunityAnswer[]
notifications Notification[]
}
model Ticket {
id String @id @default(cuid())
title String
description String
category String
priority Priority
status TicketStatus @default(open)
ticketCode String @unique
userId String
user User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model FAQ {
id String @id @default(cuid())
question String
answer String
category String
views Int @default(0)
isOfficial Boolean @default(true)
}
model CommunityAnswer {
id String @id @default(cuid())
question String
answer String
isVerified Boolean @default(false)
authorId String
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
}🔒 Security
Security is not bolted on — it is layered at every level of the stack.
Incoming Request
│
├─── Helmet ────────────── Strict HTTP headers · Content Security Policy
├─── CORS ──────────────── Controlled cross-origin access
├─── Rate Limiter ──────── 100 req/15min (auth) · 15 req/min (Yaksha)
├─── authenticateToken ─── JWT validation on all protected routes
└─── requireAdmin ──────── Role guard on all admin endpoints
Content Security Policy — Production
| Directive | Allowed Origins |
|---|---|
default-src |
'self' |
script-src |
'self' 'unsafe-inline' |
style-src |
'self' 'unsafe-inline' fonts.googleapis.com |
font-src |
'self' fonts.gstatic.com |
img-src |
'self' data: https://* |
connect-src |
'self' https://* |
Yaksha API Key Isolation
Browser
│
│ POST /api/chat (only the user's message travels here)
▼
Express Server ────────────────────────────────► Gemini API
↑
GEMINI_API_KEY lives here only.
Never bundled into client code.
Never visible in DevTools · Network tab · Browser memory.
Passwords are bcrypt-hashed before storage. No plaintext credentials exist anywhere in the system.
🌐 Deployment
Build for production
npm run buildProduces:
dist/— compiled, tree-shaken React SPA (statically served)dist/server.cjs— fully bundled backend (Node.js CommonJS, zero install at runtime)
Run in production
NODE_ENV=production node dist/server.cjsBinds to 0.0.0.0:PORT. All unmatched routes fall back to index.html for client-side routing.
Platform recommendations
| Platform | Notes |
|---|---|
| Railway | Auto-detects Node.js. Set env vars in dashboard. Zero config needed. |
| Render | Free tier available. Set NODE_ENV=production + GEMINI_API_KEY in env. |
| Fly.io | Global edge deployment. Run fly launch — auto-detects project. |
| VPS / Ubuntu | nginx for SSL termination · pm2 for process management |
📄 License
This project is open-source. See LICENSE for details.
Built for the interns. By the interns.
This Pull Request adds the FAQ integration for IIT-ROPAR.
https://github.com/varun2spark/Samagama_FAQ
Team Lead : Varun
Members :
Tarun Kumar
Tanisha Jain
Girik Shukla
Uday Bhardwaj
Antra Mishra
Dwig Yadav
Yazhini P.L
Ashika Agrawal
Sanskar Agrawal