---
title: "คู่มือผู้ดูแลระบบ"
titleEn: "Administrator Manual"
clauses: ["4.10.2"]
phase: 3
category: "คู่มือ"
generated: false
---

# คู่มือผู้ดูแลระบบ (Administrator Manual)

**ระบบ:** MBU Buddhist AI — Admin Portal (`/admin`)
**อ้างอิง TOR:** ข้อ 4.10.2 (คู่มือผู้ดูแลระบบ ภาษาไทย) ประกอบภาคผนวก ก ข้อ 6 (Admin Portal) และข้อ 7 (Dashboard & Report)
**ฉบับ:** 1.0 — วันที่ 3 ตุลาคม พ.ศ. 2569
**ผู้อ่าน:** ผู้ดูแลระบบ (ADMIN), ผู้ดูแลระบบสูงสุด (SUPER_ADMIN) และคณะกรรมการตรวจรับ — การติดตั้ง/ปฏิบัติการเซิร์ฟเวอร์ดูที่ `/documents/deployment-guide`, `/documents/backup-restore-guide`, `/documents/system-documentation`

> ทุกหน้าที่อธิบายในคู่มือนี้มีอยู่จริงใน `src/app/[locale]/admin/*` (client component อยู่ที่ `src/components/admin/*`) ชื่อปุ่มตรงกับหน้าจอภาษาไทย

---

## 1. การเข้าใช้งาน Admin Portal

### 1.1 เงื่อนไขการเข้าถึง

1. บัญชีต้องมีบทบาท `ADMIN` หรือ `SUPER_ADMIN` — บัญชีอื่นที่เข้าสู่ระบบแล้วถูกพากลับหน้าแรก และ API ตอบ 403 (`src/app/[locale]/admin/layout.tsx`)
2. ต้องเข้าจาก IP ที่อยู่ในรายการ `ADMIN_IP_ALLOWLIST` (ตั้งในไฟล์ `.env`; ค่าเริ่มต้นเฉพาะเครื่องตนเอง `127.0.0.1,::1,::ffff:127.0.0.1`) — IP อื่นได้รับ 403 ทั้งหน้าเว็บ `/admin*` และ API `/api/admin*` และระบบบันทึก Audit Log เหตุการณ์ปฏิเสธ
   - รูปแบบรายการ: IP ตรงตัว, prefix ลงท้าย `.` หรือ `*` (เช่น `10.0.0.` หรือ `10.0.0.*`), หรือ `*` (อนุญาตทั้งหมด — ไม่แนะนำ) คั่นด้วยจุลภาค
   - ระบบอ่าน IP จาก header `x-forwarded-for` (ค่าแรก) หรือ `x-real-ip` จึงต้องติดตั้งหลัง reverse proxy/Ingress ที่เขียน header นี้ทับเสมอใน Production เพื่อป้องกันการปลอม header
3. เข้าสู่ระบบที่ `/login` ด้วยบัญชีผู้ดูแล แล้วไปที่ `/admin` (หรือเมนูผู้ใช้ → Admin Portal)

### 1.2 นโยบายรหัสผ่านผู้ดูแล (ก.6.1.4)

- รหัสผ่านบทบาท ADMIN/SUPER_ADMIN ต้องยาว **≥12 ตัวอักษร ผสม 4 ชนิด** (พิมพ์เล็ก พิมพ์ใหญ่ ตัวเลข สัญลักษณ์) และไม่เกิน 128 ตัว — นิยามใน `src/domain/identity/password-policy.ts` (ผู้ใช้ทั่วไป ≥8 ตัวมีตัวอักษรและตัวเลข)
- บัญชีสาธิตของผู้ดูแลใน `seed/users.json` เป็นไปตามนโยบายนี้ (รหัสผ่านดูได้ใน README — ไม่ระบุในเอกสารนี้)
- ข้อจำกัดของระบบสาธิต: ยังไม่มีหน้าตั้ง/เปลี่ยนรหัสผ่านของผู้ดูแล และการยกระดับผู้ใช้เป็น ADMIN ด้วยการเปลี่ยนบทบาทไม่บังคับเปลี่ยนรหัสผ่าน — ใน Production ควรกำหนดขั้นตอนให้ผู้ได้รับสิทธิ์ตั้งรหัสผ่านใหม่ตามนโยบาย และ **เปลี่ยนรหัสผ่านบัญชีสาธิตทั้งหมดก่อนเปิดใช้งานจริง**
- การป้องกันการเดารหัสผ่าน: ผิด 5 ครั้ง/15 นาทีต่อบัญชี หรือ 20 ครั้ง/15 นาทีต่อ IP → ล็อก 15 นาที และ `/api/auth/login` จำกัด 10 ครั้ง/นาที/IP

### 1.3 โครงหน้า Admin Portal

แถบเมนูซ้าย (`AdminSidebar`) แบ่ง 6 กลุ่ม แสดงบทบาทของผู้ใช้ใต้ชื่อ Admin Portal (มือถือ/แท็บเล็ต: กดปุ่ม **เมนู**)

| กลุ่ม | เมนู |
|---|---|
| ภาพรวม | Dashboard, การแจ้งเตือน |
| ผู้ใช้ | ผู้ใช้, คำขอ PDPA, Audit Log |
| AI | ตั้งค่า AI, Prompt, Guardrails, โหมด Unavailable, อัตราค่าโทเคน |
| ฐานองค์ความรู้ | ฐานองค์ความรู้, งานนำเข้า |
| ประเมินผล | ประเมินผล AI, ชุดทดสอบ, เปรียบเทียบ, รายงาน AI Security |
| ปฏิบัติการ | Defect Log, รายงาน SLA, สำรองข้อมูล, ลบ/ทำลายข้อมูล |

การเปลี่ยนแปลงค่าทุกหน้า **มีผลทันทีโดยไม่ต้อง deploy** (ระบบอ่านค่าจากฐานข้อมูลทุกคำขอ) และการเปลี่ยนแปลงสำคัญถูกบันทึกใน Audit Log

## 2. ตารางสิทธิ์ตามบทบาท (Roles Matrix)

| ความสามารถ | GENERAL_USER | ADMIN | SUPER_ADMIN |
|---|:---:|:---:|:---:|
| ถาม-ตอบ, ประวัติ, สิทธิเจ้าของข้อมูล (`/privacy`) | ✓ | ✓ | ✓ |
| Dhamma Talk | เมื่อได้รับสิทธิ์ | เมื่อได้รับสิทธิ์ | เมื่อได้รับสิทธิ์ |
| เข้า Admin Portal (จาก IP ที่อนุญาต) | — | ✓ | ✓ |
| Dashboard, การแจ้งเตือน, รายงาน SLA, Defect Log | — | ✓ | ✓ |
| ค้นหา/ดู/แก้ไข/ระงับ/ลบผู้ใช้ทั่วไป, เปิด/ปิดสิทธิ์ Dhamma Talk | — | ✓ | ✓ |
| แก้ไขบัญชี SUPER_ADMIN | — | — | ✓ |
| เปลี่ยนบทบาทผู้ใช้ (role) | — | — | ✓ (ยกเว้นบทบาทของตนเอง) |
| ระงับบัญชีของตนเอง | — | — | — |
| ดำเนินการคำขอ PDPA ของผู้ใช้ทั่วไป | — | ✓ | ✓ |
| ดำเนินการคำขอ PDPA แบบลบ/ถอนยินยอมของบัญชี SUPER_ADMIN | — | — | ✓ |
| Audit Log: ค้นหา ตรวจ hash chain ส่งออก | — | ✓ | ✓ |
| ตั้งค่า AI, Prompt, Guardrails, Unavailable, อัตราค่าโทเคน | — | ✓ | ✓ |
| ฐานองค์ความรู้: นำเข้า แก้ไข ลบ re-index | — | ✓ | ✓ |
| ประเมินผล: ชุดทดสอบ รัน เปรียบเทียบ รายงาน | — | ✓ | ✓ |
| สำรองข้อมูล (`/admin/backup`) | — | — | ✓ |
| ลบ/ทำลายข้อมูล (`/admin/data-destruction`) | — | — | ✓ |

บทบาทกำหนดที่ `src/domain/identity/rbac.ts` และบังคับทุก API ด้วย `withApi({ auth })` กฎเฉพาะของการแก้ไขผู้ใช้อยู่ใน `src/application/identity/admin-user-usecases.ts`

## 3. ภาพรวม

### 3.1 Dashboard (`/admin/dashboard`, `/admin`)

- **ช่วงเวลา:** วัน / สัปดาห์ / เดือน / ปี / กำหนดเอง (เลือกตั้งแต่วันที่–ถึงวันที่) และติ๊ก **เทียบช่วงก่อนหน้า**
- **KPI:** บัญชีทั้งหมด (และบัญชีใหม่ในช่วง), ผู้ใช้รายวัน (DAU), ผู้ใช้รายเดือน (MAU), บทสนทนา (แยก Q&A / Dhamma Talk), คำถาม, คำถามเฉลี่ยต่อบทสนทนา (รวมและแยกโหมด)
- **โทเคน:** กราฟแท่งซ้อน input/thinking/output รายวันพร้อมเส้นเพดานต่อวัน, รายเดือน, มาตรวัดการใช้ใน 24 ชั่วโมงล่าสุดเทียบเพดาน, โทเคนเฉลี่ยต่อคำถาม/บทสนทนาแยกโหมดเทียบเป้า, ประมาณการค่าใช้จ่าย (จากอัตราในหน้าอัตราค่าโทเคน), บัญชีที่ใช้โทเคนสูงสุด
- **ข้อเสนอแนะ:** สัดส่วน 👍/👎
- ข้อมูลอ่านสดจากฐานข้อมูล (ป้าย “อัปเดตล่าสุด: เมื่อสักครู่ (สด)”)

### 3.2 การแจ้งเตือน (`/admin/alerts`)

- ประวัติการแจ้งเตือน: เวลา ประเภท ระดับ หัวเรื่อง ผู้รับ และการส่ง (**บันทึกในระบบ** / **ส่งอีเมลแล้ว** / **ส่งไม่สำเร็จ**)
- ประเภทการแจ้งเตือน: โทเคนถึงเกณฑ์ (`threshold_tokens`), ค่าใช้จ่ายถึงเกณฑ์ (`threshold_cost`), เข้า Unavailable อัตโนมัติ (`auto_unavailable`), อัตราความผิดพลาดของ API แชตเกิน 5% ใน 15 นาที (`error_rate`), งานนำเข้าล้มเหลว (`ingestion_failed`), ระบบ (`system`)
- ปุ่ม **ส่งการแจ้งเตือนทดสอบ** — ส่งไปยัง `ALERT_EMAIL_TO`
- เกณฑ์ (เพดานโทเคน, % เริ่มแจ้งเตือน) ตั้งที่หน้าตั้งค่า AI
- ถ้าไม่ได้ตั้ง `SMTP_HOST` ระบบบันทึกการแจ้งเตือนไว้ในหน้านี้แทนการส่งอีเมล (ระบบสาธิตไม่มี SMTP จริง)

## 4. ผู้ใช้

### 4.1 ผู้ใช้ (`/admin/users`, `/admin/users/[id]`)

- ค้นหาด้วยอีเมลหรือชื่อ กรองบทบาท/สถานะ ตารางแสดงชื่อ อีเมล (ถอดรหัสเฉพาะในหน้าผู้ดูแล) บทบาท สถานะ วันสมัคร ใช้งานล่าสุด และสิทธิ์ Dhamma Talk
- หน้ารายละเอียด: แก้ชื่อแสดง, เปิด/ปิด **สิทธิ์ Dhamma Talk** (ค่าเริ่มต้นปิด), **ระงับ/ยกเลิกระงับ** บัญชี, **ลบ** (soft delete), เปลี่ยน **บทบาท** (เฉพาะ SUPER_ADMIN), ดูรายการบทสนทนาของผู้ใช้ (การเปิดดูถูกบันทึก audit `conversation_accessed`), สร้างคำขอ PDPA แทนผู้ใช้
- ทุกการเปลี่ยนแปลงบันทึก audit `user_changed` / `role_changed` พร้อมค่าก่อน/หลัง (ชื่อแสดงถูกปิดบังใน audit)

### 4.2 คำขอ PDPA (`/admin/privacy-requests`)

| ประเภทคำขอ | ผลเมื่อกด “ดำเนินการ” |
|---|---|
| ขอสำเนาข้อมูล (`access_copy`) | สร้างไฟล์ JSON สำเนาข้อมูลของผู้ใช้ (เก็บในโฟลเดอร์สำเนาข้อมูลข้าง `STORAGE_DIR`) |
| ขอลบข้อมูล/บัญชี (`erase`) | ลบบทสนทนา ข้อความ ข้อเสนอแนะ และทำให้บัญชีไม่สามารถระบุตัวตนได้ (ชื่อ “ผู้ใช้ที่ถูกลบ”, อีเมลนิรนาม) |
| ถอนความยินยอม (`withdraw_consent`) | บันทึกเวลาถอนและระงับบัญชี |

- สถานะ: รอดำเนินการ / ดำเนินการแล้ว / ปฏิเสธ พร้อมหมายเหตุและผู้ดำเนินการ — บันทึก audit `privacy_request`
- กำหนดเวลาตามนโยบาย: ดำเนินการภายใน 30 วัน

### 4.3 Audit Log (`/admin/audit-log`)

- ตัวกรอง: ค้นหา (เป้าหมาย/IP/รายละเอียด), ชนิดเหตุการณ์, ผู้กระทำ (อีเมลหรือรหัส), ช่วงวันที่
- คอลัมน์: เวลา ผู้กระทำ IP ชนิดเหตุการณ์ เป้าหมาย ก่อน/หลัง ผล (สำเร็จ/ล้มเหลว)
- ชนิดเหตุการณ์: `login_success`, `login_failed`, `logout`, `user_changed`, `role_changed`, `config_changed`, `prompt_changed`, `document_imported`, `document_deleted`, `conversation_accessed`, `evaluation_run`, `privacy_request`, `data_destruction`, `defect_changed`, `system`
- ปุ่ม **ตรวจสอบความสมบูรณ์ (hash chain)** — ยืนยันว่าไม่มีแถวถูกแก้ไขหรือลบ (ถ้าผิดปกติจะแจ้งลำดับที่พบ)
- **ส่งออก CSV** และ **พิมพ์/PDF** (มุมมองสำหรับพิมพ์)
- Audit Log แก้ไข/ลบไม่ได้ในระดับฐานข้อมูล (trigger) และไม่ถูกลบแม้สั่งทำลายข้อมูล

## 5. การตั้งค่า AI

### 5.1 ตั้งค่า AI (`/admin/ai-config`)

ค่าแบ่งกลุ่ม แต่ละช่องแสดงค่าตั้งต้นและปุ่ม **ใช้ค่าตั้งต้น** กด **บันทึก** แล้ว “มีผลทันที ไม่ต้อง deploy”

| กลุ่ม | ค่าหลัก (ค่าตั้งต้น) |
|---|---|
| โมเดลภาษา (LLM) | provider (`typhoon`), model (`typhoon-v2.5-30b-a3b-instruct`), fallback models — แสดงว่าตั้ง API key แล้วหรือ “ยังไม่ได้ตั้ง API key — ระบบจะใช้ mock แทน” |
| โทเคนและความยาวข้อความ | เพดานรวม 24 ชม. (10,000,000), margin (10%), % เริ่มแจ้งเตือน (80), เพดานต่อ prompt Q&A (10,000) / Dhamma Talk (50,000), thinking budget (2,000), max output (1,500), ความยาวคำถามสูงสุด (2,000 ตัวอักษร) |
| การเก็บรักษาบทสนทนา | ระยะเก็บ (90 วัน), รอบการลบอัตโนมัติ (60 นาที) + ปุ่ม **ลบบทสนทนาที่หมดอายุทันที** |
| การสืบค้น | candidateK (50), finalK (10, สูงสุด 10), rrfK (60), reranker (`heuristic` หรือ `tei`) |
| การประเมินผล | โมเดลผู้ตัดสิน, ค่ารับประกันรายชุด |
| Unavailable / อื่น ๆ | สถานะและข้อความ, มูลค่าสัญญา, สกุลเงิน, เวอร์ชันนโยบายความเป็นส่วนตัว |

- ปุ่ม **ทดสอบ LLM** เรียกโมเดลตามค่าที่บันทึกอยู่ แสดง provider, โมเดล, เวลาตอบ, โทเคน และคำตอบ (ถ้าไม่มี API key จะแจ้งว่าใช้ mock แทน)
- **Snapshot:** ทุกการบันทึกสร้างสำเนาค่าก่อนเปลี่ยน แผง snapshot แสดงรายการพร้อมผู้แก้/เวลา/เหตุผล กด **ย้อนกลับ** เพื่อคืนค่า (บันทึก audit `config_changed`)
- การเปลี่ยน LLM provider: เลือก provider/model ที่หน้านี้ แล้วให้ผู้ดูแลเซิร์ฟเวอร์ใส่ API key ที่มหาวิทยาลัยจัดหาในไฟล์ `.env` (`TYPHOON_API_KEY`, `OPENAI_API_KEY`+`OPENAI_BASE_URL`, `GEMINI_API_KEY`, `ANTHROPIC_API_KEY`) — หน้าเว็บไม่แสดงค่า key

### 5.2 Prompt (`/admin/prompts`)

| key | หน้าที่ |
|---|---|
| `qa-persona` | บุคลิกบรรณารักษ์และกติกาการตอบ (ถาม-ตอบ) |
| `dhamma-talk` | เรียบเรียงบทธรรมบรรยาย |
| `guard-classifier` | จำแนกขอบเขตคำถาม (เมื่อใช้ LLM จริง) |
| `judge` | ผู้ตัดสินคะแนน 0–3 ในการประเมิน NT-2 |
| `query-rewrite` | ปรับ/ขยายคำค้น |

1. เลือก Prompt → ดูรายการเวอร์ชัน (เวอร์ชัน ผู้แก้ เวลา บันทึกการเปลี่ยนแปลง ป้าย “ใช้งานอยู่”)
2. **เปิดในช่องแก้ไข** → แก้เนื้อหา + บันทึกการเปลี่ยนแปลง → บันทึกเป็นเวอร์ชันใหม่ (เลือกให้ใช้งานทันทีได้)
3. เลือก 2 เวอร์ชันเพื่อดู **diff** แบบเทียบบรรทัด
4. **ใช้เวอร์ชันนี้ / ย้อนกลับมาเวอร์ชันนี้** → มีผลกับคำถามถัดไปทันที (บันทึก audit `prompt_changed`)
5. ทางเลือกด้วยสคริปต์: แก้ไฟล์ `config/prompts/<key>.v<n>.md` แล้วรัน `npm run prompts:publish`

### 5.3 Guardrails (`/admin/guardrails`)

4 แท็บ: **ขอบเขตที่ตอบ** (`scope_allow`), **หัวข้อปฏิเสธ** (`refuse_sensitive`), **รูปแบบ injection** (`injection_pattern`), **รูปแบบใช่-ไม่ใช่** (`yes_no_pattern`)

- **เพิ่มหัวข้อ/แก้ไข:** รหัสหัวข้อ (เช่น `politics`, `religion_comparison`, `mental_health`), ชื่อไทย/อังกฤษ, รูปแบบบรรทัดละ 1 รายการ (คำสำคัญ หรือ regex ในรูป `/รูปแบบ/flags` — ระบบตรวจ regex ก่อนบันทึก), ข้อความปฏิเสธไทย/อังกฤษ (ว่าง = ใช้ข้อความมาตรฐาน), ลำดับ, เปิดใช้งาน
- สวิตช์เปิด/ปิดรายหัวข้อ, ลบหัวข้อ
- ช่อง **ทดสอบข้อความ**: พิมพ์คำถามเพื่อดูผลการจำแนกก่อนใช้งานจริง
- มีผลกับคำถามถัดไปทันที

### 5.4 โหมด Unavailable (`/admin/unavailable`)

- สถานะปัจจุบัน: เปิดให้บริการตามปกติ / ปิดให้บริการ (ผู้ดูแลสั่ง) / ปิดอัตโนมัติ — โทเคนถึงเพดาน
- สวิตช์ **ปิดให้บริการแชตบอตชั่วคราว** + ข้อความแจ้งผู้ใช้ไทย/อังกฤษ → ผู้ใช้เห็นแบนเนอร์ทุกหน้าและส่งคำถามไม่ได้ (เอกสารยังเปิดอ่านได้)
- **ล้างสถานะปิดอัตโนมัติ** (ระบบกลับมาให้บริการเองเมื่อยอด 24 ชม. ต่ำกว่าเพดาน)
- แสดงโทเคนที่ใช้ใน 24 ชั่วโมงล่าสุดเทียบเพดาน

### 5.5 อัตราค่าโทเคน (`/admin/pricing`)

ตารางอัตราต่อ 1 ล้านโทเคน (ขาเข้า / Thinking / ขาออก) ต่อ provider + โมเดล และสกุลเงิน — เพิ่ม/แก้/ลบได้ ใช้ประมาณการค่าใช้จ่ายใน Dashboard และ `TokenUsage.estimatedCost`

## 6. ฐานองค์ความรู้

### 6.1 ฐานองค์ความรู้ (`/admin/knowledge-base`)

- **การ์ดความครอบคลุม:** จำนวนเอกสาร/chunks, เล่มฉบับ มมร. ที่มีข้อมูลจาก 91 เล่ม (แยกปิฎก) เทียบเป้า 20% ของงวดที่ 2, ฉบับหลวง 45 เล่ม, สถิติตามประเภท/ปิฎก/ฉบับ
- **อัปโหลดเอกสารใหม่:** ไฟล์ PDF, TXT, MD, TEI-XML, DOCX ≤20MB + metadata (ชื่อ, ประเภท, ฉบับ, ปิฎก, นิกาย, พระสูตร, เล่ม, เล่ม มมร., ตัวย่อ, precedence, หมายเหตุที่มา) → **อัปโหลดและนำเข้า** ระบบอ่านไฟล์ → กรองข้อความ → แบ่ง chunk → สร้าง embedding → ทำดัชนี อัตโนมัติ
- **รายการเอกสาร:** ค้นหา กรองประเภท/สถานะ; แก้ metadata และ **precedence (0–2)** — ดัชนีอัปเดตทันทีและบันทึก audit; ลบเอกสาร (สร้างงานชนิด delete); **Re-index** เอกสารที่เลือก หรือ **Re-index ทั้งหมด**
- ค่า precedence เริ่มต้น: พระไตรปิฎก 1.0 > อรรถกถา 0.9 > ฎีกา 0.8 > ร่วมสมัย 0.7 > ธรรมะพ่อแม่ครูอาจารย์ 0.6
- **รายละเอียดเอกสาร** (`/admin/knowledge-base/[id]`): metadata ที่มา งานนำเข้าล่าสุด และรายการ chunk (ลำดับ หัวข้อ เล่ม/ข้อ/หน้า โทเคน ป้าย oversized เนื้อหา)
- ไฟล์ PDF ที่เป็นภาพสแกน (ไม่มีชั้นข้อความ) จะล้มเหลวพร้อมข้อความให้ทำ OCR ก่อน

### 6.2 งานนำเข้า (`/admin/knowledge-base/jobs`)

- รายการงาน 50 รายการล่าสุด: ชนิด (นำเข้า / re-index ทั้งหมด / re-index ที่เลือก / ลบ) สถานะ (queued / running / completed / partial / failed) จำนวนสำเร็จ/ล้มเหลว
- รายละเอียด: stage ของแต่ละเอกสาร (parse → sanitize → chunk → embed → index → done/failed) ข้อความผิดพลาด จำนวน chunk เวลาที่ใช้
- ปุ่ม **รันซ้ำเฉพาะที่ล้มเหลว**
- งานที่มีรายการล้มเหลวจะสร้างการแจ้งเตือน `ingestion_failed`

## 7. ประเมินผล AI

### 7.1 ภาพรวม (`/admin/evaluation`)

- KPI: ชุดที่มีผลการประเมิน, ผ่านเกณฑ์ขั้นต่ำ TOR, ถึงค่ารับประกัน, สถานะการตรวจรับ (ต้องผ่านครบทุกชุด — ก.5.3.1)
- ตาราง 7 Benchmark (DS-1, NT-2, RET-1, RET-2, RET-3, GR-1, GR-2): จำนวนข้อเทียบ TOR, เวอร์ชัน, เกณฑ์ขั้นต่ำ, ค่ารับประกัน, ผลล่าสุด และปุ่ม **Run** ต่อชุด (เลือก label baseline / acceptance / adhoc)
- ปุ่ม **Export Baseline Report** → เขียน `docs/deliverables/baseline-evaluation-report.md` แล้วเปิดในศูนย์เอกสาร
- การรันเป็นแบบ async ความคืบหน้าแสดงเป็น “ข้อที่เสร็จ/ทั้งหมด” — การรันกับ LLM จริงมีค่าใช้จ่ายโทเคน (บันทึกเป็นโหมด EVALUATION แยกจากเพดานบริการผู้ใช้)

### 7.2 ชุดทดสอบ (`/admin/evaluation/datasets`, `/admin/evaluation/datasets/[id]`)

- สร้างชุดใหม่ (ชื่อ ชนิด accuracy/judge/retrieval/guardrail รหัส เกณฑ์ ค่ารับประกัน จำนวนข้อตาม TOR) แก้/ลบชุด (ลบได้เฉพาะชุดที่ยังไม่มีการรัน)
- จัดการข้อทดสอบ: เพิ่ม/แก้/ลบ ค้นหา แบ่งหน้า
- **นำเข้า CSV** หัวตาราง `ordinal,question,choices,expected_answer,expected_refs,expect_refusal,level` และ **ดาวน์โหลดแม่แบบ CSV**
- ทุกการเปลี่ยนข้อทดสอบเพิ่มเลขเวอร์ชันของชุด (ก.5.2.4)

### 7.3 ผลการรัน (`/admin/evaluation/runs/[id]`)

สรุปชุด/เวอร์ชันชุด, prompt และเวอร์ชัน, โมเดล, โมเดลผู้ตัดสิน, คะแนน, ผ่านเกณฑ์ TOR และค่ารับประกัน + ตารางผลรายข้อ (คำถาม คำตอบของระบบ เฉลย คะแนน เหตุผล เวลา) กรองเฉพาะข้อที่ไม่ผ่านได้

### 7.4 เปรียบเทียบ (`/admin/evaluation/compare`)

เลือก 2 รอบของชุดเดียวกัน → เทียบเวอร์ชัน prompt/ชุด/โมเดล และผลรายข้อพร้อม delta

### 7.5 รายงาน AI Security (`/admin/evaluation/security-report`)

กด **รันการทดสอบ** → รัน GR-1, GR-2 และชุด Prompt Injection ภายใน (INJ 20 เคส) → แสดงอัตราการป้องกันรวม รายชุด และรายประเภทการโจมตี เทียบเกณฑ์ 80% (หน้าอัปเดตทุก 3 วินาที) → **ส่งออก .md** เป็น `docs/deliverables/guardrail-security-report.md`

## 8. ปฏิบัติการ

### 8.1 Defect Log (`/admin/defect-log`)

- บันทึกข้อบกพร่อง: โมดูล รายละเอียด ความรุนแรง เวลาที่มหาวิทยาลัยแจ้ง ผู้รับผิดชอบ ระยะที่พบ
- ระบบคำนวณ SLA อัตโนมัติ: critical/high **24 ชม.**, medium **48 ชม.**, low **80 ชม. (10 วันทำการ)** นับเป็นชั่วโมงทำการ และแสดงกำหนดเวลา
- เปลี่ยนสถานะ open → in_progress → resolved → closed; ปิดระดับ high/critical ต้องกรอกวิธีแก้และมาตรการป้องกันซ้ำ
- **มหาวิทยาลัยยืนยันผล** → ระบบคำนวณชั่วโมงที่เกินและค่าปรับประมาณการ (0.025% ของมูลค่าสัญญาต่อชั่วโมง)
- การ์ดสรุป: High/Critical คงค้าง (ต้องเป็น 0 ก่อนตรวจรับ), เกินกำหนด SLA, รอยืนยัน, ค่าปรับประมาณการ — ส่งออก CSV ได้

### 8.2 รายงาน SLA (`/admin/sla-report`)

เลือกช่วง “session ปัจจุบัน” หรือ “รายเดือน” → Availability (เกณฑ์ ≥95%), TTFT p95 (≤15 วินาที), error rate (≤5%), p95 latency, defect ที่เกิน SLA → **ส่งออก .md** เป็น `docs/deliverables/sla-monthly-report.md` (รายงานรายเดือนต้องส่งภายในวันที่ 15 ของเดือนถัดไป — TOR 12.5)

### 8.3 สำรองข้อมูล (`/admin/backup`) — SUPER_ADMIN

- กด **สำรองข้อมูลตอนนี้** → ระบบเรียก `scripts/backup-db.sh` (สำเนาฐานข้อมูลด้วย `sqlite3 .backup` + tar ไฟล์อัปโหลด) และแสดงรายการไฟล์ในโฟลเดอร์ `backups/` พร้อมคำสั่งกู้คืนของแต่ละไฟล์
- **การกู้คืนต้องรันเองที่เซิร์ฟเวอร์** (ไม่มีปุ่มในหน้าเว็บเพราะเขียนทับฐานข้อมูล): หยุดแอป → `bash scripts/restore-db.sh backups/<ไฟล์>.db` → เปิดแอปใหม่ แล้วตรวจที่ Dashboard — รายละเอียดใน `/documents/backup-restore-guide`

### 8.4 ลบ/ทำลายข้อมูล (`/admin/data-destruction`) — SUPER_ADMIN

ใช้เมื่อสิ้นสุดสัญญา (TOR 4.11.3) — **ลบจริงและย้อนกลับไม่ได้ ควรสำรองข้อมูลก่อน**

1. เลือกขอบเขต: ไฟล์อัปโหลด / บทสนทนา (พร้อมข้อความ อ้างอิง ข้อเสนอแนะ) / บันทึกการใช้โทเคน / ผลการประเมิน / บัญชีผู้ใช้ทั่วไป (พร้อมข้อมูลที่เกี่ยวข้อง)
2. พิมพ์ข้อความ **ยืนยันการลบ** ในช่องยืนยัน แล้วกด **ลบข้อมูลที่เลือก** → ยืนยันในหน้าต่างเตือน
3. ระบบสร้าง **หนังสือรับรองการลบ/ทำลายข้อมูล** (รายการตาราง/โฟลเดอร์ จำนวนก่อนลบ คงเหลือ ผู้สั่ง เวลา) บันทึกที่ `docs/deliverables/data-destruction-certificate.md` และดาวน์โหลดได้
4. Audit Log ไม่ถูกลบในทุกกรณี และการลบถูกบันทึก audit `data_destruction`

## 9. งานประจำที่แนะนำ

| ความถี่ | งาน | หน้า/คำสั่ง |
|---|---|---|
| ทุกวัน | ตรวจการแจ้งเตือน และโทเคน 24 ชม. เทียบเพดาน | `/admin/alerts`, `/admin/dashboard` |
| ทุกวัน | ตรวจคำขอ PDPA ที่รอดำเนินการ | `/admin/privacy-requests` |
| ทุกสัปดาห์ | ตรวจ hash chain ของ Audit Log และงานนำเข้าที่ล้มเหลว | `/admin/audit-log`, `/admin/knowledge-base/jobs` |
| ทุกสัปดาห์ | สำรองข้อมูล (หรือกำหนดเวลาอัตโนมัติที่เซิร์ฟเวอร์) | `/admin/backup` / `bash scripts/backup-db.sh` |
| หลังแก้ prompt/config/นำเข้าเอกสารชุดใหญ่ | รัน Benchmark ที่เกี่ยวข้องและเปรียบเทียบกับรอบก่อน | `/admin/evaluation` |
| ทุกเดือน (ภายในวันที่ 15) | ส่งออกรายงาน SLA | `/admin/sla-report` |
| ก่อนตรวจรับงวด | ไม่มี Defect High/Critical คงค้าง, Benchmark ผ่านเกณฑ์, ออกรายงาน | `/admin/defect-log`, `/admin/evaluation`, `npm run report:all` |

## 10. การแก้ปัญหาเบื้องต้น

| อาการ | สาเหตุที่เป็นไปได้ | วิธีแก้ |
|---|---|---|
| เปิด `/admin` ได้ 403 “IP not allowed” | IP ไม่อยู่ใน `ADMIN_IP_ALLOWLIST` | เพิ่ม IP/prefix ในไฟล์ `.env` แล้วรีสตาร์ตแอป |
| ถูกพากลับหน้าแรกเมื่อเปิด `/admin` | บัญชีไม่ใช่ ADMIN/SUPER_ADMIN | ให้ SUPER_ADMIN เปลี่ยนบทบาท |
| คำตอบเป็นข้อความรูปแบบตายตัว | ไม่มี API key ของ provider ที่เลือก ระบบใช้ Mock | ใส่ API key ใน `.env` แล้วกด **ทดสอบ LLM** |
| ผู้ใช้ได้รับ “ถึงเพดานการใช้งานประจำวัน” | โทเคน 24 ชม. ถึงเพดาน (ปิดอัตโนมัติ) | เพิ่มเพดานที่ตั้งค่า AI หรือรอยอดลดลง แล้วล้างสถานะที่หน้า Unavailable |
| เอกสารใหม่ค้นไม่เจอ | งานนำเข้ายังไม่เสร็จหรือล้มเหลว | ตรวจที่งานนำเข้า แล้วรันซ้ำ / Re-index |
| ปุ่ม Backup/ทำลายข้อมูลแจ้งไม่มีสิทธิ์ | บทบาท ADMIN | ใช้บัญชี SUPER_ADMIN |
| การแจ้งเตือนไม่ถูกส่งเป็นอีเมล | ไม่ได้ตั้ง SMTP | ตั้ง `SMTP_HOST/PORT/USER/PASS`, `ALERT_EMAIL_TO` แล้วกดส่งการแจ้งเตือนทดสอบ |
