Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/praveenarya123/sps-backend/llms.txt

Use this file to discover all available pages before exploring further.

Roles

Every user account in SPS School Backend carries a single role that determines what they are allowed to do. The role is stored on the User document, embedded in the JWT at login, and checked by route middleware before each protected request is processed.
The role is embedded in the JWT payload at login time. After a token is issued, the role cannot change without the user logging in again to receive a new token.

The seven roles

SUPER_ADMIN

Full system access. Intended for top-level administrators who need unrestricted access to all resources and configurations across the platform.

ACADEMIC_ADMIN

Manages academic operations such as classes, sections, and academic records. Coordinates between teachers and students at the institutional level.

STUDENT_ADMIN

Handles student enrollment and record management. Creates and updates student profiles, manages roll numbers, class assignments, and sections.

FINANCE_ADMIN

Manages fee records and financial operations. Creates fee entries and reviews payment statuses for students.

OPERATIONS_ADMIN

Oversees day-to-day operational administration including attendance workflows and application processing at the administrative level.

TEACHER

Creates and manages assignments for their classes. Reviews and approves or rejects student applications directed to them.

STUDENT

Submits assignments and sends applications to teachers. Views their own attendance and fee records.

How roles are assigned

A role is set at registration time in the request body. The role field is stored directly on the User document.
1

Client sends registration request

The POST /api/auth/register endpoint accepts a role field in the JSON body.
request body
{
  "name": "Priya Sharma",
  "email": "priya@school.edu",
  "password": "secret123",
  "role": "TEACHER"
}
2

Role is persisted on the User document

Mongoose validates the value against the enum before saving. If the value is not one of the seven valid roles, the document is rejected.
models/User.js
role: {
  type: String,
  enum: [
    "SUPER_ADMIN",
    "ACADEMIC_ADMIN",
    "STUDENT_ADMIN",
    "FINANCE_ADMIN",
    "OPERATIONS_ADMIN",
    "TEACHER",
    "STUDENT"
  ]
}
3

JWT is issued at login

When the user logs in via POST /api/auth/login, a JWT is signed with the user’s _id and role in the payload.
JWT payload (decoded)
{
  "id": "64f1a2b3c4d5e6f7a8b9c0d1",
  "role": "TEACHER",
  "iat": 1700000000,
  "exp": 1700086400
}
There is no built-in endpoint to change a user’s role after registration. Role updates require direct database intervention or a custom admin endpoint.

How role checking works

Protected routes apply two middleware functions in sequence: an auth middleware that verifies the JWT and attaches req.user, followed by a role middleware that compares req.user.role to the required value.
middleware/roleMiddleware.js
module.exports = (role) => {
  return (req, res, next) => {
    if (req.user.role !== role)
      return res.status(403).json({ message: "Access denied" });
    next();
  };
};
A route that requires the TEACHER role is registered like this:
routes/teacher.js
router.post(
  "/assignment",
  authMiddleware,      // 1. Verify JWT, populate req.user
  roleMiddleware("TEACHER"), // 2. Check req.user.role === "TEACHER"
  createAssignment    // 3. Run the handler
);

What happens when the role doesn’t match

If the authenticated user’s role does not match the required role, the middleware short-circuits the request and returns a 403 response immediately. The route handler is never called.
403 response
{
  "message": "Access denied"
}
The middleware performs an exact string equality check. A SUPER_ADMIN is not automatically granted access to routes guarded by other roles. Each role must be explicitly authorized per route.

Role-to-endpoint mapping

The table below shows the intended role for each endpoint group. Routes marked open (auth only) require a valid JWT but have no role guard in the current implementation.
EndpointMethodRequired roleNotes
/api/auth/registerPOSTNonePublic — no auth required
/api/auth/loginPOSTNonePublic — no auth required
/api/student/addPOSTNone (currently open)Intended for STUDENT_ADMIN
/api/student/listGETNone (currently open)Intended for STUDENT_ADMIN, ACADEMIC_ADMIN
/api/teacher/assignmentPOSTTEACHERRole guard enforced in source
/api/attendance/markPOSTNone (currently open)Intended for TEACHER, OPERATIONS_ADMIN
/api/attendance/student/:idGETNone (currently open)Intended for TEACHER, STUDENT
/api/assignment/submitPOSTNone (currently open)Intended for STUDENT
/api/application/sendPOSTNone (currently open)Intended for STUDENT
/api/application/approve/:idPUTNone (currently open)Intended for TEACHER
/api/finance/createPOSTNone (currently open)Intended for FINANCE_ADMIN
/api/finance/listGETNone (currently open)Intended for FINANCE_ADMIN
Most endpoints currently rely only on JWT authentication, not role enforcement. Adding roleMiddleware to these routes is recommended before deploying to production.

Build docs developers (and LLMs) love