Reflectify is a comprehensive feedback management system for educational institutions. This API provides endpoints for managing academic structures, feedback forms, analytics, and user authentication.
Base URL: http://localhost:4000/api/v1 (Development) | https://reflectify-backend.onrender.com/api/v1 (Production)
Student Data Management: As of the latest version, the system has migrated from using the legacy Student table to the OverrideStudent table for all student data management. This is a critical architectural change that affects:
- Email Distribution: All feedback form emails are now sent to students managed in the
OverrideStudenttable - Form Access:
FormAccessrecords are created withoverrideStudentIdreferences instead ofstudentId - Data Integrity: The legacy
Studenttable is no longer used for active operations - Database Relations: All student-related queries now target the
OverrideStudentmodel
The system uses Redis + BullMQ for reliable email delivery with the following configuration:
- Rate Limiting: 1 email per 4 seconds with exponential backoff
- Retry Logic: 5 attempts with exponential delay starting at 4 seconds
- Queue Processing: Background job processing with Gmail SMTP integration
- Fallback Mechanism: Direct email sending when queue is unavailable
- JWT Authentication - Used for admin/faculty access
- Service API Key - Used for service-to-service communication
- Token-based Access - Used for student feedback submissions
SUPER_ADMIN- Full system accessHOD- Head of Department privilegesAsstProf- Assistant Professor privilegesLabAsst- Lab Assistant privileges
Authorization: Bearer <jwt_token>
Content-Type: application/json
x-api-key: <service_api_key>
Content-Type: application/json
{
"status": "success",
"message": "Operation completed successfully",
"data": {
// Response data
}
}{
"status": "fail" | "error",
"message": "Error description"
}POST /auth/register
Access: Public
Request Body:
{
"name": "string",
"email": "string",
"password": "string",
"designation": "HOD | AsstProf | LabAsst"
}POST /auth/super-register
Access: Public (restricted by business logic)
Request Body:
{
"name": "string",
"email": "string",
"password": "string",
"designation": "SUPER_ADMIN"
}POST /auth/login
Access: Public
Request Body:
{
"email": "string",
"password": "string"
}Response:
{
"status": "success",
"message": "Logged in successfully",
"token": "jwt_token",
"data": {
"admin": {
"id": "string",
"name": "string",
"email": "string",
"designation": "string",
"isSuper": "boolean"
}
}
}GET /auth/me
Access: Private (All authenticated users)
Headers: Authorization: Bearer <token>
PATCH /auth/update-password
Access: Private (All authenticated users)
Headers: Authorization: Bearer <token>
Request Body:
{
"currentPassword": "string",
"newPassword": "string"
}GET /academic-years
Access: Private (All authenticated users)
POST /academic-years
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"yearString": "2024-25",
"startDate": "2024-08-01T00:00:00.000Z",
"endDate": "2025-07-31T00:00:00.000Z",
"isActive": true
}GET /academic-years/:id
Access: Private (All authenticated users)
PATCH /academic-years/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /academic-years/:id
Access: Private (SUPER_ADMIN, HOD)
GET /colleges
Access: Private (All authenticated users)
POST /colleges
Access: Private (SUPER_ADMIN)
GET /colleges/primary
Access: Private (All authenticated users)
PATCH /colleges/primary
Access: Private (SUPER_ADMIN, HOD)
DELETE /colleges/primary
Access: Private (SUPER_ADMIN)
PATCH /colleges/primary/batch-update
Access: Private (SUPER_ADMIN, HOD)
GET /departments
Access: Private (All authenticated users)
Query Parameters: ?collegeId=<id>&isActive=<boolean>
POST /departments
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"name": "Computer Science",
"abbreviation": "CS",
"collegeId": "string"
}GET /departments/:id
Access: Private (All authenticated users)
PATCH /departments/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /departments/:id
Access: Private (SUPER_ADMIN, HOD)
POST /departments/batch
Access: Private (SUPER_ADMIN, HOD)
GET /semesters
Access: Private (All authenticated users)
Query Parameters: ?departmentId=<id>&academicYearId=<id>&semesterNumber=<number>
POST /semesters
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"semesterNumber": 1,
"semesterType": "ODD | EVEN",
"departmentId": "string",
"academicYearId": "string"
}GET /semesters/:id
Access: Private (All authenticated users)
PATCH /semesters/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /semesters/:id
Access: Private (SUPER_ADMIN, HOD)
POST /semesters/batch
Access: Private (SUPER_ADMIN, HOD)
GET /semesters/dept/:id
Access: Private (SUPER_ADMIN, HOD, AsstProf, LabAsst)
GET /divisions
Access: Private (All authenticated users)
Query Parameters: ?departmentId=<id>&semesterId=<id>
POST /divisions
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"name": "A",
"capacity": 60,
"semesterId": "string"
}GET /divisions/:id
Access: Private (All authenticated users)
PATCH /divisions/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /divisions/:id
Access: Private (SUPER_ADMIN, HOD)
POST /divisions/batch
Access: Private (SUPER_ADMIN, HOD)
GET /subjects
Access: Private (SUPER_ADMIN, HOD, AsstProf)
Query Parameters: ?semesterId=<id>&subjectType=<MANDATORY|ELECTIVE>
POST /subjects
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"name": "Data Structures",
"code": "CS201",
"abbreviation": "DS",
"credits": 4,
"subjectType": "MANDATORY | ELECTIVE",
"semesterId": "string"
}GET /subjects/:id
Access: Private (SUPER_ADMIN, HOD, AsstProf)
PATCH /subjects/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /subjects/:id
Access: Private (SUPER_ADMIN, HOD)
GET /subjects/semester/:semesterId
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /subjects/abbreviations/:deptAbbr?
Access: Private (All authenticated users)
POST /subjects/batch
Access: Private (SUPER_ADMIN, HOD)
GET /faculties
Access: Private (All authenticated users)
Query Parameters: ?departmentId=<id>&designation=<string>
POST /faculties
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"name": "John Doe",
"email": "john.doe@example.com",
"employeeId": "EMP001",
"abbreviation": "JD",
"designation": "Professor",
"departmentId": "string"
}GET /faculties/:id
Access: Private (All authenticated users)
PATCH /faculties/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /faculties/:id
Access: Private (SUPER_ADMIN, HOD)
GET /faculties/abbreviations/:deptAbbr?
Access: Private (All authenticated users)
POST /faculties/batch
Access: Private (SUPER_ADMIN, HOD)
GET /students
Access: Private (All authenticated users)
Query Parameters: ?divisionId=<id>&academicYearId=<id>&rollNumber=<string>
POST /students
Access: Private (SUPER_ADMIN, HOD, AsstProf)
Request Body:
{
"name": "Jane Smith",
"email": "jane.smith@student.edu",
"rollNumber": "2024CS001",
"divisionId": "string",
"academicYearId": "string"
}GET /students/:id
Access: Private (All authenticated users)
PATCH /students/:id
Access: Private (SUPER_ADMIN, HOD, AsstProf)
DELETE /students/:id
Access: Private (SUPER_ADMIN, HOD)
POST /students/batch
Access: Private (SUPER_ADMIN, HOD)
GET /subject-allocations
Access: Private (SUPER_ADMIN, HOD, AsstProf)
Query Parameters: ?facultyId=<id>&subjectId=<id>&divisionId=<id>&lectureType=<type>
POST /subject-allocations
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"facultyId": "string",
"subjectId": "string",
"divisionId": "string",
"academicYearId": "string",
"lectureType": "LECTURE | LAB | TUTORIAL | SEMINAR | PROJECT"
}GET /subject-allocations/:id
Access: Private (SUPER_ADMIN, HOD, AsstProf)
PATCH /subject-allocations/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /subject-allocations/:id
Access: Private (SUPER_ADMIN, HOD)
GET /feedback-questions/categories
Access: Private (SUPER_ADMIN, HOD, AsstProf)
POST /feedback-questions/categories
Access: Private (SUPER_ADMIN, HOD, AsstProf)
Request Body:
{
"name": "Teaching Effectiveness",
"description": "Questions related to teaching methods"
}GET /feedback-questions/categories/:id
Access: Private (SUPER_ADMIN, HOD, AsstProf)
PATCH /feedback-questions/categories/:id
Access: Private (SUPER_ADMIN, HOD, AsstProf)
DELETE /feedback-questions/categories/:id
Access: Private (SUPER_ADMIN, HOD)
GET /feedback-questions/form/:formId/questions
Access: Private (SUPER_ADMIN, HOD, AsstProf)
POST /feedback-questions/form/:formId/questions
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"questionText": "How would you rate the clarity of explanation?",
"questionType": "RATING | TEXT | MULTIPLE_CHOICE",
"categoryId": "string",
"isRequired": true,
"order": 1
}PATCH /feedback-questions/questions/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /feedback-questions/questions/:id
Access: Private (SUPER_ADMIN, HOD)
PATCH /feedback-questions/questions/batch
Access: Private (SUPER_ADMIN, HOD)
GET /feedback-forms/access/:token
Access: Public (Token-based)
GET /feedback-forms
Access: Private (SUPER_ADMIN, HOD, AsstProf)
Query Parameters: ?status=<DRAFT|ACTIVE|CLOSED>&semesterId=<id>
GET /feedback-forms/:id
Access: Private (SUPER_ADMIN, HOD, AsstProf)
PATCH /feedback-forms/:id
Access: Private (SUPER_ADMIN, HOD)
DELETE /feedback-forms/:id
Access: Private (SUPER_ADMIN, HOD)
POST /feedback-forms/generate
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"semesterId": "string",
"title": "Mid-semester Feedback",
"description": "Feedback for mid-semester evaluation",
"questionCategoryIds": ["string"]
}PATCH /feedback-forms/bulk-status
Access: Private (SUPER_ADMIN, HOD)
POST /feedback-forms/:id/questions
Access: Private (SUPER_ADMIN, HOD)
PATCH /feedback-forms/:id/status
Access: Private (SUPER_ADMIN, HOD)
POST /student-responses/submit/:token
Access: Public (Token-based)
Request Body:
{
"responses": [
{
"questionId": "string",
"rating": 5,
"textResponse": "string"
}
]
}GET /student-responses/check-submission/:token
Access: Public (Token-based)
GET /analytics/semesters-with-responses
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/semesters/:id/overall-rating
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/semesters/:id/subject-wise-rating
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/semesters/:id/high-impact-areas
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/semester-trend-analysis
Access: Private (SUPER_ADMIN, HOD, AsstProf)
Query Parameters: ?subjectId=<id>
GET /analytics/annual-performance-trend
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/semesters/:id/division-batch-comparisons
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/semesters/:id/lab-lecture-comparison
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/faculty/:facultyId/performance/:academicYearId
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/faculty/performance/:academicYearId
Access: Private (SUPER_ADMIN, HOD)
GET /analytics/total-responses
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/semester-divisions-with-responses
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/visual/grouped-bar-chart/:facultyId
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/visual/line-chart/:facultyId
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/visual/unique-faculties
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/visual/unique-subjects
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/visual/radar-chart/:facultyId
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /analytics/visual/subject-performance/:subjectId
Access: Private (SUPER_ADMIN, HOD, AsstProf)
GET /dashboard/stats
Access: Private (SUPER_ADMIN, HOD, AsstProf)
Response:
{
"status": "success",
"data": {
"totalStudents": 1500,
"totalFaculty": 80,
"totalDepartments": 8,
"activeFeedbackForms": 5,
"totalResponses": 12000,
"responseRate": 85.5
}
}GET /academic-structure
Access: Private (All authenticated users)
Response:
{
"status": "success",
"data": {
"colleges": [
{
"id": "string",
"name": "string",
"departments": [
{
"id": "string",
"name": "string",
"semesters": [
{
"id": "string",
"semesterNumber": 1,
"divisions": [
{
"id": "string",
"name": "A",
"capacity": 60
}
]
}
]
}
]
}
]
}
}POST /upload/student-data
Access: Private (SUPER_ADMIN, HOD)
Content-Type: multipart/form-data
Form Data:
file: Excel file containing student data
POST /upload/faculty-data
Access: Private (SUPER_ADMIN, HOD)
Content-Type: multipart/form-data
Form Data:
file: Excel file containing faculty data
POST /upload/subject-data
Access: Private (SUPER_ADMIN, HOD)
Content-Type: multipart/form-data
Form Data:
file: Excel file containing subject data
POST /upload/faculty-matrix
Access: Private (SUPER_ADMIN, HOD)
Content-Type: multipart/form-data
Form Data:
file: Excel file containing faculty allocation matrix
POST /emails/send-form-access
Access: Private (SUPER_ADMIN, HOD)
Request Body:
{
"formId": "string",
"recipientGroups": ["students", "faculty"]
}DELETE /database/clean
Access: Private (SUPER_ADMIN only)
These endpoints require API key authentication via x-api-key header.
GET /service/faculties/abbreviations
Access: Service (API Key required)
GET /service/faculties/abbreviations/:deptId
Access: Service (API Key required)
GET /service/subjects/abbreviations
Access: Service (API Key required)
GET /service/subjects/abbreviations/:deptId
Access: Service (API Key required)
GET /health
Access: Public
Response:
{
"message": "Backend API's running at /api/v1"
}400- Bad Request (Invalid input data)401- Unauthorized (Invalid credentials or missing token)403- Forbidden (Insufficient permissions)404- Not Found (Resource not found)409- Conflict (Duplicate data)422- Unprocessable Entity (Validation errors)500- Internal Server Error
When request validation fails, the API returns detailed error information:
{
"status": "fail",
"message": "Validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}The API implements rate limiting to prevent abuse:
- General endpoints: 100 requests per 15 minutes per IP
- Authentication endpoints: 5 requests per 15 minutes per IP
- Upload endpoints: 10 requests per hour per user
DATABASE_URL=postgresql://username:password@localhost:5432/reflectify
JWT_SECRET=your-super-secret-jwt-key
JWT_EXPIRES_IN=7d
SERVICE_API_KEY=your-service-api-key
NODE_ENV=development|production
PORT=4000
# Email Configuration (Gmail SMTP)
SMTP_USER=your-gmail-email@gmail.com
SMTP_PASS=your-app-specific-password
SMTP_FROM=your-display-name@gmail.com
# Redis Configuration (for email queue)
REDIS_URL=rediss://your-redis-url:6379
# Frontend URLs (for email links)
FRONTEND_DEV_URL=http://localhost:3000
FRONTEND_PROD_URL=https://your-production-domain.com- Development: All origins allowed
- Production: Only
https://reflectify.liveallowed
enum Designation {
SUPER_ADMIN
HOD
AsstProf
LabAsst
}
enum SubjectType {
MANDATORY
ELECTIVE
}
enum LectureType {
LECTURE
LAB
TUTORIAL
SEMINAR
PROJECT
}
enum FormStatus {
DRAFT
ACTIVE
CLOSED
}
enum SemesterTypeEnum {
ODD
EVEN
}const fetch = require('node-fetch');
const baseUrl = 'http://localhost:4000/api/v1';
const token = 'your-jwt-token';
// Example: Get all departments
const response = await fetch(`${baseUrl}/departments`, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
const data = await response.json();
console.log(data);- Helmet.js - Security headers
- CORS - Cross-origin resource sharing
- JWT - Token-based authentication
- Role-based authorization - Fine-grained access control
- Input validation - Zod schema validation
- SQL injection protection - Prisma ORM
- Rate limiting - Request throttling
- Set
NODE_ENV=production - Use strong JWT secrets
- Configure proper CORS origins
- Set up SSL/TLS certificates
- Use environment variables for sensitive data
- Enable request logging
- Set up monitoring and alerting
This documentation covers all available endpoints in the Reflectify Backend API. For additional support or clarification, please refer to the source code or contact the development team.