Cloudflare Workers backend for Singularity AKTU result analysis platform.
Production Server: https://singularity-server.devxoshakya.workers.dev/
Create a .env file in this directory with the following variables:
# Database
DATABASE_URL=your_mongodb_connection_string
# Better Auth Configuration
BETTER_AUTH_SECRET=your_random_secret_key_here
BETTER_AUTH_URL=https://your-worker-url.workers.dev
# CORS
CORS_ORIGIN=https://your-frontend-domain.com
# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secretCopy .env.example to .env and fill in your values:
cp .env.example .envUse Wrangler to set secrets for production:
# Set all secrets
wrangler secret put DATABASE_URL
wrangler secret put BETTER_AUTH_SECRET
wrangler secret put BETTER_AUTH_URL
wrangler secret put CORS_ORIGIN
wrangler secret put GOOGLE_CLIENT_ID
wrangler secret put GOOGLE_CLIENT_SECRETOr set them via the Cloudflare Dashboard:
- Go to Workers & Pages
- Select your worker
- Go to Settings > Variables
- Add each environment variable as a secret
- Go to Google Cloud Console
- Create a new project or select existing one
- Enable Google+ API
- Go to Credentials > Create Credentials > OAuth 2.0 Client ID
- Configure OAuth consent screen
- Add authorized redirect URIs:
https://your-worker-url.workers.dev/api/auth/callback/googlehttp://localhost:8787/api/auth/callback/google(for local dev)
- Copy Client ID and Client Secret to your environment variables
Returns detailed result information for a specific student by their roll number.
Endpoint: GET /api/result/by-rollno
Query Parameters:
rollNo(required) - Student's roll number (must be numeric digits only)sem(optional) -1..8,latest, orall(default)
Example Request:
GET https://singularity-server.devxoshakya.workers.dev/api/result/by-rollno?rollNo=1234567890123&sem=latestSuccess Response (200 OK):
{
"success": true,
"data": {
"id": "507f1f77bcf86cd799439011",
"rollNo": "1234567890123",
"enrollmentNo": "EN123456789",
"fullName": "John Doe",
"blocked": false,
"fatherName": "Father Name",
"course": "B.Tech",
"branch": "Computer Science",
"year": 2,
"CarryOvers": [],
"divison": "First Division",
"cgpa": "8.6",
"instituteName": "MIET",
"latestResultStatus": "Pass",
"latestCOP": "8.7",
"semester": "1",
"evenOdd": "Odd",
"totalMarksObtained": 862,
"resultStatus": "CP( 0)",
"SGPA": 9.86,
"dateOfDeclaration": "25/06/24",
"subjects": [
{
"code": "BAS101",
"name": "Engineering Physics",
"type": "Theory",
"internal": "30",
"external": "67",
"backPaper": "--",
"grade": "A+"
}
]
}
}Response Notes:
- When
sem=1..8orsem=latest,semestersarray is omitted and selected semester fields are flattened ondata. - When
semis omitted (orsem=all),semestersis included.
Error Responses:
400 Bad Request- Invalid or missing roll numberOr with validation details:{ "error": "Roll number is required" }{ "error": "Validation failed", "details": [...] }404 Not Found- Result not found{ "error": "Result not found for the provided roll number" }500 Internal Server Error- Server error{ "error": "Internal server error" }
Returns all student results for a specific year.
Endpoint: GET /api/result/by-year
Query Parameters:
year(required) - Academic year (1-4)sem(optional) -1..8,latest, orall(default)
Example Request:
GET https://singularity-server.devxoshakya.workers.dev/api/result/by-year?year=2&sem=latestSuccess Response (200 OK):
{
"success": true,
"data": [
{
"id": "507f1f77bcf86cd799439011",
"rollNo": "1234567890123",
"enrollmentNo": "EN123456789",
"fullName": "John Doe",
"blocked": false,
"fatherName": "Father Name",
"course": "B.Tech",
"branch": "Computer Science",
"year": 2,
"CarryOvers": [],
"divison": "First Division",
"cgpa": "8.6",
"instituteName": "MIET",
"latestResultStatus": "Pass",
"latestCOP": "8.7",
"semester": "4",
"evenOdd": "Even",
"totalMarksObtained": 792,
"resultStatus": "CP( 0)",
"SGPA": 8.91,
"dateOfDeclaration": "14/08/25",
"subjects": [...]
}
],
"totalCount": 150
}Error Responses:
400 Bad Request- Invalid parametersOr with validation details:{ "error": "Year is required" }{ "error": "Validation failed", "details": [ { "message": "Year must be between 1 and 4", "path": ["year"] } ] }500 Internal Server Error- Server error{ "error": "Internal server error" }
Notes:
- Results are ordered by roll number in ascending order
- Endpoint uses Prisma Accelerate caching for optimized performance
- For
sem=latest, API computes the maximum semester available in the selected year and returns only students having that semester - Students with incomplete semester progression (for example dropped out at sem 2 while latest is sem 5) are excluded for
sem=latest - When
sem=1..8orsem=latest,semestersis omitted and selected semester fields are flattened per student
Comprehensive analytics API for student performance visualization.
Student status is now derived from carry-over count only:
Pass:0carry oversPCP:1to2carry oversFail:>= 3carry overs
Carry-over parsing supports both payload shapes:
- Historical object records:
{ session, sem, cop } - No-backlog marker:
["No Backlogs"]
Endpoint: GET /api/analytics/student-status-distribution
Query Params:
year(optional)branch(optional, normalized branch code such asCSE,ECE)
Response shape:
{
"success": true,
"data": {
"total": 1500,
"distribution": [
{ "status": "Pass", "count": 1200, "percentage": 80, "fill": "var(--chart-1)" },
{ "status": "PCP", "count": 250, "percentage": 16.67, "fill": "var(--chart-2)" },
{ "status": "Fail", "count": 50, "percentage": 3.33, "fill": "var(--chart-3)" }
]
}
}Endpoint: GET /api/analytics/branch-status-breakdown
Query Params:
year(optional)
Returns branch-wise pass/pcp/fail counts and pass rate.
Endpoint: GET /api/analytics/year-branch-comparison
Query Params:
years(optional, default1,2,3,4)branches(optional)metric(optional:avgSgpa|passRate|avgMarks)
Endpoint: GET /api/analytics/performance-metrics
Important: this endpoint now requires exactly two years for comparison.
Accepted query formats:
- Preferred:
years=2,1 - Backward compatible:
year=2&compareWith=1
Query Params:
years(required unless using backward-compatible pair)year+compareWith(backward-compatible pair)branch(optional)
Error response:
{
"success": false,
"error": "Please provide exactly 2 years using `years=Y1,Y2` (or `year` and `compareWith`)."
}Success response includes both years:
{
"success": true,
"data": {
"current": {
"year": 2,
"avgSgpa": 7.82,
"avgMarks": 684.2,
"passRate": 81.4,
"totalStudents": 1400,
"topPerformers": 120,
"withBacklogs": 322,
"statusDistribution": { "Pass": 1078, "PCP": 250, "Fail": 72 }
},
"compare": {
"year": 1,
"avgSgpa": 7.55,
"avgMarks": 663.1,
"passRate": 78.9,
"totalStudents": 1360,
"topPerformers": 98,
"withBacklogs": 351,
"statusDistribution": { "Pass": 1073, "PCP": 210, "Fail": 77 }
},
"comparison": {
"baseYear": 2,
"compareYear": 1,
"metrics": {
"avgSgpa": "+3.6%",
"passRate": "+3.2%",
"trend": "up"
}
},
"insights": ["..."]
}
}Endpoint: GET /api/analytics/semester-progression
Query Params:
year(optional)branch(optional)
Endpoint: GET /api/analytics/sgpa-range-distribution
Query Params:
year(optional)branch(optional)semester(optional:latestor1..8)
Endpoint: GET /api/analytics/backlog-analysis
Important: year is now mandatory to avoid expensive full-dataset scans.
Query Params:
year(required)branch(optional)groupBy(optional:semester|subject|branch, defaultsemester)
Backlog active/cleared computation now uses carry-over history + latest COP codes:
- Active backlog code: still present in
latestCOP - Cleared backlog code: present in history but not in
latestCOP
Error response:
{
"success": false,
"error": "`year` query param is required for backlog analysis."
}Success response now includes meta:
{
"success": true,
"data": [
{
"category": "CSE",
"activeBacklogs": 120,
"clearedBacklogs": 280,
"totalBacklogs": 400,
"clearanceRate": 70
}
],
"meta": {
"year": 2,
"groupBy": "branch",
"students": 1500,
"studentsWithBacklogs": 325,
"activeBacklogs": 240,
"clearedBacklogs": 510,
"totalBacklogs": 750,
"clearanceRate": 68
}
}Endpoint: GET /api/analytics/branch-performance-radar
Query Params:
year(optional)
Endpoint: GET /api/analytics/top-performers
Query Params:
limit(optional, default10)year(optional)branch(optional)metric(optional:sgpa|marks)
| Endpoint | Method | Purpose | Chart Type |
|---|---|---|---|
/api/analytics/student-status-distribution |
GET | Pass/PCP/Fail counts | Pie Chart |
/api/analytics/branch-status-breakdown |
GET | Branch-wise status breakdown | Grouped Bar Chart |
/api/analytics/year-branch-comparison |
GET | Multi-year branch comparison | Area Chart |
/api/analytics/performance-metrics |
GET | KPI cards + mandatory 2-year comparison | Stats Cards |
/api/analytics/semester-progression |
GET | Semester trends | Line Chart |
/api/analytics/sgpa-range-distribution |
GET | SGPA distribution | Histogram |
/api/analytics/backlog-analysis |
GET | Backlog active/cleared analysis | Stacked Bar Chart |
/api/analytics/branch-performance-radar |
GET | Multi-dimensional branch metrics | Radar Chart |
/api/analytics/top-performers |
GET | Top students leaderboard | Radial Bar / Table |
bun run devbun run deploy