# บทที่ 10: Pull Request (PR) และ Code Review - ทำที่ไหน และทำอย่างไร

## หัวข้อหลัก

- Pull Request คืออะไร
- ทำ PR ที่ไหนผ่านเว็บแพลตฟอร์ม
- ขั้นตอน: ทำอย่างไรให้ถูกต้อง
- Code Review Checklist
- Best Practices

---

## 📑 สารบัญ

1. [Pull Request คืออะไร](#1-pull-request-pr-คืออะไร)
   - [Definition](#11-definition)
   - [Platforms](#12-platforms-ที่ใช้-pr)

2. [ทำ PR ที่ไหน (GitHub)](#2-ทำ-pr-ที่ไหน-github)

3. [🚀 Quick Start](#-quick-start-สำหรับผู้เริ่มต้น)

4. [ขั้นตอนโดยละเอียด](#3-ขั้นตอนโดยละเอียด-ทำอย่างไรให้ถูกต้อง)
   - [ขั้นที่ 1: สร้าง Feature Branch](#ขั้นที่-1-สร้าง-feature-branch-และ-commit)
   - [ขั้นที่ 2: สร้าง PR](#ขั้นที่-2-สร้าง-pull-request-บน-github)
   - [ขั้นที่ 3: Code Review](#ขั้นที่-3-code-review--reviewer-ตรวจสอบ)
   - [ขั้นที่ 4: แก้ไขโค้ด](#ขั้นที่-4-author-แก้ไขตามคำแนะนำ)
   - [ขั้นที่ 5: Approve & Merge](#ขั้นที่-5-reviewer-approve)

5. [Timeline ตัวอย่าง](#4-📅-timeline-pr-example)

6. [PR Template](#5-📧-pr-template-optional)

7. [Good vs Bad PR](#6-✅-good-pr-vs-❌-bad-pr)

8. [อะไรที่-ห้ามทำ](#7-❌-อะไรที่-ห้ามทำ)

9. [PR Comments](#8-💬-ตัวอย่าง-comments-ที่ดี)

10. [Merge & Status](#9-🔀-merge--status)

11. [Checklist](#11-สรุป-checklist-for-pr)

12. [สรุป](#สรุป)

---

## 1. Pull Request (PR) คืออะไร?

### 1.1 Definition

**Pull Request** = ขอให้ merge feature branch เข้า main branch พร้อมให้ทีม review ก่อน

```
Developer A: feature/login
             ↓
        (สร้าง PR)
             ↓
        Code Review
        - Reviewer B: ตรวจสอบโค้ด
        - Reviewer C: ตรวจสอบโค้ด
             ↓
        ✅ Approve
             ↓
       Merge เข้า main
             ↓
       Delete branch
```

### 1.2 Platforms ที่ใช้ PR

| Platform   | ชื่อเรียก             |
| ---------- | --------------------- |
| **GitHub** | **Pull Request (PR)** |
| GitLab     | Merge Request (MR)    |
| Bitbucket  | Pull Request (PR)     |

_สำหรับคอร์สนี้เราใช้ **GitHub** เป็นหลัก_

---

## 2. ทำ PR ที่ไหน? (GitHub)

**URL:** `https://github.com/username/project-name/pulls`

**หรือ:**

1. เปิด https://github.com/company/project
2. คลิก "Pull requests" tab → ทำเสร็จ!

---

## 🚀 Quick Start สำหรับผู้เริ่มต้น

**ลำดับการทำ PR ครั้งแรก:**

```
1️⃣  git checkout -b feature/your-feature
2️⃣  [แก้ไขโค้ด]
3️⃣  git add . && git commit -m "feat: Your message"
4️⃣  git push origin feature/your-feature
5️⃣  เปิด GitHub → คลิก "Create Pull Request"
6️⃣  กรอก Title + Description
7️⃣  รอ Reviewer ตรวจสอบ
8️⃣  แก้ตามคำแนะนำ (ถ้ามี)
9️⃣  รอ Approve และ Merge
🔟 Done! 🎉
```

**เพียงเท่านี้เอง!** ส่วนรายละเอียดดูข้างล่าง

---

## 3. ขั้นตอนโดยละเอียด: ทำอย่างไรให้ถูกต้อง

### **ขั้นที่ 1: สร้าง Feature Branch และ Commit**

#### 1.1 Clone Project

```bash
git clone https://github.com/company/project.git
cd project
```

#### 1.2 สร้าง Feature Branch

```bash
# ตั้งชื่อให้ชัดเจน
git checkout -b feature/user-authentication

# หรือ feature type อื่นๆ
git checkout -b bugfix/fix-login-error
git checkout -b refactor/improve-performance
```

#### 1.3 ทำการแก้ไขโค้ด

```javascript
// src/auth.js
export function login(email, password) {
  // Validation
  if (!email || !password) {
    throw new Error("Email and password required");
  }

  // Check user
  const user = db.findUser(email);
  if (!user) {
    throw new Error("User not found");
  }

  // Verify password
  if (!user.verifyPassword(password)) {
    throw new Error("Invalid password");
  }

  return user;
}
```

#### 1.4 Commit Changes

```bash
# Stage changes
git add src/auth.js

# Commit (message ให้ชัดเจน)
git commit -m "feat: Add user login function with validation"

# ถ้ามีหลาย files
git add .
git commit -m "feat: Implement user authentication system

- Add login function
- Add password validation
- Add error handling
- Add unit tests"
```

#### 1.5 Push ขึ้น Remote

```bash
git push origin feature/user-authentication
```

---

### **ขั้นที่ 2: สร้าง Pull Request บน GitHub**

#### 2.1 วิธีที่ 1: ผ่าน GitHub Web UI (ง่ายสุด)

```
1. เปิด https://github.com/company/project
2. ไปที่ "Pull requests" tab
3. คลิก "New pull request" (สีเขียว)
4. เลือก branches:
   - Base: main (เป้าหมาย ที่ต้อง merge เข้าไป)
   - Compare: feature/user-authentication (ที่ต้อง merge)
5. กรอกข้อมูล PR:
   - Title: "Add user authentication" (ให้ชัดเจน)
   - Description: (ดูข้อ 2.3)
   - Assignees: เลือก reviewer
   - Labels: feature, authentication
6. คลิก "Create pull request"
```

**ภาพ:**

```
┌─────────────────────────────────────────┐
│  main                                   │
│   ↑ (Merge target)                      │
│  ┌─────────────────────────────────────┐│
│  │  feature/user-authentication        ││
│  │   ↓ (Source to merge)               ││
│  └─────────────────────────────────────┘│
│                                         │
│  Title: Add user authentication         │
│  Description: describe PR               │
│  Reviewers: @alice, @bob                │
│  Labels: feature, authentication        │
│  Assignees: @developer-a                │
│                                         │
│  [Create pull request Button]           │
└─────────────────────────────────────────┘
```

#### 2.2 วิธีที่ 2: ผ่าน GitHub CLI (เร็ว)

```bash
# ต้องติดตั้ง GitHub CLI ก่อน
brew install gh        # macOS
# หรือ choco install gh  # Windows

# สร้าง PR
gh pr create --title "Add user authentication" \
             --body "Implement login & signup logic with validation" \
             --assignee @alice,@bob \
             --label "feature,authentication"
```

#### 2.3 PR Description ควรมีอะไรบ้าง?

```markdown
## Description

อธิบายว่าทำอะไร และทำไม

Implement user authentication system:

- Add login functionality
- Add email validation
- Add password hashing
- Add error handling

## Type of Change

✅ New feature
☐ Bug fix
☐ Breaking change
☐ Documentation update

## Related Issue

Fixes #123

## How to Test

ให้ reviewer test อย่างไร:

1. npm install
2. npm test -- auth.test.js
3. npm run dev
4. ไปที่ http://localhost:3000/login
5. ลองใส่ email & password

## Screenshots (if UI change)

สำหรับ UI changes ใส่รูป

## Checklist

- [x] Code follows style guide
- [x] Tests added
- [x] Documentation updated
- [ ] Breaking change documented
```

---

### **ขั้นที่ 3: Code Review - Reviewer ตรวจสอบ**

#### 3.1 Reviewer ทำอะไร?

```
1. เปิด PR
2. ไปที่ "Files changed" tab
3. ดูรายการไฟล์ที่เปลี่ยน
4. ดู Code diff (เปรียบเทียบเก่า vs ใหม่):
   - สีแดง = ลบออก
   - สีเขียว = เพิ่มเข้ามา
5. เพิ่ม Comments
6. Decision: Approve / Request Changes
```

#### 3.2 ตัวอย่าง Code Review

**Reviewer Comments on Line 10:**

```javascript
// ❌ Issue
export function login(email, password) {
  // Missing email validation!

  const user = db.findUser(email);
  return user;
}
```

**Reviewer Comment:**

```
"Need email format validation before
querying database. What if email is not in valid format?"
function validateEmail(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
```

#### 3.3 Reviewer Options

```
☐ Comment
   └─ แค่ comment ไม่บังคับให้แก้

☐ Approve
   └─ โค้ดดี พร้อม merge

☑ Request changes
   └─ ต้องแก้ไขก่อน merge ได้
```

#### 3.4 Code Review Checklist (Essential)

**Reviewer ตรวจสอบ 5 สิ่งสำคัญนี้:**

```markdown
✅ **Functionality** - โค้ดทำงานตามที่ต้องการ?
✅ **Logic** - โค้ดถูกต้องไม่มีบั๊ก?
✅ **Tests** - มี tests ประกอบเพียงพอ?
✅ **Style** - ตั้งชื่อตัวแปร comments ชัดเจน?
✅ **Security** - ไม่มี Input validation ปัญหา?
```

_(Advanced checklist เช่น Performance, N+1 queries เอาไว้โครงการที่ใหญ่ขึ้น)_

---

### **ขั้นที่ 4: Author แก้ไขตามคำแนะนำ**

#### 4.1 Reviewer บอกให้แก้

```
PR Status: "Changes requested"
Reviewer comment: "Need email validation"
```

#### 4.2 Author แก้ไข

```bash
# Edit file ตามข้อเสนอ
echo "// src/auth.js
function validateEmail(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

export function login(email, password) {
  if (!validateEmail(email)) {
    throw new Error('Invalid email format');
  }

  const user = db.findUser(email);
  return user;
}" > src/auth.js

# Commit แก้ไข (ข้อความชัดเจน)
git add src/auth.js
git commit -m "fix: Add email validation to login function"

# Push ขึ้นไป (PR จะ update อัตโนมัติ)
git push origin feature/user-authentication
```

**Result:** PR จะไป update ให้เห็น commits ใหม่

---

### **ขั้นที่ 5: Reviewer Approve**

#### 5.1 หลังจาก Author แก้เสร็จ

```
1. Reviewer ดู commits ใหม่
2. พอใจแล้ว → คลิก "Approve"
3. PR Status: "All checks passed ✅"
```

#### 5.2 Merge

```
1. ก่อน merge ต้องได้ approval จาก reviewer
2. คลิก "Merge pull request"
3. เลือก merge strategy:
   - Create a merge commit (default)
   - Squash and merge (บีบ commits)
   - Rebase and merge (สะอาด)
4. Confirm merge
5. Delete branch (อัตโนมัติ)
```

---

## 4. 📅 Timeline PR (Example)

**ห้างชื่อ:**

```
Monday   : Developer A สร้าง PR
Monday   : Reviewer B คน๋าชื่อ คำแนะนำ "Need validation"
Monday   : Developer A แก้ไข + push
Tuesday  : Reviewer B & C approve ✅
Tuesday  : Merge เข้า main
Tuesday  : Deploy เข้า Production 🚀
```

---

## 5. 📧 PR Template (Optional)

**สร้างตาม `.github/pull_request_template.md`**

```markdown
## What?

[Describe your changes]

## Why?

[Why this change?]

## Testing

[How to test?]

## Checklist

- [ ] Tests added
- [ ] No breaking changes
- [ ] Code reviewed by me
```

---

## 6. ✅ Good PR vs ❌ Bad PR

| ด้าน           | ✅ ทำแบบนี้                   | ❌ อย่าทำแบบนี้   |
| -------------- | ----------------------------- | ----------------- |
| **Title**      | "feat: Add login"             | "update"          |
| **Size**       | < 400 lines                   | > 1000 lines      |
| **Commits**    | บ่อยๆ เล็กๆ                   | ทั้งหมด 1 commits |
| **Tests**      | มี tests                      | "Tested manually" |
| **Comment**    | "Good point, but consider..." | "This is wrong!"  |
| **Force push** | ❌ ห้าม                       | ❌ ห้าม           |

---

## 7. ❌ อะไร ที่ **ห้ามทำ**

```
❌ Force push: git push -f (ลบ history)
❌ Merge เอง โดยไม่รอ approval
❌ PR เก่าแล้ว ไม่แก้ไข (> 1 สัปดาห์)
❌ Ignore reviewer comments
```

---

## 8. 💬 ตัวอย่าง Comments ที่ดี

✅ **ดี:**

```
"Good point! Consider using switch statement for cleaner code?"
```

❌ **ไม่ดี:**

```
"This is wrong. Fix it."
```

---

## 9. 🔀 Merge - ใช้ Default ก็ได้!

**สำหรับเริ่มต้น:** ใช้ "Create a merge commit" ก็พอ

_(Advanced: Squash/Rebase เอาไว้โครงการใหญ่)_

---

## 10. 🟢 PR Status

- 🟡 **Waiting Review** - รอ reviewer
- 🔴 **Changes Requested** - แก้ไข
- 🟢 **Approved** - ผ่าน ✅
- 🟣 **Merged** - เสร็จสิ้น 🎉

---

## 11. สรุป Checklist for PR

### Before Creating PR ✅

- [ ] สร้าง feature branch จากต้นน้ำ
- [ ] Commit messages ชัดเจน
- [ ] Tests เขียนแล้ว
- [ ] Self-review โค้ด
- [ ] Lint/format ถูกต้อง

### When Creating PR ✅

- [ ] Title ชัดเจน
- [ ] Description รายละเอียด
- [ ] Assign reviewers
- [ ] Link related issues
- [ ] Add labels

### During Review ✅

- [ ] Respond to comments
- [ ] Fix issues
- [ ] Re-request review
- [ ] Acknowledge feedback

### Before Merging ✅

- [ ] ได้ approvals พอ (2+)
- [ ] Tests all pass ✅
- [ ] No conflicts
- [ ] CI/CD green ✅

---

## สรุป

| ขั้นตอน      | ที่ไหน | เครื่องมือ | ผู้ทำ              |
| ------------ | ------ | ---------- | ------------------ |
| 1. Commit    | Local  | Git        | Developer          |
| 2. Push      | GitHub | Git        | Developer          |
| 3. Create PR | GitHub | Web/CLI    | Developer          |
| 4. Review    | GitHub | Web        | Reviewer           |
| 5. Fix       | Local  | Git        | Developer          |
| 6. Approve   | GitHub | Web        | Reviewer           |
| 7. Merge     | GitHub | Web        | Developer/Reviewer |

**PR & Code Review ช่วยให้:**

- 📊 Code Quality สูง
- 🔍 Bugs ลดลง
- 📚 Knowledge sharing
- 👥 Team culture ดี

Good PR = Good Code = Happy Team! 🎉
