# Edge Cases Quick Reference

> สรุปกรณีพิเศษที่ต้องระวังในระบบ E-Learning - สำหรับอ้างอิงด่วน

## 📋 สารบัญ Edge Cases

| # | Edge Case | ความเสี่ยง | แนวทางแก้ไข |
|---|-----------|-----------|-------------|
| 1 | [การเปลี่ยนบทบาทโดย Admin](#1-การเปลี่ยนบทบาทผู้ใช้) | 🟡 ปานกลาง | Invalidate sessions + audit log |
| 2 | [หลักสูตรถูกซ่อน/ลบ](#2-หลักสูตรถูกซ่อนลบ) | 🟡 ปานกลาง | Read-only mode สำหรับผู้ลงทะเบียนแล้ว |
| 3 | [ลงทะเบียนซ้ำ](#3-ลงทะเบียนซ้ำ) | 🟢 ต่ำ | ตรวจสอบและ redirect |
| 4 | [ข้ามลำดับบทเรียน](#4-ข้ามลำดับบทเรียน) | 🟡 ปานกลาง | ตรวจสอบ prerequisite |
| 5 | [ทำแบบทดสอบหลายครั้ง](#5-ทำแบบทดสอบหลายครั้ง) | 🟡 ปานกลาง | จำกัดครั้ง + cooldown |
| 6 | [แก้ไขขณะมีคนใช้งาน](#6-แก้ไขขณะมีคนใช้งาน) | 🔴 สูง | Soft delete + แจ้งเตือน |
| 7 | [ลบ Instructor ที่มีหลักสูตร](#7-ลบ-instructor-ที่มีหลักสูตร) | 🔴 สูง | บังคับโอนหลักสูตรก่อน |
| 8 | [เข้าถึงข้อมูลข้ามหลักสูตร](#8-เข้าถึงข้อมูลข้ามหลักสูตร) | 🔴 สูง | Middleware ตรวจสอบ ownership |
| 9 | [เพิ่มเนื้อหาหลังจบหลักสูตร](#9-เพิ่มเนื้อหาหลังจบหลักสูตร) | 🟡 ปานกลาง | เนื้อหาใหม่ = เสริม (ไม่บังคับ) |
| 10 | [Maintenance Mode](#10-maintenance-mode) | 🟡 ปานกลาง | Auto-save + แจ้งเตือนล่วงหน้า |
| 11 | [Video Progress Tracking](#11-video-progress-tracking) | 🟡 ปานกลาง | Save ทุก 5 วินาที + last_watched_at |

---

## 1. การเปลี่ยนบทบาทผู้ใช้

> **หมายเหตุ**: ไม่มีการเปลี่ยนบทบาทระหว่าง Student-Instructor ในการใช้งานปกติ  
> เกิดขึ้นเฉพาะกรณีพิเศษที่ Admin จัดการ (เช่น แก้ไขข้อมูลผิดพลาด)

**ปัญหา**: Token/Session เก่ายังมีสิทธิ์เดิม

**วิธีแก้**:
```javascript
// Admin เปลี่ยนบทบาท (กรณีพิเศษ)
// 1. บันทึก audit log (ระบุเหตุผล)
// 2. อัปเดตบทบาท
// 3. Invalidate sessions ทั้งหมด
// 4. แจ้งเตือนผู้ใช้ทางอีเมล
// 5. บังคับ login ใหม่
```

**Key Points**:
- ✅ เฉพาะ Admin เท่านั้น
- ✅ ต้องระบุเหตุผลและบันทึก audit log
- ✅ Invalidate sessions ทันที
- ✅ แจ้งเตือนผู้ใช้ทางอีเมล

---

## 2. หลักสูตรถูกซ่อน/ลบ

**ปัญหา**: Student ที่ลงทะเบียนแล้วควรเข้าถึงได้หรือไม่?

**วิธีแก้**:
- **ซ่อน**: Student ที่ลงทะเบียนแล้ว → เข้าถึงได้ปกติ
- **ลบ**: Student ที่ลงทะเบียนแล้ว → Read-only mode

**Key Points**:
- ✅ ใช้ Soft Delete
- ✅ ใบประกาศนียบัตรที่ออกแล้วยังใช้ได้
- ❌ ห้ามทำแบบทดสอบใหม่ในหลักสูตรที่ถูกลบ

---

## 3. ลงทะเบียนซ้ำ

**ปัญหา**: ข้อมูลความคืบหน้าจะเป็นอย่างไร?

**วิธีแก้**:
```javascript
if (existingEnrollment) {
  return redirect(`/courses/${courseId}`);
}
```

**Key Points**:
- ✅ ตรวจสอบก่อนสร้าง enrollment
- ✅ Redirect ไปที่หลักสูตร
- ❌ ห้ามรีเซ็ตความคืบหน้า

---

## 4. ข้ามลำดับบทเรียน

**ปัญหา**: Student ใช้ Direct URL ข้ามลำดับ

**วิธีแก้**:
```javascript
// ตรวจสอบว่าเรียน Lesson ก่อนหน้าครบหรือไม่
if (!allPreviousCompleted) {
  return { access: false, nextAvailableLesson };
}
```

**Key Points**:
- ✅ ตรวจสอบที่ Backend (ห้ามพึ่ง Frontend)
- ✅ แสดง Lesson ถัดไปที่เข้าถึงได้
- ✅ รองรับหลักสูตรที่ไม่บังคับลำดับ

---

## 5. ทำแบบทดสอบหลายครั้ง

**ปัญหา**: จำกัดครั้ง? คะแนนไหนที่นับ? รอกี่นาที?

**วิธีแก้**:
```javascript
// ตรวจสอบ:
// 1. จำนวนครั้งที่ทำได้ (maxAttempts)
// 2. ระยะเวลารอ (cooldownMinutes)
// 3. นโยบายคะแนน (HIGHEST/LATEST/FIRST/AVERAGE)
```

**Key Points**:
- ✅ ใช้คะแนนสูงสุด (HIGHEST) เป็นค่าเริ่มต้น
- ✅ กำหนด cooldown ได้ต่อแบบทดสอบ
- ✅ เก็บประวัติการทำทุกครั้ง

---

## 6. แก้ไขขณะมีคนใช้งาน

**ปัญหา**: Student กำลังดู Lesson อยู่ แต่ Instructor ลบ

**วิธีแก้**:
```javascript
// ใช้ Soft Delete
if (activeViewers.length > 0) {
  markAsDeleted(); // ลบถาวรใน 24 ชม.
  notifyInstructor();
}
```

**Key Points**:
- ✅ ใช้ Soft Delete แทน Hard Delete
- ✅ แจ้งเตือน Instructor ว่ามีคนดูอยู่
- ✅ Student ที่เข้าถึงก่อนหน้า → ดูต่อได้

---

## 7. ลบ Instructor ที่มีหลักสูตร

**ปัญหา**: หลักสูตรจะกลายเป็น "ไม่มีเจ้าของ"

**วิธีแก้**:
```javascript
if (courses.length > 0) {
  return error('กรุณาโอนหลักสูตรก่อน');
}
// ใช้ Soft Delete (deactivate)
```

**Key Points**:
- ✅ บังคับโอนหลักสูตรก่อนลบ
- ✅ ใช้ Soft Delete (deactivate)
- ✅ เก็บ Audit Log

---

## 8. เข้าถึงข้อมูลข้ามหลักสูตร

**ปัญหา**: Instructor A ดูข้อมูลหลักสูตรของ Instructor B

**วิธีแก้**:
```javascript
// Middleware ตรวจสอบ ownership
if (role === 'INSTRUCTOR' && course.instructorId !== userId) {
  return 403;
}
```

**Key Points**:
- ✅ ตรวจสอบ ownership ที่ Backend
- ✅ Admin → read-only access
- ✅ Instructor → เฉพาะหลักสูตรของตนเอง

---

## 9. เพิ่มเนื้อหาหลังจบหลักสูตร

**ปัญหา**: ความคืบหน้ากลับไม่ครบ 100%

**วิธีแก้**:
```javascript
// คำนวณจากเนื้อหาตอนลงทะเบียน
if (originalProgress === 100 && certificateIssued) {
  return { progress: 100, newContentAvailable: true };
}
```

**Key Points**:
- ✅ ใบประกาศนียบัตรยังใช้ได้
- ✅ เนื้อหาใหม่ = เสริม (ไม่บังคับ)
- ✅ แสดงป้าย "มีเนื้อหาใหม่"

---

## 10. Maintenance Mode

**ปัญหา**: Student กำลังทำแบบทดสอบ

**วิธีแก้**:
```javascript
// 1. แจ้งเตือนล่วงหน้า 24 ชม.
// 2. Auto-save ทุก 30 วินาที
// 3. เก็บ draft 24 ชม.
// 4. Admin เข้าถึงได้
```

**Key Points**:
- ✅ Auto-save แบบทดสอบทุก 30 วินาที
- ✅ แจ้งเตือนล่วงหน้า
- ✅ กู้คืนข้อมูลได้ภายใน 24 ชม.

---

## 11. Video Progress Tracking

**ปัญหา**: Student ดูวีดีโอค้างไว้หลายแท็บ หรือปิดเบราว์เซอร์กลางคัน

**วิธีแก้**:
```javascript
// 1. Save progress ทุก 5 วินาที
// 2. ใช้ last_watched_at เป็นตัวตัดสิน
// 3. Auto-complete เมื่อดู 90%+
// 4. Resume จากตำแหน่งล่าสุด
```

**Key Points**:
- ✅ Save progress ทุก 5 วินาที (ไม่บ่อยเกินไป)
- ✅ ใช้ `last_watched_at` ตัดสินว่า session ไหนล่าสุด
- ✅ Auto-complete เมื่อดู ≥ 90%
- ✅ Resume จากตำแหน่งที่บันทึกล่าสุด
- ❌ ไม่ save เมื่อ video pause หรือ buffering

**Concurrent Updates**:
```javascript
// แท็บ A: บันทึกที่ 5:00 (14:00:00)
// แท็บ B: บันทึกที่ 3:00 (14:00:05)
// → ใช้แท็บ B (last_watched_at ใหม่กว่า)
```

---

## 🔒 หลักการสำคัญ (Best Practices)

### 1. Soft Delete > Hard Delete
- ใช้ `isDeleted` flag แทนการลบจริง
- เก็บข้อมูลไว้สำหรับ audit trail
- ป้องกันการสูญหายของข้อมูล

### 2. Invalidate Sessions เมื่อเปลี่ยนสิทธิ์
- เปลี่ยนบทบาท → logout ทันที
- ลบบัญชี → invalidate sessions
- เปลี่ยนรหัสผ่าน → logout devices อื่น

### 3. ตรวจสอบสิทธิ์ที่ Backend เสมอ
- Frontend = UX (ซ่อน/แสดง UI)
- Backend = Security (ป้องกันการเข้าถึง)
- ห้ามพึ่งพา Frontend เพียงอย่างเดียว

### 4. Auto-save สำหรับข้อมูลสำคัญ
- แบบทดสอบ → auto-save ทุก 30 วินาที
- เนื้อหาที่กำลังเขียน → auto-save
- เก็บ draft ไว้อย่างน้อย 24 ชม.

### 5. แจ้งเตือนผู้ใช้
- Maintenance → แจ้งล่วงหน้า 24 ชม.
- ลบเนื้อหา → แจ้งว่ามีคนดูอยู่
- เปลี่ยนแปลงสำคัญ → ส่งอีเมลแจ้ง

---

## 📊 สรุปความเสี่ยงและลำดับความสำคัญ

### 🔴 ความเสี่ยงสูง (ต้องจัดการก่อน)
1. แก้ไขขณะมีคนใช้งาน
2. ลบ Instructor ที่มีหลักสูตร
3. เข้าถึงข้อมูลข้ามหลักสูตร

### 🟡 ความเสี่ยงปานกลาง
4. การเปลี่ยนบทบาทโดย Admin (กรณีพิเศษ)
5. หลักสูตรถูกซ่อน/ลบ
6. ข้ามลำดับบทเรียน
7. ทำแบบทดสอบหลายครั้ง
8. เพิ่มเนื้อหาหลังจบหลักสูตร
9. Maintenance Mode

### 🟢 ความเสี่ยงต่ำ
10. ลงทะเบียนซ้ำ

---

## 🔗 เอกสารที่เกี่ยวข้อง

- [ตารางสิทธิ์แบบเต็ม](./permissions_matrix.md)
- [User Roles and Capabilities](./user_roles_and_capabilities.md)
- [System Architecture](./elearning_architecture.md)
