SLIDE 01 · COURSE 1145 204 · WEEK 10
Sprint Integration Milestone
System Integration & API Alignment
สำหรับแพลตฟอร์ม Grocery POS
จุดเปลี่ยนสำคัญของโครงงานชั้นปีที่ 2 จากโมดูลที่แยกกันทำงาน (UI, API, Database) สู่ระบบขายหน้าร้านที่เชื่อมต่อกันอย่างสมบูรณ์ เที่ยงตรงด้านข้อมูล และรับมือความผิดพลาดหน้างานได้จริง
01 · FULL-STACK
FE + BE + DB
เชื่อมต่อหน้าจอแคชเชียร์ API และฐานข้อมูล 3NF ไร้รอยต่อ
02 · CONTRACT
API Schema
ตกลงรูปแบบ JSON, ชื่อฟิลด์ และ HTTP Status ให้ตรงกัน
03 · STATE & ACID
FSM + Lock
คุมสถานะหน้าจอ ป้องกันกดจ่ายซ้ำ และกันสต็อกติดลบ
04 · RESILIENCE
Error Flow
ระบบล้มเหลวอย่างปลอดภัย ตะกร้าไม่หาย ข้อมูลไม่พัง
ทำไมสัปดาห์ที่ 10 จึงเป็นจุดชี้วัดความสำเร็จของทีม?
ใน Sprint 1–2 นักศึกษามักแบ่งงานกันทำ: ทีมหน้าบ้าน (Frontend) ใช้ข้อมูลจำลอง (Mock JSON), ทีมหลังบ้าน (Backend) เขียน Endpoint ตามความเข้าใจ, และฐานข้อมูล (Database) ถูกออกแบบแยกไว้ เมื่อนำมารวมกันจึงมักเกิดอาการ Integration Hell เช่น ชื่อฟิลด์ไม่ตรงกัน คำนวณราคารวมเพี้ยน หรือสต็อกถูกตัดซ้ำซ้อน
AGILE SPRINT ALIGNMENT (1145 204)
Sprint 1: Database Schema (3NF) & User Authentication
Sprint 2: POS Order Screen & Barcode Lookup
Sprint 3 (Week 10+): Full Integration, Stock Alert & Error Handling
SLIDE 02 · FULL-STACK ARCHITECTURE
3-Tier Separation of Concerns
สถาปัตยกรรม 3 ชั้น แยกหน้าที่ชัดเจน ไม่ผูกติดกัน
คลิกเลือกแต่ละขั้นตอนด้านล่างเพื่อดูว่าคำสั่งจากเครื่องแคชเชียร์ (Frontend) เดินทางผ่าน Business Layer (Backend) ไปยังฐานข้อมูล (Database) และย้อนกลับมาแสดงผลอย่างไร
STEP 01 · FRONTEND PRESENTATION
Frontend (HTML/CSS/JS): รับอินพุตและจัดการ UI State
หน้าจอ POS มีหน้าที่สแกนบาร์โค้ด จัดการรายการในตะกร้า และแสดงผลสถานะให้รวดเร็ว ห้ามเก็บ Logic การคำนวณภาษี/ส่วนลดสุทธิเป็นความจริงเด็ดขาด และห้ามเชื่อมต่อ SQL โดยตรง
กฎเหล็กสถาปัตยกรรม: ส่งเฉพาะ product_id และ quantity ไปให้ Backend เป็นผู้คำนวณยอดเงินจากราคาจริงในฐานข้อมูลเสมอ
LIVE LAYER PAYLOAD / BOUNDARY
SLIDE 03 · DATABASE SCHEMA ALIGNMENT
MySQL / PostgreSQL (3NF)
โครงสร้างฐานข้อมูลเชิงสัมพันธ์ (3NF) ของระบบ Grocery POS
ฐานข้อมูลที่ดีต้องป้องกันข้อมูลขยะตั้งแต่ระดับ Schema (Constraints) ไม่ใช่รอเช็กแค่ฝั่งหน้าจอ
| ตาราง (Table) |
คอลัมน์หลัก (Key Columns) |
การเชื่อมโยงกับ POS Flow |
Constraint ที่ต้องมี |
| Users |
user_id, username, password_hash, role_enum |
ระบุตัวตนแคชเชียร์ (Cashier / Manager) เพื่อบันทึกผู้เปิดบิล |
UNIQUE(username) |
| Categories |
category_id, category_name |
จัดกลุ่มสินค้า (เครื่องดื่ม, อาหารแห้ง, ของสด, ของใช้) บนปุ่มลัด |
NOT NULL |
| Products |
product_id, barcode, category_id, name, price |
แหล่งความจริงเดียว (Single Source of Truth) ของราคาขายต่อหน่วย |
UNIQUE(barcode), CHECK(price >= 0) |
| Inventory |
inventory_id, product_id, stock_quantity, unit, reorder_level |
ตัดสต็อกอัตโนมัติและเช็กเกณฑ์แจ้งเตือนใกล้หมด (Reorder Alert) |
CHECK(stock_quantity >= 0) |
| Orders |
order_id, user_id, order_datetime, total_amount, payment_method, status |
เก็บหัวบิล ยอดสุทธิ ช่องทางชำระ (PromptPay/Cash/Card) และสถานะ |
FK(user_id), ENUM status |
| Order_Items |
order_item_id, order_id, product_id, quantity, unit_price, subtotal |
บันทึกรายการสินค้าและ Snapshot ราคา ณ วันที่ขาย |
CHECK(quantity > 0) |
ทำไม Order_Items ต้องเก็บ unit_price ซ้ำอีกครั้ง?
หากเดือนหน้าปรับราคาสินค้าในตาราง Products ยอดขายย้อนหลังในใบเสร็จเก่าต้องไม่เปลี่ยนตาม การ Snapshot ราคาไว้ใน Order_Items คือมาตรฐานระบบ POS ที่ถูกต้อง
Abstraction Layer (Table Data Gateway):
เขียนโค้ด SQL ไว้ในชั้น Repository / Gateway เท่านั้น ห้ามเขียน SQL ปนใน Route Handler หรือ Controller เพื่อให้ทดสอบ Logic ได้โดยไม่ต้องต่อ DB จริงทุกครั้ง
SLIDE 04 · API CONTRACT ALIGNMENT
Contract-First Development
API Alignment: สัญญาระหว่างหน้าบ้านกับหลังบ้านต้องตรงกัน 100%
สลับดูความแตกต่างระหว่าง API ที่ต่างคนต่างเขียน (Unaligned) กับ API ที่ทำ Contract ร่วมกันก่อนลงมือเชื่อมต่อ (Aligned)
REQUEST · POST /api/v1/orders
จุดที่ต้องตกลงร่วมกันใน API Spec ก่อนเริ่มเชื่อมต่อ:
1) รูปแบบชื่อคีย์ (camelCase หรือ snake_case ต้องเหมือนกันทั้งระบบ) · 2) รูปแบบวันเวลา (ISO-8601 UTC) · 3) ชนิดข้อมูลของราคา (Number/Decimal ไม่ใช่ String) · 4) รูปแบบ Error Envelope เดียวกันทุก Endpoint
SLIDE 05 · LIVE INTEGRATION SANDBOX
Interactive POS Flow
ทดลองเชื่อมต่อจริง: ตะกร้าสินค้า → API Payload → SQL Transaction
เพิ่มสินค้าในตะกร้าและกด ส่งคำสั่งซื้อ (Checkout) เพื่อดู Request JSON, การทำงานของ SQL Transaction และ Response ที่ระบบส่งกลับมาแบบเรียลไทม์
แคตตาล็อกสินค้า Grocery POS
| สินค้า (SKU) |
ราคา (฿) |
คงเหลือ |
เพิ่มลงตะกร้า |
สถานะตะกร้าสินค้า
เลือกสินค้าอย่างน้อย 1 รายการเพื่อจำลองการ Checkout
1. FRONTEND REQUEST JSON (CLIENT → SERVER)
2. BACKEND DB TRANSACTION TRACE
3. SERVER RESPONSE
SLIDE 06 · CONCURRENCY & ACID TRANSACTIONS
Risk Mitigation (1145 204)
ป้องกัน Race Condition: เมื่อ 2 แคชเชียร์ขายสินค้าชิ้นสุดท้ายพร้อมกัน
โจทย์ความเสี่ยงหลักของระบบ POS คือการตัดสต็อกขนานกันหลายจุด กดจำลองสถานการณ์ด้านล่างเมื่อสต็อกคงเหลือ 2 ชิ้น แต่แคชเชียร์ A ต้องการ 2 ชิ้น และแคชเชียร์ B ต้องการ 1 ชิ้นในเวลาเดียวกัน
| เวลา |
แคชเชียร์ A (สั่ง 2 ชิ้น) |
แคชเชียร์ B (สั่ง 1 ชิ้น) |
สต็อกใน DB |
ผลลัพธ์: สต็อกติดลบและข้อมูลคลาดเคลื่อน (-1 ชิ้น!)
ทั้งสองเครื่องอ่านค่าสต็อกได้ 2 ชิ้นพร้อมกัน แล้วคำนวณในหน่วยความจำแยกกัน ส่งผลให้ขายเกินสต็อกจริง
SLIDE 07 · FRONTEND STATE & FSM
Prevent Double-Submit
State Management: คุมวงจรหน้าจอ POS ด้วย Finite State Machine
การสร้างตัวแปร boolean กระจัดกระจาย (isLoading, isPaid, hasError) ทำให้ปุ่มค้างหรือเผลอกดตัดเงินซ้ำได้ ใช้ State Machine เพื่อบังคับเฉพาะการเปลี่ยนสถานะที่ถูกต้อง
STATE 1
IDLE
ตะกร้าว่าง พร้อมสแกน
STATE 2
CART_READY
มีสินค้า แก้ไข/กดจ่ายได้
STATE 3
SUBMITTING
ล็อกปุ่มจ่าย รอ API
STATE 4
PAID_RECEIPT
สำเร็จ พิมพ์ใบเสร็จ
STATE 5
ERROR_RETRY
ล้มเหลว คงตะกร้าไว้
จำลองการส่ง Event ให้ State Machine
สถานะปัจจุบันและการป้องกัน UI
สถานะเริ่มต้น IDLE: ปุ่มชำระเงินถูกปิด (Disabled) จนกว่าจะสแกนสินค้า
แยกประเภท State ให้ชัดเจน
1. Server State (มาจาก Backend): รายการสินค้า, ราคา, ยอดคงเหลือล่าสุด — ต้อง Re-fetch หรืออัปเดตหลัง Checkout เสมอ
2. Client UI State (อยู่ในเบราว์เซอร์): ตะกร้าสินค้าชั่วคราว, ช่องทางชำระเงินที่เลือก, สถานะ Modal/Loading
3. Idempotency Key: สร้าง UUID ประจำออเดอร์ตั้งแต่ตอนเข้า SUBMITTING เพื่อกันการสร้างบิลซ้ำหากแคชเชียร์กด Retry
SLIDE 08 · ROBUST ERROR HANDLING
HTTP Status & Error Envelope
Error Handling ที่ดี: ไม่เงียบ ไม่พังทั้งระบบ และบอกทางออกชัดเจน
ห้ามส่ง HTTP 200 OK พร้อมข้อความ {"error": "fail"} และห้ามปล่อยให้แคชเชียร์เห็นข้อความดิบของฐานข้อมูล (SQL Stack Trace)
| HTTP Status |
ความหมายทางธุรกิจ (Grocery POS) |
การจัดการฝั่ง Backend |
การตอบสนองฝั่ง Frontend |
| 201 Created |
สร้างบิลและตัดสต็อกสำเร็จสมบูรณ์ |
COMMIT และส่งข้อมูลใบเสร็จกลับ |
ล้างตะกร้า แสดงใบเสร็จ + แจ้งเตือนหากมีสินค้าใกล้หมด |
| 400 Bad Request |
จำนวนสินค้าติดลบ หรือ Payload ผิดรูปแบบ |
Schema Validation ปฏิเสธก่อนแตะ DB |
ชี้ช่องที่ผิด (Inline Error) ให้แก้ไขทันที |
| 401 / 403 |
เซสชันหมดอายุ หรือแคชเชียร์ไม่มีสิทธิ์แก้ไขราคา |
Middleware ตรวจ JWT & Role |
เก็บตะกร้าไว้ชั่วคราว เปิดหน้า Login ซ้ำโดยข้อมูลไม่หาย |
| 404 Not Found |
สแกนบาร์โค้ดแล้วไม่พบสินค้าในฐานข้อมูล |
คืน Error Code PRODUCT_NOT_FOUND |
ส่งเสียงเตือนสั้นๆ เปิดช่องค้นหาชื่อสินค้าด้วยมือ |
| 409 Conflict |
สินค้าในสต็อกเหลือไม่พอตามจำนวนที่สั่ง |
ROLLBACK คืนค่า available_qty |
แจ้งจำนวนที่เหลือจริง ปุ่มปรับลดจำนวนใน 1 คลิก |
| 500 / 503 |
ฐานข้อมูลล่ม หรือ Payment Gateway Timeout |
บันทึก Log ภายใน ปิดบัง Stack Trace |
แสดงปุ่ม "ลองส่งใหม่" (ใช้ Idempotency Key เดิม) |
มาตรฐาน Standard Error Envelope:
{ "success": false, "error": { "code": "INSUFFICIENT_STOCK", "message": "สินค้าเหลือไม่พอ", "details": { "available": 1, "requested": 3 }, "retryable": false } }
SLIDE 09 · FAILURE RECOVERY LAB
Resilient POS UX
ห้องทดลองสถานการณ์วิกฤต: เลือกเหตุการณ์เพื่อดูวิธีรับมือที่ถูกต้อง
ในร้านขายของชำที่มีลูกค้าต่อแถว การจัดการข้อผิดพลาดต้องคำนึงถึงทั้งความถูกต้องของข้อมูลและประสบการณ์การทำงานของแคชเชียร์
1. สินค้าหมดระหว่างรอจ่ายเงิน (409 Conflict)
HTTP 409 · INSUFFICIENT_STOCK
สิ่งที่พังหากไม่ป้องกัน
Backend ยอมให้ตัดสต็อกจนติดลบ หรือส่ง 500 ทำให้หน้าจอค้างและตะกร้า 15 รายการหายหมด
ทางออกที่ถูกต้อง (BE + FE)
DB Rollback ทันที และส่งจำนวนคงเหลือจริงกลับมา หน้าจอไฮไลต์เฉพาะรายการที่มีปัญหาให้แคชเชียร์ปรับจำนวน
SLIDE 10 · INTEGRATION TESTING & CI
Verification Before Demo
ทดสอบการเชื่อมต่อ อย่าเชื่อคำว่า "เครื่องผมรันผ่านแล้ว"
Continuous Integration ที่แท้จริงคือการทดสอบเส้นทางจาก UI ผ่าน API ลง Database ให้ทำงานร่วมกันได้สม่ำเสมอทุกครั้งที่แก้โค้ด
TESTING PYRAMID FOR 1145 204
3 ระดับการทดสอบก่อนส่งงาน
1. Unit Test (ใช้ In-Memory Gateway): ทดสอบฟังก์ชันคำนวณส่วนลด/ภาษี และกฎตัดสต็อกให้รวดเร็วโดยไม่ต้องรอ DB จริง
2. API Integration Test: ยิง HTTP Request จริงเข้า Endpoint แล้วตรวจทั้ง Status Code, JSON Schema และการเปลี่ยนค่าในตาราง Orders / Inventory
3. E2E Smoke Test (หน้างาน): สแกนสินค้า → กดจ่าย PromptPay → สต็อกลดลง → แจ้งเตือน Reorder ทำงานเมื่อสต็อกต่ำกว่าเกณฑ์
COMMON INTEGRATION PITFALLS
4 จุดตายตอนรวมโค้ดหน้าบ้าน-หลังบ้าน
CORS Blocked: หน้าบ้านรันพอร์ต 5173 แต่หลังบ้านพอร์ต 3000 แล้วลืมตั้งค่า Access-Control-Allow-Origin
Hardcoded localhost URL: ฝัง URL ตายตัวในโค้ด JS แทนการใช้ Environment Variable (.env)
Silent Catch Block: เขียน catch (err) { console.log(err) } โดยไม่แจ้งเตือนผู้ใช้
Time Zone Mismatch: เวลาหน้าจอไทย (+07:00) ไม่ตรงกับเวลาเซิร์ฟเวอร์ (UTC) ทำให้สรุปยอดขายรายวันผิดวัน
เคล็ดลับ Clean Code: ตั้งไฟล์กลางเพียงจุดเดียวฝั่ง Frontend (เช่น apiClient.js) สำหรับแนบ Authorization Header, แปลง JSON และดักจับ HTTP 401/500 แบบรวมศูนย์ ไม่ต้องเขียน fetch() ซ้ำซ้อนทุกหน้า
SLIDE 11 · EVALUATION RUBRIC & READINESS
25 Points Integration Criteria
เกณฑ์ประเมินการเชื่อมต่อระบบ & แบบประเมินความพร้อมของทีม
อ้างอิงเกณฑ์ให้คะแนนการบูรณาการระบบ (25 คะแนน) ของรายวิชา และติ๊กเช็กลิสต์เพื่อประเมินสถานะโครงงานของกลุ่มคุณ (บันทึกสถานะให้อัตโนมัติ)
TEAM INTEGRATION CHECKLIST (8 MILESTONES)
สถานะความพร้อมของกลุ่ม
0 / 8
ปรับปรุง (0–13 คะแนน)
เริ่มตรวจเช็กจาก API Contract และ DB Transaction ก่อน
| ระดับคะแนน |
เกณฑ์การพิจารณา (1145 204) |
| ดีเยี่ยม (22–25) |
เชื่อมต่อ FE–BE–DB สมบูรณ์ API Contracts ชัดเจน Error Handling ครบถ้วน และโค้ดตามมาตรฐาน Clean Code |
| ดี (18–21) |
เชื่อมต่อทำงานตามฟังก์ชันหลักได้ API specs ถูกต้อง มีระบบจัดการข้อผิดพลาดพื้นฐาน |
| พอใช้ (14–17) |
ยังพบ Bugs ในบางกรณี Error Handling ไม่ครอบคลุม หรือโครงสร้างโค้ดยังซับซ้อน |
| ปรับปรุง (0–13) |
ไม่สามารถเชื่อมต่อ FE และ BE ให้ทำงานร่วมกันได้ หรือเกิด Error รุนแรงระหว่างทำงาน |
SLIDE 12 · WRAP-UP & ACTION PLAN
Interactive Check
ทบทวนความเข้าใจ & สิ่งที่ต้องส่งมอบในสัปดาห์ถัดไป
ตอบคำถามสถานการณ์สั้น 3 ข้อเพื่อตรวจสอบความเข้าใจ ก่อนนำทีมไปปฏิบัติจริงใน Sprint ปิดงาน
NEXT STEPS · WEEK 10 → WEEK 11
แผนปฏิบัติการ 4 ขั้นตอนหลังจบคาบ
1. Freeze API Contract: ตกลง JSON Request/Response ของทุก Endpoint ในเอกสาร/Swagger ให้จบภายในสัปดาห์นี้
2. Implement Atomic Checkout: ใช้ DB Transaction + เช็กสต็อกระดับ SQL ใน POST /api/v1/orders
3. Wire Central Error Handler: ทำให้ทุกหน้าจอรับ Error Envelope และคงตะกร้าสินค้าไว้เมื่อเกิดความผิดพลาด
4. Record Demo & Test Cases: ทดสอบกรณี Normal Flow + Out-of-Stock + Network Error เพื่อเตรียมประเมิน
ผลคะแนนแบบทดสอบ
ตอบคำถามทั้ง 3 ข้อเพื่อดูสรุปผล