1145 204 · WEEK 10 · GROCERY POS PLATFORM

System Integration & API Alignment

01 / 12
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

          
RESPONSE · 201 CREATED

          
จุดที่ต้องตกลงร่วมกันใน 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 ข้อเพื่อดูสรุปผล