# Agent Skills - E-Learning Backend Development

> คู่มือสำหรับ AI Agent ในการพัฒนา Backend ของระบบ E-Learning Platform  
> **Tech Stack**: Node.js + Express + Prisma + PostgreSQL + MinIO (S3)

---

## 🎯 Overview

ระบบ E-Learning Platform เป็น REST API ที่รองรับ:
- **3 บทบาทหลัก**: Admin, Instructor, Student
- **107+ endpoints** ครอบคลุมการจัดการคอร์ส, บทเรียน, แบบทดสอบ, ประกาศ, รายงาน
- **Multi-language support**: Thai (th) และ English (en)
- **File management**: Video streaming, attachments, certificates
- **Real-time features**: Video progress tracking, quiz attempts

---

## 📚 Core Concepts

### 1. Multi-Language Data Structure
ข้อมูลที่แสดงผลต้องรองรับ 2 ภาษา:
```javascript
{
  "title": {
    "th": "Python สำหรับผู้เริ่มต้น",
    "en": "Python for Beginners"
  }
}
```

### 2. Role-Based Access Control (RBAC)
```javascript
// 3 บทบาทหลัก
- ADMIN: จัดการระบบทั้งหมด
- INSTRUCTOR: สร้างและจัดการคอร์สของตนเอง
- STUDENT: ลงทะเบียนและเรียนคอร์ส
```

### 3. Course Hierarchy
```
Course
  └─ Chapters (บท)
      └─ Lessons (บทเรียน)
          ├─ Video (optional)
          ├─ Attachments (0-10 files)
          └─ Quiz (optional)
```

### 4. Lesson Prerequisites
- Sequential lessons: ต้องเรียนตามลำดับ
- Prerequisite lessons: ระบุบทเรียนที่ต้องจบก่อน
- Quiz requirements: ต้องผ่านแบบทดสอบก่อน

---

## 🔐 Authentication & Authorization

### JWT Token Structure
```javascript
{
  userId: 123,
  username: "john_doe",
  email: "john@example.com",
  role: "STUDENT",
  iat: 1234567890,
  exp: 1234654290
}
```

### Login Methods
- **Username + Password**
- **Email + Password**

### Key Endpoints
```
POST /api/auth/register
POST /api/auth/login
POST /api/auth/logout
POST /api/auth/refresh
POST /api/auth/password/reset-request
POST /api/auth/password/reset
```

---

## 👥 User Management

### User Profile Structure
```javascript
{
  id: 1,
  username: "john_doe",
  email: "john@example.com",
  role: { code: "STUDENT", name: {...} },
  profile: {
    prefix: "Mr.",
    first_name: "John",
    last_name: "Doe",
    phone: "0812345678",
    avatar_url: "https://..."
  }
}
```

### Key Endpoints
```
GET /api/users/me
GET /api/users/me/profile
PUT /api/users/me/profile
PUT /api/users/me/password
```

---

## 📚 Course Management

### Course Status Flow
```
DRAFT → PENDING → APPROVED/REJECTED → PUBLISHED
```

### Course Structure
```javascript
{
  id: 1,
  title: { th: "...", en: "..." },
  description: { th: "...", en: "..." },
  thumbnail: "https://...",
  price: 990,
  is_free: false,
  have_certificate: true,
  status: "APPROVED",
  category_id: 1,
  instructors: [
    { user_id: 5, is_primary: true },
    { user_id: 10, is_primary: false }
  ]
}
```

### Multi-Instructor Support
- **Primary Instructor**: สามารถจัดการทุกอย่างในคอร์ส
- **Co-Instructors**: ช่วยสอนและจัดการเนื้อหา
- ห้ามลบ instructor คนสุดท้าย

### Key Endpoints

**Public:**
```
GET /api/courses
GET /api/courses/:courseId
```

**Student:**
```
POST /api/students/courses/:courseId/enroll
GET /api/students/courses
GET /api/students/courses/:courseId/learn
```

**Instructor:**
```
POST /api/instructor/courses
GET /api/instructor/courses
PUT /api/instructor/courses/:courseId
DELETE /api/instructor/courses/:courseId
POST /api/instructor/courses/:courseId/submit
POST /api/instructor/courses/:courseId/clone
```

**Instructors Management:**
```
GET /api/instructor/courses/:courseId/instructors
POST /api/instructor/courses/:courseId/instructors
DELETE /api/instructor/courses/:courseId/instructors/:userId
PUT /api/instructor/courses/:courseId/instructors/:userId/primary
```

---

## 📖 Chapters & Lessons

### Lesson Types
- **video**: วีดีโอบทเรียน
- **text**: เนื้อหาข้อความ
- **pdf**: เอกสาร PDF
- **quiz**: แบบทดสอบ

### Create Lesson (One Request)
สามารถสร้าง lesson พร้อม video และ attachments ในครั้งเดียว:

```http
POST /api/instructor/courses/:courseId/chapters/:chapterId/lessons
Content-Type: multipart/form-data

title_th: "บทที่ 1"
title_en: "Lesson 1"
type: "video"
video: <file>
attachments[]: <file1>
attachments[]: <file2>
descriptions[0][th]: "สไลด์"
descriptions[0][en]: "Slides"
```

### Lesson Prerequisites
```javascript
{
  is_sequential: true,  // ต้องเรียนตามลำดับ
  prerequisite_lesson_ids: [1, 2],  // ต้องจบบทเรียนนี้ก่อน
  require_pass_quiz: true  // ต้องผ่านแบบทดสอบ
}
```

### Key Endpoints

**Chapters:**
```
POST /api/instructor/courses/:courseId/chapters
PUT /api/instructor/courses/:courseId/chapters/:chapterId
DELETE /api/instructor/courses/:courseId/chapters/:chapterId
PUT /api/instructor/courses/:courseId/chapters/reorder
```

**Lessons:**
```
POST /api/instructor/courses/:courseId/chapters/:chapterId/lessons
PUT /api/instructor/courses/:courseId/lessons/:lessonId
DELETE /api/instructor/courses/:courseId/lessons/:lessonId
PUT /api/instructor/courses/:courseId/lessons/reorder
```

**Prerequisites:**
```
GET /api/instructor/courses/:courseId/lessons/:lessonId/prerequisites
POST /api/instructor/courses/:courseId/lessons/:lessonId/prerequisites
```

---

## 📎 Attachments

### File Limits
- **Max file size**: 100 MB per file
- **Max attachments**: 10 files per lesson
- **Total size**: 500 MB per lesson

### Allowed File Types
- **Documents**: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX
- **Archives**: ZIP, RAR, 7Z
- **Images**: JPG, PNG, GIF
- **Text**: TXT, CSV

### Key Endpoints
```
POST /api/instructor/courses/:courseId/lessons/:lessonId/attachments
GET /api/instructor/courses/:courseId/lessons/:lessonId/attachments
PUT /api/instructor/courses/:courseId/lessons/:lessonId/attachments/:attachmentId
DELETE /api/instructor/courses/:courseId/lessons/:lessonId/attachments/:attachmentId
PUT /api/instructor/courses/:courseId/lessons/:lessonId/attachments/reorder
GET /api/students/lessons/:lessonId/attachments/:attachmentId/download
```

---

## 📹 Video Progress Tracking

### Auto-Save Progress
- บันทึกทุก **5 วินาที** ขณะดูวีดีโอ
- Auto-complete เมื่อดู **≥ 90%**
- Resume จากตำแหน่งล่าสุด

### Data Structure
```javascript
{
  lesson_id: 5,
  video_progress_seconds: 450,
  video_duration_seconds: 900,
  video_progress_percentage: 50.00,
  is_completed: false,
  last_watched_at: "2024-12-24T14:00:00Z"
}
```

### Key Endpoints
```
POST /api/students/lessons/:lessonId/progress
GET /api/students/lessons/:lessonId/progress
```

---

## 🎯 Quizzes & Assessments

### Quiz Configuration
```javascript
{
  title: { th: "...", en: "..." },
  passing_score: 70,  // คะแนนผ่าน (%)
  time_limit: 30,  // นาที
  max_attempts: 3,  // จำนวนครั้งที่ทำได้
  cooldown_minutes: 60,  // ระยะเวลารอระหว่างครั้ง
  score_policy: "HIGHEST",  // HIGHEST, LATEST, FIRST, AVERAGE
  shuffle_questions: true,
  shuffle_choices: true,
  show_answers_after_completion: true
}
```

### Question Types
- **multiple_choice**: เลือกตอบ (1 คำตอบ)
- **true_false**: จริง/เท็จ
- **multiple_select**: เลือกหลายคำตอบ

### Key Endpoints

**Instructor:**
```
POST /api/instructor/courses/:courseId/lessons/:lessonId/quiz
PUT /api/instructor/quizzes/:quizId
DELETE /api/instructor/quizzes/:quizId
POST /api/instructor/quizzes/:quizId/questions
PUT /api/instructor/quizzes/:quizId/questions/:questionId
DELETE /api/instructor/quizzes/:quizId/questions/:questionId
```

**Student:**
```
GET /api/students/quizzes/:quizId
POST /api/students/quizzes/:quizId/submit
GET /api/students/quizzes/:quizId/attempts
GET /api/students/quizzes/:quizId/attempts/:attemptId
```

---

## 📢 Announcements

### Announcement Structure
```javascript
{
  id: 1,
  course_id: 1,
  title: { th: "...", en: "..." },
  content: { th: "...", en: "..." },
  is_pinned: true,
  attachments: [...],
  created_at: "2024-12-23T10:00:00Z"
}
```

### Key Endpoints

**Student:**
```
GET /api/students/courses/:courseId/announcements
GET /api/students/courses/:courseId/announcements/:announcementId
```

**Instructor:**
```
GET /api/instructor/courses/:courseId/announcements
POST /api/instructor/courses/:courseId/announcements
PUT /api/instructor/courses/:courseId/announcements/:announcementId
DELETE /api/instructor/courses/:courseId/announcements/:announcementId
```

---

## 📊 Progress & Certificates

### Course Progress Calculation
```javascript
progress_percentage = (completed_lessons / total_lessons) * 100
```

### Certificate Issuance
- ออกอัตโนมัติเมื่อจบคอร์ส 100%
- เฉพาะคอร์สที่ `have_certificate = true`
- เก็บไฟล์ PDF ใน S3

### Key Endpoints
```
GET /api/students/progress
GET /api/students/courses/:courseId/progress
GET /api/students/courses/:courseId/certificate
GET /api/students/certificates
```

---

## 🔄 Course Cloning

### What Gets Cloned
✅ **Copied:**
- Course info (title, description, price)
- All chapters and lessons
- All quizzes and questions
- All attachments (files copied to new location)
- Lesson prerequisites
- Sort orders

❌ **NOT Copied:**
- Enrollments
- Student progress
- Reviews/ratings
- Approval status (new course = DRAFT)

### Key Endpoint
```
POST /api/instructor/courses/:courseId/clone
```

---

## 🔒 Access Control & Permissions

### Lesson Access Check
```
GET /api/students/courses/:courseId/lessons/:lessonId/access-check
```

**Response (Locked):**
```javascript
{
  can_access: false,
  reason: "incomplete_prerequisites",
  required_lessons: [1, 2],
  missing_lessons: [2],
  next_available_lesson: { id: 2, title: "..." }
}
```

### Ownership Validation
```javascript
// Middleware ตรวจสอบ
if (role === 'INSTRUCTOR' && course.instructorId !== userId) {
  return 403;
}
```

---

## 📈 Reports & Analytics

### Student Reports
```
GET /api/students/progress
GET /api/students/courses/:courseId/progress
```

### Instructor Reports
```
GET /api/instructor/courses/:courseId/statistics
GET /api/instructor/courses/:courseId/students
GET /api/instructor/courses/:courseId/students/export
GET /api/instructor/dashboard
```

### Admin Dashboard
```
GET /api/admin/statistics
GET /api/admin/reports/revenue
GET /api/admin/reports/users
GET /api/admin/reports/courses
```

---

## ⚠️ Edge Cases & Best Practices

### 1. Soft Delete > Hard Delete
```javascript
// ใช้ flag แทนการลบจริง
{ isDeleted: true, deletedAt: "..." }
```

### 2. Concurrent Video Progress
```javascript
// ใช้ last_watched_at ตัดสินว่า session ไหนล่าสุด
if (newProgress.last_watched_at > currentProgress.last_watched_at) {
  updateProgress(newProgress);
}
```

### 3. Quiz Attempt Validation
```javascript
// ตรวจสอบก่อนให้ทำแบบทดสอบ
if (attempts >= maxAttempts) return error;
if (lastAttempt + cooldown > now) return error;
```

### 4. Lesson Lock Check
```javascript
// ตรวจสอบที่ Backend เสมอ
if (!allPreviousCompleted) {
  return { access: false, nextAvailableLesson };
}
```

### 5. Multi-Instructor Constraints
```javascript
// ห้ามลบ instructor คนสุดท้าย
if (instructors.length === 1) {
  return error("Cannot remove last instructor");
}
```

---

## 🗄️ Database Schema (Prisma)

### Key Models
```prisma
model User {
  id       Int      @id @default(autoincrement())
  username String   @unique
  email    String   @unique
  password String
  role     Role     @relation(...)
  profile  Profile?
}

model Course {
  id              Int      @id @default(autoincrement())
  title           Json     // { th: "", en: "" }
  description     Json
  price           Decimal
  is_free         Boolean
  have_certificate Boolean
  status          CourseStatus
  chapters        Chapter[]
  instructors     CourseInstructor[]
}

model Lesson {
  id                      Int      @id @default(autoincrement())
  title                   Json
  content                 Json
  type                    LessonType
  video_url               String?
  is_sequential           Boolean
  prerequisite_lessons    LessonPrerequisite[]
  attachments             Attachment[]
  quiz                    Quiz?
}

model Quiz {
  id                            Int      @id @default(autoincrement())
  title                         Json
  passing_score                 Int
  time_limit                    Int?
  max_attempts                  Int?
  cooldown_minutes              Int?
  score_policy                  ScorePolicy
  show_answers_after_completion Boolean
  questions                     Question[]
}
```

---

## 🔧 Technical Implementation

### File Upload (MinIO/S3)
```javascript
// Video upload
const videoPath = `courses/${courseId}/lessons/${lessonId}/video.mp4`;
await s3.upload(videoPath, videoFile);

// Attachment upload
const attachmentPath = `lessons/${lessonId}/attachments/${filename}`;
await s3.upload(attachmentPath, file);
```

### Video Progress Auto-Save
```javascript
// Frontend: Save ทุก 5 วินาที
setInterval(() => {
  if (!video.paused) {
    saveProgress(video.currentTime, video.duration);
  }
}, 5000);
```

### JWT Middleware
```javascript
const authMiddleware = async (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  const decoded = jwt.verify(token, JWT_SECRET);
  req.user = await prisma.user.findUnique({ where: { id: decoded.userId } });
  next();
};
```

### Role-Based Middleware
```javascript
const requireRole = (roles) => (req, res, next) => {
  if (!roles.includes(req.user.role.code)) {
    return res.status(403).json({ error: "Forbidden" });
  }
  next();
};
```

---

## 📋 Error Codes

| Code | Description |
|------|-------------|
| `INVALID_CREDENTIALS` | อีเมล/รหัสผ่านไม่ถูกต้อง |
| `ALREADY_ENROLLED` | ลงทะเบียนซ้ำ |
| `LESSON_LOCKED` | บทเรียนถูกล็อค |
| `INCOMPLETE_PREREQUISITES` | ยังไม่จบบทเรียนที่ต้องเรียนก่อน |
| `QUIZ_NOT_PASSED` | ยังไม่ผ่านแบบทดสอบ |
| `MAX_ATTEMPTS_EXCEEDED` | ทำแบบทดสอบเกินจำนวนครั้ง |
| `COOLDOWN_ACTIVE` | ต้องรอก่อนทำแบบทดสอบอีกครั้ง |
| `FILE_TOO_LARGE` | ไฟล์ใหญ่เกินไป |
| `INVALID_FILE_TYPE` | ประเภทไฟล์ไม่รองรับ |
| `COURSE_NOT_FOUND` | ไม่พบคอร์ส |
| `UNAUTHORIZED` | ไม่มีสิทธิ์เข้าถึง |

---

## 🎯 Development Checklist

### สำหรับทุก Endpoint
- [ ] Validate input data (Joi/Zod)
- [ ] Check authentication (JWT)
- [ ] Check authorization (Role/Ownership)
- [ ] Handle errors properly
- [ ] Return consistent response format
- [ ] Log important actions
- [ ] Add rate limiting

### สำหรับ File Upload
- [ ] Validate file type
- [ ] Validate file size
- [ ] Generate unique filename
- [ ] Upload to S3/MinIO
- [ ] Save metadata to database
- [ ] Handle upload errors

### สำหรับ Multi-Language
- [ ] Accept `lang` query parameter
- [ ] Return appropriate language
- [ ] Fallback to default language
- [ ] Validate both languages exist

---

## 📚 Related Documentation

- [API Endpoints Reference](../docs/api-docs/api_endpoints.md)
- [API Usage Examples](../docs/api-docs/api_usage_examples.md)
- [Edge Cases Quick Reference](../docs/api-docs/edge_cases_quick_reference.md)
- [Development Setup](../docs/development_setup.md)

---

## 🚀 Quick Start Commands

```bash
# Install dependencies
npm install

# Setup database
npx prisma migrate dev

# Seed database
npx prisma db seed

# Start development server
npm run dev

# Run tests
npm test
```

---

**Last Updated**: 2026-01-07  
**Version**: 1.0.0
