# D4: รายงานคุณภาพและความปลอดภัย - คำแนะนำทีละขั้นตอน

## สำหรับนักศึกษา

---

## ภาพรวม D4

**D4 (รายงานคุณภาพและความปลอดภัย)** เป็นผลงานส่งมอบที่สำคัญในสัปดาห์ที่ 11-13 ซึ่งต้องเสนอข้อมูลครบถ้วนเกี่ยวกับ:

- การวัดคุณภาพซอฟต์แวร์ (Quality Metrics)
- การประกันคุณภาพ (Quality Assurance)
- การประเมินความปลอดภัย (Security Assessment)
- การทดสอบประสิทธิภาพ (Performance Analysis)
- การบริหารความเสี่ยง (Risk Management)

**กำหนดเวลาส่งงาน:** สิ้นสัปดาห์ที่ 13

---

## ขั้นตอนการทำ D4

### ขั้นตอนที่ 1: เตรียมข้อมูลจาก D1, D2, D3 (1-2 ชั่วโมง)

1. **รวบรวมข้อมูลทั้งหมด:**
   - โครงการของคุณจากที่จัดเก็บ
   - ไฟล์โค้ดต้นฉบับ
   - ไฟล์การทดสอบทั้งหมด (Jest test suite)
   - ไฟล์การตั้งค่า (.eslintrc, jest.config.js)

2. **ตรวจสอบ:**
   - ทุกคลาส/ฟังก์ชันมีการทดสอบแล้ว
   - การออกแบบ (D2) มีคุณภาพสูง
   - เอกสาร (D1) สมบูรณ์

---

### ขั้นตอนที่ 2: วัดตัวชี้วัดคุณภาพ (2-3 ชั่วโมง)

#### 2.1 จำนวนบรรทัดโค้ด (Lines of Code - LOC)

```bash
# Install perl using Chocolatey (if you have it)
choco install strawberryperl
# ติดตั้ง cloc
npm install -g cloc

# นับ LOC ของโค้ดต้นฉบับ
cloc src/

# ผลลัพธ์ตัวอย่าง:
#    Language      Files    Blank    Comment    Code
#    JavaScript       15       150       200    2450
```

**สิ่งที่ต้องทำ:**

- [ ] นับจำนวน LOC ของโค้ดต้นฉบับ
- [ ] บันทึกผลลัพธ์ใน D4 (ส่วน 2.1)
- [ ] อธิบาย: ขนาดโครงการนี้เหมาะสมหรือไม่

---

#### 2.2 ความครอบคลุมของการทดสอบ (Jest)

```bash
# รัน Jest พร้อมวัดความครอบคลุม
npm test -- --coverage

# ผลลัพธ์ตัวอย่าง:
# PASS  src/__tests__/user.test.js
# ──────────────────────────────────
# File      | % Stmts | % Branch | % Funcs | % Lines
# ──────────────────────────────────
# user.js   |    85.5 |     72.2 |     88.9 |    85.0
# ──────────────────────────────────
```

**สิ่งที่ต้องทำ:**

- [ ] รัน Jest coverage สำหรับโครงการทั้งหมด
- [ ] บันทึกค่า 4 ค่า: Statements, Branches, Functions, Lines
- [ ] เป้าหมายคือ **≥ 80%** สำหรับทั้งหมด
- [ ] ถ้าต่ำกว่า 80%: เขียนการทดสอบเพิ่มเติมเพื่อปรับปรุง
- [ ] ถ่ายภาพหรือคัดลอกผลลัพธ์ในภาคผนวก

---

#### 2.3 ความซับซ้อนของฟังก์ชัน (Cyclomatic Complexity)

ใช้ ESLint หรือ SonarQube:

```bash
# ESLint - ติดตั้ง eslint-plugin-complexity
npm install --save-dev eslint-plugin-complexity

# ในไฟล์ .eslintrc.json เพิ่ม:
{
  "plugins": ["complexity"],
  "rules": {
    "complexity/complexity": ["warn", 10]
  }
}

# รัน eslint
npx eslint src/ --format json > report.json
```

**สิ่งที่ต้องค้นหา:**

- ฟังก์ชันที่มี complexity > 10
- ลิสต์ 5-10 ฟังก์ชันที่มี complexity สูงสุด

**ตัวอย่าง:**

```
ชื่อฟังก์ชัน                          ความซับซ้อน
─────────────────────────────────────────
processUserData()                    15
validateInput()                      12
calculateTotal()                     11
formatDate()                         8
```

---

#### 2.4 ความหนาแน่นของข้อบกพร่อง (Defect Density)

**สูตร:** (จำนวนข้อบกพร่อง / LOC) × 1000

**ตัวอย่าง:**

```
ข้อบกพร่องที่พบจากการทดสอบ: 8 ข้อ
จำนวนบรรทัดโค้ด: 2,450
ความหนาแน่นของข้อบกพร่อง = (8 / 2,450) × 1,000 = 3.27 ข้อ/KLOC

เป้าหมาย: ≤ 1.0 ข้อ/KLOC
สถานะ: ไม่ผ่าน (ต้องแก้ไข)
```

**สิ่งที่ต้องทำ:**

- [ ] นับจำนวนข้อบกพร่องที่พบ (จากการทดสอบใน D3)
- [ ] คำนวณ Defect Density
- [ ] ระบุสัดส่วนของข้อบกพร่องที่แก้ไขแล้ว

---

### ขั้นตอนที่ 3: การประเมิน QA (2 ชั่วโมง)

#### 3.1 ประตูคุณภาพ (Quality Gates)

กำหนดประตูคุณภาพที่เข้มงวด:

```
กฎประตูคุณภาพ:
────────────────────────
1. ความครอบคลุมการทดสอบ ≥ 80% (ต้องผ่าน)
2. ความซับซ้อนของฟังก์ชัน ≤ 10 (ต้องผ่าน)
3. ปัญหาวิกฤต = 0 (ต้องผ่าน)
4. อัตราการผ่านการทดสอบ ≥ 95% (ต้องผ่าน)

สถานะ: ผ่าน / ไม่ผ่าน
```

**สิ่งที่ต้องทำ:**

- [ ] สร้าง 3-5 ประตูคุณภาพที่เหมาะสมกับโครงการ
- [ ] ทดสอบว่าโค้ดของคุณผ่านประตูทั้งหมด
- [ ] ถ้า ไม่ผ่าน ต้องแก้ไข

---

#### 3.2 เครื่องมือวิเคราะห์สแตติก

##### ตัวเลือก A: ESLint (สำหรับ JavaScript)

```bash
# ติดตั้ง
npm install --save-dev eslint eslint-plugin-node eslint-plugin-security

# สร้างการตั้งค่า
npx eslint --init

# รัน
npx eslint src/ --format json > eslint-report.json

# ดูผลลัพธ์
npx eslint src/
```

**ผลลัพธ์ตัวอย่าง:**

```
src/user.js
  45:2  error  ห้ามใช้ var ใช้ const หรือ let ควรใช้  no-var
  67:8  warning  ตัวแปร temp ไม่ได้ใช้                 no-unused-vars
  89:1  error  ขาดเครื่องหมายอัฒภาค                  semi
```

**บันทึก:**

- [ ] จำนวนปัญหาวิกฤต: \_\_
- [ ] จำนวนปัญหาหลัก: \_\_
- [ ] จำนวนปัญหารอง: \_\_
- [ ] แก้ไขทั้งหมดแล้วหรือไม่

---

##### ตัวเลือก B: SonarQube (สำหรับโครงการใหญ่)

```bash
# ดาวน์โหลด SonarQube Community Edition
# https://www.sonarqube.org/downloads/

# เริ่มต้น SonarQube
./sonarqube/bin/[ระบบปฏิบัติการ]/sonar.sh console

# ติดตั้ง SonarScanner
npm install --save-dev sonar-scanner

# วิเคราะห์โค้ด
npx sonar-scanner \
  -Dsonar.projectKey=my-app \
  -Dsonar.sources=src \
  -Dsonar.host.url=http://localhost:9000
```

**ดูรายงานที่:** http://localhost:9000

**บันทึก:**

- [ ] จำนวน Bug: \_\_
- [ ] จำนวนช่องโหว่: \_\_
- [ ] จำนวน Code Smell: \_\_
- [ ] ช่องโหว่ด้านความปลอดภัย: \_\_

---

#### 3.3 กระบวนการตรวจสอบโค้ด (Code Review)

**1. ทำการตรวจสอบโค้ดอย่างเป็นระบบ:**

```bash
# ดูจำนวน Pull Request
git log --oneline --grep="Merge pull request" | wc -l

# ดูจำนวน commits
git log --oneline | wc -l
```

**2. สร้าง รายการตรวจสอบโค้ด:**

```
รายการตรวจสอบโค้ด
──────────────────────────
- [ ] โค้ดตามหลักเกณฑ์การตั้งชื่อ
- [ ] ฟังก์ชันมีเอกสารประกอบ (JSDoc)
- [ ] ไม่มีค่าที่เขียนลงในโค้ด
- [ ] มีการจัดการข้อผิดพลาด
- [ ] มีกรณีทดสอบ
- [ ] ไม่มี console.log ในโค้ดผลิตชน
- [ ] ประสิทธิภาพเป็นที่ยอมรับได้
- [ ] ปฏิบัติตามหลักการความปลอดภัย
- [ ] ไม่มี TODO/FIXME ที่ยังค้างไว้
- [ ] ความเห็นชัดเจนและมีประโยชน์
```

**3. ทำการตรวจสอบ:**

- [ ] ตรวจสอบ 5-10 Pull Request
- [ ] บันทึกจำนวนปัญหาต่อ PR
- [ ] ระบุปัญหาทั่วไปที่พบบ่อย

---

### ขั้นตอนที่ 4: การประเมินความปลอดภัย (2-3 ชั่วโมง)

#### 4.1 การตรวจสอบ OWASP Top 10

**1. OWASP A01 - การควบคุมการเข้าถึงที่เสีย**

```javascript
// ไม่ดี - ไม่มีการตรวจสอบการให้สิทธิ
app.get("/api/user/:id", (req, res) => {
  User.findById(req.params.id).then((user) => {
    res.json(user); // ใครก็เข้าถึงได้
  });
});

// ดี - มีการตรวจสอบการให้สิทธิ
app.get("/api/user/:id", (req, res) => {
  if (req.user.id !== req.params.id) {
    return res.status(403).json({ error: "Forbidden" });
  }
  User.findById(req.params.id).then((user) => {
    res.json(user);
  });
});
```

**สิ่งที่ต้องตรวจ:**

- [ ] ทุก endpoint มีการตรวจสอบการยืนยันตัวตน
- [ ] การควบคุมการเข้าถึงตามบทบาท (RBAC) ถูกต้อง
- [ ] ข้อมูลไว้ความลับไม่สามารถเข้าถึงได้โดยอนุญาต

---

**2. OWASP A02 - ความล้มเหลวด้านการเข้ารหัส**

```javascript
// ไม่ดี - เก็บรหัสผ่านเป็นข้อความธรรมชาติ
database.save({ username: "john", password: "mypassword123" });

// ดี - แฮช รหัสผ่านด้วย bcrypt
const bcrypt = require("bcrypt");
const hashedPassword = await bcrypt.hash(password, 10);
database.save({ username: "john", password: hashedPassword });
```

**สิ่งที่ต้องตรวจ:**

- [ ] รหัสผ่านถูกแฮชด้วย bcrypt/scrypt
- [ ] ข้อมูลไว้ความลับถูกเข้ารหัส
- [ ] บังคับใช้ HTTPS ในทุก endpoint

---

**3. OWASP A03 - Injection**

```javascript
// ไม่ดี - SQL Injection
const query = `SELECT * FROM users WHERE id = ${userId}`;
db.execute(query);

// ดี - ใช้ parameterized query
const query = "SELECT * FROM users WHERE id = ?";
db.execute(query, [userId]);
```

**สิ่งที่ต้องตรวจ:**

- [ ] ทุก database queries ใช้ parameterized statements
- [ ] มีการตรวจสอบ input ที่ client และ server
- [ ] ทำความสะอาด input ของผู้ใช้ทั้งหมด

---

**สิ่งที่ต้องทำ:**

- [ ] สร้างตารางการประเมิน OWASP 10 รายการ
- [ ] ให้คะแนน ระดับความเสี่ยง (สูง/ปานกลาง/ต่ำ)
- [ ] บันทึก สถานะ (ผ่าน / ไม่ผ่าน)

---

#### 4.2 การทดสอบความปลอดภัย

**ทดสอบด้วย:**

```bash
# 1. OWASP Dependency Check (หาไลบรารีที่มีช่องโหว่)
npm audit

# 2. Snyk (สแกนหาช่องโหว่)
npm install -g snyk
snyk test

# 3. การทดสอบด้วยตนเอง
```

**สิ่งที่ต้องทดสอบ:**

- [ ] การยืนยันตัวตน: ทดสอบ login/logout
- [ ] การให้สิทธิ: ทดสอบการเข้าถึงตามบทบาท
- [ ] การตรวจสอบ Input: ทดสอบ XSS, SQL injection
- [ ] การจัดการข้อผิดพลาด: ไม่เปิดเผย stack trace

---

### ขั้นตอนที่ 5: การทดสอบประสิทธิภาพ (2 ชั่วโมง)

#### 5.1 การทดสอบภาระงาน (Load Testing)

**ใช้ Apache JMeter หรือ k6:**

```bash
# ติดตั้ง k6
# https://k6.io/docs/getting-started/installation/

# สร้าง test script (load-test.js)
import http from 'k6/http';
import { check } from 'k6';

export let options = {
  vus: 10,          // ผู้ใช้เสมือน 10 คน
  duration: '30s',  // ระยะเวลา 30 วินาที
};

export default function () {
  let response = http.get('http://localhost:3000/api/users');
  check(response, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
  });
}

# รัน test
k6 run load-test.js
```

**ผลลัพธ์ตัวอย่าง:**

```
ผ่าน status is 200
ผ่าน response time < 500ms

  checks.........................: 100.0%
  data_received....................: 2.3 MB
  data_sent........................: 456 kB
  http_req_duration................: avg=120ms
  http_req_receiving...............: avg=10ms
  http_reqs........................: 300
  vus..............................: 10
```

**บันทึก:**

- [ ] เวลาการตอบสนองเฉลี่ย: \_\_ มิลลิวินาที
- [ ] เวลาการตอบสนอง P95: \_\_ มิลลิวินาที
- [ ] ปริมาณงาน: \_\_ คำขอ/วินาที
- [ ] อัตราข้อผิดพลาด: \_\_%

---

#### 5.2 ข้อเสนอแนะการเพิ่มประสิทธิภาพ

ถ้าประสิทธิภาพต่ำ:

```javascript
// ไม่ดี - ปัญหา N+1 query
const users = await User.find();
for (let user of users) {
  const posts = await Post.find({ userId: user.id }); // N queries
}

// ดี - Eager loading / Batch query
const users = await User.find().populate("posts"); // 1 query
```

**รายการตรวจสอบการเพิ่มประสิทธิภาพ:**

- [ ] ใช้ caching (Redis)
- [ ] ใช้ pagination สำหรับ large datasets
- [ ] ใช้ eager loading สำหรับ relationships
- [ ] ใช้ indexes ใน database
- [ ] เพิ่มประสิทธิภาพรูปภาพ (compression, lazy loading)
- [ ] Minify CSS/JavaScript

---

### ขั้นตอนที่ 6: การอัปเดตการบริหารความเสี่ยง (1 ชั่วโมง)

**ดึงความเสี่ยงจาก D3:**

```
ความเสี่ยงต้นฉบับ (จากสัปดาห์ที่ 3):
────────────────────────────────
1. หมดเวลาการเชื่อมต่อ database
2. ความครอบคลุมการทดสอบไม่เพียงพอ
3. ช่องคำบวาประสิทธิภาพใน API
4. ช่องโหว่ความปลอดภัยในการยืนยันตัวตน
5. ความขัดแย้งตารางเวลาของสมาชิกทีม
```

**อัปเดตสถานะ:**

```
ตารางการประเมินความเสี่ยง:
────────────────────────────────────────────────
ความเสี่ยง          สถานะ          วิธีลดความเสี่ยง    ผู้รับผิดชอบ  วันที่
────────────────────────────────────────────────
หมดเวลา DB         ลดความเสี่ยง   Connection pool    John        2025-03-10
ความครอบคลุมต่ำ    แก้ไขแล้ว     เพิ่ม 50 test      Jane        2025-03-12
ช่องคำบวา API      ใช้งานอยู่     ใช้ caching       Tom         In Progress
ช่องโหว่ Auth      แก้ไขแล้ว     ใช้ patches       Alice       2025-03-15
ความขัดแย้ง        ลดความเสี่ยง   วางแผนใหม่        Team        2025-03-16
```

**สิ่งที่ต้องทำ:**

- [ ] ดึงความเสี่ยงทั้งหมดจาก D3
- [ ] อัปเดตสถานะของแต่ละความเสี่ยง
- [ ] บันทึกการดำเนินการลดความเสี่ยง
- [ ] ระบุผู้รับผิดชอบและกำหนดเวลา

---

### ขั้นตอนที่ 7: การเขียนรายงาน (1-2 ชั่วโมง)

**ใช้ template D4-TEMPLATE-TH.docx**

**โครงสร้าง:**

1. **บทสรุปผู้บริหาร (300 คำ)**
   - คะแนนคุณภาพโดยรวม
   - ผลการค้นพบที่สำคัญ
   - ข้อเสนอแนะ 3 อันดับแรก

2. **ตัวชี้วัดคุณภาพ (พร้อมแผนภูมิ)**
   - LOC, Coverage, Complexity, Defect Density
   - เปรียบเทียบกับเป้าหมาย

3. **กระบวนการ QA**
   - ผลลัพธ์ประตูคุณภาพ
   - ผลการวิเคราะห์สแตติก
   - สรุปการตรวจสอบโค้ด

4. **การประเมินความปลอดภัย**
   - ตารางการตรวจสอบ OWASP
   - ช่องโหว่ที่พบ
   - สถานะการแก้ไข

5. **ประสิทธิภาพ**
   - ผลการทดสอบภาระงาน
   - ช่องคำบวาที่ระบุ
   - แผนการเพิ่มประสิทธิภาพ

6. **การบริหารความเสี่ยง**
   - ตารางสถานะความเสี่ยง
   - ความเสี่ยงใหม่ที่พบ
   - ไทม์ไลน์การลดความเสี่ยง

7. **บทสรุป**
   - การประเมินคุณภาพ
   - ความพร้อมสำหรับการปล่อยรุ่น
   - ปัญหาวิกฤตที่ยังค้างอยู่
   - ขั้นตอนต่อไปสำหรับ D5

---

## รายการตรวจสอบก่อนการส่งงาน D4

```
เอกสาร
□ ตั้งชื่อไฟล์: D4-[ชื่อโครงการ]-[วันที่].docx
□ เพิ่มข้อมูลโครงการ (ชื่อ สมาชิก วันที่)
□ มีบทสรุปผู้บริหาร 3-4 หน้า
□ การจัดรูปแบบสมบูรณ์ (ฟอนต์ หัวเรื่อง ระยะห่าง)

ตัวชี้วัดคุณภาพ
□ LOC นับแล้ว
□ Code Coverage วัด Jest ≥ 80%
□ Cyclomatic Complexity วิเคราะห์แล้ว
□ Defect Density คำนวณแล้ว
□ ทั้งหมดมีการแสดงภาพ (ตาราง/แผนภูมิ)

กระบวนการ QA
□ ประตูคุณภาพกำหนดและผ่าน
□ ผลลัพธ์ ESLint/SonarQube
□ ตรวจสอบโค้ด 5+ PR บันทึกปัญหา
□ รายการตรวจสอบสมบูรณ์

ความปลอดภัย
□ การประเมิน OWASP Top 10 สมบูรณ์
□ ทดสอบการยืนยันตัวตน
□ ทดสอบการให้สิทธิ
□ ทดสอบการตรวจสอบ Input
□ ไม่มีช่องโหว่วิกฤต

ประสิทธิภาพ
□ ทดสอบภาระงานแล้ว
□ เวลาการตอบสนอง ≤ 500ms
□ อัตราข้อผิดพลาด < 5%
□ ข้อเสนอแนะการเพิ่มประสิทธิภาพ

การบริหารความเสี่ยง
□ ตารางความเสี่ยงอัปเดต
□ ทั้งหมดมีการลดความเสี่ยง
□ ความเสี่ยงใหม่ระบุแล้ว

คุณภาพเอกสาร
□ ไม่มีข้อผิดพลาดการสะกดและไวยากรณ์
□ ส่วนทั้งหมดมีรายละเอียดเพียงพอ
□ ภาคผนวกและเอกสารอ้างอิงสมบูรณ์
□ ระบุหมายเลขหน้าถูกต้อง
```

---

## เก็งคะแนน ตัวชี้วัด

| ตัวชี้วัด          | เป้าหมาย  | เกรด A      | เกรด B      | เกรด C     |
| ------------------ | --------- | ----------- | ----------- | ---------- |
| **LOC**            | -         | 1,500-3,500 | 1,000-4,000 | 500-5,000  |
| **Coverage**       | ≥ 80%     | 90-100%     | 80-89%      | 70-79%     |
| **Complexity**     | ≤ 10      | < 8         | 8-10        | 10-15      |
| **Defect Density** | ≤ 1.0     | < 0.5       | 0.5-1.0     | 1.0-2.0    |
| **OWASP**          | ≤ 2 วิกฤต | 0 วิกฤต     | ≤ 1 วิกฤต   | ≤ 3 วิกฤต  |
| **Response Time**  | ≤ 500ms   | < 200ms     | 200-500ms   | 500-1000ms |

---

## คำแนะนำเพื่อความสำเร็จ

1. **เริ่มต้นเร็ว:** การวัดตัวชี้วัดใช้เวลา ไม่ต้องรอจนถึงสัปดาห์ที่ 13
2. **ทำ D4 ขณะเขียน D2/D3:** ไม่ต้องรอให้เสร็จสิ้น
3. **ใช้เครื่องมืออัตโนมัติ:** ESLint, Jest, SonarQube อัตโนมัติ
4. **บันทึกทั้งหมด:** ถ่ายภาพผลลัพธ์ทั้งหมด
5. **ตรงไปตรงมา:** ไม่ต้อง fake metrics - ให้จริง

---

## ติดต่อ

ถ้ามีคำถาม:

- อีเมล: wittawas@buu.ac.th
- เวลาสำนักงาน: วันพฤหัสบดี 10:00 - 12:00 นาฬิกา
- Classroom: https://classroom.google.com/c/[รหัส]

---

**ปรับปรุงครั้งล่าสุด:** มีนาคม 2025
**เวลารวม:** 10-15 ชั่วโมง
