คู่มือทดสอบระบบ — SEO-ONLINE
เอกสารฉบับนี้สำหรับลูกค้าและ QA ใช้ตรวจสอบระบบก่อนรับมอบงาน. ครอบคลุม flow หลัก ๆ ของทุก module และเงื่อนไข permission ที่ตกลงไว้.
ผู้ใช้ทดสอบ (Seeded)
| Username | Password | Role |
master | changeme1234 | Master Admin |
staff | changeme1234 | Staff Admin |
> ⚡ ในโหมด dev/staging มีปุ่ม DEV QUICK LOGIN ที่หน้า login — คลิกเพื่อ auto-fill credentials เลย
1. การเข้าสู่ระบบและความปลอดภัย
TC-1.1 Login สำเร็จ
- เปิด URL ของระบบ → redirect ไป
/login
- กรอก
master / changeme1234 → กด "เข้าสู่ระบบ"
- ผล: redirect ไป
/dashboard, เห็น chip ชื่อ + role ที่ก้น Sidebar
TC-1.2 Login ผิด — แสดง error
- กรอก username ถูก, password ผิด → กดเข้าสู่ระบบ
- ผล: ข้อความ "ชื่อผู้ใช้งานหรือรหัสผ่านไม่ถูกต้อง"
TC-1.3 Rate limit ป้องกัน brute-force
- กรอกรหัสผ่านผิดต่อเนื่อง 6 ครั้งภายใน 1 นาที
- ผล: ครั้งที่ 6 แสดง "พยายามเข้าสู่ระบบเกินจำนวนที่กำหนด ลองใหม่ในอีก N นาที"
- รอ 15 นาที → login ได้ตามปกติ
TC-1.4 เปลี่ยนรหัสผ่าน
- Login → คลิก "เปลี่ยนรหัสผ่าน" ที่ก้น Sidebar
- กรอกรหัสปัจจุบัน + รหัสใหม่ (≥ 8 ตัว) → ยืนยัน
- ผล: modal ปิด, logout แล้ว login ด้วยรหัสใหม่ผ่าน
- Modal ลอยอยู่หน้าทุก content (ไม่หลุดข้าง Sidebar)
TC-1.5 Auth gate
- logout → พิมพ์
/dashboard ตรง URL bar
- ผล: redirect ไป
/login?next=/dashboard
2. User Management (Permission Matrix)
TC-2.1 Master เห็นและจัดการ User ทุกคน (ยกเว้น Master คนอื่น)
- Login เป็น
master → ไปหน้า /users
- ผล: หน้าชื่อ "User Management", เห็นรายการผู้ใช้, ปุ่ม edit/delete ของ Master คนอื่น disable
- กดเพิ่ม User ใหม่ → modal "เพิ่มผู้ใช้งานใหม่" → field labels "Username / Password / ประเภทผู้ใช้งาน (Role Status)" → เลือก role ได้ทั้ง Master/Staff
- คลิก edit row ของตัวเอง → field "Role" และ "สถานะ" ถูก disable พร้อม hint สีเหลือง
TC-2.2 Staff จัดการได้แค่ตัวเอง
- Login เป็น
staff → ไปหน้า /users
- ผล: เห็นรายการผู้ใช้ทั้งหมด, ปุ่ม edit/delete ของคนอื่น disable หมด
- เพิ่ม User ใหม่ → role dropdown เห็นแค่ "Staff Admin"
TC-2.3 ป้องกันการล็อกตัวเอง
- Master เปิด edit row ตัวเอง
- ผล: ฟิลด์ Role + Status disable
- ปุ่ม Delete ของ row ตัวเอง disable
TC-2.4 Modal ลบ User
- กดถังขยะที่ row อื่น → modal "ยืนยันการลบ User?"
- ผล: กรอบแดง + title แดง + body "คุณต้องการลบผู้ใช้งาน X ออกจากระบบใช่หรือไม่?"
3. Inventory (ตรวจสอบสินค้า)
TC-3.1 Master นำเข้าสินค้า — Hybrid subtype picker
- Login
master → /inventory
- กรอกฟอร์ม: สาขา ADS, ID|Pass|2FA
- dropdown "เลือกประเภทสินค้า" — เห็น 3 ตัวเลือกพิเศษบนสุด:
- "ไม่ระบุประเภทสินค้า (ให้คนจัดประเภทระบุภายหลัง)"
- "อื่น ๆ (ระบุเอง)"
- (เส้นแบ่ง)
- กลุ่ม subtype ตาม category
- กด search box แล้วพิมพ์ "FB" → filter เหลือเฉพาะ FB
- ลองเลือก "อื่น ๆ (ระบุเอง)" → text field "ระบุประเภทสินค้า" โผล่ขึ้นมา
- กด "เพิ่มเข้าคลังสินค้า" → row ใหม่ขึ้นในตาราง QC
TC-3.2 Staff QC ผ่าน/ไม่ผ่าน (ทำได้)
- Login
staff → /inventory
- ผล: ไม่เห็นฟอร์มนำเข้า, เห็นเฉพาะตาราง QC
- subtitle "ตรวจสอบคุณภาพสินค้า (Check User)"
- กด "ผ่าน" → row หายไป
- กด "ไม่ผ่าน" → modal กรอบแดง → เลือกสาเหตุ → ยืนยัน → row หาย
TC-3.3 Workflow — Pre-categorized vs unspecified
- Pre-categorized: import พร้อม subtype "เฟสผูกบัตร" → QC pass → status = CATEGORIZED ทันที (ข้าม /categorization)
- Unspecified: import ด้วย "ไม่ระบุประเภท" → QC pass → status = QC_PASS → ไปดูที่ /categorization
- อื่น ๆ: import ด้วยข้อความฟรี → QC pass → status = QC_PASS → /categorization
TC-3.4 Pagination
- ถ้ามี row > 10 → เห็น Pagination Bar ด้านล่าง
- กดหน้า 2 → แสดง row 11-20
TC-3.5 ข้อมูลถูก encrypt ใน DB
- นำเข้าสินค้าใหม่ผ่าน UI
- เปิด DB:
docker compose exec db psql -U seo seo_online -c "SELECT \"loginData\" FROM \"Product\" ORDER BY \"createdAt\" DESC LIMIT 1;"
- ผล: ค่าขึ้นต้นด้วย
enc:v1: (ไม่ใช่ plaintext)
4. Sales & Categorization (ประเภทสินค้า)
TC-4.1 จัดประเภทสินค้า
- ไป
/categorization
- ผล: เห็น 3 cards (เฟสบุ๊ค/เพจ/LINE OA) + ตาราง "สินค้าที่ผ่าน QC"
- กด "เลือกประเภท" บน row → modal เปิด → SearchableSelect dropdown
- เลือก subtype → ยืนยัน → row หาย, นับใน category card +1
TC-4.2 คลิก Category card ดูสินค้าทั้งหมดในหมวด
- คลิก card "ประเภทเฟสบุ๊ค"
- ผล: ไปหน้า
/products?cat=FB (filtered by FB)
5. All Products (สินค้าทั้งหมด)
TC-5.1 ดูสินค้าทุกสถานะ
- ไป
/products (จาก Sidebar รายการที่ 2)
- ผล: เห็น 7 tabs ของสถานะ + chips กรองหมวด + chips กรองสาขา
- คลิก "จัดประเภทแล้ว" → filter เหลือ CATEGORIZED
- เพิ่ม "เฟสบุ๊ค" + "ADS" → กรอง 3 ชั้น (URL params:
?status=CATEGORIZED&cat=FB&branch=ADS)
- ดู column "วันที่ QC" + "ผู้สร้าง" — ข้อมูลครบจริงจาก DB
TC-5.2 Pagination
- ถ้ามี > 15 row → เห็น pagination bar
- เลื่อนหน้า → URL ยังคง filter เดิม
6. Product Transfer (โยกสินค้า)
TC-6.1 Master โอนทันที (COMPLETED)
- Login
master → /transfer
- คลิก dropdown "เลือกสินค้า" → เห็น ⓘ tooltip "แสดง 100 รายการล่าสุด..."
- เลือกสินค้า + สาขาปลายทาง + กดบันทึก
- ผล: row ใหม่สถานะ "สำเร็จ" (สีเขียว) ทันที
TC-6.2 Staff ต้องรอ Master อนุมัติ (PENDING)
- Login
staff → /transfer
- สร้างคำขอโยกย้าย
- ผล: row ใหม่สถานะ "รอ Master ยืนยัน" (สีเหลือง)
TC-6.3 Master กดอนุมัติเป็นชุด
- Login
master → มี PENDING รออยู่
- กดปุ่ม "กดรับเฟสทั้งหมดที่แจ้ง"
- ผล: ทุก PENDING เปลี่ยนเป็น COMPLETED, สินค้าย้ายไปสาขาปลายทาง
TC-6.4 Server-side product search
- คลิก dropdown "เลือกสินค้า" — ค่าเริ่มต้น 100 รายการล่าสุด
- พิมพ์ "ADS" (≥ 2 ตัวอักษร) → spinner → ผลจากฐานข้อมูลทั้งหมด
- พิมพ์ "เฟสผูกบัตร" → ผลเฉพาะ subtype นั้น (รวมที่อยู่นอก 100 แรก)
TC-6.5 Searchable problem dropdown
- dropdown "ระบุปัญหา (ถ้ามี)" — search ได้
- พิมพ์ "เข้า" → filter เหลือ "ปัญหา 1: เข้าไม่ได้"
7. Claims & Defective (เคลม/สินค้าเสีย)
TC-7.1 บันทึก claim ลูกค้า
- ไป
/claims → กด "เปิดเคสเคลมลูกค้า"
- ผล: modal กรอบฟ้า (cyan) + icon ฟ้า
- กรอกชื่อลูกค้า + รหัสเฟส + IssueType → ยืนยัน
- row ใหม่ในตาราง, badge "CLAIM" สีฟ้า
TC-7.2 บันทึกสินค้าเสีย
- กด "แจ้งสินค้าเสีย"
- ผล: modal กรอบแดง (danger) + icon แดง
- กรอกรหัสสินค้า + เลือกสาเหตุ → ยืนยัน
- badge "DEFECTIVE" สีแดง
TC-7.3 Refund — cap จาก SystemConfig
- กด "เบิกงบชดเชย (Max ฿X)" — X = ค่าใน SystemConfig
- ผล: modal กรอบเขียว (success) + icon เขียว
- กรอก amountTHB เกิน cap → error "จำนวนเงินเกิน ฿X ต่อรายการ" (server-side block)
- กรอกตามเกณฑ์ → ยืนยัน → stat "งบชดเชยคงเหลือ" ลดลง
TC-7.4 Pagination
- ตารางประวัติ — pagination 10 row/หน้า
8. Reception & Log (รับสินค้า & log) — Master เท่านั้น
TC-8.1 Staff เข้าไม่ได้
- Login
staff → พิมพ์ /reception ตรง URL
- ผล: redirect ไป
/dashboard
TC-8.2 Master ใช้งานได้
- Login
master → /reception
- กด "จัดการข้อมูล ADS" → กรอก ID + หมายเหตุ → ยืนยัน
- ผล: banner สำเร็จ, Activity Log ที่ด้านล่างมี entry ใหม่
reception:ADS
TC-8.3 ค้นหา Activity Log
- พิมพ์ "ADS" ในช่องค้นหา
- ผล: ตารางกรองเฉพาะ row ที่มี "ADS" ใน action/detail
TC-8.4 Pagination
- ถ้ามี > 15 row → pagination bar
9. Settings (ตั้งค่าระบบ) — Master เท่านั้น
TC-9.1 Sidebar visibility
- Login
master → เห็นเมนู "ตั้งค่าระบบ" (icon ฟันเฟือง)
- Login
staff → ไม่เห็น เมนูนี้
TC-9.2 Tab order ตามความปลอดภัย
- เปิด
/settings → เห็น 5 tabs:
- สาขา (default)
- หมวดสินค้า
- ประเภทย่อย
- สาเหตุปัญหา
- ค่าระบบ ⚠ (ท้ายสุด เพราะอันตราย)
TC-9.3 เพิ่มสาขาใหม่
- tab "สาขา" → กรอก Code "TEST" / Name "สาขาทดสอบ" → เพิ่ม
- ผล: row ใหม่ปรากฏ + ใน /inventory dropdown สาขามีตัวเลือกใหม่
TC-9.4 ปิดใช้งานสาขา
- กด "ปิดใช้งาน" บน row "TEST"
- ผล: สถานะ "Inactive", ใน /inventory dropdown ไม่เห็น
TC-9.5 System Config — refund budget + cap
- tab "ค่าระบบ ⚠" → เห็น 2 ฟิลด์ + warning info
- แก้ "งบชดเชยรายวัน" จาก 1000 → 2500
- แก้ "เพดานต่อรายการ" → 800
- กด "บันทึกค่าระบบ"
- ผล: banner เขียว
- ไป /claims → "งบชดเชยคงเหลือ ฿2,500 / 2,500" ทันที (ไม่ต้องรอ cache TTL)
- ปุ่ม "เบิกงบชดเชย (Max ฿800)" — cap ใหม่
- ลอง refund > 800 → server-block
TC-9.6 Validation
- ตั้งเพดาน > งบรายวัน → error "เพดานต่อรายการต้องไม่เกินงบรายวัน"
- ตั้งค่าลบ → error "ต้องเป็นจำนวนบวก"
10. Dashboard
TC-10.1 Master เห็น Super Admin Overview
- Login
master → /dashboard
- ผล: 4 stat cards (Total Stock / Pending QC / Transfer / Defective) + 5 module cards
- Module 1 icon = cubes-stacked (ไม่ว่าง)
- Module 5: "รอรับสินค้าเข้า (ADS/DAJA/KEN)" + "กิจกรรมล่าสุด (Activity Log)"
TC-10.2 Staff เห็น Main Dashboard
- Login
staff → /dashboard
- ผล: 4 stat cards จาก DB จริง:
- "นำเข้าวันนี้" — Product created today
- "ผ่าน QC วันนี้" — Product QC'd today
- "โอนสำเร็จวันนี้" — Transfer completed today
- "สินค้าทั้งหมด (เดือนนี้)" — Product created this month
- Bottom bar: Database Connected, Last Update จาก Activity Log ล่าสุดจริง, Security: User Role Level
TC-10.3 ตัวเลขอัพเดทเมื่อ data เปลี่ยน
- Master เพิ่มสินค้าใน /inventory → /dashboard "สินค้าในระบบทั้งหมด" +1 ทันที (cache invalidate)
- กด QC ผ่าน → "นำเข้าวันนี้" / "ผ่าน QC วันนี้" อัพ
11. Sidebar — Active state + Sticky
TC-11.1 Active state
- คลิกเมนูใด ๆ → border + bg ของเมนูนั้นค้างเป็นสี cyan
- ดู URL — ตรง
TC-11.2 Sticky scroll
- ไปหน้าที่ content ยาว (เช่น /products มี 40 rows)
- scroll down → sidebar + user chip + ปุ่มเปลี่ยนรหัส + ออกจากระบบ ค้างที่ viewport เสมอ
12. Cache Invalidation (Data freshness)
TC-12.1 Rename Subtype → กระทบทุก list
- Master → /settings → tab "ประเภทย่อย" → แก้ชื่อ subtype X เป็น "X-V2"
- ไป /inventory → ตาราง column "ประเภท" แสดง "X-V2" ทันที (ไม่รอ TTL)
- ไป /products → ตารางก็ใช้ชื่อใหม่
TC-12.2 Toggle Branch → กระทบ dropdown
- /settings → tab "สาขา" → กด "ปิดใช้งาน" สาขา KEN
- /inventory → dropdown สาขาไม่มี KEN
- /products → chip กรองสาขา ไม่มี KEN
TC-12.3 Rename Username → กระทบ activity log + transfer list
- /users → แก้ username "staff" → "staff_renamed"
- /transfer → column "ผู้ส่งรายการ" แสดงชื่อใหม่
- /reception → Activity Log column "ผู้ดำเนินการ" แสดงชื่อใหม่
TC-12.4 Update System Config → กระทบ /claims + /dashboard
- /settings → tab "ค่าระบบ ⚠" → เปลี่ยน budget เป็น 3000
- /claims → stat "งบชดเชยคงเหลือ ฿3,000 / 3,000" ทันที
- /dashboard (master) → Module 3 "งบชดเชยคงเหลือ ฿3,000.00"
13. ความปลอดภัย (ดู OWASP_REVIEW.md)
| OWASP | Status |
| A01 Broken Access Control | ✓ |
| A02 Cryptographic Failures | ✓ |
| A03 Injection | ✓ |
| A04 Insecure Design | ✓ |
| A05 Security Misconfiguration | ✓ |
เกณฑ์ผ่าน
ระบบจะถือว่า ผ่านการรับมอบ เมื่อ:
- TC-1.x ถึง TC-12.x ทั้งหมด pass
- Unit tests ผ่านครบ (
npm run test)
- Load test 100 req/sec ผ่านที่ p(95) < 500ms (
npm run test:load)
- OWASP Top 5 mitigated ครบ
- ไม่มี data leak ใน plain text ที่ DB (TC-3.5 ผ่าน)
หากพบปัญหา รายงานเข้า issue tracker พร้อม screenshot + ขั้นตอน reproduce