🔀

Legacy Route Compatibility

Old flat paths like /submit-news, /validate_login still work via the shim in routes/legacy.js. Migrate clients to /api/* paths and then remove the shim.

🔐

Auth

/api/auth
POST /api/auth/login Validate credentials + return role
Body
usernamestringrequired
passwordstringrequired
POST /api/auth/check-user Check if user is active admin
Body
usernamestringrequired
POST /api/auth/resolve-role Resolve admin / super_admin role
Body
usernamestringrequired
Response
rolestring"admin" | "super_admin"
📰

News

/api/news
POST /api/news/submit Add to News + Category + Lang collections
Body
titlestringrequired
descstringrequired
hinTitlestringoptional
hinDescstringoptional
newslinkstringoptional
imagelinkstringoptional
categorystringrequired
usernamestringrequired
🎯

Quiz

/api/quiz
POST /api/quiz/submit Add single quiz question to News feed
Body
questionstringrequired
question1–4stringrequired
correctAnswerstring"Option 1"–"Option 4"
descriptionstringoptional
usernamestringrequired
POST /api/quiz/bulk-upload Upload .xlsx — bulk study/quiz questions
Multipart Form
file.xlsxrequired
Required Columns in Sheet
Exam/Categorystringrequired
Subjectstringrequired
Sectionstringrequired
Chapterstringrequired
typestring"news" | "study"
📚

Questions

/api/questions
GET /api/questions/exams List all exam categories
Response
bodystring[]exam names
GET /api/questions/subjects?exam= Subjects within an exam
Query
examstringrequired
GET /api/questions/sections?exam=&subject= Sections within exam+subject
Query
examstringrequired
subjectstringrequired
GET /api/questions/chapters?exam=&subject=§ion= Chapters in a section
Query
examstringrequired
subjectstringrequired
sectionstringrequired
GET /api/questions?exam=&subject=§ion=&chapters= Fetch full question objects
Query
chaptersstringcomma-separated list
POST /api/questions/update Partial update a question by QID
Body
qidstringrequired
dataobjectfields to update
POST /api/questions/delete Remove a question from RTDB
Body
qidstringrequired
POST /api/questions/report Flag a question with a reason
Body
qidstringrequired
messagestringrequired
usernamestringrequired
GET /api/questions/reported List all reported questions
Response
countnumbertotal reports
dataobjectqid → question+reason
POST /api/questions/upload-image Upload image to Cloud Storage
Multipart Form
qidstringrequired
imagefileimage/*
Response
imgUrlstringpublic GCS URL
GET /api/questions/pending-images Questions awaiting image upload
Response
dataobjectqid → { images[], hasImgUploaded }
🔔

Notifications

/api/notifications
POST /api/notifications/broadcast Send to all subscribers (bilingual)
Body
title_enstringrequired
title_histringoptional
fixed_desc_enstringrequired
fixed_desc_histringoptional
childKeystringrequired
imagelinkstringrequired
POST /api/notifications/user Push to a specific OneSignal player ID
Body
playerIdstringrequired — OneSignal player ID
headingstringoptional
messagestringrequired
notificationTypestringoptional
childCodestringoptional
POST /api/notifications/test Send a test broadcast notification
Body — same as /broadcast
title_en, title_histringrequired
body_en, body_histringrequired
childKey, imagelinkstringrequired
🏆

Leaderboard

/api/leaderboard
GET /api/leaderboard/reset Award top 3, notify, then zero scores
Notes
Rank 1+50%bonus on points
Rank 2+30%bonus on points
Rank 3+10%bonus on points