> ## 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

> Role-based access control in SPS School Backend — the seven user roles, how they are assigned, and how the middleware enforces them.

# 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.

<Note>
  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.
</Note>

## The seven roles

<CardGroup cols={2}>
  <Card title="SUPER_ADMIN" icon="crown" color="#2563EB">
    Full system access. Intended for top-level administrators who need unrestricted access to all resources and configurations across the platform.
  </Card>

  <Card title="ACADEMIC_ADMIN" icon="graduation-cap" color="#7C3AED">
    Manages academic operations such as classes, sections, and academic records. Coordinates between teachers and students at the institutional level.
  </Card>

  <Card title="STUDENT_ADMIN" icon="users" color="#059669">
    Handles student enrollment and record management. Creates and updates student profiles, manages roll numbers, class assignments, and sections.
  </Card>

  <Card title="FINANCE_ADMIN" icon="money-bill" color="#D97706">
    Manages fee records and financial operations. Creates fee entries and reviews payment statuses for students.
  </Card>

  <Card title="OPERATIONS_ADMIN" icon="gears" color="#DC2626">
    Oversees day-to-day operational administration including attendance workflows and application processing at the administrative level.
  </Card>

  <Card title="TEACHER" icon="chalkboard-user" color="#0891B2">
    Creates and manages assignments for their classes. Reviews and approves or rejects student applications directed to them.
  </Card>

  <Card title="STUDENT" icon="user-graduate" color="#65A30D">
    Submits assignments and sends applications to teachers. Views their own attendance and fee records.
  </Card>
</CardGroup>

## 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.

<Steps>
  <Step title="Client sends registration request">
    The `POST /api/auth/register` endpoint accepts a `role` field in the JSON body.

    ```json request body theme={null}
    {
      "name": "Priya Sharma",
      "email": "priya@school.edu",
      "password": "secret123",
      "role": "TEACHER"
    }
    ```
  </Step>

  <Step title="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.

    ```javascript models/User.js theme={null}
    role: {
      type: String,
      enum: [
        "SUPER_ADMIN",
        "ACADEMIC_ADMIN",
        "STUDENT_ADMIN",
        "FINANCE_ADMIN",
        "OPERATIONS_ADMIN",
        "TEACHER",
        "STUDENT"
      ]
    }
    ```
  </Step>

  <Step title="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.

    ```json JWT payload (decoded) theme={null}
    {
      "id": "64f1a2b3c4d5e6f7a8b9c0d1",
      "role": "TEACHER",
      "iat": 1700000000,
      "exp": 1700086400
    }
    ```
  </Step>
</Steps>

<Warning>
  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.
</Warning>

## 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.

```javascript middleware/roleMiddleware.js theme={null}
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:

```javascript routes/teacher.js theme={null}
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.

```json 403 response theme={null}
{
  "message": "Access denied"
}
```

<Info>
  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.
</Info>

## 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.

| Endpoint                       | Method | Required role         | Notes                                          |
| ------------------------------ | ------ | --------------------- | ---------------------------------------------- |
| `/api/auth/register`           | POST   | None                  | Public — no auth required                      |
| `/api/auth/login`              | POST   | None                  | Public — no auth required                      |
| `/api/student/add`             | POST   | None (currently open) | Intended for `STUDENT_ADMIN`                   |
| `/api/student/list`            | GET    | None (currently open) | Intended for `STUDENT_ADMIN`, `ACADEMIC_ADMIN` |
| `/api/teacher/assignment`      | POST   | `TEACHER`             | Role guard enforced in source                  |
| `/api/attendance/mark`         | POST   | None (currently open) | Intended for `TEACHER`, `OPERATIONS_ADMIN`     |
| `/api/attendance/student/:id`  | GET    | None (currently open) | Intended for `TEACHER`, `STUDENT`              |
| `/api/assignment/submit`       | POST   | None (currently open) | Intended for `STUDENT`                         |
| `/api/application/send`        | POST   | None (currently open) | Intended for `STUDENT`                         |
| `/api/application/approve/:id` | PUT    | None (currently open) | Intended for `TEACHER`                         |
| `/api/finance/create`          | POST   | None (currently open) | Intended for `FINANCE_ADMIN`                   |
| `/api/finance/list`            | GET    | None (currently open) | Intended for `FINANCE_ADMIN`                   |

<Tip>
  Most endpoints currently rely only on JWT authentication, not role enforcement. Adding `roleMiddleware` to these routes is recommended before deploying to production.
</Tip>
