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

# Data models

> Mongoose schemas for all seven resources in SPS School Backend — fields, types, constraints, relationships, and example documents.

# Data models

SPS School Backend uses [Mongoose](https://mongoosejs.com) to define schemas for MongoDB. There are seven collections, each documented below with its fields, constraints, and an example document.

## Relationships overview

The diagram below shows how collections reference each other via `ObjectId` fields.

```mermaid theme={null}
erDiagram
    User ||--o{ Assignment : "teacherId"
    Student ||--o{ Attendance : "studentId"
    Student ||--o{ Submission : "studentId"
    Student ||--o{ Application : "studentId"
    Student ||--o{ Fee : "studentId"
    Assignment ||--o{ Submission : "assignmentId"
    User ||--o{ Application : "teacherId"
```

## Models

<AccordionGroup>
  <Accordion title="User" icon="circle-user" defaultOpen={false}>
    Stores credentials and role information for every person who can log in to the system. Each email address must be unique.

    ### Fields

    <ParamField path="body.name" type="string">
      Full name of the user.
    </ParamField>

    <ParamField path="body.email" type="string" required>
      Email address. Must be unique across all users. Used as the login identifier.
    </ParamField>

    <ParamField path="body.password" type="string" required>
      Bcrypt-hashed password. Never returned in API responses.
    </ParamField>

    <ParamField path="body.role" type="string">
      One of seven allowed values: `SUPER_ADMIN`, `ACADEMIC_ADMIN`, `STUDENT_ADMIN`, `FINANCE_ADMIN`, `OPERATIONS_ADMIN`, `TEACHER`, `STUDENT`. Enforced by a Mongoose enum constraint. See [Roles](/concepts/roles) for details.
    </ParamField>

    ### Schema source

    ```javascript models/User.js theme={null}
    const userSchema = new mongoose.Schema({
      name: String,
      email: { type: String, unique: true },
      password: String,
      role: {
        type: String,
        enum: [
          "SUPER_ADMIN",
          "ACADEMIC_ADMIN",
          "STUDENT_ADMIN",
          "FINANCE_ADMIN",
          "OPERATIONS_ADMIN",
          "TEACHER",
          "STUDENT"
        ]
      }
    });
    ```

    ### Example document

    ```json MongoDB document theme={null}
    {
      "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
      "name": "Ananya Verma",
      "email": "ananya@school.edu",
      "password": "$2b$10$...",
      "role": "TEACHER",
      "__v": 0
    }
    ```

    <Warning>
      The `password` field stores the bcrypt hash. Never expose this field in API responses.
    </Warning>
  </Accordion>

  <Accordion title="Student" icon="user-graduate" defaultOpen={false}>
    Represents a student enrolled at the school. Distinct from the `User` model — a student record holds academic identity (class, section, roll number) rather than login credentials.

    ### Fields

    <ParamField path="body.name" type="string">
      Full name of the student.
    </ParamField>

    <ParamField path="body.email" type="string">
      Email address for the student. Not required to be unique at the schema level.
    </ParamField>

    <ParamField path="body.class" type="string">
      Class or grade the student belongs to (e.g., `"10A"`, `"Grade 5"`).
    </ParamField>

    <ParamField path="body.section" type="string">
      Section within the class (e.g., `"A"`, `"B"`).
    </ParamField>

    <ParamField path="body.rollNumber" type="number">
      Numeric roll number assigned to the student within their class and section.
    </ParamField>

    ### Schema source

    ```javascript models/Student.js theme={null}
    const studentSchema = new mongoose.Schema({
      name: String,
      email: String,
      class: String,
      section: String,
      rollNumber: Number
    });
    ```

    ### Example document

    ```json MongoDB document theme={null}
    {
      "_id": "64f2b3c4d5e6f7a8b9c0d2e3",
      "name": "Rohan Mehta",
      "email": "rohan.mehta@school.edu",
      "class": "10A",
      "section": "B",
      "rollNumber": 14,
      "__v": 0
    }
    ```

    <Info>
      `Student._id` is the primary foreign key referenced by `Attendance`, `Submission`, `Application`, and `Fee` documents.
    </Info>
  </Accordion>

  <Accordion title="Attendance" icon="calendar-check" defaultOpen={false}>
    Records a single attendance event for one student on one date.

    ### Fields

    <ParamField path="body.studentId" type="ObjectId" required>
      Reference to the `Student._id` this record belongs to.
    </ParamField>

    <ParamField path="body.date" type="Date" required>
      The calendar date of the attendance event.
    </ParamField>

    <ParamField path="body.status" type="string" required>
      Attendance status for the day. Typical values are `"PRESENT"` and `"ABSENT"`, but the schema does not enforce an enum.
    </ParamField>

    ### Schema source

    ```javascript models/Attendance.js theme={null}
    const attendanceSchema = new mongoose.Schema({
      studentId: mongoose.Schema.Types.ObjectId,
      date: Date,
      status: String
    });
    ```

    ### Example document

    ```json MongoDB document theme={null}
    {
      "_id": "64f3c4d5e6f7a8b9c0d3e4f5",
      "studentId": "64f2b3c4d5e6f7a8b9c0d2e3",
      "date": "2024-03-15T00:00:00.000Z",
      "status": "PRESENT",
      "__v": 0
    }
    ```

    ### Relationships

    | Field       | References    | Description                    |
    | ----------- | ------------- | ------------------------------ |
    | `studentId` | `Student._id` | The student this record is for |

    <Tip>
      To query all attendance records for a student, filter by `studentId`. To check attendance for a class on a specific date, join with the `Student` collection on `class` and `section`.
    </Tip>
  </Accordion>

  <Accordion title="Assignment" icon="file-pen" defaultOpen={false}>
    Represents a task or assessment created by a teacher for a class.

    ### Fields

    <ParamField path="body.classId" type="number" required>
      Numeric identifier of the class the assignment is for.
    </ParamField>

    <ParamField path="body.title" type="string" required>
      Title or name of the assignment.
    </ParamField>

    <ParamField path="body.dueDate" type="Date">
      Deadline by which students must submit their work.
    </ParamField>

    <ParamField path="body.teacherId" type="ObjectId" required>
      Reference to the `User._id` of the teacher who created the assignment.
    </ParamField>

    ### Schema source

    ```javascript models/Assignment.js theme={null}
    const assignmentSchema = new mongoose.Schema({
      classId: Number,
      title: String,
      dueDate: Date,
      teacherId: mongoose.Schema.Types.ObjectId
    });
    ```

    ### Example document

    ```json MongoDB document theme={null}
    {
      "_id": "64f4d5e6f7a8b9c0d4e5f6a7",
      "classId": 10,
      "title": "Chapter 5 — Algebra Problem Set",
      "dueDate": "2024-03-22T23:59:59.000Z",
      "teacherId": "64f1a2b3c4d5e6f7a8b9c0d1",
      "__v": 0
    }
    ```

    ### Relationships

    | Field       | References | Description                             |
    | ----------- | ---------- | --------------------------------------- |
    | `teacherId` | `User._id` | The teacher who created this assignment |

    <Info>
      `Assignment._id` is referenced by `Submission.assignmentId` to link student submissions back to the original task.
    </Info>
  </Accordion>

  <Accordion title="Submission" icon="file-arrow-up" defaultOpen={false}>
    Records a student's submitted work for a specific assignment.

    ### Fields

    <ParamField path="body.assignmentId" type="ObjectId" required>
      Reference to the `Assignment._id` this submission is for.
    </ParamField>

    <ParamField path="body.studentId" type="ObjectId" required>
      Reference to the `Student._id` of the student who submitted.
    </ParamField>

    <ParamField path="body.fileUrl" type="string">
      URL pointing to the uploaded submission file (e.g., a cloud storage URL).
    </ParamField>

    <ParamField path="body.submittedAt" type="Date">
      Timestamp of when the submission was received.
    </ParamField>

    ### Schema source

    ```javascript models/Submission.js theme={null}
    const submissionSchema = new mongoose.Schema({
      assignmentId: mongoose.Schema.Types.ObjectId,
      studentId: mongoose.Schema.Types.ObjectId,
      fileUrl: String,
      submittedAt: Date
    });
    ```

    ### Example document

    ```json MongoDB document theme={null}
    {
      "_id": "64f5e6f7a8b9c0d5e6f7a8b9",
      "assignmentId": "64f4d5e6f7a8b9c0d4e5f6a7",
      "studentId": "64f2b3c4d5e6f7a8b9c0d2e3",
      "fileUrl": "https://storage.example.com/submissions/rohan-chapter5.pdf",
      "submittedAt": "2024-03-21T14:30:00.000Z",
      "__v": 0
    }
    ```

    ### Relationships

    | Field          | References       | Description                    |
    | -------------- | ---------------- | ------------------------------ |
    | `assignmentId` | `Assignment._id` | The assignment being submitted |
    | `studentId`    | `Student._id`    | The student who submitted      |
  </Accordion>

  <Accordion title="Application" icon="envelope" defaultOpen={false}>
    Represents a formal request sent from a student to a teacher — for example, a leave request, an extension, or any other workflow requiring teacher approval.

    ### Fields

    <ParamField path="body.studentId" type="ObjectId" required>
      Reference to the `Student._id` of the applicant.
    </ParamField>

    <ParamField path="body.teacherId" type="ObjectId" required>
      Reference to the `User._id` of the teacher the application is addressed to.
    </ParamField>

    <ParamField path="body.type" type="string">
      Category of the application (e.g., `"LEAVE"`, `"EXTENSION"`, `"OTHER"`).
    </ParamField>

    <ParamField path="body.message" type="string">
      The body of the application — the student's written request.
    </ParamField>

    <ParamField path="body.status" type="string" default="PENDING">
      Current state of the application. Defaults to `"PENDING"`. Updated by the teacher to `"APPROVED"` or `"REJECTED"`.
    </ParamField>

    ### Schema source

    ```javascript models/Application.js theme={null}
    const applicationSchema = new mongoose.Schema({
      studentId: mongoose.Schema.Types.ObjectId,
      teacherId: mongoose.Schema.Types.ObjectId,
      type: String,
      message: String,
      status: { type: String, default: "PENDING" }
    });
    ```

    ### Example document

    ```json MongoDB document theme={null}
    {
      "_id": "64f6f7a8b9c0d6e7f8a9b0c1",
      "studentId": "64f2b3c4d5e6f7a8b9c0d2e3",
      "teacherId": "64f1a2b3c4d5e6f7a8b9c0d1",
      "type": "LEAVE",
      "message": "I will be unable to attend school on March 25 due to a family function.",
      "status": "PENDING",
      "__v": 0
    }
    ```

    ### Relationships

    | Field       | References    | Description                                     |
    | ----------- | ------------- | ----------------------------------------------- |
    | `studentId` | `Student._id` | The student making the request                  |
    | `teacherId` | `User._id`    | The teacher who reviews and acts on the request |

    <Note>
      `status` defaults to `"PENDING"` when a new application is created. The teacher updates it to `"APPROVED"` or `"REJECTED"` via `PUT /api/application/:id`.
    </Note>
  </Accordion>

  <Accordion title="Fee" icon="receipt" defaultOpen={false}>
    Represents a fee record assigned to a student, tracking the amount owed and its payment status.

    ### Fields

    <ParamField path="body.studentId" type="ObjectId" required>
      Reference to the `Student._id` this fee is charged to.
    </ParamField>

    <ParamField path="body.amount" type="number" required>
      The fee amount in the school's base currency unit.
    </ParamField>

    <ParamField path="body.status" type="string">
      Payment status. Typical values are `"PAID"` and `"UNPAID"`, but the schema does not enforce an enum.
    </ParamField>

    ### Schema source

    ```javascript models/Fee.js theme={null}
    const feeSchema = new mongoose.Schema({
      studentId: mongoose.Schema.Types.ObjectId,
      amount: Number,
      status: String
    });
    ```

    ### Example document

    ```json MongoDB document theme={null}
    {
      "_id": "64f7a8b9c0d7e8f9a0b1c2d3",
      "studentId": "64f2b3c4d5e6f7a8b9c0d2e3",
      "amount": 12500,
      "status": "UNPAID",
      "__v": 0
    }
    ```

    ### Relationships

    | Field       | References    | Description                   |
    | ----------- | ------------- | ----------------------------- |
    | `studentId` | `Student._id` | The student who owes this fee |

    <Tip>
      To list all unpaid fees, query the `Fee` collection with `{ status: "UNPAID" }`. Combine with a `Student` lookup to display student names.
    </Tip>
  </Accordion>
</AccordionGroup>

## Field constraints summary

The table below consolidates all schema-level constraints across every model.

| Model       | Field    | Constraint                                             |
| ----------- | -------- | ------------------------------------------------------ |
| User        | `email`  | `unique: true`                                         |
| User        | `role`   | `enum` — must be one of the seven defined role strings |
| Application | `status` | `default: "PENDING"`                                   |

<Info>
  All other fields use Mongoose's loose defaults — they are optional unless your application-level validation enforces them. Consider adding `required: true` to critical foreign-key fields like `studentId` and `teacherId` in production.
</Info>
