เฟสที่สองของ Premium — รับ JSON ที่ normalize จากเฟส 1 → ผ่าน data-quality gate (กันยอดติดลบ/SKU ซ้ำ) → idempotent UPSERT เข้า warehouse. โฟกัสเฉพาะ load — ยังไม่ deploy cloud (เฟส 3)
เฟสนี้คือชั้นเก็บข้อมูลให้ถูกและเชื่อถือได้ — ส่งต่อ deploy ในเฟสหน้า
natural key เปิดทาง idempotent · views ป้อน Looker โดยตรง
ข้อมูลพังถูกกันออกก่อนเข้าคลัง · รันซ้ำ window เดิมแถวไม่เบิ้ล
พิสูจน์ได้ด้วย python load_demo.py (รันด้วย sqlite ตรรกะเดียวกับ Postgres)
output จริงจากการรัน load_demo.py
| platform | orders | revenue |
|---|---|---|
| shopee | 1 | ฿1,380 |
| lazada | 1 | ฿1,890 |
| tiktok | 1 | ฿870 |
| shopify | 1 | ฿720 |
| line | 1 | ฿1,850 |
9 กรณีผ่านครบ
| # | กรณีทดสอบ | ผลที่คาดหวัง | ผล |
|---|---|---|---|
| 1 | quality: ยอดติดลบ | reject + เหตุผล "negative total_amount" | ✅ ผ่าน |
| 2 | idempotency (รันซ้ำ) | แถวเท่าเดิม 5→5 ไม่เบิ้ล | ✅ ผ่าน |
| 3 | UPSERT update คีย์เดิม | อัปเดตค่า ไม่สร้างแถวใหม่ | ✅ ผ่าน |
| 4 | dup natural key ใน batch | reject กันซ้ำ | ✅ ผ่าน |
| 5 | missing sku | reject | ✅ ผ่าน |
| 6 | negative stock | reject | ✅ ผ่าน |
| 7 | aggregation รายแพลตฟอร์ม | revenue/orders ถูกต้อง | ✅ ผ่าน |
| 8 | โหลดข้อมูลสะอาด | 5/6 orders + 5 inventory เข้าคลัง | ✅ ผ่าน |
| 9 | import โดยไม่มี deps | lazy import + sqlite stdlib | ✅ ผ่าน |
โฟลเดอร์ premium-delivery/phase2/
ระบบ ingestion + warehouse พร้อมแล้ว — เฟส 3 จะแพ็กเป็น Docker ขึ้น Cloud Run + ตั้ง Cloud Scheduler ให้รันเองทุก 4 ชม. + เก็บ secret ใน Secret Manager + provision Cloud SQL จริง