563 lines
9.8 KiB
Markdown
563 lines
9.8 KiB
Markdown
# API Usage Examples for ERD v3
|
|
|
|
## 🔐 Authentication
|
|
|
|
### Register with Username
|
|
```http
|
|
POST /api/auth/register
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"username": "john_doe",
|
|
"email": "john@example.com",
|
|
"password": "SecurePass123!",
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"prefix": "Mr."
|
|
}
|
|
```
|
|
|
|
**Response 201**:
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": 1,
|
|
"username": "john_doe",
|
|
"email": "john@example.com",
|
|
"role": {
|
|
"id": 3,
|
|
"code": "STUDENT",
|
|
"name": {
|
|
"th": "นักเรียน",
|
|
"en": "Student"
|
|
}
|
|
},
|
|
"profile": {
|
|
"prefix": "Mr.",
|
|
"first_name": "John",
|
|
"last_name": "Doe"
|
|
}
|
|
},
|
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Login with Username
|
|
```http
|
|
POST /api/auth/login
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"username": "john_doe",
|
|
"password": "SecurePass123!"
|
|
}
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": 1,
|
|
"username": "john_doe",
|
|
"email": "john@example.com",
|
|
"role": {
|
|
"code": "STUDENT",
|
|
"name": {"th": "นักเรียน", "en": "Student"}
|
|
}
|
|
},
|
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Login with Email
|
|
```http
|
|
POST /api/auth/login
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "john@example.com",
|
|
"password": "SecurePass123!"
|
|
}
|
|
```
|
|
|
|
**Response**: Same as username login
|
|
|
|
---
|
|
|
|
## 👤 User Profile
|
|
|
|
### Get User Info
|
|
```http
|
|
GET /api/users/me
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"username": "john_doe",
|
|
"email": "john@example.com",
|
|
"email_verified_at": "2026-01-01T10:00:00Z",
|
|
"role": {
|
|
"id": 3,
|
|
"code": "STUDENT",
|
|
"name": {"th": "นักเรียน", "en": "Student"}
|
|
},
|
|
"created_at": "2026-01-01T10:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Get User Profile Details
|
|
```http
|
|
GET /api/users/me/profile
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"user_id": 1,
|
|
"prefix": "Mr.",
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"phone": "0812345678",
|
|
"avatar_url": "https://s3.../avatars/john.jpg",
|
|
"created_at": "2026-01-01T10:00:00Z",
|
|
"updated_at": "2026-01-05T15:30:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Update Profile
|
|
```http
|
|
PUT /api/users/me/profile
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"prefix": "Dr.",
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"phone": "0898765432",
|
|
"avatar_url": "https://s3.../avatars/john-new.jpg"
|
|
}
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"prefix": "Dr.",
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"phone": "0898765432",
|
|
"avatar_url": "https://s3.../avatars/john-new.jpg",
|
|
"updated_at": "2026-01-06T11:00:00Z",
|
|
"updated_by": 1
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎓 Multi-Instructor Support
|
|
|
|
### List Course Instructors
|
|
```http
|
|
GET /api/instructor/courses/1/instructors
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"instructors": [
|
|
{
|
|
"id": 1,
|
|
"user_id": 5,
|
|
"username": "prof_smith",
|
|
"name": "Prof. John Smith",
|
|
"avatar_url": "https://s3.../avatars/smith.jpg",
|
|
"is_primary": true,
|
|
"joined_at": "2026-01-01T10:00:00Z"
|
|
},
|
|
{
|
|
"id": 2,
|
|
"user_id": 10,
|
|
"username": "dr_jane",
|
|
"name": "Dr. Jane Doe",
|
|
"avatar_url": "https://s3.../avatars/jane.jpg",
|
|
"is_primary": false,
|
|
"joined_at": "2026-01-05T14:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Add Instructor to Course
|
|
```http
|
|
POST /api/instructor/courses/1/instructors
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"user_id": 15,
|
|
"is_primary": false
|
|
}
|
|
```
|
|
|
|
**Response 201**:
|
|
```json
|
|
{
|
|
"id": 3,
|
|
"course_id": 1,
|
|
"user_id": 15,
|
|
"username": "ta_mike",
|
|
"name": "Mike Johnson",
|
|
"is_primary": false,
|
|
"joined_at": "2026-01-06T11:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Set Primary Instructor
|
|
```http
|
|
PUT /api/instructor/courses/1/instructors/10/primary
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"message": "Primary instructor updated",
|
|
"instructors": [
|
|
{
|
|
"user_id": 5,
|
|
"is_primary": false
|
|
},
|
|
{
|
|
"user_id": 10,
|
|
"is_primary": true
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Remove Instructor
|
|
```http
|
|
DELETE /api/instructor/courses/1/instructors/15
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"message": "Instructor removed successfully"
|
|
}
|
|
```
|
|
|
|
**Error 400** (Last instructor):
|
|
```json
|
|
{
|
|
"error": {
|
|
"code": "LAST_INSTRUCTOR",
|
|
"message": "Cannot remove the last instructor from course"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎓 Certificates
|
|
|
|
### Get My Certificates
|
|
```http
|
|
GET /api/students/certificates
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"certificates": [
|
|
{
|
|
"id": 1,
|
|
"course_id": 1,
|
|
"course_title": "Python for Beginners",
|
|
"completion_date": "2026-01-05",
|
|
"file_path": "https://s3.../certificates/cert-user1-course1.pdf",
|
|
"issued_at": "2026-01-05T16:00:00Z"
|
|
},
|
|
{
|
|
"id": 2,
|
|
"course_id": 3,
|
|
"course_title": "Web Development Bootcamp",
|
|
"completion_date": "2025-12-20",
|
|
"file_path": "https://s3.../certificates/cert-user1-course3.pdf",
|
|
"issued_at": "2025-12-20T10:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Get Course Certificate
|
|
```http
|
|
GET /api/students/courses/1/certificate
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"course_id": 1,
|
|
"course_title": "Python for Beginners",
|
|
"student_name": "John Doe",
|
|
"completion_date": "2026-01-05",
|
|
"file_path": "https://s3.../certificates/cert-user1-course1.pdf",
|
|
"issued_at": "2026-01-05T16:00:00Z"
|
|
}
|
|
```
|
|
|
|
**Error 404** (Not completed):
|
|
```json
|
|
{
|
|
"error": {
|
|
"code": "CERTIFICATE_NOT_FOUND",
|
|
"message": "Certificate not available. Complete the course first."
|
|
}
|
|
}
|
|
```
|
|
|
|
**Error 400** (Course doesn't issue certificates):
|
|
```json
|
|
{
|
|
"error": {
|
|
"code": "NO_CERTIFICATE",
|
|
"message": "This course does not issue certificates"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔒 Role Management (Admin)
|
|
|
|
### List All Roles
|
|
```http
|
|
GET /api/admin/roles
|
|
Authorization: Bearer <admin-token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"roles": [
|
|
{
|
|
"id": 1,
|
|
"code": "ADMIN",
|
|
"name": {
|
|
"th": "ผู้ดูแลระบบ",
|
|
"en": "Administrator"
|
|
},
|
|
"description": {
|
|
"th": "มีสิทธิ์เต็มในการจัดการระบบ",
|
|
"en": "Full system access"
|
|
}
|
|
},
|
|
{
|
|
"id": 2,
|
|
"code": "INSTRUCTOR",
|
|
"name": {
|
|
"th": "ผู้สอน",
|
|
"en": "Instructor"
|
|
},
|
|
"description": {
|
|
"th": "สามารถสร้างและจัดการคอร์สเรียน",
|
|
"en": "Can create and manage courses"
|
|
}
|
|
},
|
|
{
|
|
"id": 3,
|
|
"code": "STUDENT",
|
|
"name": {
|
|
"th": "นักเรียน",
|
|
"en": "Student"
|
|
},
|
|
"description": {
|
|
"th": "สามารถลงทะเบียนและเรียนคอร์ส",
|
|
"en": "Can enroll and learn courses"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Get Role Details
|
|
```http
|
|
GET /api/admin/roles/2
|
|
Authorization: Bearer <admin-token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"id": 2,
|
|
"code": "INSTRUCTOR",
|
|
"name": {
|
|
"th": "ผู้สอน",
|
|
"en": "Instructor"
|
|
},
|
|
"description": {
|
|
"th": "สามารถสร้างและจัดการคอร์สเรียน",
|
|
"en": "Can create and manage courses"
|
|
},
|
|
"user_count": 45,
|
|
"created_at": "2026-01-01T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 Course with Certificate
|
|
|
|
### Get Course Details (with have_certificate)
|
|
```http
|
|
GET /api/courses/1
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"title": {
|
|
"th": "Python สำหรับผู้เริ่มต้น",
|
|
"en": "Python for Beginners"
|
|
},
|
|
"description": {...},
|
|
"price": 990,
|
|
"is_free": false,
|
|
"have_certificate": true,
|
|
"instructors": [
|
|
{
|
|
"user_id": 5,
|
|
"name": "Prof. John Smith",
|
|
"is_primary": true
|
|
},
|
|
{
|
|
"user_id": 10,
|
|
"name": "Dr. Jane Doe",
|
|
"is_primary": false
|
|
}
|
|
],
|
|
"total_lessons": 50,
|
|
"total_duration": 1200,
|
|
"status": "APPROVED"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Quiz with show_answers_after_completion
|
|
|
|
### Get Quiz
|
|
```http
|
|
GET /api/students/quizzes/1
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response 200**:
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"title": {"th": "แบบทดสอบท้ายบท", "en": "Chapter Quiz"},
|
|
"description": {...},
|
|
"passing_score": 60,
|
|
"time_limit": 30,
|
|
"shuffle_questions": true,
|
|
"shuffle_choices": true,
|
|
"show_answers_after_completion": true,
|
|
"questions": [...]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Submit Quiz (with answers shown)
|
|
```http
|
|
POST /api/students/quizzes/1/submit
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"answers": [
|
|
{"question_id": 1, "choice_id": 3},
|
|
{"question_id": 2, "choice_id": 7}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Response 200** (show_answers_after_completion = true):
|
|
```json
|
|
{
|
|
"attempt_id": 1,
|
|
"score": 75,
|
|
"total_questions": 10,
|
|
"correct_answers": 8,
|
|
"is_passed": true,
|
|
"answers": [
|
|
{
|
|
"question_id": 1,
|
|
"question": {"th": "Python คืออะไร?"},
|
|
"your_answer": 3,
|
|
"correct_answer": 3,
|
|
"is_correct": true,
|
|
"explanation": {"th": "Python เป็นภาษาโปรแกรมมิ่ง..."}
|
|
},
|
|
{
|
|
"question_id": 2,
|
|
"question": {"th": "ตัวแปรใน Python..."},
|
|
"your_answer": 7,
|
|
"correct_answer": 8,
|
|
"is_correct": false,
|
|
"explanation": {"th": "ตัวแปรใน Python ไม่ต้องประกาศชนิดข้อมูล"}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Response 200** (show_answers_after_completion = false):
|
|
```json
|
|
{
|
|
"attempt_id": 1,
|
|
"score": 75,
|
|
"total_questions": 10,
|
|
"correct_answers": 8,
|
|
"is_passed": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔗 Related Documentation
|
|
|
|
- [API Endpoints Reference](./api_endpoints.md)
|
|
- [ERD v3 Schema](./ER/ERD_v3_improved.txt)
|
|
- [Edge Cases](./edge_cases_quick_reference.md)
|