# สัปดาห์ที่ 7: Code Standards, Sprint Planning & Development Kickoff

## 📋 วัตถุประสงค์การเรียนรู้

หลังจากเรียนในสัปดาห์นี้ นักศึกษาจะสามารถ:

1. **Coding Standards:** เขียน Coding Standards Document ที่ชัดเจนและครอบคลุม
2. **Code Review Process:** ทำ Peer Code Review อย่างมีประสิทธิภาพ
3. **Git Workflows:** ใช้ Git Branching Strategy อย่างถูกต้อง
4. **Sprint Planning:** วางแผน Sprint และสร้าง Sprint Backlog ที่สมจริง
5. **Project Kickoff:** เตรียมทีมให้พร้อมเข้าสู่ Development Phase

---

### ส่วนที่ 1: มาตรฐานการเขียนโค้ด (Coding Standards) และแนวปฏิบัติที่ดี (Best Practices)

#### 1.1 เหตุใดมาตรฐานการเขียนโค้ดจึงสำคัญ?

**ข้อเท็จจริง:**

- 70% ของเวลาสำหรับนักพัฒนา (Developer) ใช้ในการอ่านโค้ด (ไม่ใช่การเขียน)
- โค้ดที่มีลักษณะต่างกัน = ยากในการอ่าน + ข้อบกพร่อง (Bug) มากขึ้น
- ลักษณะที่สอดคล้องกัน (Consistent Style) = ลดการรับความรู้สึก (Cognitive Load)
- มาตรฐาน = ทีมใช้ภาษาเดียวกัน

**ประโยชน์:**

```
ด้วยมาตรฐานการเขียนโค้ด:
✓ อ่านและเข้าใจได้ง่าย
✓ บำรุงรักษาได้ง่ายขึ้น
✓ การตรวจสอบโค้ด (Code Review) เร็วขึ้น
✓ ข้อบกพร่องน้อยลง
✓ สมาชิกทีมใหม่ปรับตัวได้เร็ว
✓ ลดต้นทุนการปรับปรุงโค้ด (Refactoring)

โดยไม่มีมาตรฐาน:
✗ ความไม่เป็นระเบียบและไม่สอดคล้อง
✗ ต้นทุนการบำรุงรักษาสูง
✗ การตรวจสอบโค้ดช้า
✗ ความรู้อยู่แยกส่วน (Knowledge Silos)
✗ หนี้เทคนิค (Technical Debt) สะสมตัว (ปัญหาด้านโค้ดและการออกแบบที่สะสม เมื่อทีมเลือกที่จะสร้างโค้ดไม่ดีเพื่อความเร็ว แต่ไม่กลับมาแก้ไขเมื่อถึงเวลา)
```

#### 1.2 พื้นที่สำคัญของมาตรฐานการเขียนโค้ด

**1. การตั้งชื่อตัวแปร (Naming Conventions)**

```
คลาส (Classes):
- PascalCase: UserService, ProductRepository
- คำนาม (Nouns): ✓ User, ✗ user, ✗ do_something

เมธอด (Methods):
- camelCase: getUserById(), createOrder()
- กริยา (Verbs): ✓ get, create, delete, ✗ data, ✗ info
- บูลีน (Booleans): ใช้ is/has/can: isActive, hasPermission

ตัวแปร (Variables):
- camelCase: userName, productId
- อธิบายได้: ✓ totalPrice, ✗ x, ✗ temp

ค่าคงที่ (Constants):
- UPPER_SNAKE_CASE: MAX_RETRY_COUNT, DB_TIMEOUT

แพ็คเกจ/โมดูล (Packages/Modules):
- ตัวพิมพ์เล็ก (lowercase): com.company.project.service

ฐานข้อมูล (Database):
- snake_case: user_id, created_at
- ความสอดคล้องในการใช้เอกพจน์หรือพหูพจน์
```

**2. การจัดระเบียบโค้ด (Code Organization)**

```
โครงสร้างโฟลเดอร์ (Layered Architecture):

src/
├── controllers/       (ชั้น API)
├── services/          (ตรรกะธุรกิจ)
├── models/            (โครงสร้างข้อมูล)
├── repositories/      (การเข้าถึงข้อมูล)
├── middlewares/       (Middlewares)
├── utils/             (ประโยชน์ใช้สอย)
├── config/            (การกำหนดค่า)
├── constants/         (ค่าคงที่)
├── errors/            (ข้อยกเว้นกำหนดเอง)
└── index.js           (จุดเข้า)
tests/
├── controllers/
├── services/
├── models/
└── repositories/
.env
package.json
.gitignore

การตั้งชื่อไฟล์:
- ส่วนประกอบ/คลาส: UserController.js (ไม่ใช่ user-controller.js)
- ทดสอบ: UserController.test.js (หรือ UserController.spec.js)
- ตัวอักษร PascalCase สำหรับชื่อคลาส
- ตัวอักษร camelCase สำหรับตัวแปรอื่นๆ
```

**3. การจัดระเบียบคลาสและเมธอด (Class & Method Organization)**

```javascript
// ลำดับภายในไฟล์/คลาส:

// 1. ค่าคงที่ (Constants)
const MAX_NAME_LENGTH = 100;
const DEFAULT_TIMEOUT = 5000;

// 2. Helper Functions (ฟังก์ชันช่วยเหลือ)
const validateEmail = (email) => {
  return email.includes("@");
};

// 3. Main Class/Module
class User {
  // 3.1 Constructor (ตัวสร้าง)
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  // 3.2 Public Methods (เมธอดสาธารณะ)
  async save() {
    // บันทึกผู้ใช้
  }

  getName() {
    return this.name;
  }

  // 3.3 Private Methods (เมธอดส่วนตัว)
  #validate() {
    // ตรวจสอบข้อมูล
  }

  #sanitize() {
    // ทำความสะอาดข้อมูล
  }

  // 3.4 Override/Special Methods
  toString() {
    return `User(${this.name}, ${this.email})`;
  }
}

// 4. Exports
module.exports = User;
```

**แนวทาง:**

- ความยาวสูงสุดของเมธอด: 50 บรรทัด
- เมธอดส่วนตัว (#privateMethod) จัดกลุ่มไว้ด้วยกัน
- ความรับผิดชอบเดียว (Single Responsibility) ต่อเมธอด
- ใช้ async/await สำหรับการดำเนินการแบบอะซิงโครนัส

**4. ความเห็นและเอกสาร (Comments & Documentation)**

```javascript
// ความเห็นที่ดี:

// WHY: พยายาม 3 ครั้งเพื่อจัดการกับข้อผิดพลาดเครือข่าย (Network Errors)
const MAX_RETRIES = 3;

// ใช้ Binary Search สำหรับประสิทธิภาพ O(log n)
function findUser(users, targetId) {
  // ...
}

// ข้ามองค์ประกอบแรกเพราะมันว่างเปล่าเสมอ
const [, ...validItems] = items;

// ความเห็นที่ไม่ดี:
// i++ เพื่อเพิ่ม i (ชัดเจนอยู่แล้ว)
i++;

// TODO: แก้ไขนี้ (แต่มันถูกแก้ไขแล้ว - ล้าสมัย)
// ส่วนโค้ดที่ออกแบบมา (ใช้ Git History!)
// const x = 10;
// const y = 20;

// JSDoc Documentation:
/**
 * คำนวณราคาทั้งหมดของคำสั่งซื้อรวมภาษี
 *
 * @param {Array<Item>} items - รายการสินค้าในคำสั่งซื้อ
 * @param {number} taxRate - อัตราภาษีเป็นทศนิยม (เช่น 0.07 สำหรับ 7%)
 * @returns {number} ราคาทั้งหมดรวมภาษี
 * @throws {Error} หาก taxRate < 0 หรือ > 1
 *
 * @example
 * const total = calculateTotal(items, 0.07);
 * console.log(total);
 */
function calculateTotal(items, taxRate) {
  if (taxRate < 0 || taxRate > 1) {
    throw new Error("อัตราภาษีต้องเป็น 0-1");
  }
  // ...
}
```

**5. การจัดการข้อผิดพลาด (Error Handling)**

**Logger vs Console.log - ความแตกต่างที่สำคัญ:**

```javascript
// ❌ CONSOLE.LOG - อย่าใช้ในสินค้า!
console.log("User created"); // ปรากฏในหน้าต่างเทอร์มินัล
console.error("Error!"); // ไม่มีวันที่/เวลา
// ปัญหา:
// - ไม่บันทึกลงไฟล์
// - หายไปเมื่อเซิร์ฟเวอร์รีสตาร์ท
// - ไม่มีระดับสำคัญ (INFO, WARN, ERROR)
// - ไม่มีรหัสติดตามข้อผิดพลาด (Trace ID)

// ✅ LOGGER - ใช้สำหรับสินค้า
logger.info("User created"); // บันทึกลงไฟล์
logger.warn("Low memory"); // [2025-01-10 09:15:24] WARN: Low memory
logger.error("DB error", error); // [2025-01-10 09:15:25] ERROR: DB error\n<stack trace>
// ข้อดี:
// - บันทึกลงไฟล์ถาวร (.log files)
// - มีวันที่/เวลา/ระดับสำคัญ
// - สามารถค้นหาปัญหาในอดีตได้
// - สามารถส่งไปให้บริการเฝ้าระวัง (Monitoring)
```

**ไฟล์ logger บันทึกอยู่ที่ไหน?**

```javascript
// 1. ตั้งค่า Logger ใน config/logger.js

const winston = require("winston");

const logger = winston.createLogger({
  level: "info", // ระดับขั้นต่ำที่จะบันทึก
  format: winston.format.combine(
    winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
    winston.format.errors({ stack: true }),
    winston.format.splat(),
    winston.format.json(),
  ),
  defaultMeta: { service: "my-app" },
  transports: [
    // ❌ ERROR logs → logs/error.log
    new winston.transports.File({
      filename: "logs/error.log",
      level: "error",
    }),

    // ℹ️ COMBINED logs → logs/combined.log
    new winston.transports.File({
      filename: "logs/combined.log",
    }),

    // เทอร์มินัล (เฉพาะระหว่างพัฒนา)
    new winston.transports.Console({
      format: winston.format.simple(),
    }),
  ],
});

module.exports = logger;

// 2. ใช้ Logger ในโค้ด
const logger = require("./config/logger");

logger.info("Server started"); // → บันทึกลงทั้ง logs/combined.log และเทอร์มินัล
logger.error("DB error", error); // → บันทึกลง logs/error.log และ logs/combined.log
```

**โครงสร้างโฟลเดอร์ของบันทึก:**

```
project/
├── src/
│   ├── config/
│   │   └── logger.js (ตั้งค่า logger)
│   ├── services/
│   └── app.js
│
├── logs/                          ← 📁 ไฟล์บันทึก
│   ├── error.log                  ← ❌ เฉพาะข้อผิดพลาด
│   ├── error.log.1                ← ❌ ไฟล์เก่า (Rotation)
│   ├── error.log.2                ← ❌ ไฟล์เก่า (Rotation)
│   ├── combined.log               ← ℹ️ ทั้งหมด (INFO, WARN, ERROR)
│   ├── combined.log.1             ← ℹ️ ไฟล์เก่า
│   └── combined.log.2             ← ℹ️ ไฟล์เก่า
│
└── package.json
```

**การดูไฟล์บันทึก (View Log Files):**

```bash
# ดูไฟล์ error.log
cat logs/error.log

# ดูสุดท้าย 50 บรรทัด
tail -50 logs/combined.log

# ดูแบบ live (ตามเนื้อที่อัปเดต)
tail -f logs/combined.log

# ค้นหา error ของ user email
grep "john@example.com" logs/combined.log

# นับจำนวน error
grep "ERROR" logs/combined.log | wc -l
```

**ตัวอย่างไฟล์ error.log:**

```log
[2025-01-10T09:05:30.123Z] ERROR: [my-app]
  Error: Cannot find user
  Error: at UserService.getUser (/app/src/services/UserService.js:25:15)
  Error: at async POST /api/users/123 (/app/src/routes/users.js:15:8)
  Message: ไม่พบผู้ใช้: 123
  Stack: UserError: ไม่พบผู้ใช้: 123
    at UserService.getUser (/app/src/services/UserService.js:25:15)
    at async POST /api/users/123 (/app/src/routes/users.js:15:8)

[2025-01-10T09:15:45.456Z] ERROR: [my-app]
  Error: Database connection failed
  Message: ไม่สามารถเชื่อมต่อ PostgreSQL
  Code: ECONNREFUSED
  Host: db.example.com
  Port: 5432
```

**ระดับบันทึก (Logging Levels):**

```javascript
logger.debug("โครงสร้างข้อมูลยูเซอร์", user); // 🔍 เฉพาะการพัฒนา
logger.info("ผู้ใช้บันทึกสำเร็จ"); // ℹ️ ข้อมูล
logger.warn("ความเร็ว DB ช้า: 500ms"); // ⚠️ เตือน
logger.error("ล้มเหลว DB", error); // ❌ ข้อผิดพลาด
logger.fatal("ไม่สามารถเชื่อมต่อ DB"); // 🔴 ร้ายแรง - หยุดการทำงาน
```

**ตัวอย่างการใช้ Logger ที่ถูกต้อง:**

```javascript
// ❌ ไม่ดี - ใช้ console.log
async function saveUser(user) {
  try {
    await db.save(user);
    console.log("User saved"); // หายไปในไฟล์เซิร์ฟเวอร์
  } catch (error) {
    console.error(error); // ไม่ชัดเจน, ไม่มีบริบท
  }
}

// ✅ ดี - ใช้ Logger (บันทึกลงไฟล์ logs/combined.log)
async function saveUser(user) {
  try {
    logger.info(`บันทึกผู้ใช้: ${user.email}`);
    await db.save(user);
    logger.info(`บันทึกผู้ใช้สำเร็จ: ${user.email}`);
  } catch (error) {
    // ไปยัง logs/error.log และ logs/combined.log
    logger.error(`ล้มเหลวบันทึกผู้ใช้: ${user.email}`, {
      error: error.message,
      stack: error.stack,
      email: user.email,
      timestamp: new Date(),
    });
    throw new DatabaseError("ไม่สามารถบันทึกผู้ใช้ได้");
  }
}
```

````

**ตัวอย่างไฟล์บันทึก (Log File):**

```log
[2025-01-10 08:00:15] INFO: Server started on port 3000
[2025-01-10 08:15:22] INFO: User login: john@example.com
[2025-01-10 08:15:23] INFO: Database query: SELECT * FROM users (145ms)
[2025-01-10 08:45:10] WARN: High memory usage: 876MB
[2025-01-10 09:05:30] ERROR: Failed to send email: john@example.com
  Error: SMTP connection timeout
  Stack: at SMTPClient.connect (/app/services/EmailService.js:45:12)
[2025-01-10 10:22:15] INFO: Cache cleared
[2025-01-10 10:25:00] FATAL: Cannot connect to database - Shutting down
````

**สถานการณ์จริง - ทำไมต้องใช้ Logger?**

```
🔴 สถานการณ์: ผู้ใช้บ่น "ล่าสุดปุ่มสร้างไม่ทำงาน!"

❌ หากใช้ console.log:
- ผลลัพธ์: ?????????
- ไม่มีบันทึก = ไม่รู้เกิดอะไร

✅ หากใช้ Logger:
- เปิดไฟล์ log: tail -f server.log
- [2025-01-10 14:22:15] ERROR: POST /api/users - Validation failed
  {
    "email": "invalid-email",
    "error": "Email format invalid"
  }
- รู้ทันที: นั่น! ล้มเหลว validation
```

```javascript
// ดี:
async function getUserById(userId) {
  try {
    const user = await userRepository.findById(userId);
    return user;
  } catch (error) {
    if (error.name === "UserNotFoundError") {
      logger.warn(`ไม่พบผู้ใช้: ${userId}`);
      throw new ApplicationError("ไม่พบผู้ใช้");
    }
    logger.error(
      `ข้อผิดพลาดที่ไม่คาดคิดในการดึงข้อมูลผู้ใช้: ${userId}`,
      error,
    );
    throw new SystemError("ข้อผิดพลาดของระบบ", error);
  }
}

// ไม่ดี:
async function getUserById(userId) {
  try {
    const user = await userRepository.findById(userId);
    return user;
  } catch (error) {
    // ไม่ทำอะไร - ปิดบังข้อผิดพลาด!
  }
}

// หรือ
async function getUserById(userId) {
  try {
    const user = await userRepository.findById(userId);
    return user;
  } catch (error) {
    console.log("ข้อผิดพลาด!"); // อย่าใช้ console.log ในสินค้า!
  }
}
```

**6. ความซับซ้อนของโค้ด (Code Complexity)**

```javascript
// แนวทางความซับซ้อน (Cyclomatic Complexity):
// 1-5:   ง่าย, จัดการได้
// 5-10:  ปานกลาง, ระวัง
// 10-15: ซับซ้อน, ต้องตรวจสอบ
// >15:   ซับซ้อนมาก, ต้องปรับปรุง!

// ตัวอย่าง (ความซับซ้อนสูง) - ไม่ดี:
function processOrder(a, b, c, d, e) {
  if (a && b) {
    if (c || d) {
      if (e) {
        // ... การประมวลผล
      }
    }
  }
}

// ปรับปรุงเป็น - ดี:
function processOrder(a, b, c, d, e) {
  if (isValidOrder(a, b, c, d, e)) {
    // ... การประมวลผล
  }
}

function isValidOrder(a, b, c, d, e) {
  return a && b && (c || d) && e;
}
```

---

### ส่วนที่ 2: กระบวนการตรวจสอบโค้ด (Code Review Process)

#### 2.1 การตรวจสอบโค้ดคืออะไร?

**คำจำกัดความ:** การตรวจสอบอย่างเป็นระบบของการเปลี่ยนแปลงโค้ดโดยสมาชิกทีมก่อนการรวมผลการทำงาน (Merge)

**เพราะเหตุใด**

- จับข้อบกพร่อง (Bug) ตั้งแต่เริ่มต้น (ช่วยประหยัดต้นทุน)
- แบ่งปันความรู้
- ตรวจสอบให้เป็นไปตามมาตรฐาน
- ปรับปรุงคุณภาพโค้ด
- ระบุปัญหาด้านความปลอดภัย (Security Issues)

**สถิติ:**

- การตรวจสอบโค้ดจับข้อบกพร่องได้ 60-90%
- การตรวจสอบโดยเพื่อนมีประสิทธิภาพมากกว่าการทดสอบเพียงอย่างเดียว
- การตรวจสอบปรับปรุงคุณภาพโค้ดขึ้น 20-30%

#### 2.2 กระบวนการตรวจสอบโค้ด

```
1. นักพัฒนาสร้างสาขา (Feature Branch)
2. นักพัฒนาเขียนโค้ด & เขียนการทดสอบ
3. นักพัฒนาสร้างคำขอการดึงข้อมูล (Pull Request - PR)
4. การตรวจสอบอัตโนมัติทำงาน (Linter, Tests)
5. การตรวจสอบโค้ด (Peers review code)
6. แก้ไขข้อเสนอแนะและอัปเดต PR
7. อนุมัติ & รวมผลเข้ากับสาขา develop
8. สร้างและปรับใช้ (Deploy) ไปยังเวทีการสาธารณะ (Staging)
```

#### 2.3 รายการตรวจสอบโค้ด (Code Review Checklist)

**การทำงาน (Functionality):**

```
☐ โค้ดทำสิ่งที่ควรจะทำ
☐ จัดการกรณีขอบเขต (Edge Cases) ✓ ดู examples
☐ การจัดการข้อผิดพลาดเหมาะสม
☐ ไม่มีข้อบกพร่องที่ชัดเจน
☐ ประสิทธิภาพที่ยอมรับได้
☐ ไม่มีค่าคงที่ที่เข้ารหัส (Hardcoded Values)
☐ ไม่มีโค้ดการดีบัก (Debugging Code) เหลืออยู่
```

**📌 Edge Cases - ตัวอย่างจริง:**

```
สถานการณ์: Function searchProduct(name)

❌ ไม่จัดการ Edge Cases:
  const results = products.filter(p => p.name === name);
  return results[0]; // หาก name ว่าง หรือไม่มี = Error!

❌ Cases ที่อาจเกิด:
  - name = null → Error!
  - name = undefined → Error!
  - name = "" (string ว่าง) → ไม่หาอะไร
  - name = "  SHIRT  " (มี space) → หาไม่เจอ "SHIRT"
  - database ว่าง → return undefined แล้ว [0] = Error!
  - case sensitive: "shirt" vs "Shirt" → หาไม่เจอ

✅ จัดการ Edge Cases:
function searchProduct(name) {
  // 1. ตรวจสอบ input
  if (!name || typeof name !== 'string') {
    throw new Error('Name must be non-empty string');
  }

  // 2. ทำความสะอาด input
  const cleanName = name.trim().toLowerCase();
  if (cleanName.length === 0) {
    return []; // return empty array ไม่ใช่ null
  }

  // 3. หาด้วย case-insensitive
  const results = products.filter(p =>
    p.name.toLowerCase().includes(cleanName)
  );

  // 4. ตรวจสอบผลลัพธ์
  return results.length > 0 ? results : [];
}

// Test cases ที่ต้องทำ:
searchProduct(null);           // ❌ Error
searchProduct(undefined);      // ❌ Error
searchProduct("");            // ✅ []
searchProduct("   ");         // ✅ []
searchProduct("shirt");       // ✅ [product1, product2]
searchProduct("SHIRT");       // ✅ [product1, product2]
searchProduct("xyz");         // ✅ []
```

**คุณภาพโค้ด (Code Quality):**

```
☐ เป็นไปตามการตั้งชื่อตัวแปร
☐ โค้ดอ่านและบำรุงรักษาได้ง่าย
☐ เมธอดไม่ยาวเกินไป (< 50 บรรทัด)
☐ คลาสมีเอกราชความรับผิดชอบ (Single Responsibility) ✓ ดู SOLID
☐ หลักการ DRY (ไม่ซ้ำกัน)
☐ หลักการ SOLID ถูกนำไปใช้
☐ บทธรรมที่เหมาะสม (Appropriate Abstractions)
```

**📌 SOLID Principles อธิบายสั้นๆ:**

```
S - Single Responsibility (ความรับผิดชอบเดียว)
  ❌ Class User: บันทึก + ส่งอีเมล + แสดง (3 หน้าที่)
  ✅ Class User: เก็บข้อมูล เท่านั้น
     Class EmailService: ส่งอีเมล
     Class UserDisplay: แสดงผล

O - Open/Closed (เปิดขยาย, ปิดแก้ไข)
  ❌ ต้องแก้ไข old code เมื่อเพิ่มฟีเจอร์ใหม่
  ✅ สร้าง class/interface ใหม่ สืบทอด ไม่ต้องแก้ old code

L - Liskov Substitution (สามารถแทนกันได้)
  ❌ Penguin extends Bird, มี method fly() (penguin บินไม่ได้!)
  ✅ Bird extends Animal, Dog extends Animal แยกตามจริง

I - Interface Segregation (หลีกเลี่ยง interface ใหญ่)
  ❌ interface Worker { code(), test(), deploy() } - QA ต้อง implement code()
  ✅ interface Coder { code() }, interface Tester { test() }

D - Dependency Inversion (ไม่ dependency บน implementation)
  ❌ UserService dependency บน MySQLDatabase class
  ✅ UserService dependency บน Database interface
```

**การทดสอบ (Testing):**

```
☐ เขียนการทดสอบหน่วย (Unit Tests) (> 80% Coverage)
☐ การทดสอบมีความหมาย (ไม่ใช่แค่ Mock)
☐ กรณีขอบเขตได้รับการทดสอบ
☐ กรณีข้อผิดพลาดได้รับการทดสอบ
☐ ไม่มีโค้ดการทดสอบในการเผยแพร่ (Production)
```

**เอกสาร (Documentation):**

```
☐ โค้ดมีความเห็นที่ดี (อธิบาย WHY ไม่ใช่ WHAT)
☐ เมธอดสาธารณะมี Docstrings
☐ อัลกอริทึมที่ซับซ้อนอธิบายไว้
☐ การเปลี่ยนแปลง API ถูกบันทึก
☐ การกำหนดค่า (Configuration) อธิบายไว้
```

**ความปลอดภัย (Security):**

```
☐ ไม่มีช่องโหว่การฉีดเข้า SQL (SQL Injection)
☐ ไม่มีรหัสผ่าน/ความลับถูกเข้ารหัส (Hardcoded Secrets)
☐ ตรวจสอบการป้อนข้อมูล (Input Validation) เสร็จสิ้น
☐ ตรวจสอบการยืนยันตัวตน (Authentication)
☐ ตรวจสอบการให้สิทธิ์ (Authorization)
☐ ไม่มีข้อมูลที่ละเอียดอ่อนถูกบันทึก (Logged)
```

**อื่นๆ:**

```
☐ ไม่มีการเพิ่มการพึ่งพา (Dependencies) ที่ไม่จำเป็น
☐ ไม่มีการเปลี่ยนแปลงที่ทำให้ไม่สามารถใช้ (Breaking Changes)
☐ ประวัติ Git สะอาด
☐ ข้อความ Commit ชัดเจน
☐ คำอธิบาย PR ชัดเจน
```

#### 2.4 แนวปฏิบัติที่ดีของการตรวจสอบโค้ด

**สำหรับผู้ตรวจสอบ (Reviewers):**

```
1. ตรวจสอบอย่างรวดเร็ว (ภายใน 24 ชั่วโมง)
2. เป็นสร้างสรรค์และใจดี
   ✓ "พิจารณาปรับปรุงสิ่งนี้เป็นวิธีตัวช่วย"
   ✗ "โค้ดนี้แย่มาก"
3. มุ่งเน้นไปที่โค้ด ไม่ใช่บุคคล
   ✓ "ตรรกะนี้สับสน"
   ✗ "คุณไม่รู้วิธีการเขียนโค้ด"
4. ถามคำถาม อย่าเรียกร้อง
   ✓ "จะเกิดอะไรขึ้นหากผู้ใช้ส่ง null?"
   ✗ "คุณลืมตรวจสอบ null"
5. อนุมัติเมื่อพอใจ
6. แนะนำการปรับปรุง (ไม่บล็อก)
7. ติดตามปัญหาที่สำคัญ
```

**สำหรับผู้ส่ง (Reviewees):**

```
1. เก็บ PR ให้เล็ก (< 400 บรรทัด)
2. เขียนคำอธิบาย PR ที่ชัดเจน
3. ทำการเปลี่ยนแปลงครั้งเดียวต่อ PR
4. ตอบสนองต่อข้อเสนอแนะอย่างสร้างสรรค์
5. อัปเดต PR ตามความเห็น
6. ขอการตรวจสอบเมื่อพร้อม
7. ขอบคุณผู้ตรวจสอบ
```

---

### ส่วนที่ 3: ลำดับการทำงานของ Git (Git Workflows) & กลยุทธ์การสาขา (Branching Strategy)

#### 3.1 กลยุทธ์ Git Flow

![Git Flow](https://angsila.cs.buu.ac.th/~wittawas/682/88744065/gitflow.png)

## 📊 การอ่านรูป Git Flow

รูปแสดงลำดับการไหลของ commits ในสาขาต่างๆ:

```
🟢 Master (สีเขียว)     = สาขาการผลิต (Production)
🟣 Hotfix (สีม่วง)      = แก้ไขฉุกเฉิน
🟨 Release (สีเหลือง)   = เตรียมปล่อยสินค้า
🟠 Develop (สีส้ม)      = สาขาพัฒนาหลัก
🔵 Feature (สีน้ำเงิน)  = ฟีเจอร์ใหม่
```

---

## 🔄 ขั้นตอนการไหลตามรูป

### ขั้นตอนที่ 1: ฟีเจอร์พัฒนา (Feature Development)

```
🔵 Feature Branches (2 สาขา)
   ├─ commit → commit → commit (Feature 1)
   └─ commit → commit → commit → commit (Feature 2)
        ↓
🟠 Develop (รวมฟีเจอร์ทั้งหมด)
   ├─ commit → commit → commit → commit
```

**ความหมาย:**

- นักพัฒนา A สร้าง `feature/user-auth` → ทำงาน 3 commits
- นักพัฒนา B สร้าง `feature/payment` → ทำงาน 4 commits
- ทั้งสองสาขารวมเข้า `develop` (via Pull Request)
- **Develop รวม features ทั้งหมด** ✓

---

### ขั้นตอนที่ 2: Release Preparation (เตรียมปล่อยสินค้า)

```
🟠 Develop (เสร็จสปริ้นท์)
   │
   └─→ 🟨 Release Branch
       ├─ commit 1: Update version v0.2 → v1.0
       ├─ commit 2: Fix release bugs
       └─ commit 3: Update CHANGELOG
            ↓ (รวมลงคำส่ง)
       ├─→ 🟢 Master (Tag: v1.0) ✓ ปล่อยให้ผู้ใช้!
       │
       └─→ 🟠 Develop (Sync back) - ทีมรู้ v1.0 ออก
```

**ความหมาย:**

- เมื่อ Develop เสถียร → สร้าง `release/v1.0` branch
- ใน Release branch: **เฉพาะแก้บัง + version bump**
- **รวมเข้า Master** → Tag v1.0 → ปล่อยให้ผู้ใช้ 🎉
- **รวมกลับ Develop** → ทีมรู้ว่า v1.0 ออกมาแล้ว

**ตัวอย่างจากรูป:**

```
v0.1 → v0.2 → Release (Testing) → v1.0 (Deployed!)
                    ↑                    ↑
                Release branch      Master + Tag
```

---

### ขั้นตอนที่ 3: Hotfix (แก้ฉุกเฉิน)

```
🟢 Master (v1.0 ใช้งานจริง)
   │
   └─→ 🟣 Hotfix Branch
       ├─ commit 1: แก้ Security bug
       └─ commit 2: เพิ่ม Test
            ↓
       ├─→ 🟢 Master (Tag: v1.0.1) ✓ ปล่อยด่วน!
       │
       └─→ 🟠 Develop (Sync) - ทีมรู้และ update
```

**ความหมาย:**

- ผู้ใช้พบ bug สำคัญในเวอร์ชัน v1.0
- สร้าง `hotfix/security-patch` **จาก Master โดยตรง** (ไม่ใช่ Develop!)
- ทำการแก้ไข → Tag v1.0.1 → ปล่อยด่วนให้ผู้ใช้
- **รวมกลับ Develop** → ทีมรู้และเอา fix ไปด้วย

---

## 📌 ความสำคัญของแต่ละสาขา (ตามรูป)

### 🟢 Master Branch

```
Master:   v0.1 ──→ v0.2 ──────→ v1.0 ──→ (ต่อไป)
          ↑        ↑            ↑
          Tag      Tag          Tag

ความหมาย: Master = "เวอร์ชันที่ปล่อยให้ผู้ใช้"
         - เสถียร ✓
         - ตรวจสอบแล้ว ✓
         - ได้ Tag ✓
```

### 🟠 Develop Branch

```
Develop: Feature1 → Feature2 → (รวมฟีเจอร์) → Release → (Sync) → ต่อไป
         ↑          ↑           ↑              ↑         ↑
         ongoing   ongoing    เสร็จ          ตรวจสอบ  ทีมรู้

ความหมาย: Develop = "เวิร์คชอป" ของทีม
         - สะสม features
         - ยังไม่เสถียร (อาจ bug)
         - กำลังทดสอบ
```

### 🟨 Release Branch

```
Release Branch (3 commits):
  ├─ commit 1: Update version 0.2 → 1.0
  ├─ commit 2: Fix release bugs
  └─ commit 3: Update CHANGELOG
      ↓
  รวม → Master v1.0

ความหมาย: Release = "เตรียมปล่อย"
         - ทดสอบฟีเจอร์สุดท้าย
         - แก้บัง ไม่เพิ่มฟีเจอร์ใหม่
         - อัปเดต version & docs
```

### 🟣 Hotfix Branch

```
Hotfix Branch:
  ├─ commit 1: แก้ Security bug
  └─ commit 2: Test hotfix
      ↓
  รวม → Master v1.0.1 (ด่วน!)

ความหมาย: Hotfix = "เร่งด่วน"
         - มาจาก Master โดยตรง
         - แก้ไขเร็ว ด่วน
         - ปล่อยเร็ว
```

### 🔵 Feature Branches

```
Feature 1: commit → commit → commit ↘
                                    → รวม Develop
Feature 2: commit → commit → commit → commit ↗

ความหมาย: Feature = "ฟีเจอร์ใหม่"
         - แยกจาก Develop
         - นักพัฒนาคนละสาขา
         - ลบหลังรวมผล
```

---

## 🎯 ตัวอย่างเลขที่จากรูป

### Version Progress ตามรูป

```
Master timeline:
v0.1 ──(tag)──→ v0.2 ──(tag)──→ v1.0 ──(tag)──→ [ต่อไป]
 ↑              ↑               ↑
 Release 1      Release 2       Release 3
```

### Develop Timeline (ตามรูป)

```
Develop:
  ├─ Features ทำงาน (commits)
  ├─ Features ทำงาน (commits)
  ├─ Features สะสม
  ├─ Release branch ตัดออก
  ├─ Release ปล่อย v1.0
  ├─ Sync back from Master
  └─ ทีมเริ่มพัฒนา features ต่อเพื่อ v1.1
```

---

## 📊 ตารางเปรียบเทียบ (ตามรูป)

| ขั้นตอน | สาขา      | จำนวน Commits | เหตุการณ์            | ผลลัพธ์          |
| ------- | --------- | ------------- | -------------------- | ---------------- |
| **1**   | Feature 1 | 3             | นักพัฒนา A ทำงาน     | รอการรวม         |
| **2**   | Feature 2 | 4             | นักพัฒนา B ทำงาน     | รอการรวม         |
| **3**   | Develop   | +7            | รวม Feature 1+2      | เสร็จ features   |
| **4**   | Release   | 3             | ทดสอบ + version bump | ไปยัง Master     |
| **5**   | Master    | +1 (Tag)      | Tag v1.0             | ปล่อยให้ผู้ใช้ ✓ |
| **6**   | Hotfix    | 2             | แก้ security bug     | v1.0.1           |

---

## 🔀 สูตร Git Flow ตามรูป

```
┌─ Feature Branch 1 (3 commits)
│                  ↘
│                   → Develop (Feature 1+2+...)
│                  ↗
└─ Feature Branch 2 (4 commits)

Develop (เสถียร) → Release/v1.0 (3 commits)
                   ├─ → Master (Tag v1.0) ← ปล่อยให้ผู้ใช้
                   └─ → Develop (Sync)

Master (v1.0) → Hotfix/security (2 commits)
               ├─ → Master (Tag v1.0.1) ← ปล่อยด่วน
               └─ → Develop (Sync)
```

---

## ⏱️ ไทม์ไลน์ (Timeline) ตามรูป

```
Week 1-2 (Develop):
┌─ Feature 1: ──●──●──●
├─ Feature 2: ──●──●──●──●
└─ Develop:    ──●──●──●──●──●──●──●
                   ↑ Merged features

Week 3 (Release):
  Release: ──●──●──●
           ↓ (ทดสอบ)

Week 4 (Deploy):
  Master: ──●  (Tag v1.0)
          ↓
        ปล่อยให้ผู้ใช้! 🎉

Week 5 (User Reports Bug):
  Hotfix: ──●──●
          ↓ (ด่วน)
  Master: ──●  (Tag v1.0.1)
```

---

## ✅ ข้อดีของ Git Flow ตามรูป

```
✓ Master = Production ที่เสถียร
  - v0.1, v0.2, v1.0 ทั้งหมดเสถียร
  - ผู้ใช้ไว้วางใจได้

✓ Develop = แยกจาก Production
  - Features ทำงานแยกกัน
  - ไม่บ่ายกัน
  - รวมเมื่อเสร็จ

✓ Release = ขั้นตอนกลาง
  - ทดสอบก่อนปล่อย
  - แก้บัง ไม่แก้ไขใหญ่

✓ Hotfix = เร่งด่วนได้
  - แก้ bug ผลิตจริง ได้เร็ว
  - ไม่รอสปริ้นท์ถัดไป
```

---

## 📌 สรุป

**Git Flow ตามรูป:**

1. **Feature branches** ทำงาน (สีน้ำเงิน)
2. **รวม Develop** (สีส้ม)
3. **สร้าง Release** (สีเหลือง) → ทดสอบ
4. **ปล่อย Master** (สีเขียว) → v1.0 ✓
5. **แก้ Hotfix** (สีม่วง) → ด่วน v1.0.1
6. **Sync back Develop** → ทีมรู้

**ลำดับ:** Feature → Develop → Release → Master → (Hotfix) ✓

#### 3.2 การตั้งชื่อสาขา (Branch Naming Conventions)

```
สาขาฟีเจอร์:
feature/user-authentication
feature/shopping-cart
feature/payment-integration

สาขาแก้ไขข้อบกพร่อง:
bugfix/fix-login-validation
bugfix/cart-calculation-error

สาขาแก้ไขฉุกเฉิน (แก้ไขการผลิต):
hotfix/critical-security-patch
hotfix/crash-on-null-user

สาขาเผยแพร่:
release/v1.0.0
release/v1.1.0

รูปแบบ:
[type]/[description-in-lowercase-with-hyphens]

❌ ชื่อไม่ดี:
- feature-1, fix-1 (ไม่อธิบายถึง)
- Feature/Something (ตัวพิมพ์ไม่สอดคล้อง)
- feature/fix_stuff (ตัวคั่นผสมกัน)
```

#### 3.3 มาตรฐานข้อความ Commit (Commit Message Standards)

```
รูปแบบ:
<type>(<scope>): <subject>

<body>

<footer>

ตัวอย่าง:
feat(auth): เพิ่มการยืนยันตัวตน (Email Verification)

เพิ่มฟีเจอร์การยืนยันทางอีเมล เพื่อเสริมความปลอดภัยของบัญชี
ผู้ใช้ต้องยืนยันอีเมลภายใน 24 ชั่วโมงหลังจากสมัครสมาชิก

- สร้าง Token การยืนยัน
- ส่งอีเมลการยืนยัน
- ตรวจสอบ Token เมื่อยืนยัน
close #123

ประเภท (Types):
- feat: ฟีเจอร์ใหม่
- fix: แก้ไขข้อบกพร่อง
- docs: เอกสาร
- style: ลักษณะโค้ด (ไม่มีการเปลี่ยนแปลงหน้าที่)
- refactor: ปรับปรุงโค้ด
- perf: ปรับปรุงประสิทธิภาพ
- test: เพิ่ม/แก้ไขการทดสอบ
- chore: กระบวนการสร้าง, การพึ่งพา

ขอบเขต (Scope): ฟีเจอร์หรือส่วนประกอบที่ได้รับผลกระทบ

หัวเรื่อง (Subject):
- เขียนเหมือนกับการสั่ง "ให้ทำ...": เช่น "เพิ่มฟีเจอร์ login" ไม่ใช่ "เพิ่มฟีเจอร์ login แล้ว", "ให้เพิ่มฟีเจอร์ login"
- ตัวพิมพ์เล็กในภาษาอังกฤษ (ยกเว้นคำที่เหมาะสม)
- < 50 อักขระ

เนื้อความ (Body):
- เหตุใด ไม่ใช่อะไร
- อ้างอิงปัญหาที่เกี่ยวข้อง
- ขั้นบรรทัดใหม่ ที่ 72 ตัวอักษร (72 อักขระพอดีกับหน้าจอ terminal ส่วนใหญ่)

ส่วนท้าย (Footer):
- อ้างอิงปัญหา: Closes #123, Fixes #456
- การเปลี่ยนแปลงที่ทำให้ไม่สามารถใช้: BREAKING CHANGE: description
```

#### 3.4 แม่แบบคำขอการดึงข้อมูล (Pull Request Template)

```
## คำอธิบาย (Description)
คำอธิบายสั้นๆ ของการเปลี่ยนแปลง

## ประเภทของการเปลี่ยนแปลง (Type of Change)
- [ ] ฟีเจอร์ใหม่
- [ ] แก้ไขข้อบกพร่อง
- [ ] ปรับปรุงโค้ด
- [ ] เอกสาร

## ปัญหาที่เกี่ยวข้อง (Related Issues)
close #123

## การทดสอบที่ทำ (Testing Done)
- [ ] เขียนการทดสอบหน่วย
- [ ] ทดสอบด้วยตนเอง (Manual Testing)
- [ ] ตรวจสอบกรณีขอบเขต

## รายการตรวจสอบ (Checklist)
- [ ] โค้ดเป็นไปตามแนวทางสไตล์
- [ ] เพิ่มความเห็น (โดยเฉพาะ WHY)
- [ ] การทดสอบครอบคลุมการเปลี่ยนแปลง
- [ ] เอกสารอัปเดต
- [ ] ไม่มีการเปลี่ยนแปลงที่ทำให้ไม่สามารถใช้
- [ ] ไม่มีค่าคงที่ที่เข้ารหัส
```

---

### ส่วนที่ 4: วางแผนสปริ้นท์เชิงลึก (Sprint Planning Deep Dive)

#### 4.1 สปริ้นท์ (Sprint) คืออะไร?

**วางแผนสปริ้นท์ (Sprint Planning) = ทีมตกลงวัตถุประสงค์ที่จะบรรลุในสปริ้นท์ 2 สัปดาห์**

**วัตถุประสงค์:** สร้างรายการงาน (Backlog) ของสปริ้นท์ที่ทีมสามารถทำได้อย่างสมจริง

**ระยะเวลา:** 2 ชั่วโมงสำหรับสปริ้นท์ 2 สัปดาห์ (กฎ 1 ชั่วโมง: 1 ชั่วโมงต่อ 1 สัปดาห์)

#### 4.2 กระบวนการวางแผนสปริ้นท์

ขั้นตอนที่ 1: ทบทวนรายการต้องทำ (Product Backlog) (30 นาที)

- เจ้าของผลิตภัณฑ์ (PO) นำเสนอรายการลำดับความสำคัญสูง
- ชี้แจงข้อกำหนด (Requirements)
- ตอบคำถาม

ขั้นตอนที่ 2: พูดถึงความสามารถ (Capacity) (15 นาที)

- คำนวณชั่วโมงที่มี
  = (สมาชิกทีม × ชั่วโมงทำงาน/สัปดาห์ × 2 สัปดาห์)
  - วันลา, สอบ, ประชุม
    = ความสามารถการทำงานจริง
- ประมาณความเร็ว (Velocity) (ตามข้อมูลจากสปริ้นท์ที่ผ่านมา)

ตัวอย่าง:

- 4 สมาชิกทีม
- 8 ชั่วโมง/วัน, 5 วัน/สัปดาห์
- 2 สัปดาห์ × 80 ชั่วโมง = 160 ชั่วโมงที่มี
- ลบการประชุม (20 ชั่วโมง), วันลา (8 ชั่วโมง)
- ที่มี: ~130 ชั่วโมง
- ที่ 60-70% ผลผลิต: ~85-90 ชั่วโมงจริง

ขั้นตอนที่ 3: เลือกเรื่องราว (User Stories) (60 นาที)

- ทีมอภิปรายและประมาณความพยายาม (Effort)
- เลือกเรื่องราวที่ตรงกับความสามารถ
- รวมจุด (Story Points) ≤ ความเร็วที่ทีมสามารถทำได้ในสปริ้นท์หนึ่ง

ขั้นตอนที่ 4: สร้างงาน (Tasks) (45 นาที)

- แบ่งเรื่องราวเป็นงาน (4-8 ชั่วโมงต่อหน่วย)
- มอบหมายให้สมาชิกทีม
- ระบุงานที่ต้องทำเสร็จ ก่อนที่งานนี้จะเริ่มได้ (Dependencies)

ขั้นตอนที่ 5: ยืนยันวัตถุประสงค์สปริ้นท์ (5 นาที)

- จะบรรลุอะไร?
- เกณฑ์ความสำเร็จ?

#### 4.3 แม่แบบวางแผนสปริ้นท์ (Sprint Planning Template)

สปริ้นท์: สปริ้นท์ 1 (สัปดาห์ 1-2, date1 - date2)
วัตถุประสงค์สปริ้นท์: "ให้สำเร็จการตั้งค่าโครงการและนำไปใช้การรับรองความถูกต้องหลัก"

รายการงานสปริ้นท์:

```
เรื่องราวผู้ใช้ที่ 1: การลงทะเบียนผู้ใช้ (8 จุด)
├── งาน 1.1: สร้างแบบจำลอง (Model) ผู้ใช้ (นักพัฒนา A, 4 ชั่วโมง) - วิกฤต
├── งาน 1.2: สร้าง API การลงทะเบียน (นักพัฒนา B, 6 ชั่วโมง) - บล็อก
├── งาน 1.3: เพิ่มการตรวจสอบอีเมล (นักพัฒนา C, 4 ชั่วโมง)
└── งาน 1.4: เขียน unit test (QA, 4 ชั่วโมง)

เรื่องราวผู้ใช้ที่ 2: เข้าสู่ระบบผู้ใช้ (13 จุด)
├── งาน 2.1: นำไปใช้การเข้ารหัส (Hashing) รหัสผ่าน (นักพัฒนา A, 6 ชั่วโมง)
├── งาน 2.2: สร้าง API เข้าสู่ระบบ (นักพัฒนา B, 6 ชั่วโมง)
├── งาน 2.3: สร้าง JWT Token (นักพัฒนา C, 6 ชั่วโมง)
└── งาน 2.4: ทำ Integration Test (QA, 8 ชั่วโมง)

เรื่องราวผู้ใช้ที่ 3: ตั้งรหัสผ่านใหม่ (5 จุด)
├── งาน 3.1: แม่แบบอีเมล (นักพัฒนา A, 4 ชั่วโมง)
├── งาน 3.2: API ตั้งรหัสผ่านใหม่ (นักพัฒนา B, 4 ชั่วโมง)
└── งาน 3.3: การทดสอบ (QA, 4 ชั่วโมง)

เรื่องราวผู้ใช้ที่ 4: ตั้งส่ง CI/CD (8 จุด) [DevOps]
├── งาน 4.1: การกำหนดค่า GitHub Actions (QA, 4 ชั่วโมง)
├── งาน 4.2: ทดสอบ Automate Test (QA, 4 ชั่วโมง)
├── งาน 4.3: การตั้งค่า Linter (QA, 2 ชั่วโมง)
└── งาน 4.4: การปรับใช้ (Deploy) ไปยังสภาพแวดล้อมสำหรับทดสอบก่อนปล่อยจริง (QA, 2 ชั่วโมง)

ความสามารถสปริ้นท์:

- รวมจุด: 34 จุด
- ความเร็วประมาณ: 32-40 จุด
- สถานะ: ✓ สมจริง

การจัดสรรทีม:
- นักพัฒนา A (80 ชั่วโมง): งาน 1.1, 2.1, 3.1 (ลำดับความสำคัญ: การรับรองความถูกต้อง)
- นักพัฒนา B (80 ชั่วโมง): งาน 1.2, 2.2, 3.2 (ลำดับความสำคัญ: การรับรองความถูกต้อง)
- นักพัฒนา C (60 ชั่วโมง): งาน 1.3, 2.3 (ลำดับความสำคัญ: การรับรองความถูกต้อง)
- QA (60 ชั่วโมง): งาน 1.4, 2.4, 4.1-4.4 (ลำดับความสำคัญ: การทดสอบ)

พิธีสปริ้นท์:

- การอัพเดต (Daily Standup): 09:00 ทุกวัน (15 นาที)
- การนำเสนอผลสปริ้นท์ (Sprint Review): วันศุกร์ 14:00 (1 ชั่วโมง)
- การทบทวน (Retrospective): วันศุกร์ 15:00 (1 ชั่วโมง)

คำจำกัดความของการทำเสร็จ (Definition of Done):

- [ ] เขียนโค้ด & ผ่าน Linter
- [ ] การทดสอบหน่วย (>80% Coverage)
- [ ] การทดสอบการรวมเข้าด้วยกันผ่าน
- [ ] Pull Request ต้องได้รับการอนุมัติจากผู้ตรวจสอบ
  อย่างน้อย 2 คนก่อนที่จะสามารถรวมเข้า (Merge)
- [ ] เอกสารอัปเดต
- [ ] CI/CD Pipeline ผ่านการทดสอบทั้งหมด
- [ ] ปรับใช้ (Deploy) ไปยังเซิร์ฟเวอร์ทดสอบ
- [ ] การทดสอบยอมรับของเจ้าของผลิตภัณฑ์ผ่านแล้ว

```

#### 4.4 ความเร็วและแผนภูมิ (Velocity & Burndown Chart)

**📌 Velocity (ความเร็ว)**

```
Velocity = จุด (Story Points) ที่ทีมสำเร็จต่อสปริ้นท์

ตัวอย่าง:
Sprint 1: สำเร็จ 28 points (ประมาณ 30)
Sprint 2: สำเร็จ 32 points (ประมาณ 30)
Sprint 3: สำเร็จ 30 points (ประมาณ 30)
Sprint 4: สำเร็จ 35 points (ประมาณ 30)

Average Velocity = (28 + 32 + 30 + 35) / 4 = 31 points/sprint

ใช้ Velocity สำหรับ:

1️⃣ วางแผนสปริ้นท์ถัดไป
   - Sprint 5: เลือก 30-31 points (ตามความเร็วเฉลี่ย)
   - ไม่เลือก 50 points (unrealistic)

2️⃣ พยากรณ์เสร็จเมื่อไหร่
   - Backlog: 150 points
   - Velocity: 31 points/sprint
   - เสร็จภายใน: 150 ÷ 31 = ~5 sprints
   - ประมาณ: 10 สัปดาห์

3️⃣ ตรวจจับปัญหา
   - Velocity ลด Sprint 1→2 (28→32 ✓ increase, ดี)
   - Velocity ลด Sprint 4→5 (35→15 ❌ drop, ปัญหา!)
   - เหตุ: ใครลาป่วย? requirement เปลี่ยน? มี bug?
```

**📌 Burndown Chart**

![burndown-good](https://4squareviews.com/wp-content/uploads/2016/02/burn-down-chart.png)

```
Burndown = กราฟแสดง "ทีมทำความสำเร็จไปแล้วเท่าไหร่?"

- X-axis: วัน (Day 1, 2, 3, ... 10)
- Y-axis: points ที่เหลือ (35, 30, 25, ... 0)
- อุดมคติ: ลดลงเป็นเส้นตรง (0 points ช่วง 10 วัน)
- จริง: วิมาน (บันไดขึ้นลง)

✅ Burndown ที่ดี (ตามแผน):

วันที่ 1: เหลือ 35 points (เริ่ม)
วันที่ 2: เหลือ 28 points (ลด 7) ✓
วันที่ 3: เหลือ 21 points (ลด 7) ✓
วันที่ 4: เหลือ 14 points (ลด 7) ✓
วันที่ 5: เหลือ  7 points (ลด 7) ✓
วันที่ 10: เหลือ 0 points (เสร็จ!) ✓

ความหมาย: ทีมทำงานอย่างสม่ำเสมอทุกวัน = จะเสร็จเวลา!
```

❌ Burndown ที่ไม่ดี (ล่าช้า):

![burndown-bad](https://us.v-cdn.net/6031209/uploads/ZZHBB9IWEBJH/image.png)

```
วันที่ 1-3: เหลือ 35 points (ไม่ลด!) ❌
วันที่ 4-5: เหลือ 35 points (ยังไม่ลด!) ❌
วันที่ 6-10: เหลือ 35→28→21→14→7→0 (ลดอย่างรวดเร็ว)

⚠️ ปัญหา: ทีมไม่ทำงานตั้งแต่เริ่มสปริ้นท์!
→ คิดว่าจะเสร็จเวลาไหม? ไม่!

🔧 สาเหตุที่เป็นไปได้:
1. ติดขัด (Blocking) - รอ API จากทีมอื่น
2. Requirement ไม่ชัดเจน - เสียเวลาคิด
3. Scope Creep - requirement เพิ่มขึ้น
4. ประมาณผิด - นึกว่า 5 hours จริง 15 hours

🔧 วิธีแก้ (ต้องทำ ณ วันที่ 5):
- หากเบื้องหลัง: ลด scope (ของบางรายการไม่เสร็จ)
- ขอความช่วยเหลือจากทีมอื่น
- ชี้แจง requirement ใหม่
- Velocity อาจต้องปรับลง (ทีมช้าจริง ๆ)
```

**📌 Burndown จริง ๆ อาจจะ ...**

```
Day 1-2: ค้นพบสิ่งใหม่ (points เพิ่ม) ⬆️
Day 3-4: โค้ด (points ลด) ⬇️
Day 5: bug (points เพิ่มเล็กน้อย) ⬆️
Day 6-7: ซ่อม bug (points ลด) ⬇️
Day 8-10: testing (points ลด) ⬇️

ความหมาย:
- ⬆️ หมายถึง: เพิ่มงาน (bug, change request)
- ⬇️ หมายถึง: ทำเสร็จ (completed work)
- กราฟควรลดลงโดยรวม (ถึงวันสุดท้าย)

📈 Burndown ช่วยตรวจจับ:
- Day 5 ยังเหลือ 20 points (เสร็จได้ไหม?)
- ถ้าไม่แก้ปัญหา = จะไม่เสร็จวันที่ 10
- ต้องเปลี่ยนแผนตอนนี้ (ไม่ใช่วันที่ 10)
```

```
- อุดมคติ: ลดลงเป็นเส้นตรง
- ความเป็นจริง: บันได (การทำงานให้เสร็จจริง)
- ต่ำกว่าอุดมคติ: ไปตามแผน ✓
- สูงกว่าอุดมคติ: เบื้องหลังตารางเวลา ❌

การดำเนินการ:

1. ระบุปัญหาการสกัดกั้น (ถามในการอัพเดต)
2. ลดขอบเขต (Scope)
3. ขอความช่วยเหลือจากสมาชิกทีมอื่น
4. ย้ายเรื่องราวที่ไม่สำเร็จไปยังสปริ้นท์ถัดไป
```

---

### ส่วนที่ 5: การเตรียมทีมให้สำเร็จ (Setting Team Up for Success)

#### 5.1 การตั้งค่าสภาพแวดล้อมการพัฒนา (Development Environment Setup)

```
สมาชิกของนักพัฒนาแต่ละคนควรมี:

1. การควบคุมเวอร์ชัน (Version Control)
   - Git ติดตั้งในเครื่อง
   - เข้าถึง GitHub/GitLab
   - SSH key ตั้งค่า

2. ชุดการพัฒนา (Development Stack)
   - เวอร์ชันภาษาที่ถูกต้อง (Java, Python 3.9, Node 16, ฯลฯ)
   - โปรแกรมที่ช่วยอัตโนมัติ (Build Tools) (Maven, Gradle, pip, npm, ฯลฯ)
      - ดาวน์โหลดไลบรารี่ (Libraries/Dependencies)
      - รวมโค้ด (Compile)
      - ทดสอบ (Test)
      - สร้างไฟล์ปล่อยสินค้า (Build packages)
      - ปรับใช้ (Deploy)
  - IDE/ตัวแก้ไขตั้งค่า

3. ฐานข้อมูล (Database)
   - ฐานข้อมูล (local MySQL, PostgreSQL, MongoDB)
   - ฐานข้อมูลการทดสอบตั้งค่า
   - ข้อมูลตัวอย่าง

4. การพึ่งพา (Dependencies)
   - ติดตั้งไลบรารี่ที่จำเป็นทั้งหมด ที่โปรเจกต์ของเราต้องการเพื่อทำงาน
   ตัวอย่าง:
    - Spring Framework (สำหรับ Java)
    - Express (สำหรับ Node.js)
    - NumPy (สำหรับ Python)
    - JUnit (สำหรับการทดสอบ)
   - เวอร์ชันที่ถูกต้อง (ตรวจสอบ pom.xml, requirements.txt)

5. การกำหนดค่า (Configuration)
   - ไฟล์ .env ตั้งค่า
   - คุณสมบัติแอปพลิเคชันตั้ง
   - Endpoint API ที่กำหนด

รายการตรวจสอบ:
$ git clone <repo>
$ cd project
$ ./setup.sh (หรือการตั้งค่าด้วยตนเอง)
$ npm install (pip install หรือ mvn clean install ฯลฯ)
$ ./run.sh (หรือเริ่มแอป)
✓ แอปควรทำงานที่ http://localhost:8080

```

#### 5.2 การสื่อสารและการเพิ่มระดับ (Communication & Escalation)

```
การสื่อสารในแต่ละวัน:

- 09:00 การอัพเดต (15 นาที)
- คำถามในช่องทาง Slack หรือเครื่องมือสื่อสารอื่น เพื่อถามคำถามเกี่ยวกับการพัฒนา งาน ปัญหา ฯลฯ ในระหว่างวันทำงาน
- คำขอตรวจสอบโค้ดใน PR

การสื่อสารรายสัปดาห์:

- บทวิจารณ์สปริ้นท์วันศุกร์ (1 ชั่วโมง)
- การทบทวนการทำงานวันศุกร์ (1 ชั่วโมง)
- การอัปเดตสถานะให้ผู้สอน

เส้นทางการเพิ่มระดับ:
ปัญหา → การดำเนินการทันที → หากไม่ได้รับการแก้ไขใน 1 วัน → เพิ่มระดับ

ตัวอย่าง:

- ปัญหาการสกัดกั้น API → ถามในการอัพเดต
- ต้องการชี้แจงเกี่ยวกับข้อมูลจำเพาะ API → ติดต่อเจ้าของผลิตภัณฑ์
- สภาพแวดล้อมการทดสอบหยุดทำงาน → บอก QA
- ไม่สามารถแก้ไข → บอกผู้จัดการสปริ้นท์ (SM) → บอกผู้สอน

สัญญา SLA การตอบสนอง:

- ฉุกเฉิน: 1-2 ชั่วโมง
  ├─ Production ล่ม (Down)
  ├─ Critical security bug
  ├─ Data loss risk
  ├─ Payment system ไม่ทำงาน
  ├─ API endpoint 500 error
  └─ Database ล่ม
- สำคัญ: 24 ชั่วโมง
  ├─ Feature ใหญ่ไม่ทำงาน → ผลกระทบมาก
  ├─ Performance issue → ช้า แต่ยังใช้ได้
  ├─ UI bug ที่เห็นบ่อย → ผู้ใช้เคล้ไม่ใจ
  ├─ Integration test ล้มเหลว → Deployment ติด
  ├─ ตารางเวลา feature อยู่เสี่ยง → Risk สูง
  └─ Backend API validation ผิด → Business logic error
- Low Priority: 2-3 วัน
  ├─ UI typo → "Sumbit" instead of "Submit"
  ├─ Button color ไม่สวย → Aesthetic
  ├─ Documentation ล้าสมัย → Nice to have
  ├─ Code refactoring suggestion → ปรับปรุง
  ├─ Performance optimization → ไม่ urgent
  ├─ Feature request ใหม่ → "Nice to have"
  └─ Error message unclear → Usability improvement

```

#### 5.3 ข้อผิดพลาดทั่วไปในสปริ้นท์แรก (Common Mistakes in First Sprint)

**🚫 ข้อผิดพลาดที่ 1: การยอมรับเกินกำลัง (Over-committing)**

```
ตัวอย่าง:

- ความเร็วของทีมที่ไม่จริง (สปริ้นท์แรก)
- ผู้จัดการคาดหวัง 50 จุด
- ทีมเลือก 50 จุดเพื่อให้ "ดูเก่ง"

ผลลัพธ์:
✗ สปริ้นท์ล้มเหลว
✗ ทีมขาดแรงจูงใจ
✗ สูญเสียความไว้วางใจ

วิธีแก้ไข:
✓ ประมาณการอย่างปลอดภัยสำหรับสปริ้นท์ 1
✓ เกินกว่าไม่ถึงค่อนข้างดี
✓ สร้างโมเมนตัมจากความสำเร็จ
✓ เพิ่มความเร็วอย่างค่อยเป็นค่อยไป

```

**🚫 ข้อผิดพลาดที่ 2: ไม่ระบุการพึ่งพา (Not Identifying Dependencies)**

```
ตัวอย่าง:

- นักพัฒนา A รอ API ของนักพัฒนา B (การพึ่งพางาน)
- นักพัฒนา B ยังไม่เริ่มต้น
- นักพัฒนา A ถูกบล็อก ไม่สามารถทำงาน

ผลลัพธ์:
✗ นักพัฒนาว่างงาน
✗ เวลาเสีย
✗ ตารางเวลาล้มเหลว

วิธีแก้ไข:
✓ สร้างแผนที่การพึ่งพาในการวางแผนสปริ้นท์
✓ เรียงลำดับงานตามการพึ่งพา
✓ เริ่มเส้นทางวิกฤตก่อน
✓ มีงานสำรองเมื่อถูกบล็อก

```

**🚫 ข้อผิดพลาดที่ 3: ข้ามการทดสอบเพื่อ "ประหยัดเวลา"**

```
ตัวอย่าง:

- นักพัฒนา: "ไม่มีเวลาสำหรับการทดสอบหน่วย"
- รวมโค้ดที่ยังไม่ทดสอบ
- ข้อบกพร่องพบในการรวมเข้าด้วยกัน → แก้ไข ต้อง 2 วัน

ผลลัพธ์:
✗ หนี้เทคนิค (Technical Debt)
✗ ข้อบกพร่องมากขึ้นในภายหลัง
✗ ช้าลงในภาพรวม

วิธีแก้ไข:
✓ การทดสอบ = ส่วนหนึ่งของการประมาณงาน
✓ คำจำกัดความของการทำเสร็จ = รวมการทดสอบ
✓ ไม่มีการรวมเข้าด้วยกันโดยไม่มีการทดสอบ
✓ คุณภาพก่อน ความเร็วที่สอง

```

**🚫 ข้อผิดพลาดที่ 4: เวลาตรวจสอบโค้ดไม่เพียงพอ**

```
ตัวอย่าง:

- วันสุดท้ายของสปริ้นท์: 20 PR รอการตรวจสอบ
- ผู้ตรวจสอบ: "ตรวจสอบอย่างรวดเร็ว ต้องรวมเข้า"
- ข้อบกพร่องผ่านไป

ผลลัพธ์:
✗ คุณภาพโค้ดต่ำ
✗ ปัญหาด้านความปลอดภัย
✗ การเผยแพร่มีข้อบกพร่อง

วิธีแก้ไข:
✓ การตรวจสอบโค้ด = งานประจำวัน (ไม่ใช่สิ้นสปริ้นท์)
✓ เก็บคิวของ PR ให้เล็ก
✓ ขีดจำกัดการตรวจสอบ: 2-3 PR ต่อคนต่อวัน
✓ เวลาทุ่มเทสำหรับการตรวจสอบในแต่ละเช้า

```

**🚫 ข้อผิดพลาดที่ 5: ไม่สื่อสารกับทีม (Not Talking to Team)**

```
ตัวอย่าง:

- นักพัฒนาติดขัด แต่ไม่ถาม
- รอ 2 วันหวังว่าจะแก้ไขได้เอง
- ถามในที่สุด → ใช้เวลา 30 นาทีกับความช่วยเหลือ

ผลลัพธ์:
✗ เวลาเสีย
✗ พลาดวัตถุประสงค์สปริ้นท์
✗ ความหงุดหงิด

วิธีแก้ไข:
✓ การอัพเดตประจำวัน = ห้ามลดลง
✓ "ติดขัด > 1 ชั่วโมง? ขอความช่วยเหลือ"
✓ การเขียนโค้ดคู่ (Pair Programming) หากจำเป็น
✓ เพิ่มระดับปัญหาการสกัดกั้นทันที

```

**🚫 ข้อผิดพลาดที่ 6: การเปลี่ยนแปลงสคีมาฐานข้อมูลตรงกลางสปริ้นท์**

```
ตัวอย่าง:

- สปริ้นท์เริ่มต้นด้วยสคีมา V1
- ตรงกลางสปริ้นท์: "เราต้องเพิ่มฟิลด์ X"
- นักพัฒนา A ต้องเปลี่ยนโค้ด, นักพัฒนา B ด้วย
- ความขัดแย้งการรวมเข้า & ปรับปรุงซ้ำ

ผลลัพธ์:
✗ ปรับปรุงซ้ำ & ล่าช้า
✗ การโยกย้ายฐานข้อมูล (Migrations) ขาด
✗ ความเสี่ยงการสูญเสียข้อมูล

วิธีแก้ไข:
✓ ยุติสคีมา ก่อนเริ่มสปริ้นท์
✓ หากต้องการการเปลี่ยนแปลง → ลดขอบเขต
✓ ทดสอบการโยกย้าย ก่อนรวมเข้า
✓ การเปลี่ยนแปลงสคีมา = การตรวจสอบความเสี่ยงสูง

```

**🚫 ข้อผิดพลาดที่ 7: การเพิกเฉยต่อประสิทธิภาพ "สำหรับตอนนี้"**

```

ตัวอย่าง:

- นักพัฒนา: "ทำงานได้ดีในเครื่อง ปล่อยได้"
- คิวรี N+1 ฟิลด์ที่ไม่มีดัชนี
- การผลิต: คิวรีช้า ทำให้เซิร์ฟเวอร์ล้มเหลว

ผลลัพธ์:
✗ การหยุดทำงาน (Outage)
✗ การโทษ
✗ การแก้ไขฉุกเฉิน (มีค่ามากขึ้น)

วิธีแก้ไข:
✓ การตรวจสอบประสิทธิภาพในการตรวจสอบโค้ด
✓ ทดสอบการโหลดก่อนปรับใช้
✓ คิวรี DB = ส่วนหนึ่งของคำจำกัดความของการทำเสร็จ
✓ ฟิลด์ดัชนีที่สำคัญตั้งแต่วันแรก

```

**🚫 ข้อผิดพลาดที่ 8: การกำหนดค่าไม่ถูกบันทึก (Configuration Not Documented)**

```
ตัวอย่าง:

- นักพัฒนา A: "แค่ตั้ง API_KEY ใน .env"
- นักพัฒนา B: "ไฟล์ .env ไหน? ค่าไหน?"
- นักพัฒนา B เสียเวลา 1 ชั่วโมงคิดออก

ผลลัพธ์:
✗ ปรับตัวช้า
✗ ข้อผิดพลาดการตั้งค่า
✗ เวลาเสีย

วิธีแก้ไข:
✓ .env.example ที่มีคีย์ทั้งหมด
✓ สคริปต์การตั้งค่า: ./setup.sh ตั้งค่าอัตโนมัติ
✓ README: คำแนะนำการตั้งค่าชัดเจน
✓ ทดสอบ: "นักพัฒนาใหม่ทำงานได้ใน 15 นาทีหรือไม่?"

```

**รายการตรวจสอบการบรรเทา (Mitigation Checklist):**

1. **Conservative Capacity** → 30-40% buffer ไม่สมหวัง
2. **Dependencies Mapped** → รู้ลำดับงาน, หลีกเลี่ยง blocking
3. **Definition of Done** → Test + Docs + Review ยาก
4. **Daily Code Review** → ไม่ใช่วันสุดท้าย
5. **Daily Standup** → 09:00 บังคับ, ติดขัด detected เร็ว
6. **Schema Finalized** → Frozen ก่อน Sprint 1 เริ่ม
7. **Performance Reviewed** → ตรวจสอบทุก code review
8. **Setup Tested** → ด้วยคนใหม่, < 15 นาที
9. **Escalation Clear** → ติดขัด > 1 ชั่วโมง → บอก
10. **Risk Register** → 5 ความเสี่ยงสูง + mitigation

**ผลลัพธ์:**

- Sprint 1 success rate สูง
- ทีมพร้อมและมั่นใจ
- ลดปัญหาและ blocking
- Quality ดี
- ผู้ใช้พอใจ

---

# 🎯 กิจกรรม (Activities)

### 🕐 Activity 1: Code Review Workshop (40 นาที)

**วัตถุประสงค์:** ทำการตรวจสอบโค้ดโดยเพื่อนเพื่อเรียนรู้แนวปฏิบัติที่ดี

**ลำดับการทำ:**

**ส่วนที่ 1: วิเคราะห์โค้ดตัวอย่าง (15 นาที)**

โค้ดตัวอย่าง (มีปัญหา):

```javascript
// ❌ โค้ดที่มีปัญหา:
class UserService {
  saveUser(u) {
    try {
      const query =
        "INSERT INTO users VALUES ('" + u.name + "', '" + u.email + "')";
      db.execute(query);
    } catch (e) {
      // เพิกเฉย - ไม่ขึ้น error!
    }
  }

  getUser(i) {
    const s = "SELECT * FROM users WHERE id = " + i;
    const l = db.query(s);
    if (l.length > 0) return l[0];
    return null;
  }
}
```

**ปัญหาที่ต้องหา:**

```
☐ ช่องโหว่การฉีดเข้า SQL (การต่อสตริง - ใช้ Parameterized Query!)
☐ การจับ exception แล้วไม่ทำอะไรเลย
☐ การตั้งชื่อแย่มาก (u, i, s, l - ไม่ชัดเจน)
☐ ไม่มีการบันทึก (Logging)
☐ ไม่มีการตรวจสอบข้อมูลป้อนเข้า (Input Validation)
☐ ลอจิก null checking ที่ไม่ชัดเจน
☐ ไม่มี Async/Await
☐ ไม่มีเอกสาร JSDoc
```

**✅ โค้ดที่ปรับปรุง:**

```javascript
class UserService {
  constructor(database, logger) {
    this.database = database;
    this.logger = logger;
  }

  /**
   * บันทึกผู้ใช้ใหม่ลงในฐานข้อมูล
   * @param {Object} user - ข้อมูลผู้ใช้
   * @param {string} user.name - ชื่อผู้ใช้
   * @param {string} user.email - อีเมลผู้ใช้
   * @throws {Error} หาก validation ล้มเหลว
   */
  async saveUser(user) {
    // 1. ตรวจสอบข้อมูลป้อนเข้า
    if (!user || !user.name || !user.email) {
      throw new Error("ชื่อและอีเมลเป็นข้อมูลที่จำเป็น");
    }

    try {
      // 2. ใช้ Parameterized Query เพื่อป้องกัน SQL Injection
      const query = "INSERT INTO users (name, email) VALUES (?, ?)";
      await this.database.execute(query, [user.name, user.email]);

      this.logger.info(`บันทึกผู้ใช้เสร็จสิ้น: ${user.email}`);
    } catch (error) {
      this.logger.error("เกิดข้อผิดพลาดในการบันทึกผู้ใช้", error);
      throw new Error("ไม่สามารถบันทึกผู้ใช้ได้");
    }
  }

  /**
   * ค้นหาผู้ใช้ด้วย ID
   * @param {number} userId - ID ผู้ใช้
   * @returns {Promise<Object|null>} ผู้ใช้หรือ null
   */
  async getUserById(userId) {
    if (!Number.isInteger(userId) || userId <= 0) {
      throw new Error("ID ต้องเป็นจำนวนเต็มบวก");
    }

    try {
      // ใช้ Parameterized Query
      const query = "SELECT * FROM users WHERE id = ?";
      const results = await this.database.query(query, [userId]);

      return results.length > 0 ? results[0] : null;
    } catch (error) {
      this.logger.error(`เกิดข้อผิดพลาดในการค้นหาผู้ใช้: ${userId}`, error);
      throw new Error("ไม่สามารถค้นหาผู้ใช้ได้");
    }
  }
}

module.exports = UserService;
```

**ส่วนที่ 2: การอภิปรายทีม (15 นาที)**

- ระบุปัญหา 5-10 ข้อ
- แนะนำการปรับปรุง
- อภิปรายการ Trade-offs

**ส่วนที่ 3: นำเสนอการตรวจสอบ (10 นาที)**

ทีมหนึ่งนำเสนอการค้นพบและโค้ดที่ปรับปรุง

**ผลิตภัณฑ์ที่ส่งมอบ:**

- ✅ เอกสารข้อเสนอแนะการตรวจสอบโค้ด
- ✅ ตัวอย่างโค้ดที่ปรับปรุง
- ✅ บทเรียนที่เรียนรู้

**การให้คะแนน:**

- การระบุปัญหา: 1 จุด
- คุณภาพข้อเสนอแนะ: 1 จุด
- โค้ดที่ปรับปรุง: 0.5 จุด

---

### 🕐 Activity 2: สัมมนาการวางแผนสปริ้นท์ (Sprint Planning Workshop) (20 นาที)

**วัตถุประสงค์:** ทีมทำการวางแผนสปริ้นท์สำหรับสปริ้นท์แรก

**ลำดับการทำ:**

**ส่วนที่ 1: ประมาณเรื่องราวผู้ใช้ (8 นาที)**

```
ทีมตรวจสอบเรื่องราวผู้ใช้จากสัปดาห์ที่ 4-5:

เรื่องราว 1: เข้าสู่ระบบผู้ใช้ (ประมาณจุด)
- ความซับซ้อน? ปานกลาง
- ความพยายาม? 5-8 ชั่วโมง
- จุด? 5 (หรือ 8)

ทำซ้ำสำหรับเรื่องราว 8-10 หลัก

ใช้โป๊กเกอร์การวางแผน (Planning Poker):
- ทั้งหมดประมาณพร้อมกัน
- ถ้าต่างกัน: อภิปรายและประมาณใหม่
- เป้าหมายคือความเห็นพ้องต้องกัน
```

**ส่วนที่ 2: เลือกเรื่องราวสปริ้นท์ 1 (7 นาที)**

```
ความสามารถที่มีทั้งหมด: ~30-35 จุด

เลือกเรื่องราว:
✓ การลงทะเบียนผู้ใช้: 8 จุด
✓ เข้าสู่ระบบผู้ใช้: 8 จุด
✓ การแสดงรายการผลิตภัณฑ์: 5 จุด
✓ รถเข็นช้อปปิ้ง: 8 จุด
= 29 จุด (ต่ำกว่าความสามารถ, บัฟเฟอร์ดี)

เรื่องราวที่เหลือไปยังรายการต้องทำของสปริ้นท์ 2
```

**ส่วนที่ 3: สร้างงาน (5 นาที)**

```
สำหรับเรื่องราวเข้าสู่ระบบ (8 จุด):
- สร้างจุดสิ้นสุด API เข้าสู่ระบบ (4 ชั่วโมง) - นักพัฒนา A
- ตรรกะการตรวจสอบรหัสผ่าน (3 ชั่วโมง) - นักพัฒนา B
- การทดสอบหน่วย (2 ชั่วโมง) - QA
- การทดสอบการรวมเข้าด้วยกัน (3 ชั่วโมง) - QA
= รวม 12 ชั่วโมง (ตรงกับการประมาณจุด)
```

**ผลิตภัณฑ์ที่ส่งมอบ:**

- ✅ รายการงานสปริ้นท์ 1 (เรื่องราว + งาน)
- ✅ คำสั่งวัตถุประสงค์สปริ้นท์
- ✅ การคำนวณความสามารถ

**การให้คะแนน:**

- การให้เหตุผลในการเลือกเรื่องราว: 1 จุด
- การแบ่งงาน: 0.5 จุด
- ความสามารถที่สมจริง: 0.5 จุด

---

## 📝 การบ้าน (Homework)

### การบ้าน 1: เขียนเอกสารมาตรฐานการเขียนโค้ดที่ครบถ้วน

**ระยะเวลา:** 2-3 ชั่วโมง (ทีม)

**งาน:**

สร้างเอกสารมาตรฐานการเขียนโค้ดที่ครอบคลุม (3-5 หน้า):

```
1. ภาพรวมโครงการ (Project Overview)
   - สแต็คเทคโนโลยี (Technology Stack)
   - กลุ่มเป้าหมาย (Target Audience)

2. การตั้งชื่อตัวแปร (Naming Conventions)
   - คลาส เมธอด ตัวแปร
   - ค่าคงที่ แพ็คเกจ ฐานข้อมูล
   - ตัวอย่างสำหรับแต่ละอย่าง

3. การจัดระเบียบโค้ด (Code Organization)
   - แผนภาพโครงสร้างโฟลเดอร์
   - กฎการตั้งชื่อไฟล์
   - ลำดับการจัดระเบียบคลาส

4. ความเห็นและเอกสาร (Comments & Documentation)
   - เมื่อใดที่จะแสดงความคิดเห็น (WHY ไม่ใช่ WHAT)
   - รูปแบบ Docstring/JavaDoc
   - แนวทางความเห็นอินไลน์
   - ตัวอย่างโค้ด

5. การจัดการข้อผิดพลาด (Error Handling)
   - ลำดับชั้นข้อยกเว้น (Exception Hierarchy)
   - มาตรฐานการบันทึก (Logging Standards)
   - รูปแบบการตอบสนองข้อผิดพลาด

6. คุณภาพโค้ด (Code Quality)
   - ขีดจำกัดความซับซ้อน (Cyclomatic Complexity Limits)
   - แนวทางความยาวของเมธอด
   - แนวทางขนาดคลาส
   - การบังคับใช้หลักการ DRY

7. มาตรฐาน Git & PR (Git & PR Standards)
   - การตั้งชื่อสาขา
   - รูปแบบข้อความ Commit
   - รายการตรวจสอบ PR
   - แนวทางการตรวจสอบโค้ด

8. มาตรฐานการทดสอบ (Testing Standards)
   - เป้าหมายความครอบคลุมการทดสอบหน่วย (80%+)
   - การตั้งชื่อการทดสอบ
   - การใช้ Mock/Stub
   - การตั้งค่าข้อมูลการทดสอบ

9. แนวทางความปลอดภัย (Security Guidelines)
   - ไม่มีความลับถูกเข้ารหัส (Hardcoded Secrets)
   - ข้อกำหนดการตรวจสอบการป้อนข้อมูล
   - การป้องกันการฉีดเข้า SQL
   - ตรวจสอบการยืนยันตัวตน/การให้สิทธิ์

10. โค้ดตัวอย่าง (Example Code)
    - คลาสบริการ (Service Class) ที่เขียนได้ดี
    - ตัวควบคุม (Controller) ที่เขียนได้ดี
    - คลัง (Repository) ที่เขียนได้ดี
    - คลาสการทดสอบที่เขียนได้ดี
```

**ผลิตภัณฑ์ที่ส่งมอบ:**

- ✅ Coding_Standards.md (3-5 หน้า)
- ✅ ตัวอย่างโค้ดสำหรับแนวทางแต่ละอย่าง
- ✅ GitHub: docs/Coding_Standards.md

---

### การบ้าน 2: สร้างแผนสปริ้นท์ 1 โดยละเอียด

**ระยะเวลา:** 2-2.5 ชั่วโมง (ทีม)

**งาน:**

สร้างรายการงานสปริ้นท์ 1 พร้อมกับ:

```
1. ภาพรวมสปริ้นท์ (Sprint Overview)
   - ระยะเวลาสปริ้นท์ (5-16 มกราคม)
   - วัตถุประสงค์สปริ้นท์ (1-2 ประโยค)
   - ความสามารถทีมเป็นชั่วโมง/จุด

2. เรื่องราวผู้ใช้ที่เลือก (User Stories Selected)
   - เรื่องราว 8-10 เรื่องกับจุด
   - เรียงลำดับตามลำดับความสำคัญ
   - ระบุการพึ่งพา

3. การแบ่งงาน (Task Breakdown)
   - แต่ละเรื่องราว → งาน 3-5 อย่าง
   - การประมาณงาน (ชั่วโมง)
   - การมอบหมายงาน
   - การพึ่งพางาน

4. ตารางเวลาสปริ้นท์ (Sprint Schedule)
   - เวลาการอัพเดตรายวัน
   - วันที่/เวลาบทวิจารณ์สปริ้นท์
   - วันที่/เวลาการทบทวนการทำงาน
   - ตารางเวลาการตรวจสอบโค้ด

5. การคำนวณความเร็ว (Velocity Calculation)
   - ตามข้อมูลประวัติศาสตร์ (หากมี)
   - หรือการประมาณสำหรับสปริ้นท์แรก
   - ระดับการส่ง (จะทำให้เสร็จแน่นอน)

6. ความเสี่ยงและการบรรเทา (Risks & Mitigation)
   - ความเสี่ยงทางเทคนิค
   - ความเสี่ยงของทรัพยากร (Resource Risks)
   - ความเสี่ยงของตารางเวลา (Schedule Risks)
   - การดำเนินการบรรเทา

7. เกณฑ์ความสำเร็จ (Success Criteria)
   - คำจำกัดความของการทำเสร็จ
   - วิธีวัดความสำเร็จ
   - เกณฑ์ยอมรับต่อเรื่องราว
```

**ผลิตภัณฑ์ที่ส่งมอบ:**

- ✅ Sprint_1_Plan.md (3-4 หน้า)
- ✅ Sprint_1_Backlog.xlsx (รายการงานกับการมอบหมาย)
- ✅ GitHub: docs/Sprint_Plans/ โฟลเดอร์

---

## 📋 การมอบหมายโครงการ: ให้สำเร็จการเตรียมการพัฒนา (D2 Final)

**ครบกำหนด: สิ้นสัปดาห์ที่ 7 (ตามกำหนดเวลา D2)**

### การมอบหมาย 7.1: ให้สำเร็จมาตรฐานการเขียนโค้ดและการตั้งค่า Git (2 จุด)

**งาน:**

1. **เอกสารมาตรฐานการเขียนโค้ด**
   - ครอบคลุมทั้งหมด (การตั้งชื่อ การจัดระเบียบ ความเห็น การจัดการข้อผิดพลาด ฯลฯ)
   - ตัวอย่างชัดเจนสำหรับแนวทางแต่ละอย่าง
   - ได้รับ commit จากทีม

2. **การตั้งค่าที่เก็บ Git**
   - .gitignore ตั้งค่าอย่างถูกต้อง
   - ตั้งค่า Branch Protection Rules
   - README.md สมบูรณ์
   - แม่แบบคำขอการดึงข้อมูลสร้าง
   - ตั้งค่า GitHub Actions (พื้นฐาน)

3. **โครงสร้างพร้อม**
   - โครงสร้างโฟลเดอร์สร้าง
   - คลาส/อินเทอร์เฟซฐานในตำแหน่ง
   - การฉีดการพึ่งพา (Dependency Injection) ตั้งค่า
   - ไฟล์การกำหนดค่าตั้ง
   - สคริปต์สร้างทำงาน (mvn, npm, gradle, ฯลฯ)

**ผลิตภัณฑ์ที่ส่งมอบ:**

- ✅ Coding_Standards.md (สุดท้าย ได้รับอนุมัติจากทีม)
- ✅ ที่เก็บ GitHub ตั้งค่าอย่างสมบูรณ์
- ✅ โฟลเดอร์ Code_Skeleton/ พร้อม
- ✅ .gitignore, README, แม่แบบ .github/
- ✅ การสร้างครั้งแรกสำเร็จ (./setup.sh ทำงานสะอาด)

**การให้คะแนน:**

- ความสมบูรณ์ของมาตรฐาน: 1 จุด
- คุณภาพการตั้งค่า Git: 1 จุด

---

### การมอบหมาย 7.2: ให้สำเร็จการวางแผนและการตั้งค่าสปริ้นท์ 1 (2.5 จุด)

**งาน:**

1. **รายการงานสปริ้นท์ 1**
   - เรื่องราวผู้ใช้ 8-12 รายประมาณ
   - งานแบ่งออก (3-5 ต่อเรื่องราว)
   - การมอบหมายชัดเจน
   - ระบุการพึ่งพา

2. **ความพร้อมของการพัฒนา (Development Readiness)**
   - สภาพแวดล้อมการพัฒนาบันทึก
   - ขั้นตอนการตั้งค่าสำหรับสมาชิกทีมใหม่
   - สคีมาฐานข้อมูลสร้าง (สคริปต์ SQL)
   - ข้อมูลตัวอย่างเตรียม
   - เซิร์ฟเวอร์พัฒนาท้องถิ่นทำงาน

3. **การประสานงานทีม (Team Coordination)**
   - ตารางเวลาการอัพเดตรายวันยืนยัน
   - บทวิจารณ์สปริ้นท์/การทบทวนการทำงานกำหนดการ
   - ช่องทางการสื่อสารใช้งาน (Slack, Discord)
   - กระบวนการตรวจสอบโค้ดบันทึก
   - เส้นทางการเพิ่มระดับชัดเจน

4. **การประเมินความเสี่ยง (Risk Assessment)**
   - ความเสี่ยงทางเทคนิค 5-10 รายระบุ
   - กลยุทธ์การบรรเทากำหนด
   - ความเสี่ยงของทรัพยากร (Resource Risks) ประเมิน
   - บัฟเฟอร์ตารางเวลารวม

**ผลิตภัณฑ์ที่ส่งมอบ:**

- ✅ Sprint_1_Backlog.md (เรื่องราว + งาน + การมอบหมาย)
- ✅ Development_Environment_Setup.md (คู่มือทีละขั้นตอน)
- ✅ สคริปต์ SQL สคีมาฐานข้อมูล
- ✅ Team_Communication_Plan.md
- ✅ Risk_Register.md
- ✅ GitHub: docs/Sprint_Plans/ และ docs/Setup/

**การให้คะแนน:**

- ความสมจริงของแผนสปริ้นท์: 1.5 จุด
- ความสมบูรณ์ของการตั้งค่า: 1 จุด

---

### การมอบหมาย 7.3: การฝึกอบรมและกระบวนการตรวจสอบโค้ด (โบนัส +1 จุด)

**ครบกำหนด: สิ้นสัปดาห์ที่ 7**

**งาน:**

1. **สร้างรายการตรวจสอบการตรวจสอบโค้ด**
   - รายการตรวจสอบโดยละเอียดสำหรับผู้ตรวจสอบ
   - ตรวจสอบความปลอดภัย (Security Checks)
   - ตรวจสอบประสิทธิภาพ (Performance Checks)
   - ตรวจสอบแนวปฏิบัติที่ดี (Best Practices Checks)
   - ตัวอย่างความคิดเห็นการตรวจสอบ

2. **การฝึกอบรมการตรวจสอบโค้ดของทีม**
   - สมาชิกทีมทั้งหมดอ่านมาตรฐาน
   - อภิปรายกระบวนการตรวจสอบโค้ด
   - ฝึกตรวจสอบโค้ดตัวอย่าง
   - บันทึกบทเรียนที่เรียนรู้

3. **การตั้งค่าเครื่องมือการตรวจสอบโค้ดอัตโนมัติ**
   - GitHub Actions สำหรับ Linting
   - การทดสอบอัตโนมัติใน CI
   - รายงานความครอบคลุมโค้ด (Code Coverage)
   - ประตูคุณภาพ (Quality Gates) กำหนด

**ผลิตภัณฑ์ที่ส่งมอบ:**

- ✅ Code_Review_Checklist.md
- ✅ Code_Review_Training_Report.md
- ✅ ท่อส่ง GitHub Actions ตั้งค่า
- ✅ การตรวจสอบอัตโนมัติผ่านบน Commit เบื้องต้น

**การให้คะแนน:**

- คุณภาพของรายการตรวจสอบ: 0.5 จุด
- การตั้งค่าอัตโนมัติ: 0.5 จุด

---

## 📊 ตารางเปรียบเทียบ (Comparison Tables)

### กลยุทธ์การแตกแขนง Git (Git Branching Strategies)

| กลยุทธ์ (Strategy) | ดีที่สุดสำหรับ (Best For)      | ความซับซ้อน (Complexity) | CI/CD     |
| ------------------ | ------------------------------ | ------------------------ | --------- |
| **Git Flow**       | Large teams, multiple releases | Medium                   | Good      |
| **GitHub Flow**    | Continuous deployment          | Simple                   | Excellent |
| **Trunk Based**    | Very rapid deployment          | Low                      | Excellent |
| **Release Flow**   | Time-based releases            | Medium                   | Good      |

### Code Review Methods

| Method                  | Time      | Coverage    | Best For         |
| ----------------------- | --------- | ----------- | ---------------- |
| **Pair Programming**    | High      | 100%        | Complex code     |
| **Pull Request Review** | Medium    | Variable    | Daily workflow   |
| **Formal Inspection**   | Very High | 100%        | Critical systems |
| **Automated Review**    | Low       | Rules-based | Continuous       |

---

## ✅ สรุป (Summary)

**Coding Standards:**

- ✅ Reduce code inconsistency & bugs
- ✅ Improve readability & maintainability
- ✅ Speed up onboarding
- ✅ Cover: naming, organization, comments, error handling, testing
- ✅ Team must agree & enforce

**Code Review:**

- ✅ Catch bugs & security issues early
- ✅ Knowledge sharing & learning
- ✅ Checklist covers: functionality, quality, testing, documentation, security
- ✅ Be constructive & kind in feedback
- ✅ Keep PRs small for faster reviews

**Git Workflows:**

- ✅ Git Flow recommended (feature → develop → main)
- ✅ Clear branch naming conventions
- ✅ Commit message standards important
- ✅ Pull request templates ensure quality

**Sprint Planning:**

- ✅ Select realistic stories based on capacity
- ✅ Break into tasks (4-8 hours each)
- ✅ Team commits to sprint goal
- ✅ Track velocity for future planning
- ✅ Burndown chart shows progress

**Development Readiness:**

- ✅ Environment properly configured
- ✅ Build scripts working
- ✅ Clear communication channels
- ✅ Risk assessment done
- ✅ Team aligned & excited to start!

**D2 Complete (Final Deliverable):**

- ✅ Architecture & Design Document
- ✅ API Specifications
- ✅ Database Schema
- ✅ Coding Standards
- ✅ Code Skeleton
- ✅ Sprint 1 Plan
- ✅ Development environment ready
- ✅ Team prepared to start coding!

---

## ✅ รายการตรวจสอบ: พร้อมสำหรับเฟสการพัฒนา

**ก่อนเริ่มการพัฒนา:**

- [ ] เอกสารมาตรฐานการเขียนโค้ดอนุมัติจากทีม
- [ ] Repository Git ตั้งค่าเสร็จสิ้น
- [ ] Code Skeleton (โครงสร้างพื้นฐาน) compile & run ได้
- [ ] Database Schema สร้างเสร็จและ Migrations ทำงาน
- [ ] ข้อมูลตัวอย่างโหลดเสร็จ
- [ ] นักพัฒนาแต่ละคน: Local Setup ทำงาน
- [ ] CI/CD Pipeline (ท่อสายการปรับปรุงต่อเนื่อง) ตั้งค่าเบื้องต้นเสร็จ
- [ ] Sprint 1 Backlog (รายการงานที่ค้างของสปริ้นท์ที่ 1) ยืนยันเสร็จ
- [ ] บทบาทและความรับผิดชอบของทีม ชัดเจน
- [ ] Channels (ช่องทาง) การสื่อสาร ที่ใช้งานอยู่
- [ ] Daily Standup (การประชุมวันละครั้ง) ลงตารางเสร็จ
- [ ] Code Review Process (กระบวนการตรวจสอบโค้ด) กำหนดเสร็จ
- [ ] เป้าหมายของสปริ้นท์แรก สื่อสารแล้ว

**สัปดาห์ที่ 9:**

- ดำเนินการพัฒนาเต็มรูป
- Sprint Reviews (การทบทวนสปริ้นท์) เริ่มขึ้น
- ฟีเจอร์ที่ใช้งานได้แล้ว ส่งมอบแล้ว

---

## 📖 แหล่งอ้างอิง

### ตำราและหนังสือ

1. **"The Pragmatic Programmer"** - Hunt & Thomas (Code Quality (คุณภาพโค้ด))
2. **"Code Complete"** - McConnell (Coding Standards (มาตรฐานการเขียนโค้ด))
3. **"A Successful Git Branching Model"** - Driessen (Git Flow (ลำดับการทำงาน Git))
4. **"Scrum: The Art of Doing Twice the Work in Half the Time"** - Sutherland

### เว็บไซต์และมาตรฐาน

- [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)
- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
- [Python PEP 8](https://www.python.org/dev/peps/pep-0008/)
- [Conventional Commits](https://www.conventionalcommits.org/)
- [Git Flow Cheatsheet](https://danielkummer.github.io/git-flow-cheatsheet/)

### วิดีโอ

- YouTube: "Code Review Best Practices (วิธีปฏิบัติที่ดีที่สุด)"
- YouTube: "Git Flow Explained (อธิบาย Git Flow)"
- YouTube: "Sprint Planning Workshop (สัมมนา Sprint Planning)"
- YouTube: "How to Write Readable Code (วิธีเขียนโค้ดที่อ่านง่าย)"

### เครื่องมือ

- **Git:** GitHub, GitLab, Bitbucket
- **Code Review:** GitHub PRs (Pull Requests), Gerrit, Crucible
- **Linting (ตรวจสอบข้อผิดพลาด):** ESLint, Checkstyle, Pylint, Rubocop
- **CI/CD:** GitHub Actions, Jenkins, GitLab CI
- **Project Management (การจัดการโครงการ):** Jira, GitHub Projects, Trello

---

## 📊 การให้คะแนน สัปดาห์ที่ 7

| รายการ                          | คะแนน | วันส่งมอบ      |
| ------------------------------- | ----- | -------------- |
| การบ้าน 1: มาตรฐานการเขียนโค้ด  | 1     | สิ้นสัปดาห์ 7  |
| การบ้าน 2: แผนสปริ้นท์ที่ 1     | 1.5   | สิ้นสัปดาห์ 7  |
| ภารกิจ 7.1: มาตรฐานและ Git      | 2     | วันส่ง D2      |
| ภารกิจ 7.2: Sprint Planning     | 2.5   | วันส่ง D2      |
| ภารกิจ 7.3: Code Review (โบนัส) | +1    | สัปดาห์ 7      |
| การมีส่วนร่วมในกิจกรรม          | 1     | ระหว่างสัปดาห์ |
| **รวม**                         | **8** | -              |

---

## 👨‍🏫 ติดต่อผู้สอน

สำหรับคำถามเกี่ยวกับเนื้อหาของสัปดาห์ที่ 7:

- Email: [email ของผู้สอน]
- Office Hours (ชั่วโมงสำนักงาน): [วันและเวลา]
- Slack/Discord: [ช่องทาง]

---

**แปลว่า:** เนื้อหาของสัปดาห์ที่ 7 เสร็จสิ้นแล้ว! 🎉
