# 🎯 Activity 1 Part 2: Team Discussion Example (ตัวอย่างการอภิปรายทีม)

## 📋 บริบท

จากโค้ดตัวอย่างที่มีปัญหา (Activity 1 Part 1):

```javascript
// ❌ โค้ดที่มีปัญหา:
class UserService {
  saveUser(u) {
    try {
      const query =
        "INSERT INTO users VALUES ('" + u.name + "', '" + u.email + "')";
      db.execute(query);
    } catch (e) {
      // ไม่ทำอะไร!
    }
  }

  getUser(i) {
    const s = "SELECT * FROM users WHERE id = " + i;
    const l = db.query(s);
    if (l.length > 0) return l[0];
    return null;
  }
}
```

---

## 💬 ส่วนที่ 2: การอภิปรายทีม (15 นาที)

### ❌ ปัญหาที่ 1: SQL Injection Vulnerability (ช่องโหว่ด้านความปลอดภัย)

#### 👀 ผู้ตรวจสอบ (Reviewer) - Dev B:

```
"ดูสิ บรรทัดที่ 3-4 - string concatenation ด้วย SQL query!
 นี่เป็น SQL Injection vulnerability!

 ตัวอย่าง: หากผู้ใช้ส่ง name = "'; DROP TABLE users; --"

 Query จะเป็น:
 INSERT INTO users VALUES (''; DROP TABLE users; --', '...')

 ผลลัพธ์:
 ✓ Database ลบตารางทั้งหมด! 💥"
```

#### 👨‍💻 ผู้ส่ง (Developer) - Dev A:

```
"SQL Injection? ไง... ฉันรู้ว่า... นอกจากนั้น
 database ของเราจะลบไม่ได้หรือเปล่า?"
```

#### 👨‍🏫 Tech Lead (ผู้นำทีมเทคนิค) - Dev C:

```
"ไม่ใช่ว่า 'อาจจะ' ทำได้ หรือ 'ยากเปล่า'
 เป็น bug ด้านความปลอดภัยที่อันตรายจริง ๆ

 ลองนึกดู:
 1. Attacker อาจเป็นผู้ใช้ในระบบ
 2. หรือ API ของเรา public สำหรับทั้งโลก
 3. หรือ Form ที่ API ฉันอันตราย

 ต้องแก้ไขเสียที

 วิธี: ใช้ Parameterized Query!"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี (String Concatenation):
const query = "INSERT INTO users VALUES ('" + u.name + "', '" + u.email + "')";

// ✅ ดี (Parameterized Query):
const query = "INSERT INTO users VALUES (?, ?)";
await db.execute(query, [u.name, u.email]);

// ความหมาย:
// - ? = placeholder (ตัวแทนสำหรับค่า)
// - [u.name, u.email] = ค่าจริง
// - Database engine ทำการ escape อัตโนมัติ
// - SQL Injection: ป้องกันได้ ✓
```

#### 🔍 ทำไมวิธีนี้ปลอดภัย?

```
Database Engine ทำ:
1. Parse SQL structure: "INSERT INTO users VALUES (?, ?)"
2. Prepare statement
3. Map values [u.name, u.email] ในแบบที่ปลอดภัย
4. ไม่มีการประเมินค่าเป็น SQL

ผลลัพธ์:
- Input: name = "'; DROP TABLE users; --"
- Database เห็นเป็น: "string value เท่านั้น"
- ไม่ drop table! ✓

ตัวอย่างที่ปลอดภัย:
INSERT INTO users VALUES (''; DROP TABLE users; --', 'email@example.com')
↓
Database: "ชื่อผู้ใช้นี้ แปลก แต่ก็ได้"
↓
INSERT สำเร็จ (ไม่ drop table!)
```

#### 📚 บทเรียนที่เรียนรู้:

```
Rule: NEVER string concatenation สำหรับ SQL queries

❌ ไม่ดี:
- String concatenation: "SELECT * FROM users WHERE id = " + id
- String formatting: f"SELECT * FROM users WHERE id = {id}"
- Template literals: `SELECT * FROM users WHERE id = ${id}`

✅ ดี:
- Parameterized Query: "SELECT * FROM users WHERE id = ?"
- Prepared Statement: PreparedStatement.setInt()
- ORM (Object-Relational Mapping): Sequelize, TypeORM, JPA
```

---

### ❌ ปัญหาที่ 2: Silent Exception (ปิดบังข้อยกเว้นอย่างเงียบ)

#### 👀 ผู้ตรวจสอบ - Dev B:

```
"บรรทัดที่ 5-6: try-catch ไม่ทำอะไร!

 catch (e) {
   // ไม่ทำอะไร!
 }

 ถ้า database error → exception หายไป
 จะรู้ได้ไง ว่า save ล้มเหลว?"
```

#### 👨‍💻 Developer - Dev A:

```
"ม... ผมคิดว่า... ไม่จำเป็นเหรอ?
 Exception มาจาก database
 แค่ไม่ได้บันทึก ก็ไม่มี error"
```

#### 👨‍🏫 Tech Lead - Dev C:

```
"ไม่มี error ≠ ทำงานสำเร็จ!

ลองสถานการณ์นี้:

Step 1: User สมัครสมาชิก → ส่ง POST /api/register
Step 2: Server: saveUser(user)
Step 3: Database down (ล่ม) → Exception
Step 4: catch { } → ไม่ทำอะไร, function return (ปกติ)
Step 5: Code ดำเนิน → "สมัครสำเร็จ!" ✓ (ตอบกลับให้ user)
Step 6: User: 'ยay, บัญชีสร้างแล้ว!'
Step 7: User ลอง login → ไม่เจอบัญชี ❌

ผลลัพธ์:
- User งง: 'บัญชีไปไหน?!'
- Support: 'เกิดอะไร?'
- Ops: 'ไม่รู้, logs เป็นว่าง'
- Debug: โลกตกอยู่ใจ... 4 ชั่วโมง! 💀"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี - ปิดบังข้อยกเว้น
async saveUser(u) {
  try {
    const query = "INSERT INTO users VALUES (?, ?)";
    await db.execute(query, [u.name, u.email]);
  } catch (e) {
    // ไม่ทำอะไร!
  }
}

// ✅ ดี - จัดการอย่างถูกต้อง
async saveUser(user) {
  try {
    logger.info(`บันทึกผู้ใช้: ${user.email}`);

    const query = "INSERT INTO users (name, email) VALUES (?, ?)";
    await db.execute(query, [user.name, user.email]);

    logger.info(`บันทึกเสร็จ: ${user.email}`);
    return { success: true, userId: user.id };

  } catch (error) {
    // 1. บันทึก error
    logger.error(`ล้มเหลวบันทึกผู้ใช้: ${user.email}`, {
      errorMessage: error.message,
      errorCode: error.code,
      timestamp: new Date().toISOString()
    });

    // 2. ขว้าง exception ให้ caller รู้
    throw new DatabaseError(
      `ไม่สามารถบันทึกผู้ใช้: ${user.email}`,
      error
    );
  }
}
```

#### 📊 การเปรียบเทียบ Exception Handling:

```
┌─────────────────────────────────────────────────────────┐
│ ❌ Silent Exception (ไม่ดี)                              │
├─────────────────────────────────────────────────────────┤
│ try {                                                   │
│   saveUser(user);                                       │
│ } catch (e) {                                           │
│   // ไม่ทำ                                              │
│ }                                                       │
│                                                         │
│ ผลลัพธ์:                                                 │
│ ❌ ไม่มี log → ไม่รู้เกิดอะไร                          │
│ ❌ Caller คิดว่า "สำเร็จ"                               │
│ ❌ Data inconsistent (ข้อมูลไม่สอดคล้อง)               │
│ ❌ Debug: หลอก 4+ ชั่วโมง 💀                            │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ ✅ Proper Exception Handling (ดี)                       │
├─────────────────────────────────────────────────────────┤
│ try {                                                   │
│   await saveUser(user);                                │
│ } catch (error) {                                       │
│   logger.error("Save failed", error);  // 1. Log        │
│   throw error;                         // 2. Throw      │
│ }                                                       │
│                                                         │
│ ผลลัพธ์:                                                 │
│ ✅ Logs มี error message                                │
│ ✅ Caller รู้เกิดอะไร                                   │
│ ✅ สามารถ retry หรือ fallback                          │
│ ✅ Debug: อ่าน logs ใน 2 นาที ✓                        │
└─────────────────────────────────────────────────────────┘
```

#### 📚 บทเรียน:

```
Rule: ไม่มี "empty catch blocks"

❌ ไม่ดี:
try { ... } catch (e) { }
try { ... } catch (e) { console.log("error"); }

✅ ดี:
try {
  // do work
} catch (error) {
  logger.error("Context: what happened", error);
  throw new CustomError("User-friendly message", error);
}

Or with recovery:
try {
  // do work
} catch (error) {
  logger.warn("Retry attempt 1", error);
  return retryWithBackoff();
}

Or with alternative:
try {
  return primary();
} catch (error) {
  logger.warn("Primary failed, using fallback", error);
  return fallback();
}
```

---

### ❌ ปัญหาที่ 3: Poor Naming Conventions (ชื่อตัวแปรแย่มาก)

#### 👀 Reviewer - Dev B:

```
"ตัวแปร: u, i, s, l
 พวกนี้คืออะไร? 🤔

 - u = user? userList? unit?
 - i = id? index? input?
 - s = string? sql? schema?
 - l = list? length? logger?

 ตัวอักษรเดียว = สับสน!"
```

#### 👨‍💻 Developer - Dev A:

```
"อ้อ, ผมคิดว่า:
 - u = user
 - i = id
 - s = SQL statement
 - l = list"
```

#### 👨‍🏫 Tech Lead - Dev C:

```
"ถ้าเขียน 6 เดือนหลังจากนี้ คุณจะจำได้ไหม? 🤨

และหลาย ๆ ซอฟต์แวร์ที่ใช้ปัจจุบัน:
1. IDE autocomplete ต้องการชื่อที่มีความหมาย
2. Code search หาค่าอื่นทั้งตัว i ได้มากมาย
3. Debugger: watch 'i' ได้ยากหรือมีเยอะเกิน

ตัวอย่างปัญหา:

const u = { name: 'John', email: 'john@...' };
const i = users.findIndex(x => x.id === u.id);
const s = 'SELECT...';

6 เดือนหลังจากนี้:
- i ใช้ที่อื่น 100+ ที่
- ไม่รู้ว่า i ครั้งนี้ อันไหน
- ต้องกลับไปอ่านโค้ด

แต่ถ้าเขียน:
const userId = users.findIndex(x => x.id === user.id);

ทุกคนรู้ทันที!"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี
class UserService {
  saveUser(u) {
    const query = "INSERT INTO users VALUES ('" + u.name + "')";
    db.execute(query);
  }

  getUser(i) {
    const s = "SELECT * FROM users WHERE id = " + i;
    const l = db.query(s);
    return l[0];
  }
}

// ✅ ดี
class UserService {
  /**
   * บันทึกผู้ใช้ลงฐานข้อมูล
   * @param {Object} user - ข้อมูลผู้ใช้ที่ต้องบันทึก
   */
  async saveUser(user) {
    const query = "INSERT INTO users (name, email) VALUES (?, ?)";
    await this.database.execute(query, [user.name, user.email]);
  }

  /**
   * ค้นหาผู้ใช้ด้วย ID
   * @param {number} userId - ID ที่ต้องค้นหา
   * @returns {Promise<Object|null>} ผู้ใช้หรือ null
   */
  async getUserById(userId) {
    const query = "SELECT * FROM users WHERE id = ?";
    const searchResults = await this.database.query(query, [userId]);
    return searchResults.length > 0 ? searchResults[0] : null;
  }
}
```

#### 📊 Naming Convention Guidelines:

```
✅ ชื่อตัวแปรที่ดี:
- user, userData, currentUser (ไม่ u)
- userId, accountId (ไม่ i)
- sqlQuery, queryStatement (ไม่ s)
- resultList, userList, items (ไม่ l)
- isActive, hasPermission, canDelete (boolean)
- getUserById(), createOrder(), processPayment() (method)

❌ ชื่อตัวแปรที่ไม่ดี:
- u, a, x, y (ตัวอักษรเดียว, ยกเว้น loop counter)
- temp, temp1, temp2 (ไม่มีความหมาย)
- data, value, thing (คลุมเครือ)
- xxx, foo, bar (placeholder ที่ลืมแก้ไข)

IDE Autocomplete ช่วยได้:
- user[Ctrl+Space] → userService, userData, userId
- u[Ctrl+Space] → ???

Code Search:
- grep "userId" → 15 ผลลัพธ์ที่เกี่ยวข้อง
- grep " i " → 10,000 ผลลัพธ์ที่ไร้ประโยชน์!
```

#### 📚 บทเรียน:

```
Rule: Naming Conventions สำคัญ

ทำไม?
1. 70% ของเวลา dev ใช้ "อ่านโค้ด"
2. ชื่อชัดเจน = อ่านเร็ว
3. ชื่อสับสน = debug ช้า + ข้อบกพร่องเพิ่ม

Best Practices:
✓ Descriptive: user, userId, currentUser
✓ Consistent: camelCase สำหรับ variables
✓ Meaningful: ไม่ใช่ a, b, c (ยกเว้น loop)
✓ Pronounceable: genymdhms vs generationTimestamp
✓ Searchable: userId (ค้นหา 15 ผลลัพธ์)
              vs u (ค้นหา 10,000 ผลลัพธ์)
```

---

### ❌ ปัญหาที่ 4: No Input Validation (ไม่ตรวจสอบข้อมูลป้อนเข้า)

#### 👀 Reviewer - Dev B:

```
"saveUser(u) - ไม่ตรวจสอบ u?

 เกิดอะไรถ้า:
 - saveUser(null) → u.name = error!
 - saveUser({}) → u.name = undefined
 - saveUser({name: ''}) → เชื่อ empty name?
 - saveUser({name: 'A' * 1000}) → database problem?
 - saveUser({name: '<script>alert(1)</script>'}) → XSS?"
```

#### 👨‍💻 Developer - Dev A:

```
"ผู้ใช้จะส่งข้อมูลให้ครบถ้วน...
 และ frontend ตรวจสอบแล้วหรือเปล่า"
```

#### 👨‍🏫 Tech Lead - Dev C:

```
"❌ ไม่ถูก!

Frontend validation เป็นการ UX เท่านั้น:
 - ช่วยผู้ใช้ใส่ข้อมูลได้ถูกต้อง
 - แสดง validation error เร็ว
 - ปรับปรุง UX

แต่ Frontend validation ไม่ ensure security!

เพราะ:
1. Frontend code → users อ่านและแก้ไขได้
2. Developer tools → bypass validation ทั้งหมด
3. curl, Postman, API tools → สามารถส่ง JSON เบื้องต้น

ตัวอย่าง Bypass:

  DevTools Console:
  > fetch('/api/users', {
  >   method: 'POST',
  >   body: JSON.stringify({
  >     name: null,
  >     email: 123,
  >     admin: true  // ← ผู้ใช้พยายาม set admin!
  >   })
  > })

  Frontend validation: ข้ามไป ❌
  Backend validation: ต้องมี! ✓

Rule: Backend = Last Defense
      Frontend = UX Only
"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี - ไม่มี validation
async saveUser(user) {
  const query = "INSERT INTO users (name, email) VALUES (?, ?)";
  await db.execute(query, [user.name, user.email]);
}

// ✅ ดี - มี validation
async saveUser(user) {
  // 1. Check null/undefined
  if (!user) {
    throw new ValidationError("User object required");
  }

  // 2. Check required fields
  if (!user.name || !user.email) {
    throw new ValidationError("Name and email required");
  }

  // 3. Type validation
  if (typeof user.name !== 'string' || typeof user.email !== 'string') {
    throw new ValidationError("Name and email must be strings");
  }

  // 4. Length validation
  if (user.name.length === 0 || user.name.length > 100) {
    throw new ValidationError("Name must be 1-100 characters");
  }

  if (user.email.length === 0 || user.email.length > 255) {
    throw new ValidationError("Email must be 1-255 characters");
  }

  // 5. Format validation
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(user.email)) {
    throw new ValidationError("Invalid email format");
  }

  // 6. Sanitize (ทำความสะอาด)
  const sanitizedName = user.name.trim();
  const sanitizedEmail = user.email.trim().toLowerCase();

  // 7. Save
  const query = "INSERT INTO users (name, email) VALUES (?, ?)";
  await db.execute(query, [sanitizedName, sanitizedEmail]);
}

// ใช้ Validation Library ดีกว่า:
const { body, validationResult } = require('express-validator');

// In Express route:
router.post('/users', [
  body('name')
    .trim()
    .notEmpty().withMessage('Name required')
    .isLength({ min: 1, max: 100 }).withMessage('Name 1-100 chars'),
  body('email')
    .trim()
    .notEmpty().withMessage('Email required')
    .isEmail().withMessage('Invalid email')
    .normalizeEmail(),
], async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }

  try {
    await userService.saveUser(req.body);
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
```

#### 📊 Validation Layers:

```
┌─────────────────────────────────────────────────────┐
│ Frontend Validation (UX)                            │
│ - Real-time feedback                                │
│ - Can be bypassed easily                            │
│ - Example: required, min-length, pattern            │
└─────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────┐
│ Backend Validation (Security)                       │
│ - Enforced, cannot be bypassed                      │
│ - Check: type, length, format, range                │
│ - Sanitize: trim, lowercase, escape                 │
└─────────────────────────────────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────────┐
│ Database Constraints (Data Integrity)               │
│ - NOT NULL, UNIQUE, CHECK, foreign key              │
│ - Last defense                                      │
└─────────────────────────────────────────────────────┘
```

#### 📚 บทเรียน:

```
Rule: Never Trust User Input

❌ ไม่ดี:
- saveUser(user) → ไม่ตรวจสอบ
- const x = parseInt(userInput) → อาจ NaN
- db.query("WHERE name = '" + name + "'") → SQL injection

✅ ดี:
- Validate ทุก input
- Check null, undefined, type
- Validate length, format, range
- Sanitize (trim, escape, lowercase)
- Use libraries (express-validator, joi, yup)

Security Principle:
"Trust, but verify" → "Never trust, always verify"
```

---

### ❌ ปัญหาที่ 5: No Logging (ไม่มีการบันทึก)

#### 👀 Reviewer - Dev B:

```
"ไม่มี logging ที่ไหนเลย?
 จะรู้ได้ยังไง ว่ามี user สกัดกั้น?"
```

#### 👨‍💻 Developer - Dev A:

```
"ผมเขียน console.log ก่อน"
```

#### 👨‍🏫 Tech Lead - Dev C:

```
"❌ console.log ไม่ใช่ solution!

เหตุผล:

1. หายไปเมื่อ Restart Server
   - console.log → หน้าจอ terminal
   - Terminal close → ข้อความหายไป!
   - ผู้ใช้บ่น ต้อนสัปดาห์หลัง = ไม่มี logs

2. ไม่มี Structure
   console.log('error'); ← ไม่รู้:
   - เกิดเมื่อไหร่?
   - Error code?
   - Stack trace?
   - Context ไหน?

3. ไม่มี Timestamp
   console output:
   error
   error
   another error
   ← เกิดเมื่อไหร่? ไม่รู้!

4. ไม่สามารถ Filter/Search
   tail -f output | grep userId
   ← ยาก เพราะ format ไม่ standard

Logger ดีกว่า 100 เท่า!
"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี - console.log
async saveUser(user) {
  try {
    console.log('saving user');
    await db.execute(query, [user.name, user.email]);
    console.log('user saved');
  } catch (error) {
    console.error(error);
  }
}

// ✅ ดี - Logger
const logger = require('./config/logger');

async saveUser(user) {
  try {
    logger.info(`Saving user: ${user.email}`);
    await db.execute(query, [user.name, user.email]);
    logger.info(`User saved successfully: ${user.email}`);
  } catch (error) {
    logger.error(`Failed to save user: ${user.email}`, {
      error: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString()
    });
    throw new DatabaseError('Cannot save user', error);
  }
}
```

#### 📊 Logger vs console.log:

```
┌────────────────────────────────────────────────────┐
│ console.log (ไม่ดี)                                │
├────────────────────────────────────────────────────┤
│ console.log('User saved');                         │
│                                                    │
│ ❌ หายไปเมื่อ restart                             │
│ ❌ ไม่มี timestamp                                │
│ ❌ ไม่มี level (INFO, WARN, ERROR)                │
│ ❌ ไม่สามารถ grep ได้ง่าย                         │
│ ❌ ไม่สามารถ rotate ได้                           │
│ ❌ ไม่สามารถส่ง remote ได้                        │
└────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────┐
│ logger.info() (ดี)                                 │
├────────────────────────────────────────────────────┤
│ logger.info('User saved');                         │
│                                                    │
│ ✅ บันทึกลงไฟล์ถาวร                               │
│ ✅ มี timestamp อัตโนมัติ                         │
│ ✅ มี level (INFO, WARN, ERROR, DEBUG)            │
│ ✅ สามารถ grep ได้ง่าย                            │
│ ✅ สามารถ rotate files ได้                        │
│ ✅ สามารถส่ง CloudWatch, Datadog ได้              │
│                                                    │
│ Output ตัวอย่าง:                                  │
│ [2025-01-10T09:15:23.456Z] INFO: User saved       │
│ [2025-01-10T09:15:24.789Z] ERROR: Save failed     │
└────────────────────────────────────────────────────┘
```

#### 📚 บทเรียน:

```
Rule: Use Logger, Not console.log

❌ ไม่ดี:
- console.log() ในโปรดักชั่น
- console.error() ใน error handling
- debug statements ลืมลบ

✅ ดี:
- logger.info('context: action')
- logger.warn('potential issue')
- logger.error('error occurred', error)
- logger.debug('dev only') → disabled in prod

Logger Levels:
- DEBUG: development only
- INFO: important events
- WARN: something unusual
- ERROR: error that needs attention
- FATAL: critical, system shutting down

Tool Recommendations:
- Node.js: winston, pino, bunyan
- Python: logging module
- Java: log4j, slf4j, logback
- Go: logrus, zap
```

---

### ❌ ปัญหาที่ 6: No Async/Await (ไม่ใช้ Async/Await)

#### 👀 Reviewer - Dev B:

```
"db.query(s) ← ทำไมไม่ใช้ async?
 Database I/O = ช้า, ต้อง async"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี - Synchronous (blocking)
function getUser(userId) {
  const result = db.query(query); // ← Block! ⏸️
  return result[0];
}

// ✅ ดี - Asynchronous (non-blocking)
async function getUser(userId) {
  const result = await db.query(query); // ← Async ✓
  return result[0];
}
```

#### 📚 บทเรียน:

```
Rule: Use async/await สำหรับ I/O

❌ ไม่ดี:
- Synchronous database calls
- Synchronous file reads
- Synchronous HTTP requests

✅ ดี:
- async function
- await database calls
- Promise-based APIs
```

---

### ❌ ปัญหาที่ 7: No JSDoc Documentation (ไม่มีเอกสาร JSDoc)

#### 👀 Reviewer - Dev B:

```
"saveUser(u) - ไม่มี documentation
 - ต้องส่ง parameter อะไร?
 - Return อะไร?
 - Throw error ไหน?"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี - ไม่มี JSDoc
async saveUser(user) {
  // ...
}

// ✅ ดี - มี JSDoc
/**
 * บันทึกผู้ใช้ใหม่ลงฐานข้อมูล
 *
 * @param {Object} user - ข้อมูลผู้ใช้
 * @param {string} user.name - ชื่อผู้ใช้ (1-100 chars)
 * @param {string} user.email - อีเมล (valid email format)
 *
 * @returns {Promise<Object>} บัญชีผู้ใช้ที่สร้าง
 * @returns {number} returns.id - User ID
 * @returns {string} returns.name - ชื่อผู้ใช้
 * @returns {string} returns.email - อีเมล
 *
 * @throws {ValidationError} หากข้อมูลไม่ถูกต้อง
 * @throws {DatabaseError} หากฐานข้อมูลล้มเหลว
 *
 * @example
 * const user = await userService.saveUser({
 *   name: 'John Doe',
 *   email: 'john@example.com'
 * });
 * console.log(user.id);
 */
async saveUser(user) {
  // ... validate & save
}
```

---

### ❌ ปัญหาที่ 8: Performance Issues (ปัญหาด้านประสิทธิภาพ)

#### 👀 Reviewer - Dev B:

```
"getUser(i) ← ตรวจสอบประสิทธิภาพไหม?

 SELECT * ← fetch ทั้งหมด?
 → ต้องให้ specific columns!

 WHERE id = i ← มี index ไหม?
 → ต้องมี index on id!"
```

#### ✅ วิธีแก้ไข:

```javascript
// ❌ ไม่ดี - Performance issue
async getUser(userId) {
  const query = "SELECT * FROM users WHERE id = " + userId; // ← N+1, no index
  const results = await db.query(query);
  return results[0];
}

// ✅ ดี - Optimized
async getUser(userId) {
  const query = "SELECT id, name, email, created_at FROM users WHERE id = ?";
  const results = await db.query(query, [userId]);
  return results[0];
}

// SQL: ensure INDEX created
CREATE INDEX idx_users_id ON users(id);
```

---

## 📋 สรุป: ปัญหา 8 ข้อ + วิธีแก้ไข

| #   | ปัญหา            | ความรุนแรง  | วิธีแก้             | เวลา |
| --- | ---------------- | ----------- | ------------------- | ---- |
| 1   | SQL Injection    | 🔴 Critical | Parameterized Query | 1m   |
| 2   | Silent Exception | 🟠 High     | Log + Throw         | 2m   |
| 3   | Poor Naming      | 🟡 Medium   | Descriptive names   | 1m   |
| 4   | No Validation    | 🟠 High     | Check input         | 3m   |
| 5   | No Logging       | 🟡 Medium   | Use logger          | 2m   |
| 6   | No Async/Await   | 🟡 Medium   | async/await         | 1m   |
| 7   | No JSDoc         | 🟡 Medium   | Add JSDoc           | 1m   |
| 8   | Performance      | 🟡 Medium   | Index, Optimize     | 2m   |

**รวมเวลา:** 13 นาที

---

## ✅ โค้ดที่ปรับปรุงแล้ว (Final Code)

```javascript
const logger = require("./config/logger");

/**
 * บริการจัดการผู้ใช้
 *
 * ตัวอย่างการเขียนโค้ดที่ดี:
 * - SQL Injection protection ✓
 * - Error handling ✓
 * - Input validation ✓
 * - Logging ✓
 * - Async/await ✓
 * - JSDoc ✓
 * - Performance ✓
 */
class UserService {
  constructor(database, logger) {
    this.database = database;
    this.logger = logger;
  }

  /**
   * บันทึกผู้ใช้ใหม่ลงฐานข้อมูล
   *
   * @param {Object} user - ข้อมูลผู้ใช้
   * @param {string} user.name - ชื่อผู้ใช้ (1-100 chars)
   * @param {string} user.email - อีเมล (valid format)
   * @returns {Promise<Object>} ผู้ใช้ที่สร้าง
   * @throws {ValidationError} ข้อมูลไม่ถูกต้อง
   * @throws {DatabaseError} ฐานข้อมูลล้มเหลว
   */
  async saveUser(user) {
    try {
      // 1. Validate input
      this.validateUserInput(user);

      // 2. Sanitize
      const sanitizedName = user.name.trim();
      const sanitizedEmail = user.email.trim().toLowerCase();

      // 3. Log attempt
      this.logger.info(`บันทึกผู้ใช้: ${sanitizedEmail}`);

      // 4. Execute (Parameterized Query - safe!)
      const query = "INSERT INTO users (name, email) VALUES (?, ?)";
      const result = await this.database.execute(query, [
        sanitizedName,
        sanitizedEmail,
      ]);

      // 5. Log success
      this.logger.info(`บันทึกสำเร็จ: ${sanitizedEmail}`);

      return { success: true, userId: result.insertId };
    } catch (error) {
      // 6. Handle error properly
      this.logger.error(`ล้มเหลวบันทึก: ${user?.email || "unknown"}`, {
        error: error.message,
        stack: error.stack,
      });
      throw new DatabaseError("Cannot save user", error);
    }
  }

  /**
   * ค้นหาผู้ใช้ด้วย ID
   *
   * @param {number} userId - ID ผู้ใช้
   * @returns {Promise<Object|null>} ผู้ใช้หรือ null
   * @throws {ValidationError} userId ไม่ถูกต้อง
   */
  async getUserById(userId) {
    try {
      // 1. Validate input
      if (!Number.isInteger(userId) || userId <= 0) {
        throw new ValidationError("User ID must be positive integer");
      }

      // 2. Query with index (specific columns)
      const query = `
        SELECT id, name, email, created_at 
        FROM users 
        WHERE id = ?
      `;
      const results = await this.database.query(query, [userId]);

      // 3. Return safely
      return results.length > 0 ? results[0] : null;
    } catch (error) {
      this.logger.error(`Failed to get user: ${userId}`, error);
      throw new DatabaseError("Cannot get user", error);
    }
  }

  /**
   * ตรวจสอบข้อมูลผู้ใช้
   *
   * @param {Object} user - ข้อมูลผู้ใช้
   * @throws {ValidationError} ข้อมูลไม่ถูกต้อง
   * @private
   */
  validateUserInput(user) {
    if (!user || typeof user !== "object") {
      throw new ValidationError("User must be an object");
    }

    if (!user.name || typeof user.name !== "string") {
      throw new ValidationError("Name must be non-empty string");
    }

    if (user.name.length > 100) {
      throw new ValidationError("Name max 100 characters");
    }

    if (!user.email || typeof user.email !== "string") {
      throw new ValidationError("Email must be non-empty string");
    }

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(user.email)) {
      throw new ValidationError("Invalid email format");
    }
  }
}

module.exports = UserService;
```

---

## 🎯 Trade-offs Discussion (อภิปรายการแลกเปลี่ยน)

### Trade-off 1: Security vs Convenience

```
Parameterized Query ช้ากว่า String Concat ไหม?
→ ไม่, ประมาณเท่า (< 1%)

Trade-off:
✓ Security: +100% (prevent SQL injection)
✗ Speed: -0% (ไม่ช้า)
✗ Coding time: +1 นาที (ไม่มากนัก)

Winner: Parameterized Query ✓
Principle: Security > Speed (99% of time)
```

### Trade-off 2: Robustness vs Performance

```
Validation + Logging + Error Handling ใช้เวลาไหม?
→ ใช่, แต่คุ้มค่า

Example:
- No validation: 1ms faster ❌ but crashes 10% of time
- With validation: 2ms (1ms slower) ✓ but stable 99.9%

Trade-off:
✓ Reliability: 10x better
✗ Speed: 1ms slower (negligible)

Winner: Validation + Logging ✓
Principle: Reliability > Speed
```

### Trade-off 3: Code Size vs Readability

```
Validation code + Error handling = 20 more lines
But:
- Time to understand: 30 seconds
- Time to debug without validation: 4 hours
- Time saved: 3.5 hours! 💰

Trade-off:
✓ Readability: 10x better
✗ Code size: 20 lines more (small)

Winner: Add validation code ✓
```

---

## 📝 สรุป: Key Takeaways

### 10 Lessons Learned

```
1️⃣ SQL Injection: Always use parameterized queries
2️⃣ Exceptions: Never silently swallow errors
3️⃣ Naming: Use descriptive variable names
4️⃣ Validation: Never trust user input
5️⃣ Logging: Use logger, not console.log
6️⃣ Async: Use async/await for I/O
7️⃣ Documentation: Write JSDoc for public functions
8️⃣ Performance: Check query plans & use indexes
9️⃣ Testing: Write unit tests for all functions
🔟 Code Review: This is how we learn & improve!
```
