1194 lines
24 KiB
Markdown
1194 lines
24 KiB
Markdown
|
|
# API Usage Examples
|
||
|
|
|
||
|
|
ตัวอย่างการใช้งาน API แบบละเอียดพร้อม Request/Response
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📋 Table of Contents
|
||
|
|
|
||
|
|
1. [Authentication Flow](#1-authentication-flow)
|
||
|
|
2. [Student Learning Journey](#2-student-learning-journey)
|
||
|
|
3. [Instructor Course Creation](#3-instructor-course-creation)
|
||
|
|
4. [Quiz Management](#4-quiz-management)
|
||
|
|
5. [Announcements](#5-announcements)
|
||
|
|
6. [Reports & Analytics](#6-reports--analytics)
|
||
|
|
7. [Payment Flow](#7-payment-flow)
|
||
|
|
8. [Admin Operations](#8-admin-operations)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. Authentication Flow
|
||
|
|
|
||
|
|
### 1.1 Register New User
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/auth/register
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"name": "John Doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"password": "SecurePass123!",
|
||
|
|
"role": "student"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"user": {
|
||
|
|
"id": 123,
|
||
|
|
"name": "John Doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"role": "student",
|
||
|
|
"created_at": "2024-12-22T16:00:00Z"
|
||
|
|
},
|
||
|
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6InN0dWRlbnQiLCJpYXQiOjE3MDMyNTk2MDAsImV4cCI6MTcwMzM0NjAwMH0.xxx",
|
||
|
|
"expiresIn": 86400
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 1.2 Login
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/auth/login
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"email": "john@example.com",
|
||
|
|
"password": "SecurePass123!",
|
||
|
|
"rememberMe": true
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"user": {
|
||
|
|
"id": 123,
|
||
|
|
"name": "John Doe",
|
||
|
|
"email": "john@example.com",
|
||
|
|
"role": "student"
|
||
|
|
},
|
||
|
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
|
|
"expiresIn": 2592000
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error 401:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": {
|
||
|
|
"code": "INVALID_CREDENTIALS",
|
||
|
|
"message": "Invalid email or password"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 1.3 Password Reset Flow
|
||
|
|
|
||
|
|
**Step 1: Request Reset**
|
||
|
|
```http
|
||
|
|
POST /api/auth/password/reset-request
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"email": "john@example.com"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"message": "Password reset email sent to john@example.com"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Reset Password**
|
||
|
|
```http
|
||
|
|
POST /api/auth/password/reset
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"token": "reset_token_from_email_abc123",
|
||
|
|
"password": "NewSecurePass456!"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"message": "Password reset successfully. Please login with your new password."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. Student Learning Journey
|
||
|
|
|
||
|
|
### 2.1 Browse Courses
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/courses?page=1&limit=12&category=1&search=python&lang=th&is_free=false&sort=popular
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"data": [
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"title": "Python สำหรับผู้เริ่มต้น",
|
||
|
|
"description": "เรียนรู้ Python จากพื้นฐานถึงขั้นสูง",
|
||
|
|
"thumbnail": "https://cdn.example.com/courses/python-101.jpg",
|
||
|
|
"price": 990,
|
||
|
|
"is_free": false,
|
||
|
|
"instructor": {
|
||
|
|
"id": 5,
|
||
|
|
"name": "Jane Smith",
|
||
|
|
"avatar": "https://cdn.example.com/avatars/jane.jpg"
|
||
|
|
},
|
||
|
|
"category": {
|
||
|
|
"id": 1,
|
||
|
|
"name": "การเขียนโปรแกรม"
|
||
|
|
},
|
||
|
|
"students_count": 1250,
|
||
|
|
"rating": 4.8,
|
||
|
|
"total_lessons": 45,
|
||
|
|
"total_duration": "12:30:00",
|
||
|
|
"status": "approved"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"pagination": {
|
||
|
|
"page": 1,
|
||
|
|
"limit": 12,
|
||
|
|
"total": 150,
|
||
|
|
"totalPages": 13
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2.2 Get Course Details
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/courses/1?lang=th
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"title": "Python สำหรับผู้เริ่มต้น",
|
||
|
|
"description": "เรียนรู้ Python จากพื้นฐานถึงขั้นสูง ครอบคลุมทุกหัวข้อสำคัญ",
|
||
|
|
"thumbnail": "https://cdn.example.com/courses/python-101.jpg",
|
||
|
|
"price": 990,
|
||
|
|
"is_free": false,
|
||
|
|
"status": "approved",
|
||
|
|
"instructor": {
|
||
|
|
"id": 5,
|
||
|
|
"name": "Jane Smith",
|
||
|
|
"bio": "Software Engineer with 10+ years experience",
|
||
|
|
"avatar": "https://cdn.example.com/avatars/jane.jpg",
|
||
|
|
"total_students": 5000,
|
||
|
|
"total_courses": 8
|
||
|
|
},
|
||
|
|
"category": {
|
||
|
|
"id": 1,
|
||
|
|
"name": "การเขียนโปรแกรม",
|
||
|
|
"description": "หลักสูตรด้านการเขียนโปรแกรม"
|
||
|
|
},
|
||
|
|
"chapters": [
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"title": "บทที่ 1: เริ่มต้นกับ Python",
|
||
|
|
"lessons_count": 5,
|
||
|
|
"sort_order": 1
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 2,
|
||
|
|
"title": "บทที่ 2: ตัวแปรและชนิดข้อมูล",
|
||
|
|
"lessons_count": 8,
|
||
|
|
"sort_order": 2
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"students_count": 1250,
|
||
|
|
"rating": 4.8,
|
||
|
|
"reviews_count": 320,
|
||
|
|
"total_lessons": 45,
|
||
|
|
"total_duration": "12:30:00",
|
||
|
|
"created_at": "2024-01-15T10:00:00Z",
|
||
|
|
"updated_at": "2024-12-20T15:30:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2.3 Enroll in Course
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/courses/1/enroll
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"enrollment_id": 456,
|
||
|
|
"course_id": 1,
|
||
|
|
"user_id": 123,
|
||
|
|
"status": "enrolled",
|
||
|
|
"progress_percentage": 0,
|
||
|
|
"enrolled_at": "2024-12-22T16:05:00Z",
|
||
|
|
"message": "Successfully enrolled in Python สำหรับผู้เริ่มต้น"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error 409 (Already Enrolled):**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": {
|
||
|
|
"code": "ALREADY_ENROLLED",
|
||
|
|
"message": "You are already enrolled in this course",
|
||
|
|
"enrollment_id": 456
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2.4 Get Learning Page
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/students/courses/1/learn
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"course": {
|
||
|
|
"id": 1,
|
||
|
|
"title": "Python สำหรับผู้เริ่มต้น",
|
||
|
|
"instructor": {
|
||
|
|
"id": 5,
|
||
|
|
"name": "Jane Smith"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"enrollment": {
|
||
|
|
"id": 456,
|
||
|
|
"status": "enrolled",
|
||
|
|
"progress_percentage": 35,
|
||
|
|
"enrolled_at": "2024-12-22T16:05:00Z"
|
||
|
|
},
|
||
|
|
"chapters": [
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"title": "บทที่ 1: เริ่มต้นกับ Python",
|
||
|
|
"sort_order": 1,
|
||
|
|
"lessons": [
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"title": "1.1 แนะนำ Python",
|
||
|
|
"type": "video",
|
||
|
|
"duration": "00:15:30",
|
||
|
|
"is_completed": true,
|
||
|
|
"is_locked": false,
|
||
|
|
"completed_at": "2024-12-22T16:20:00Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 2,
|
||
|
|
"title": "1.2 ติดตั้ง Python",
|
||
|
|
"type": "video",
|
||
|
|
"duration": "00:20:00",
|
||
|
|
"is_completed": true,
|
||
|
|
"is_locked": false,
|
||
|
|
"completed_at": "2024-12-22T16:45:00Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 3,
|
||
|
|
"title": "1.3 แบบทดสอบท้ายบท",
|
||
|
|
"type": "quiz",
|
||
|
|
"is_completed": false,
|
||
|
|
"is_locked": false
|
||
|
|
}
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 2,
|
||
|
|
"title": "บทที่ 2: ตัวแปรและชนิดข้อมูล",
|
||
|
|
"sort_order": 2,
|
||
|
|
"lessons": [
|
||
|
|
{
|
||
|
|
"id": 4,
|
||
|
|
"title": "2.1 ตัวแปรใน Python",
|
||
|
|
"type": "video",
|
||
|
|
"duration": "00:18:00",
|
||
|
|
"is_completed": false,
|
||
|
|
"is_locked": false
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2.5 Get Lesson Content
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/students/courses/1/lessons/1
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 1,
|
||
|
|
"title": "1.1 แนะนำ Python",
|
||
|
|
"content": {
|
||
|
|
"th": "<h2>แนะนำ Python</h2><p>Python เป็นภาษาโปรแกรมที่...</p>",
|
||
|
|
"en": "<h2>Introduction to Python</h2><p>Python is a programming language...</p>"
|
||
|
|
},
|
||
|
|
"type": "video",
|
||
|
|
"video_url": "https://cdn.example.com/videos/lesson-1.m3u8",
|
||
|
|
"duration": "00:15:30",
|
||
|
|
"is_completed": true,
|
||
|
|
"completed_at": "2024-12-22T16:20:00Z",
|
||
|
|
"can_access": true,
|
||
|
|
"next_lesson_id": 2,
|
||
|
|
"prev_lesson_id": null,
|
||
|
|
"chapter": {
|
||
|
|
"id": 1,
|
||
|
|
"title": "บทที่ 1: เริ่มต้นกับ Python"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error 403 (Locked Lesson):**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": {
|
||
|
|
"code": "LESSON_LOCKED",
|
||
|
|
"message": "Please complete previous lessons first",
|
||
|
|
"required_lessons": [1, 2],
|
||
|
|
"next_available_lesson": 3
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2.6 Mark Lesson as Complete
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/students/courses/1/lessons/1/complete
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"lesson_id": 1,
|
||
|
|
"is_completed": true,
|
||
|
|
"completed_at": "2024-12-22T16:20:00Z",
|
||
|
|
"progress_percentage": 38,
|
||
|
|
"next_lesson": {
|
||
|
|
"id": 2,
|
||
|
|
"title": "1.2 ติดตั้ง Python",
|
||
|
|
"is_locked": false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Instructor Course Creation
|
||
|
|
|
||
|
|
### 3.1 Create Course
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"title": {
|
||
|
|
"th": "JavaScript สำหรับผู้เริ่มต้น",
|
||
|
|
"en": "JavaScript for Beginners"
|
||
|
|
},
|
||
|
|
"description": {
|
||
|
|
"th": "เรียนรู้ JavaScript จากพื้นฐาน",
|
||
|
|
"en": "Learn JavaScript from scratch"
|
||
|
|
},
|
||
|
|
"category_id": 1,
|
||
|
|
"price": 1200,
|
||
|
|
"is_free": false,
|
||
|
|
"thumbnail": "https://cdn.example.com/thumbnails/js-101.jpg"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 25,
|
||
|
|
"title": {
|
||
|
|
"th": "JavaScript สำหรับผู้เริ่มต้น",
|
||
|
|
"en": "JavaScript for Beginners"
|
||
|
|
},
|
||
|
|
"description": {
|
||
|
|
"th": "เรียนรู้ JavaScript จากพื้นฐาน",
|
||
|
|
"en": "Learn JavaScript from scratch"
|
||
|
|
},
|
||
|
|
"category_id": 1,
|
||
|
|
"price": 1200,
|
||
|
|
"is_free": false,
|
||
|
|
"status": "draft",
|
||
|
|
"instructor_id": 5,
|
||
|
|
"created_at": "2024-12-22T16:30:00Z",
|
||
|
|
"message": "Course created successfully. Add chapters and lessons to continue."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.2 Create Chapter
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/25/chapters
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"title": {
|
||
|
|
"th": "บทที่ 1: เริ่มต้นกับ JavaScript",
|
||
|
|
"en": "Chapter 1: Getting Started with JavaScript"
|
||
|
|
},
|
||
|
|
"sort_order": 1
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 50,
|
||
|
|
"course_id": 25,
|
||
|
|
"title": {
|
||
|
|
"th": "บทที่ 1: เริ่มต้นกับ JavaScript",
|
||
|
|
"en": "Chapter 1: Getting Started with JavaScript"
|
||
|
|
},
|
||
|
|
"sort_order": 1,
|
||
|
|
"created_at": "2024-12-22T16:32:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.3 Create Lesson with Video
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/25/chapters/50/lessons
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"title": {
|
||
|
|
"th": "1.1 แนะนำ JavaScript",
|
||
|
|
"en": "1.1 Introduction to JavaScript"
|
||
|
|
},
|
||
|
|
"content": {
|
||
|
|
"th": "<p>JavaScript เป็นภาษาโปรแกรมที่ใช้ในการพัฒนาเว็บไซต์</p>",
|
||
|
|
"en": "<p>JavaScript is a programming language used for web development</p>"
|
||
|
|
},
|
||
|
|
"type": "video",
|
||
|
|
"sort_order": 1
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 100,
|
||
|
|
"chapter_id": 50,
|
||
|
|
"title": {
|
||
|
|
"th": "1.1 แนะนำ JavaScript",
|
||
|
|
"en": "1.1 Introduction to JavaScript"
|
||
|
|
},
|
||
|
|
"content": {
|
||
|
|
"th": "<p>JavaScript เป็นภาษาโปรแกรมที่ใช้ในการพัฒนาเว็บไซต์</p>",
|
||
|
|
"en": "<p>JavaScript is a programming language used for web development</p>"
|
||
|
|
},
|
||
|
|
"type": "video",
|
||
|
|
"video_url": null,
|
||
|
|
"sort_order": 1,
|
||
|
|
"created_at": "2024-12-22T16:35:00Z",
|
||
|
|
"message": "Lesson created. Upload video to complete."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.4 Upload Video
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/25/lessons/100/video
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: multipart/form-data
|
||
|
|
|
||
|
|
file: <video_file.mp4>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"lesson_id": 100,
|
||
|
|
"video_url": "https://cdn.example.com/videos/course-25/lesson-100.m3u8",
|
||
|
|
"duration": "00:15:30",
|
||
|
|
"file_size": 52428800,
|
||
|
|
"upload_completed_at": "2024-12-22T16:40:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.5 Submit Course for Approval
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/25/submit
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 25,
|
||
|
|
"status": "pending",
|
||
|
|
"submitted_at": "2024-12-22T16:45:00Z",
|
||
|
|
"message": "Course submitted for approval. You will be notified once reviewed."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error 422 (Incomplete Course):**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": {
|
||
|
|
"code": "INCOMPLETE_COURSE",
|
||
|
|
"message": "Course must have at least 1 chapter and 3 lessons",
|
||
|
|
"details": {
|
||
|
|
"chapters_count": 1,
|
||
|
|
"lessons_count": 1,
|
||
|
|
"required_lessons": 3
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Quiz Management
|
||
|
|
|
||
|
|
### 4.1 Create Quiz (Instructor)
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/25/lessons/103/quiz
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"title": {
|
||
|
|
"th": "แบบทดสอบท้ายบทที่ 1",
|
||
|
|
"en": "Chapter 1 Quiz"
|
||
|
|
},
|
||
|
|
"passing_score": 70,
|
||
|
|
"time_limit": 30,
|
||
|
|
"max_attempts": 3,
|
||
|
|
"cooldown_minutes": 60,
|
||
|
|
"score_policy": "highest"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 15,
|
||
|
|
"lesson_id": 103,
|
||
|
|
"title": {
|
||
|
|
"th": "แบบทดสอบท้ายบทที่ 1",
|
||
|
|
"en": "Chapter 1 Quiz"
|
||
|
|
},
|
||
|
|
"passing_score": 70,
|
||
|
|
"time_limit": 30,
|
||
|
|
"max_attempts": 3,
|
||
|
|
"cooldown_minutes": 60,
|
||
|
|
"score_policy": "highest",
|
||
|
|
"created_at": "2024-12-22T16:50:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 4.2 Add Question
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/quizzes/15/questions
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"question": {
|
||
|
|
"th": "JavaScript ย่อมาจากอะไร?",
|
||
|
|
"en": "What does JavaScript stand for?"
|
||
|
|
},
|
||
|
|
"question_type": "multiple_choice",
|
||
|
|
"score": 10,
|
||
|
|
"sort_order": 1,
|
||
|
|
"choices": [
|
||
|
|
{
|
||
|
|
"text": {
|
||
|
|
"th": "Java Script Language",
|
||
|
|
"en": "Java Script Language"
|
||
|
|
},
|
||
|
|
"is_correct": false,
|
||
|
|
"sort_order": 1
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"text": {
|
||
|
|
"th": "ไม่ได้ย่อมาจากอะไร เป็นชื่อภาษา",
|
||
|
|
"en": "It's not an acronym, it's a language name"
|
||
|
|
},
|
||
|
|
"is_correct": true,
|
||
|
|
"sort_order": 2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"text": {
|
||
|
|
"th": "Just Another Scripting Language",
|
||
|
|
"en": "Just Another Scripting Language"
|
||
|
|
},
|
||
|
|
"is_correct": false,
|
||
|
|
"sort_order": 3
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 45,
|
||
|
|
"quiz_id": 15,
|
||
|
|
"question": {
|
||
|
|
"th": "JavaScript ย่อมาจากอะไร?",
|
||
|
|
"en": "What does JavaScript stand for?"
|
||
|
|
},
|
||
|
|
"question_type": "multiple_choice",
|
||
|
|
"score": 10,
|
||
|
|
"sort_order": 1,
|
||
|
|
"choices": [
|
||
|
|
{
|
||
|
|
"id": 180,
|
||
|
|
"text": {
|
||
|
|
"th": "Java Script Language",
|
||
|
|
"en": "Java Script Language"
|
||
|
|
},
|
||
|
|
"is_correct": false,
|
||
|
|
"sort_order": 1
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 181,
|
||
|
|
"text": {
|
||
|
|
"th": "ไม่ได้ย่อมาจากอะไร เป็นชื่อภาษา",
|
||
|
|
"en": "It's not an acronym, it's a language name"
|
||
|
|
},
|
||
|
|
"is_correct": true,
|
||
|
|
"sort_order": 2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 182,
|
||
|
|
"text": {
|
||
|
|
"th": "Just Another Scripting Language",
|
||
|
|
"en": "Just Another Scripting Language"
|
||
|
|
},
|
||
|
|
"is_correct": false,
|
||
|
|
"sort_order": 3
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"created_at": "2024-12-22T16:55:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 4.3 Take Quiz (Student)
|
||
|
|
|
||
|
|
**Step 1: Get Quiz**
|
||
|
|
```http
|
||
|
|
GET /api/students/quizzes/15
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 15,
|
||
|
|
"title": "แบบทดสอบท้ายบทที่ 1",
|
||
|
|
"passing_score": 70,
|
||
|
|
"time_limit": 30,
|
||
|
|
"max_attempts": 3,
|
||
|
|
"cooldown_minutes": 60,
|
||
|
|
"score_policy": "highest",
|
||
|
|
"attempts_used": 1,
|
||
|
|
"can_take": true,
|
||
|
|
"next_attempt_at": null,
|
||
|
|
"best_score": 60,
|
||
|
|
"questions": [
|
||
|
|
{
|
||
|
|
"id": 45,
|
||
|
|
"question": "JavaScript ย่อมาจากอะไร?",
|
||
|
|
"question_type": "multiple_choice",
|
||
|
|
"score": 10,
|
||
|
|
"sort_order": 1,
|
||
|
|
"choices": [
|
||
|
|
{
|
||
|
|
"id": 180,
|
||
|
|
"text": "Java Script Language",
|
||
|
|
"sort_order": 1
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 181,
|
||
|
|
"text": "ไม่ได้ย่อมาจากอะไร เป็นชื่อภาษา",
|
||
|
|
"sort_order": 2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 182,
|
||
|
|
"text": "Just Another Scripting Language",
|
||
|
|
"sort_order": 3
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 2: Submit Quiz**
|
||
|
|
```http
|
||
|
|
POST /api/students/quizzes/15/submit
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"answers": [
|
||
|
|
{
|
||
|
|
"question_id": 45,
|
||
|
|
"choice_id": 181
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"question_id": 46,
|
||
|
|
"choice_id": 185
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"attempt_id": 89,
|
||
|
|
"score": 85,
|
||
|
|
"total_questions": 10,
|
||
|
|
"correct_answers": 8,
|
||
|
|
"is_passed": true,
|
||
|
|
"attempt_number": 2,
|
||
|
|
"started_at": "2024-12-22T17:00:00Z",
|
||
|
|
"completed_at": "2024-12-22T17:15:00Z",
|
||
|
|
"time_spent": "00:15:00",
|
||
|
|
"answers": [
|
||
|
|
{
|
||
|
|
"question_id": 45,
|
||
|
|
"selected_choice_id": 181,
|
||
|
|
"is_correct": true,
|
||
|
|
"score_earned": 10
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"question_id": 46,
|
||
|
|
"selected_choice_id": 185,
|
||
|
|
"is_correct": false,
|
||
|
|
"score_earned": 0,
|
||
|
|
"correct_choice_id": 186
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Announcements
|
||
|
|
|
||
|
|
### 5.1 Create Announcement with Attachments
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/instructor/courses/1/announcements
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: multipart/form-data
|
||
|
|
|
||
|
|
title: {"th": "ประกาศสำคัญ: เปลี่ยนแปลงตารางเรียน", "en": "Important: Schedule Change"}
|
||
|
|
content: {"th": "เนื้อหาประกาศ...", "en": "Announcement content..."}
|
||
|
|
is_pinned: true
|
||
|
|
published_at: 2024-12-25T10:00:00Z
|
||
|
|
attachments[]: <file1.pdf>
|
||
|
|
attachments[]: <file2.docx>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 78,
|
||
|
|
"course_id": 1,
|
||
|
|
"instructor_id": 5,
|
||
|
|
"title": {
|
||
|
|
"th": "ประกาศสำคัญ: เปลี่ยนแปลงตารางเรียน",
|
||
|
|
"en": "Important: Schedule Change"
|
||
|
|
},
|
||
|
|
"content": {
|
||
|
|
"th": "เนื้อหาประกาศ...",
|
||
|
|
"en": "Announcement content..."
|
||
|
|
},
|
||
|
|
"is_pinned": true,
|
||
|
|
"published_at": "2024-12-25T10:00:00Z",
|
||
|
|
"attachments": [
|
||
|
|
{
|
||
|
|
"id": 120,
|
||
|
|
"file_name": "file1.pdf",
|
||
|
|
"file_size": 2048576,
|
||
|
|
"mime_type": "application/pdf",
|
||
|
|
"download_url": "https://api.example.com/announcements/78/attachments/120/download"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": 121,
|
||
|
|
"file_name": "file2.docx",
|
||
|
|
"file_size": 1024000,
|
||
|
|
"mime_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||
|
|
"download_url": "https://api.example.com/announcements/78/attachments/121/download"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"created_at": "2024-12-22T17:20:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 5.2 Get Course Announcements
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/courses/1/announcements?page=1&limit=10
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"data": [
|
||
|
|
{
|
||
|
|
"id": 78,
|
||
|
|
"title": "ประกาศสำคัญ: เปลี่ยนแปลงตารางเรียน",
|
||
|
|
"content": "เนื้อหาประกาศ...",
|
||
|
|
"is_pinned": true,
|
||
|
|
"published_at": "2024-12-25T10:00:00Z",
|
||
|
|
"instructor": {
|
||
|
|
"id": 5,
|
||
|
|
"name": "Jane Smith",
|
||
|
|
"avatar": "https://cdn.example.com/avatars/jane.jpg"
|
||
|
|
},
|
||
|
|
"attachments_count": 2,
|
||
|
|
"created_at": "2024-12-22T17:20:00Z"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"pagination": {
|
||
|
|
"page": 1,
|
||
|
|
"limit": 10,
|
||
|
|
"total": 25,
|
||
|
|
"totalPages": 3
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. Reports & Analytics
|
||
|
|
|
||
|
|
### 6.1 Student Progress Report
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/students/courses/1/progress
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"course": {
|
||
|
|
"id": 1,
|
||
|
|
"title": "Python สำหรับผู้เริ่มต้น"
|
||
|
|
},
|
||
|
|
"enrollment": {
|
||
|
|
"enrolled_at": "2024-12-22T16:05:00Z",
|
||
|
|
"status": "enrolled"
|
||
|
|
},
|
||
|
|
"progress_percentage": 65,
|
||
|
|
"completed_lessons": 29,
|
||
|
|
"total_lessons": 45,
|
||
|
|
"completed_quizzes": 3,
|
||
|
|
"total_quizzes": 5,
|
||
|
|
"quiz_scores": [
|
||
|
|
{
|
||
|
|
"quiz_id": 1,
|
||
|
|
"title": "แบบทดสอบบทที่ 1",
|
||
|
|
"best_score": 85,
|
||
|
|
"attempts": 2,
|
||
|
|
"is_passed": true
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"quiz_id": 2,
|
||
|
|
"title": "แบบทดสอบบทที่ 2",
|
||
|
|
"best_score": 90,
|
||
|
|
"attempts": 1,
|
||
|
|
"is_passed": true
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"time_spent": "08:45:30",
|
||
|
|
"last_activity": "2024-12-22T17:00:00Z",
|
||
|
|
"estimated_completion": "2024-12-30T00:00:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 6.2 Instructor Course Statistics
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/instructor/courses/1/statistics
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"course": {
|
||
|
|
"id": 1,
|
||
|
|
"title": "Python สำหรับผู้เริ่มต้น"
|
||
|
|
},
|
||
|
|
"total_students": 1250,
|
||
|
|
"active_students": 850,
|
||
|
|
"completed_students": 400,
|
||
|
|
"average_progress": 68,
|
||
|
|
"average_rating": 4.8,
|
||
|
|
"total_reviews": 320,
|
||
|
|
"total_revenue": 1237500,
|
||
|
|
"completion_rate": 32,
|
||
|
|
"average_completion_time": "45 days",
|
||
|
|
"quiz_statistics": {
|
||
|
|
"average_score": 78,
|
||
|
|
"pass_rate": 85
|
||
|
|
},
|
||
|
|
"engagement": {
|
||
|
|
"daily_active_users": 120,
|
||
|
|
"weekly_active_users": 450,
|
||
|
|
"monthly_active_users": 850
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. Payment Flow
|
||
|
|
|
||
|
|
### 7.1 Create Order
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/orders
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"course_ids": [1, 5, 8]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 201:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"order_id": 567,
|
||
|
|
"user_id": 123,
|
||
|
|
"total_amount": 3570,
|
||
|
|
"status": "pending",
|
||
|
|
"items": [
|
||
|
|
{
|
||
|
|
"course_id": 1,
|
||
|
|
"title": "Python สำหรับผู้เริ่มต้น",
|
||
|
|
"price": 990
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"course_id": 5,
|
||
|
|
"title": "JavaScript Advanced",
|
||
|
|
"price": 1290
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"course_id": 8,
|
||
|
|
"title": "React Fundamentals",
|
||
|
|
"price": 1290
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"created_at": "2024-12-22T17:30:00Z",
|
||
|
|
"expires_at": "2024-12-22T18:30:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.2 Process Payment
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/orders/567/payment
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
Content-Type: application/json
|
||
|
|
|
||
|
|
{
|
||
|
|
"provider": "stripe",
|
||
|
|
"payment_method_id": "pm_1234567890"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"payment_id": 890,
|
||
|
|
"order_id": 567,
|
||
|
|
"status": "success",
|
||
|
|
"provider": "stripe",
|
||
|
|
"transaction_id": "txn_abc123xyz",
|
||
|
|
"amount": 3570,
|
||
|
|
"paid_at": "2024-12-22T17:32:00Z",
|
||
|
|
"enrollments_created": [
|
||
|
|
{
|
||
|
|
"course_id": 1,
|
||
|
|
"enrollment_id": 456
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"course_id": 5,
|
||
|
|
"enrollment_id": 457
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"course_id": 8,
|
||
|
|
"enrollment_id": 458
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. Admin Operations
|
||
|
|
|
||
|
|
### 8.1 Approve Course
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
POST /api/admin/courses/25/approve
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 25,
|
||
|
|
"title": "JavaScript สำหรับผู้เริ่มต้น",
|
||
|
|
"status": "approved",
|
||
|
|
"approved_by": 1,
|
||
|
|
"approved_at": "2024-12-22T17:40:00Z",
|
||
|
|
"message": "Course approved successfully. Instructor has been notified."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 8.2 System Statistics
|
||
|
|
|
||
|
|
**Request:**
|
||
|
|
```http
|
||
|
|
GET /api/admin/statistics
|
||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Response 200:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"users": {
|
||
|
|
"total": 10000,
|
||
|
|
"students": 9850,
|
||
|
|
"instructors": 150,
|
||
|
|
"admins": 5,
|
||
|
|
"new_this_month": 450
|
||
|
|
},
|
||
|
|
"courses": {
|
||
|
|
"total": 500,
|
||
|
|
"approved": 450,
|
||
|
|
"pending": 30,
|
||
|
|
"rejected": 20,
|
||
|
|
"new_this_month": 25
|
||
|
|
},
|
||
|
|
"enrollments": {
|
||
|
|
"total": 25000,
|
||
|
|
"active": 18000,
|
||
|
|
"completed": 7000,
|
||
|
|
"new_this_month": 1200
|
||
|
|
},
|
||
|
|
"revenue": {
|
||
|
|
"total": 12500000,
|
||
|
|
"this_month": 850000,
|
||
|
|
"last_month": 780000,
|
||
|
|
"growth_percentage": 8.97
|
||
|
|
},
|
||
|
|
"engagement": {
|
||
|
|
"daily_active_users": 2500,
|
||
|
|
"weekly_active_users": 6000,
|
||
|
|
"monthly_active_users": 9000
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📝 Notes
|
||
|
|
|
||
|
|
- All timestamps are in ISO 8601 format (UTC)
|
||
|
|
- All monetary values are in THB (Thai Baht)
|
||
|
|
- File sizes are in bytes
|
||
|
|
- Durations are in HH:MM:SS format
|
||
|
|
- Multi-language fields support `th` and `en` keys
|