building backend project laravel restful API.
This document provides a comprehensive explanation of all backend API flows, user actions, and system interactions. It is designed to help frontend developers understand how to integrate with the backend and implement role-based features.
- System Architecture Overview
- Authentication Flow ( santum)
- Admin Operations Flow
- Teacher Operations Flow
- Student Operations Flow
- Public Library Flow
- Data Relationships
- Security Model
This document provides separate flow diagrams for each user role in the Smart Learning Lab system.
graph TD
subgraph Authentication
A1[Admin Login] --> A2[POST /auth/login]
A2 --> A3[Receive JWT Token]
A3 --> A4[GET /auth/me]
A4 --> A5[Load Admin Dashboard]
end
subgraph User Management
A5 --> B1[View Users]
B1 --> B2[GET /users]
B2 --> B3{Action}
B3 -->|Create| B4[POST /users]
B3 -->|Edit| B5[PUT /users/id]
B3 -->|Delete| B6[DELETE /users/id]
B3 -->|View| B7[GET /users/id]
B4 --> B8[User Created]
B5 --> B9[User Updated]
B6 --> B10[User Deleted]
end
subgraph Department Management
A5 --> C1[View Departments]
C1 --> C2[GET /departments]
C2 --> C3{Action}
C3 -->|Create| C4[POST /departments]
C3 -->|Edit| C5[PUT /departments/id]
C3 -->|Delete| C6[DELETE /departments/id]
C4 --> C7[Department Created]
C5 --> C8[Department Updated]
C6 --> C9[Department Deleted]
end
subgraph Class Management
A5 --> D1[View Classes]
D1 --> D2[GET /classes]
D2 --> D3{Action}
D3 -->|Create| D4[POST /classes]
D3 -->|Edit| D5[PUT /classes/id]
D3 -->|Delete| D6[DELETE /classes/id]
D3 -->|Enroll| D7[POST /classes/id/enroll]
D4 --> D8[Class Created]
D5 --> D9[Class Updated]
D6 --> D10[Class Deleted]
D7 --> D11[Student Enrolled]
end
sequenceDiagram
participant Admin
participant Frontend
participant API
participant Database
Note over Admin,Database: Create New Teacher
Admin->>Frontend: Click Create User
Frontend->>Frontend: Show User Form
Admin->>Frontend: Fill form with role=teacher
Frontend->>API: POST /api/v1/users
API->>Database: INSERT user record
Database-->>API: User ID
API-->>Frontend: 201 Created
Frontend->>Frontend: Update user list
Frontend-->>Admin: Show success message
Note over Admin,Database: Delete User
Admin->>Frontend: Click Delete on user row
Frontend->>Frontend: Show confirmation dialog
Admin->>Frontend: Confirm deletion
Frontend->>API: DELETE /api/v1/users/5
API->>Database: DELETE user WHERE id=5
Database-->>API: Affected rows
API-->>Frontend: 204 No Content
Frontend->>Frontend: Remove row from list
sequenceDiagram
participant Admin
participant API
participant Database
Note over Admin,Database: Create Department with Classes
Admin->>API: POST /api/v1/departments
Note right of Admin: name: Science Dept
API->>Database: INSERT department
Database-->>API: Department ID=1
API-->>Admin: Department created
Admin->>API: POST /api/v1/classes
Note right of Admin: department_id: 1, teacher_id: 3
API->>Database: INSERT class
Database-->>API: Class ID=1
API-->>Admin: Class created
Admin->>API: POST /api/v1/classes/1/enroll
Note right of Admin: student_id: 5
API->>Database: INSERT class_student pivot
API-->>Admin: Student enrolled
| Category | Endpoint | Method | Description |
|---|---|---|---|
| Users | /api/v1/users | GET | List all users |
| Users | /api/v1/users | POST | Create new user |
| Users | /api/v1/users/{id} | GET | Get user details |
| Users | /api/v1/users/{id} | PUT | Update user |
| Users | /api/v1/users/{id} | DELETE | Delete user |
| Departments | /api/v1/departments | GET | List all departments |
| Departments | /api/v1/departments | POST | Create department |
| Departments | /api/v1/departments/{id} | GET | Get department details |
| Departments | /api/v1/departments/{id} | PUT | Update department |
| Departments | /api/v1/departments/{id} | DELETE | Delete department |
| Classes | /api/v1/classes | POST | Create class |
| Classes | /api/v1/classes/{id} | PUT | Update class |
| Classes | /api/v1/classes/{id} | DELETE | Delete class |
| Classes | /api/v1/classes/{id}/enroll | POST | Enroll student |
graph TD
subgraph Authentication
T1[Teacher Login] --> T2[POST /auth/login]
T2 --> T3[Receive JWT Token]
T3 --> T4[GET /auth/me]
T4 --> T5[Load Teacher Dashboard]
end
subgraph Quiz Management
T5 --> Q1[View My Quizzes]
Q1 --> Q2[GET /quizzes]
Q2 --> Q3{Action}
Q3 -->|Create| Q4[Create Quiz Flow]
Q3 -->|Edit| Q5[PUT /quizzes/id]
Q3 -->|Delete| Q6[DELETE /quizzes/id]
Q3 -->|View Results| Q7[GET /quizzes/id/analytics]
end
subgraph Create Quiz Flow
Q4 --> CQ1[POST /quizzes - Draft]
CQ1 --> CQ2[Add Questions]
CQ2 --> CQ3[POST /quizzes/id/questions]
CQ3 --> CQ4{More Questions?}
CQ4 -->|Yes| CQ3
CQ4 -->|No| CQ5[Set Schedule]
CQ5 --> CQ6[PUT /quizzes/id - starts_at/ends_at]
CQ6 --> CQ7[Publish]
CQ7 --> CQ8[PUT /quizzes/id - status=published]
end
subgraph Learning Path Management
T5 --> LP1[View Learning Paths]
LP1 --> LP2[GET /learning-paths]
LP2 --> LP3{Action}
LP3 -->|Create| LP4[POST /learning-paths]
LP3 -->|Edit| LP5[PUT /learning-paths/id]
LP3 -->|Delete| LP6[DELETE /learning-paths/id]
end
subgraph Document Management
T5 --> D1[View Documents]
D1 --> D2[GET /documents]
D2 --> D3{Action}
D3 -->|Upload| D4[POST /documents]
D3 -->|Delete| D5[DELETE /documents/id]
end
subgraph Class Operations
T5 --> CL1[View My Classes]
CL1 --> CL2[GET /classes]
CL2 --> CL3[Select Class]
CL3 --> CL4{Action}
CL4 -->|Enroll Student| CL5[POST /classes/id/enroll]
CL4 -->|View Leaderboard| CL6[GET /quizzes/id/leaderboard]
end
subgraph Override Management
T5 --> O1[Manage Overrides]
O1 --> O2[Select Quiz]
O2 --> O3[POST /quizzes/id/overrides]
O3 --> O4[Override Created]
end
sequenceDiagram
participant Teacher
participant Frontend
participant API
participant Database
Note over Teacher,Database: Step 1 - Create Draft Quiz
Teacher->>Frontend: Click New Quiz
Teacher->>Frontend: Fill quiz details
Frontend->>API: POST /api/v1/quizzes
Note right of Frontend: title, description, status=draft
API->>Database: INSERT quiz
Database-->>API: Quiz ID=10
API-->>Frontend: Quiz created
Frontend->>Frontend: Navigate to Question Builder
Note over Teacher,Database: Step 2 - Add MCQ Question
Teacher->>Frontend: Click Add Question
Teacher->>Frontend: Select MCQ type
Teacher->>Frontend: Enter question and options
Frontend->>API: POST /api/v1/quizzes/10/questions
Note right of Frontend: type=mcq, options with is_correct
API->>Database: INSERT question + options
API-->>Frontend: Question added
Note over Teacher,Database: Step 3 - Add True/False Question
Teacher->>Frontend: Click Add Question
Teacher->>Frontend: Select True/False type
Frontend->>API: POST /api/v1/quizzes/10/questions
Note right of Frontend: type=true_false
API->>Database: INSERT question + options
API-->>Frontend: Question added
Note over Teacher,Database: Step 4 - Schedule and Publish
Teacher->>Frontend: Click Settings
Teacher->>Frontend: Set start and end dates
Frontend->>API: PUT /api/v1/quizzes/10
Note right of Frontend: starts_at, ends_at
API->>Database: UPDATE quiz
API-->>Frontend: Quiz updated
Teacher->>Frontend: Click Publish
Frontend->>API: PUT /api/v1/quizzes/10
Note right of Frontend: status=published
API->>Database: UPDATE quiz status
API-->>Frontend: Quiz published
stateDiagram-v2
[*] --> Draft: POST /quizzes
Draft --> Draft: POST /questions
Draft --> Scheduled: PUT /quizzes - set dates
Draft --> Published: PUT /quizzes - status=published
Scheduled --> Published: PUT /quizzes - status=published
Published --> Archived: PUT /quizzes - status=archived
Archived --> [*]
note right of Draft: Add/Edit Questions
note right of Scheduled: Waiting for start date
note right of Published: Students can take quiz
note right of Archived: No longer available
sequenceDiagram
participant Teacher
participant API
participant Database
Note over Teacher,Database: Grant Extra Time to Student
Teacher->>API: POST /api/v1/quizzes/10/overrides
Note right of Teacher: user_id: 5, new_duration_minutes: 90
API->>Database: INSERT/UPDATE quiz_override
API-->>Teacher: Override created
Note over Teacher,Database: Grant Extra Attempts
Teacher->>API: POST /api/v1/quizzes/10/overrides
Note right of Teacher: user_id: 5, new_attempts_allowed: 3
API->>Database: Calculate additional_attempts
API->>Database: INSERT/UPDATE quiz_override
API-->>Teacher: Override created
| Category | Endpoint | Method | Description |
|---|---|---|---|
| Quizzes | /api/v1/quizzes | GET | List all quizzes |
| Quizzes | /api/v1/quizzes | POST | Create new quiz |
| Quizzes | /api/v1/quizzes/{id} | GET | Get quiz details |
| Quizzes | /api/v1/quizzes/{id} | PUT | Update quiz |
| Quizzes | /api/v1/quizzes/{id} | DELETE | Delete quiz |
| Questions | /api/v1/quizzes/{id}/questions | GET | List quiz questions |
| Questions | /api/v1/quizzes/{id}/questions | POST | Add question |
| Overrides | /api/v1/quizzes/{id}/overrides | POST | Create student override |
| Analytics | /api/v1/quizzes/{id}/analytics | GET | View quiz analytics |
| Learning Paths | /api/v1/learning-paths | POST | Create learning path |
| Learning Paths | /api/v1/learning-paths/{id} | PUT | Update learning path |
| Learning Paths | /api/v1/learning-paths/{id} | DELETE | Delete learning path |
| Documents | /api/v1/documents | POST | Upload document |
| Documents | /api/v1/documents/{id} | DELETE | Delete document |
| Classes | /api/v1/classes/{id}/enroll | POST | Enroll student in class |
graph TD
subgraph Authentication
S1[Student Login] --> S2[POST /auth/login]
S2 --> S3[Receive JWT Token]
S3 --> S4[GET /auth/me]
S4 --> S5[Load Student Profile]
end
subgraph View Content
S5 --> V1[View Available Quizzes]
V1 --> V2[GET /quizzes]
V2 --> V3[Filter by status=published]
S5 --> V4[View My Classes]
V4 --> V5[GET /classes]
S5 --> V6[View Learning Paths]
V6 --> V7[GET /learning-paths]
S5 --> V8[View Library]
V8 --> V9[GET /documents]
end
subgraph Take Quiz Flow
V3 --> Q1[Select Quiz]
Q1 --> Q2[GET /quizzes/id]
Q2 --> Q3[Start Attempt]
Q3 --> Q4[POST /quizzes/id/attempts]
Q4 --> Q5[Answer Questions]
Q5 --> Q6[POST /attempts/id/answers]
Q6 --> Q7{More Questions?}
Q7 -->|Yes| Q5
Q7 -->|No| Q8[Submit Quiz]
Q8 --> Q9[POST /attempts/id/submit]
Q9 --> Q10[View Results]
end
subgraph View Results
Q10 --> R1[Score Display]
R1 --> R2[Correct/Incorrect Breakdown]
R2 --> R3[View Leaderboard]
R3 --> R4[GET /quizzes/id/leaderboard]
end
subgraph Past Attempts
S5 --> P1[View My Attempts]
P1 --> P2[GET /quizzes/id/attempts]
P2 --> P3[Select Attempt]
P3 --> P4[GET /attempts/id]
P4 --> P5[View Detailed Result]
end
sequenceDiagram
participant Student
participant Frontend
participant API
participant Database
Note over Student,Database: Start Quiz Attempt
Student->>Frontend: Click Start Quiz
Frontend->>API: POST /api/v1/quizzes/10/attempts
API->>Database: Check max attempts
API->>Database: Check overrides for student
API->>Database: CREATE attempt record
Database-->>API: Attempt ID=25
API-->>Frontend: Attempt started
Frontend->>Frontend: Load quiz interface with timer
Note over Student,Database: Answer Questions
loop For each question
Frontend->>Frontend: Display question
Student->>Frontend: Select answer
Frontend->>API: POST /api/v1/attempts/25/answers
Note right of Frontend: question_id, answer_content
API->>Database: INSERT/UPDATE answer
API-->>Frontend: Answer saved
end
Note over Student,Database: Submit Quiz
Student->>Frontend: Click Submit
Frontend->>API: POST /api/v1/attempts/25/submit
API->>Database: Update attempt status=submitted
API->>API: Calculate score via ScoringService
API->>Database: Update answer.is_correct for each
API->>Database: Update attempt.score
API-->>Frontend: Return result with breakdown
Frontend->>Frontend: Display score
Frontend->>Frontend: Show correct/incorrect for each
graph LR
subgraph Response
A[attempt_id] --> B[status: submitted]
B --> C[score: 8]
C --> D[total_points: 10]
D --> E[submitted_at]
E --> F[answers array]
end
subgraph Each Answer
F --> G1[question_id]
G1 --> G2[is_correct: true/false]
G2 --> G3[points_awarded]
G3 --> G4[correct_option_id]
end
stateDiagram-v2
[*] --> NotStarted: Quiz Available
NotStarted --> InProgress: POST /attempts
InProgress --> InProgress: POST /answers
InProgress --> Submitted: POST /submit
Submitted --> [*]: View Results
note right of NotStarted: Student sees quiz in list
note right of InProgress: Timer running, autosave
note right of Submitted: Score calculated
sequenceDiagram
participant Student
participant API
participant Database
Student->>API: GET /api/v1/quizzes/10/leaderboard
API->>Database: SELECT attempts WHERE quiz_id=10
API->>API: Group by student_id
API->>API: Get best score per student
API->>API: Sort by score DESC
API->>API: Take top 10
API-->>Student: Leaderboard array
Note over Student: Display ranking table
| Category | Endpoint | Method | Description |
|---|---|---|---|
| Profile | /api/v1/auth/me | GET | Get own profile |
| Profile | /api/v1/auth/profile | PUT | Update own profile |
| Classes | /api/v1/classes | GET | List enrolled classes |
| Classes | /api/v1/classes/{id} | GET | View class details |
| Quizzes | /api/v1/quizzes | GET | List available quizzes |
| Quizzes | /api/v1/quizzes/{id} | GET | View quiz details |
| Attempts | /api/v1/quizzes/{id}/attempts | GET | List own attempts |
| Attempts | /api/v1/quizzes/{id}/attempts | POST | Start new attempt |
| Attempts | /api/v1/quizzes/{id}/leaderboard | GET | View quiz leaderboard |
| Answers | /api/v1/attempts/{id}/answers | POST | Submit answer |
| Submit | /api/v1/attempts/{id}/submit | POST | Finish and submit attempt |
| Results | /api/v1/attempts/{id} | GET | View attempt result |
| Paths | /api/v1/learning-paths | GET | List learning paths |
| Paths | /api/v1/learning-paths/{id} | GET | View learning path |
| Library | /api/v1/documents | GET | List documents |
| Library | /api/v1/documents/{id} | GET | View document |
| Library | /api/v1/documents/{id}/download | GET | Download document |
| Feature | Admin | Teacher | Student |
|---|---|---|---|
| Login/Logout | Yes | Yes | Yes |
| View Profile | Yes | Yes | Yes |
| Update Profile | Yes | Yes | Yes |
| Manage Users | Yes | No | No |
| Manage Departments | Yes | No | No |
| Create Classes | Yes | No | No |
| Update/Delete Classes | Yes | No | No |
| Enroll Students | Yes | Yes | No |
| Create Quizzes | Yes | Yes | No |
| Edit/Delete Quizzes | Yes | Yes | No |
| Add Questions | Yes | Yes | No |
| Create Overrides | Yes | Yes | No |
| View Analytics | Yes | Yes | No |
| Create Learning Paths | Yes | Yes | No |
| Upload Documents | Yes | Yes | No |
| Delete Documents | Yes | Yes | No |
| View Quizzes | Yes | Yes | Yes |
| Take Quizzes | No | No | Yes |
| View Leaderboard | Yes | Yes | Yes |
| View Library | Yes | Yes | Yes |
| Download Documents | Yes | Yes | Yes |
The Smart Learning Lab backend is built on Laravel with a RESTful API architecture. All endpoints are prefixed with /api/v1/ and use JSON for request and response bodies.
graph TD
subgraph Public Access
A[Landing Page] --> B[Public Library]
B --> C[View Documents]
B --> D[Download Documents]
end
subgraph Authentication
E[Login Page] --> F{Authenticate}
F -->|Success| G[JWT Token Issued]
F -->|Failure| H[Error Response]
G --> I{Role Check}
end
subgraph Role-Based Routing
I -->|Admin| J[Admin Dashboard]
I -->|Teacher| K[Teacher Dashboard]
I -->|Student| L[Student Profile]
end
subgraph Admin Dashboard
J --> M[Manage Users]
J --> N[Manage Departments]
J --> O[Manage Classes]
end
subgraph Teacher Dashboard
K --> P[Manage Quizzes]
K --> Q[Manage Learning Paths]
K --> R[View Analytics]
K --> S[Upload Documents]
end
subgraph Student Profile
L --> T[View Assigned Quizzes]
L --> U[Take Quizzes]
L --> V[View Results]
L --> W[View Leaderboard]
end
| Role | Access Level | Primary Functions |
|---|---|---|
| Admin | Full | System configuration, User management |
| Teacher | Elevated | Content creation, Class management |
| Student | Standard | Content consumption, Quiz participation |
Authentication is handled via Laravel Sanctum with JWT tokens. Every authenticated request must include the token in the Authorization header.
sequenceDiagram
participant User
participant Frontend
participant API
participant Database
User->>Frontend: Enter credentials
Frontend->>API: POST /api/v1/auth/login
API->>Database: Validate credentials
Database-->>API: User record
API-->>Frontend: JWT access_token
Frontend->>Frontend: Store token in localStorage
Frontend->>API: GET /api/v1/auth/me (with token)
API-->>Frontend: User profile with role
Frontend->>Frontend: Route to role-specific dashboard
| Endpoint | Method | Description | Auth Required |
|---|---|---|---|
| /api/v1/auth/login | POST | Authenticate user | No |
| /api/v1/auth/logout | POST | Invalidate current token | Yes |
| /api/v1/auth/me | GET | Get current user profile | Yes |
| /api/v1/auth/profile | PUT | Update user profile | Yes |
{
"email": "admin@smartlab.com",
"password": "password123"
}{
"access_token": "1|abc123xyz...",
"token_type": "Bearer",
"user": {
"id": 1,
"name": "Admin User",
"email": "admin@smartlab.com",
"role": "admin"
}
}Admins have full access to system configuration and user management. These operations are restricted by middleware to the admin role only.
graph LR
subgraph User Management
A1[List Users] --> A2[Create User]
A2 --> A3[View User]
A3 --> A4[Update User]
A4 --> A5[Delete User]
end
subgraph Department Management
B1[List Departments] --> B2[Create Department]
B2 --> B3[View Department]
B3 --> B4[Update Department]
B4 --> B5[Delete Department]
end
subgraph Class Management
C1[List Classes] --> C2[Create Class]
C2 --> C3[View Class]
C3 --> C4[Update Class]
C4 --> C5[Delete Class]
end
| Endpoint | Method | Description | Role Required |
|---|---|---|---|
| /api/v1/users | GET | List all users | Admin |
| /api/v1/users | POST | Create new user | Admin |
| /api/v1/users/{id} | GET | Get user details | Admin |
| /api/v1/users/{id} | PUT | Update user | Admin |
| /api/v1/users/{id} | DELETE | Delete user | Admin |
{
"name": "John Teacher",
"email": "john.teacher@school.com",
"password": "securepassword",
"role": "teacher",
"is_active": true
}| Endpoint | Method | Description | Role Required |
|---|---|---|---|
| /api/v1/departments | GET | List all departments | Admin |
| /api/v1/departments | POST | Create new department | Admin |
| /api/v1/departments/{id} | GET | Get department details | Admin |
| /api/v1/departments/{id} | PUT | Update department | Admin |
| /api/v1/departments/{id} | DELETE | Delete department | Admin |
| Endpoint | Method | Description | Role Required |
|---|---|---|---|
| /api/v1/classes | GET | List all classes | All Authenticated |
| /api/v1/classes | POST | Create new class | Admin |
| /api/v1/classes/{id} | GET | Get class details | All Authenticated |
| /api/v1/classes/{id} | PUT | Update class | Admin |
| /api/v1/classes/{id} | DELETE | Delete class | Admin |
| /api/v1/classes/{id}/enroll | POST | Enroll student in class | Admin, Teacher |
{
"student_id": 5
}Or alternatively:
{
"email": "student@school.com"
}Teachers can create and manage educational content including quizzes, learning paths, and documents. They can also view analytics for their classes.
sequenceDiagram
participant Teacher
participant API
participant Database
Note over Teacher,Database: Quiz Creation Flow
Teacher->>API: POST /api/v1/quizzes (status: draft)
API->>Database: Create quiz record
Database-->>API: Quiz ID
API-->>Teacher: Quiz created
Teacher->>API: POST /api/v1/quizzes/{id}/questions
API->>Database: Add question with options
Database-->>API: Question ID
API-->>Teacher: Question added
Teacher->>API: PUT /api/v1/quizzes/{id} (status: published)
API->>Database: Update quiz status
API-->>Teacher: Quiz published
stateDiagram-v2
[*] --> Draft: Create Quiz
Draft --> Draft: Add Questions
Draft --> Scheduled: Set start/end dates
Scheduled --> Published: Publish
Draft --> Published: Publish directly
Published --> Archived: Archive
Archived --> [*]
| Endpoint | Method | Description | Role Required |
|---|---|---|---|
| /api/v1/quizzes | GET | List all quizzes | All Authenticated |
| /api/v1/quizzes | POST | Create new quiz | Admin, Teacher |
| /api/v1/quizzes/{id} | GET | Get quiz details | All Authenticated |
| /api/v1/quizzes/{id} | PUT | Update quiz | Admin, Teacher |
| /api/v1/quizzes/{id} | DELETE | Delete quiz | Admin, Teacher |
| /api/v1/quizzes/{id}/questions | GET | List quiz questions | Admin, Teacher |
| /api/v1/quizzes/{id}/questions | POST | Add question to quiz | Admin, Teacher |
| /api/v1/quizzes/{id}/overrides | POST | Create student override | Admin, Teacher |
| /api/v1/quizzes/{id}/analytics | GET | Get quiz analytics | Admin, Teacher |
{
"class_id": 1,
"title": "Physics Midterm Exam",
"description": "Covers chapters 1-5",
"status": "draft",
"duration_minutes": 60,
"max_attempts": 2,
"starts_at": "2024-12-01 09:00:00",
"ends_at": "2024-12-31 17:00:00"
}{
"type": "mcq",
"points": 5,
"content": {
"text": "What is the formula for force?"
},
"options": [
{"content": "F = ma", "is_correct": true},
{"content": "F = mv", "is_correct": false},
{"content": "F = m/a", "is_correct": false},
{"content": "F = a/m", "is_correct": false}
]
}{
"type": "true_false",
"points": 2,
"content": {
"text": "Gravity is a force."
},
"options": [
{"content": "True", "is_correct": true},
{"content": "False", "is_correct": false}
]
}{
"user_id": 5,
"new_duration_minutes": 90,
"new_attempts_allowed": 3
}| Endpoint | Method | Description | Role Required |
|---|---|---|---|
| /api/v1/learning-paths | GET | List all learning paths | All Authenticated |
| /api/v1/learning-paths | POST | Create new learning path | Admin, Teacher |
| /api/v1/learning-paths/{id} | GET | Get learning path details | All Authenticated |
| /api/v1/learning-paths/{id} | PUT | Update learning path | Admin, Teacher |
| /api/v1/learning-paths/{id} | DELETE | Delete learning path | Admin, Teacher |
| Endpoint | Method | Description | Role Required |
|---|---|---|---|
| /api/v1/documents | GET | List all documents | Public |
| /api/v1/documents | POST | Upload new document | Admin, Teacher |
| /api/v1/documents/{id} | GET | Get document details | Public |
| /api/v1/documents/{id} | DELETE | Delete document | Admin, Teacher |
| /api/v1/documents/{id}/download | GET | Download document file | Public |
| Field | Type | Description |
|---|---|---|
| title | string | Document title |
| description | string | Document description |
| file | file | The document file (max 50MB) |
| cover_image | file | Cover image for display (optional) |
Students have a simplified interface focused on consuming content and participating in quizzes. They cannot access administrative features.
sequenceDiagram
participant Student
participant Frontend
participant API
participant Database
Student->>Frontend: View available quizzes
Frontend->>API: GET /api/v1/quizzes
API-->>Frontend: List of published quizzes
Student->>Frontend: Start quiz
Frontend->>API: POST /api/v1/quizzes/{id}/attempts
API->>Database: Create attempt record
API-->>Frontend: Attempt ID + questions
loop For each question
Student->>Frontend: Select answer
Frontend->>API: POST /api/v1/attempts/{id}/answers
API->>Database: Save answer
end
Student->>Frontend: Submit quiz
Frontend->>API: POST /api/v1/attempts/{id}/submit
API->>Database: Calculate score
API-->>Frontend: Score + breakdown
stateDiagram-v2
[*] --> Started: Start Attempt
Started --> InProgress: Answer Questions
InProgress --> InProgress: Save Answers
InProgress --> Submitted: Submit Quiz
Submitted --> [*]: View Results
| Endpoint | Method | Description | Role Required |
|---|---|---|---|
| /api/v1/quizzes | GET | List available quizzes | All Authenticated |
| /api/v1/quizzes/{id} | GET | Get quiz details | All Authenticated |
| /api/v1/quizzes/{id}/attempts | GET | List own attempts | All Authenticated |
| /api/v1/quizzes/{id}/attempts | POST | Start new attempt | All Authenticated |
| /api/v1/quizzes/{id}/leaderboard | GET | View quiz leaderboard | All Authenticated |
| /api/v1/attempts/{id}/answers | POST | Submit answer | All Authenticated |
| /api/v1/attempts/{id}/submit | POST | Finish and submit attempt | All Authenticated |
| /api/v1/attempts/{id} | GET | View attempt result | All Authenticated |
{
"id": 15,
"quiz_id": 3,
"student_id": 5,
"status": "in_progress",
"attempt_number": 1,
"started_at": "2024-12-09T10:00:00Z"
}{
"question_id": 12,
"answer_content": {
"option_id": 45
}
}{
"attempt_id": 15,
"status": "submitted",
"score": 8,
"total_points": 10,
"submitted_at": "2024-12-09T10:30:00Z",
"answers": [
{
"question_id": 12,
"is_correct": true,
"points_awarded": 5,
"correct_option_id": 45
},
{
"question_id": 13,
"is_correct": false,
"points_awarded": 0,
"correct_option_id": 50
}
]
}[
{
"id": 15,
"student_id": 5,
"score": 95,
"student": {
"id": 5,
"name": "Jane Student"
}
},
{
"id": 22,
"student_id": 8,
"score": 90,
"student": {
"id": 8,
"name": "John Student"
}
}
]The document library is publicly accessible without authentication. It serves as a knowledge repository for students and visitors.
graph TD
A[Visitor] --> B[Access Library Page]
B --> C[GET /api/v1/documents]
C --> D[Display Document List]
D --> E{User Action}
E -->|View Details| F[GET /api/v1/documents/id]
E -->|Download| G[GET /api/v1/documents/id/download]
F --> H[Display Document Info]
F --> I[Increment View Count]
G --> J[Serve File]
G --> K[Increment Download Count]
| Endpoint | Method | Description | Auth Required |
|---|---|---|---|
| /api/v1/documents | GET | List all documents | No |
| /api/v1/documents/{id} | GET | Get document details | No |
| /api/v1/documents/{id}/download | GET | Download document file | No |
{
"current_page": 1,
"data": [
{
"id": 1,
"title": "Physics Lecture Notes",
"description": "Chapter 1-5 notes",
"type": "application/pdf",
"view_count": 150,
"download_count": 45,
"cover_path": "covers/physics.jpg",
"created_at": "2024-12-01T10:00:00Z"
}
],
"per_page": 15,
"total": 25
}{
"document": {
"id": 1,
"title": "Physics Lecture Notes",
"description": "Chapter 1-5 notes",
"type": "application/pdf",
"path": "documents/physics.pdf",
"cover_path": "covers/physics.jpg",
"view_count": 151,
"download_count": 45
},
"url": "http://localhost:8000/storage/documents/physics.pdf",
"cover_url": "http://localhost:8000/storage/covers/physics.jpg"
}Understanding the relationships between entities is crucial for frontend development.
erDiagram
USER ||--o{ CLASS : teaches
USER ||--o{ QUIZ : creates
USER ||--o{ QUIZ_ATTEMPT : takes
USER ||--o{ LEARNING_PATH : creates
CLASS ||--o{ USER : enrolls
CLASS ||--o{ QUIZ : contains
QUIZ ||--o{ QUESTION : has
QUIZ ||--o{ QUIZ_ATTEMPT : generates
QUIZ ||--o{ QUIZ_OVERRIDE : has
QUESTION ||--o{ QUESTION_OPTION : has
QUIZ_ATTEMPT ||--o{ QUIZ_ANSWER : contains
DEPARTMENT ||--o{ CLASS : contains
LEARNING_PATH ||--o{ LEARNING_PATH_STAGE : has
| Parent Entity | Child Entity | Relationship Type | Description |
|---|---|---|---|
| User | Class | One-to-Many | Teacher teaches multiple classes |
| User | Quiz | One-to-Many | Teacher creates multiple quizzes |
| User | QuizAttempt | One-to-Many | Student has multiple attempts |
| Class | User (Students) | Many-to-Many | Class enrolls multiple students |
| Quiz | Question | One-to-Many | Quiz contains multiple questions |
| Question | QuestionOption | One-to-Many | Question has multiple options |
| QuizAttempt | QuizAnswer | One-to-Many | Attempt contains multiple answers |
| Quiz | QuizOverride | One-to-Many | Quiz can have student overrides |
The API implements a layered security model with route-level and controller-level protections.
graph TD
A[API Request] --> B{Has Token?}
B -->|No| C{Is Public Route?}
C -->|Yes| D[Allow Access]
C -->|No| E[401 Unauthorized]
B -->|Yes| F{Valid Token?}
F -->|No| G[401 Unauthorized]
F -->|Yes| H{Route Middleware}
H -->|Admin Only| I{Is Admin?}
I -->|Yes| J[Allow]
I -->|No| K[403 Forbidden]
H -->|Teacher/Admin| L{Is Teacher or Admin?}
L -->|Yes| M[Allow]
L -->|No| N[403 Forbidden]
H -->|Common| O[Allow - Check Controller Logic]
O --> P{Controller Authorization}
P -->|Ownership Check| Q[Verify Resource Ownership]
| Tier | Middleware | Accessible By |
|---|---|---|
| Public | None | Everyone |
| Authenticated | auth:sanctum | All logged-in users |
| Teacher/Admin | auth:sanctum + role:admin,teacher | Teachers and Admins |
| Admin Only | auth:sanctum + role:admin | Admins only |
| Code | Meaning | When Used |
|---|---|---|
| 200 | OK | Successful GET, PUT, DELETE |
| 201 | Created | Successful POST |
| 204 | No Content | Successful DELETE with no response body |
| 400 | Bad Request | Invalid request format |
| 401 | Unauthorized | Missing or invalid token |
| 403 | Forbidden | Valid token but insufficient permissions |
| 404 | Not Found | Resource does not exist |
| 422 | Unprocessable Entity | Validation errors |
| 500 | Server Error | Internal server error |
- POST /api/v1/auth/login
- POST /api/v1/auth/logout
- GET /api/v1/auth/me
- PUT /api/v1/auth/profile
- GET/POST /api/v1/users
- GET/PUT/DELETE /api/v1/users/{id}
- GET/POST /api/v1/departments
- GET/PUT/DELETE /api/v1/departments/{id}
- POST/PUT/DELETE /api/v1/classes
- POST /api/v1/classes/{id}/enroll
- POST/PUT/DELETE /api/v1/quizzes
- GET/POST/PUT/DELETE /api/v1/quizzes/{id}/questions
- POST /api/v1/quizzes/{id}/overrides
- GET /api/v1/quizzes/{id}/analytics
- POST/PUT/DELETE /api/v1/learning-paths
- POST/DELETE /api/v1/documents
- GET /api/v1/classes
- GET /api/v1/classes/{id}
- GET /api/v1/quizzes
- GET /api/v1/quizzes/{id}
- GET /api/v1/learning-paths
- GET /api/v1/learning-paths/{id}
- GET/POST /api/v1/quizzes/{id}/attempts
- GET /api/v1/quizzes/{id}/leaderboard
- POST /api/v1/attempts/{id}/answers
- POST /api/v1/attempts/{id}/submit
- GET /api/v1/attempts/{id}
- GET /api/v1/documents
- GET /api/v1/documents/{id}
- GET /api/v1/documents/{id}/download
The following diagram illustrates the major components of the system and how they interact.
graph TB
subgraph ExternalClients ["External Clients"]
style ExternalClients fill:#1a1a2e,stroke:#4fd1c5,stroke-width:2px,color:#fff
WebApp["Web Application"]
MobileApp["Mobile Application"]
Postman["API Testing Tool"]
end
subgraph LaravelApplication ["Laravel Backend Application"]
style LaravelApplication fill:#16213e,stroke:#e94560,stroke-width:2px,color:#fff
subgraph RoutingLayer ["Routing Layer"]
style RoutingLayer fill:#0f3460,stroke:#f1c40f,stroke-width:1px,color:#fff
Router["API Router"]
end
subgraph MiddlewarePipeline ["Middleware Pipeline"]
style MiddlewarePipeline fill:#0f3460,stroke:#f1c40f,stroke-width:1px,color:#fff
MW1["Security Headers"]
MW2["Rate Limiter"]
MW3["Sanctum Auth"]
MW4["Role Checker"]
MW5["Audit Logger"]
end
subgraph BusinessLogic ["Business Logic"]
style BusinessLogic fill:#0f3460,stroke:#f1c40f,stroke-width:1px,color:#fff
Controllers["Controllers"]
Services["Service Layer"]
Models["Eloquent Models"]
end
end
subgraph DataStores ["Data Stores"]
style DataStores fill:#1a1a2e,stroke:#2ecc71,stroke-width:2px,color:#fff
Database[("MySQL/SQLite Database")]
FileStorage[("File Storage")]
end
WebApp --> Router
MobileApp --> Router
Postman --> Router
Router --> MW1
MW1 --> MW2
MW2 --> MW3
MW3 --> MW4
MW4 --> MW5
MW5 --> Controllers
Controllers --> Services
Services --> Models
Models --> Database
Controllers --> FileStorage
The Routing Layer is responsible for receiving incoming HTTP requests and directing them to the appropriate handler. All routes are defined in the routes/api.php file and are prefixed with /api/v1.
The Middleware Pipeline is a chain of filters that every request must pass through before reaching the controller. Each middleware performs a specific validation or transformation.
The Business Logic layer consists of Controllers that handle HTTP transport, Services that encapsulate domain logic, and Models that represent database entities.
The Data Stores are the persistence mechanisms. The primary database stores all relational data. The file storage system holds uploaded documents.
Every API request follows a deterministic path through the application. Understanding this path is essential for debugging and extending the system.
flowchart TD
subgraph EntryPoint ["1. Entry Point"]
style EntryPoint fill:#2d3748,stroke:#68d391,stroke-width:2px,color:#fff
A["HTTP Request Arrives"]
end
subgraph GlobalMiddleware ["2. Global Middleware"]
style GlobalMiddleware fill:#4a5568,stroke:#f6ad55,stroke-width:2px,color:#fff
B["Inject Security Headers"]
C["Apply Rate Limiting"]
end
subgraph RouteMatching ["3. Route Resolution"]
style RouteMatching fill:#2d3748,stroke:#68d391,stroke-width:2px,color:#fff
D["Match URL to Route Definition"]
end
subgraph RouteMiddleware ["4. Route Middleware"]
style RouteMiddleware fill:#4a5568,stroke:#fc8181,stroke-width:2px,color:#fff
E{"Is Route Protected?"}
F["Validate Bearer Token"]
G{"Is Token Valid?"}
H["Check User Role"]
I{"Has Required Role?"}
J["Log Audit Entry"]
end
subgraph ControllerExecution ["5. Controller Execution"]
style ControllerExecution fill:#2d3748,stroke:#b794f4,stroke-width:2px,color:#fff
K["Validate Request Payload"]
L{"Is Payload Valid?"}
M["Execute Business Logic"]
N["Return JSON Response"]
end
subgraph ErrorHandling ["Error Responses"]
style ErrorHandling fill:#742a2a,stroke:#fc8181,stroke-width:2px,color:#fff
ERR1["401 Unauthorized"]
ERR2["403 Forbidden"]
ERR3["422 Unprocessable Entity"]
end
A --> B
B --> C
C --> D
D --> E
E -- "No (Public Route)" --> K
E -- "Yes" --> F
F --> G
G -- "No" --> ERR1
G -- "Yes" --> H
H --> I
I -- "No" --> ERR2
I -- "Yes" --> J
J --> K
K --> L
L -- "No" --> ERR3
L -- "Yes" --> M
M --> N
Security Headers Middleware injects HTTP headers that protect against common web vulnerabilities. These include X-Frame-Options to prevent clickjacking, X-Content-Type-Options to prevent MIME sniffing, and Content-Security-Policy to restrict resource loading.
Rate Limiter Middleware restricts the number of requests a single client can make within a time window. The default configuration allows 60 requests per minute per IP address.
Sanctum Authentication Middleware parses the Authorization header, extracts the Bearer token, and validates it against the personal_access_tokens database table. If the token is invalid or missing, the request is rejected with a 401 status code.
Role Checker Middleware verifies that the authenticated user possesses the role required by the route. If the user does not have the required role, the request is rejected with a 403 status code.
Audit Logger Middleware records details of all state-changing requests (POST, PUT, DELETE) to the audit_logs table for forensic accountability.
The relational database is the single source of truth for the application. All business entities are modeled as tables with strict foreign key constraints.
erDiagram
USERS {
bigint id PK "Primary Key"
string name "Full Name"
string email UK "Unique Email"
string password "Bcrypt Hash"
string role "admin OR teacher OR student"
boolean is_active "Account Status"
json metadata "Flexible Extension Data"
timestamp created_at
timestamp updated_at
}
DEPARTMENTS {
bigint id PK
string name "Department Name"
string code UK "Unique Code"
timestamp created_at
timestamp updated_at
}
CLASSES {
bigint id PK
bigint department_id FK "References DEPARTMENTS"
bigint teacher_id FK "References USERS"
string name "Class Name"
string code UK "Unique Code"
timestamp created_at
timestamp updated_at
}
CLASS_STUDENT {
bigint id PK
bigint class_id FK "References CLASSES"
bigint student_id FK "References USERS"
timestamp created_at
}
QUIZZES {
bigint id PK
bigint class_id FK "References CLASSES"
string title "Quiz Title"
text description "Description"
string status "draft OR published"
json settings "Duration, Attempts"
timestamp created_at
timestamp updated_at
}
QUESTIONS {
bigint id PK
bigint quiz_id FK "References QUIZZES"
string type "mcq OR true_false OR short_answer"
json content "Question Text and Data"
integer points "Point Value"
timestamp created_at
timestamp updated_at
}
QUESTION_OPTIONS {
bigint id PK
bigint question_id FK "References QUESTIONS"
string content "Option Text"
boolean is_correct "Correct Flag"
timestamp created_at
timestamp updated_at
}
QUIZ_ATTEMPTS {
bigint id PK
bigint quiz_id FK "References QUIZZES"
bigint student_id FK "References USERS"
string status "in_progress OR completed"
integer score "Final Score"
timestamp started_at
timestamp submitted_at
timestamp created_at
timestamp updated_at
}
QUIZ_ANSWERS {
bigint id PK
bigint quiz_attempt_id FK "References QUIZ_ATTEMPTS"
bigint question_id FK "References QUESTIONS"
json answer_content "Student Response"
boolean is_correct "Grading Result"
integer points_awarded "Points Received"
timestamp created_at
timestamp updated_at
}
DOCUMENTS {
bigint id PK
string title "Document Title"
string path "Storage Path"
string type "MIME Type"
text description "Description"
timestamp created_at
timestamp updated_at
}
AUDIT_LOGS {
bigint id PK
bigint user_id FK "References USERS"
string action "HTTP Method"
string endpoint "Request URI"
json payload "Request Body"
timestamp created_at
}
USERS ||--o{ DEPARTMENTS : "Admin manages"
USERS ||--o{ CLASSES : "Teacher teaches"
USERS ||--o{ CLASS_STUDENT : "Student enrolled in"
USERS ||--o{ QUIZ_ATTEMPTS : "Student performs"
USERS ||--o{ AUDIT_LOGS : "Actor triggers"
DEPARTMENTS ||--o{ CLASSES : "Contains"
CLASSES ||--o{ CLASS_STUDENT : "Enrollments"
CLASSES ||--o{ QUIZZES : "Contains"
QUIZZES ||--o{ QUESTIONS : "Has"
QUIZZES ||--o{ QUIZ_ATTEMPTS : "Instances"
QUESTIONS ||--o{ QUESTION_OPTIONS : "Has options"
QUESTIONS ||--o{ QUIZ_ANSWERS : "Receives answers"
QUIZ_ATTEMPTS ||--o{ QUIZ_ANSWERS : "Collects"
USERS Table. This is the central identity store. The role column determines what parts of the system a user can access. The metadata column is a JSON field that allows for flexible extension of user profiles without schema changes.
DEPARTMENTS Table. Represents high-level academic divisions such as Science or Mathematics. Each department has a unique code for identification.
CLASSES Table. Represents an instructional unit. Each class belongs to one department and is assigned to one teacher. The teacher_id foreign key links to the USERS table.
CLASS_STUDENT Table. A pivot table implementing the many-to-many relationship between classes and students. Each record signifies that a specific student is enrolled in a specific class.
QUIZZES Table. Represents an assessment. The status column indicates whether the quiz is visible to students. The settings column is a JSON field storing variable configurations like time limits and allowed attempts.
QUESTIONS Table. The atomic unit of an assessment. The type column indicates the question format. The content column is a JSON field storing the question text and any associated data.
QUESTION_OPTIONS Table. For multiple-choice questions, this table stores the possible answers. The is_correct boolean indicates which option is the correct answer.
QUIZ_ATTEMPTS Table. Represents a single instance of a student taking a quiz. The started_at and submitted_at timestamps are used to calculate the duration and enforce time limits.
QUIZ_ANSWERS Table. Stores the student's response to each question. The answer_content is a JSON field to accommodate different answer formats.
DOCUMENTS Table. Stores metadata for files uploaded to the knowledge library. The actual files are stored on disk; this table holds the path reference.
AUDIT_LOGS Table. An immutable record of all state-changing actions performed through the API. Used for security auditing and debugging.
All endpoints are prefixed with /api/v1. Authentication is performed via Bearer token in the Authorization header.
POST /auth/login Authenticates a user and returns an access token. Request Body: email (string, required), password (string, required). Response: JSON object containing user data and access token.
POST /auth/logout Revokes the current access token. Requires Authentication: Yes. Response: 204 No Content.
GET /auth/me Returns the currently authenticated user profile. Requires Authentication: Yes. Response: JSON object containing user data.
PUT /auth/profile Updates the authenticated user own profile. Requires Authentication: Yes. Request Body: name (string, optional), email (string, optional), password (string, optional). Response: JSON object containing updated user data.
These endpoints require administrator role.
GET /users Returns a paginated list of all users.
POST /users Creates a new user. Request Body: name, email, password, role, is_active.
GET /users/{id} Returns a specific user.
PUT /users/{id} Updates a user.
DELETE /users/{id} Deletes a user.
GET /departments Returns all departments.
POST /departments Creates a new department.
PUT /departments/{id} Updates a department.
DELETE /departments/{id} Deletes a department.
POST /classes Creates a new class. Request Body: name, code, department_id, teacher_id.
PUT /classes/{id} Updates a class.
DELETE /classes/{id} Deletes a class.
POST /classes/{class}/enroll Enrolls a student in a class. Request Body: student_id.
GET /classes Returns classes visible to the current user. Admins see all classes. Teachers see their assigned classes. Students see their enrolled classes.
GET /classes/{id} Returns class details.
GET /quizzes Returns quizzes. Teachers see quizzes they created. Students see published quizzes in their enrolled classes.
POST /quizzes Creates a new quiz (Teacher only).
PUT /quizzes/{id} Updates a quiz.
DELETE /quizzes/{id} Deletes a quiz.
GET /quizzes/{quiz}/questions Returns questions for a quiz.
POST /quizzes/{quiz}/questions Adds a question to a quiz.
PUT /quizzes/{quiz}/questions/{question} Updates a question.
DELETE /quizzes/{quiz}/questions/{question} Deletes a question.
POST /quizzes/{quiz}/attempts Starts a quiz attempt (Student only).
POST /attempts/{attempt}/answers Submits an answer for a question.
POST /attempts/{attempt}/submit Finishes and grades the attempt.
GET /attempts/{attempt} Returns attempt details with score.
GET /documents Public endpoint. Returns all documents in the library.
GET /documents/{id} Public endpoint. Returns document details and download URL.
POST /documents Protected. Teacher or Admin only. Uploads a new document. Request Body: title (string), file (file upload, max 50MB), description (optional string).
DELETE /documents/{document} Protected. Teacher or Admin only. Deletes a document.
The system implements strict role-based access control at both the route level and the business logic level.
graph TD
subgraph RoleHierarchy ["Role Hierarchy"]
style RoleHierarchy fill:#1a1a2e,stroke:#68d391,stroke-width:2px,color:#fff
Admin["ADMIN"]
Teacher["TEACHER"]
Student["STUDENT"]
Public["PUBLIC"]
end
subgraph Permissions ["System Permissions"]
style Permissions fill:#2d3748,stroke:#f6ad55,stroke-width:2px,color:#fff
P1["User Management"]
P2["Department CRUD"]
P3["Class Management"]
P4["Student Enrollment"]
P5["Quiz Creation"]
P6["Question Editing"]
P7["Document Upload"]
P8["Quiz Taking"]
P9["View Library"]
P10["View Classes"]
end
Admin --> P1
Admin --> P2
Admin --> P3
Admin --> P4
Admin --> P5
Admin --> P6
Admin --> P7
Admin --> P9
Admin --> P10
Teacher --> P5
Teacher --> P6
Teacher --> P7
Teacher --> P9
Teacher --> P10
Student --> P8
Student --> P9
Student --> P10
Public --> P9
Administrator. Has complete control over the system. Can manage all users, departments, classes, and quizzes. Responsible for initial system setup and ongoing maintenance.
Teacher. Content creator role. Can create quizzes and questions for their assigned classes. Can upload documents to the library. Can view student attempts and performance.
Student. End user role. Can view enrolled classes and available quizzes. Can take quizzes and view their own scores. Can read and download documents from the library.
Public. Unauthenticated users can access the document library for reading and downloading.
This section describes the step-by-step processes for common operations.
sequenceDiagram
autonumber
participant Admin
participant Teacher
participant Student
participant API
participant Database
rect rgb(30, 30, 60)
Note over Admin,Database: Phase 1: System Setup
Admin->>API: POST /users (Create Teacher)
API->>Database: INSERT into users
Admin->>API: POST /users (Create Student)
API->>Database: INSERT into users
Admin->>API: POST /departments
API->>Database: INSERT into departments
Admin->>API: POST /classes
API->>Database: INSERT into classes
Admin->>API: POST /classes/{id}/enroll
API->>Database: INSERT into class_student
end
rect rgb(30, 60, 30)
Note over Teacher,Database: Phase 2: Content Creation
Teacher->>API: POST /quizzes
API->>Database: INSERT into quizzes (status: draft)
Teacher->>API: POST /quizzes/{id}/questions
API->>Database: INSERT into questions
API->>Database: INSERT into question_options
Teacher->>API: PUT /quizzes/{id} (status: published)
API->>Database: UPDATE quizzes
end
rect rgb(60, 30, 30)
Note over Student,Database: Phase 3: Assessment
Student->>API: POST /quizzes/{id}/attempts
API->>Database: INSERT into quiz_attempts
API-->>Student: Return Attempt ID
loop For Each Question
Student->>API: POST /attempts/{id}/answers
API->>Database: UPSERT into quiz_answers
end
Student->>API: POST /attempts/{id}/submit
API->>Database: Calculate Score
API->>Database: UPDATE quiz_attempts
API-->>Student: Return Final Score
end
The Administrator begins by logging into the system to obtain an access token. Using this token, they create Teacher and Student user accounts. They then define the academic structure by creating Departments. Within each department, they create Classes, assigning a Teacher to each class. Finally, they enroll Students into their respective Classes using the enrollment endpoint.
The Teacher logs in and retrieves their assigned Classes. They select a Class and create a new Quiz in draft status. They add Questions to the Quiz, specifying the question type, content, point value, and for multiple-choice questions, the answer options with the correct answer marked. Once the quiz is complete, they update its status to published, making it visible to enrolled students.
The Student logs in and views their enrolled Classes. They select an available published Quiz and start an Attempt. The system creates an attempt record with a start timestamp. The student answers each question, with responses saved to the database. Upon finishing, the student submits the attempt. The system calculates the score by comparing answers to correct options and returns the final result.
The Knowledge Library is a publicly accessible repository of educational documents uploaded by Teachers.
graph LR
subgraph PublicZone ["Public Access Zone"]
style PublicZone fill:#2d3748,stroke:#68d391,stroke-width:2px,color:#fff
GETList["GET /documents"]
GETShow["GET /documents/{id}"]
end
subgraph ProtectedZone ["Protected Zone"]
style ProtectedZone fill:#742a2a,stroke:#fc8181,stroke-width:2px,color:#fff
POSTUpload["POST /documents"]
DELETERemove["DELETE /documents/{id}"]
end
subgraph Roles ["Who Can Access"]
style Roles fill:#1a1a2e,stroke:#f6ad55,stroke-width:2px,color:#fff
Anyone["Anyone (No Token)"]
TeacherAdmin["Teacher or Admin (Token Required)"]
end
Anyone --> GETList
Anyone --> GETShow
TeacherAdmin --> POSTUpload
TeacherAdmin --> DELETERemove
Teachers upload documents using a multipart form-data request containing the file, title, and optional description. The system validates the file size (maximum 50MB), stores the file in the public storage directory, and creates a database record with the file metadata. The document is immediately available for public viewing.
Any user, including unauthenticated visitors, can retrieve the document list and individual document details. The response includes a URL that points to the file in public storage, allowing direct download.
The system uses Laravel Sanctum for token-based API authentication. Upon successful login, the server generates a plaintext token which is returned to the client. The client must include this token in the Authorization header of subsequent requests. The token is hashed using SHA-256 before storage in the database.
User passwords are never stored in plaintext. Before storage, passwords are hashed using the Bcrypt algorithm with a cost factor of 10. During login, the provided password is hashed and compared against the stored hash.
To prevent abuse, the API enforces rate limiting. By default, each client IP address is limited to 60 requests per minute. Exceeding this limit results in a 429 Too Many Requests response.
All incoming data is validated using Laravel Form Request validation rules. Invalid data results in a 422 Unprocessable Entity response containing detailed error messages for each invalid field.
All state-changing operations (POST, PUT, DELETE) are logged to the audit_logs table. Each log entry contains the user ID, HTTP method, endpoint, sanitized request payload (with passwords redacted), and timestamp. This audit trail is immutable via the API.
Runtime: PHP 8.2 or higher. Extensions: BCMath, Ctype, Fileinfo, JSON, Mbstring, OpenSSL, PDO, Tokenizer, XML. Database: SQLite for development, MySQL 8.0 or higher for production. Web Server: Nginx or Apache with URL rewriting enabled.
Clone the repository to the target server. Navigate to the project directory and execute composer install to install PHP dependencies. Copy the .env.example file to .env and configure the database connection. Execute php artisan key:generate to set the application encryption key. Execute php artisan migrate --seed to create database tables and seed initial data. Execute php artisan storage:link to create the symbolic link for public file access.
For local development, execute php artisan serve to start the built-in PHP development server. The API will be available at localhost port 8000.
When modifying configuration files or seeders with local secrets that should not be pushed to version control, use the Git assume-unchanged feature.
To lock a file from being staged: git update-index --assume-unchanged database/seeders/DatabaseSeeder.php
To unlock a file: git update-index --no-assume-unchanged database/seeders/DatabaseSeeder.php
End of Document.