มาตรฐานคุณภาพเว็บและขอบเขต commerce สำหรับหลักสูตร
สืบค้นและตรวจสอบเมื่อ 9 กันยายน 2026 — เอกสารนี้เป็นฐานอ้างอิงของบทเรียน 04–07 ไม่ใช่ข้อกำหนดกฎหมายหรือคำแนะนำ PCI DSS
เป้าหมายคุณภาพร่วมกัน
ตัวอย่างทั้งสามใช้รูปแบบเดียวกัน: static UI อยู่ที่ /examples/company/, /examples/rental/, และ /examples/store/; Cloudflare Worker รับเฉพาะ /api/*; D1 เก็บข้อมูลที่ผ่านการตรวจสอบแล้ว; ไฟล์อื่นส่งต่อไป static assets. การ deploy แบบ Worker Static Assets ทำให้ asset และ Worker ถูก deploy เป็นหน่วยเดียว และ Worker เรียก env.ASSETS.fetch(request) เพื่อคืนไฟล์ได้ (Cloudflare Static Assets). ตั้ง run_worker_first: ["/api/*"] เพื่อให้ API เข้าสู่ Worker ก่อน asset ตามตัวอย่าง binding ของ Cloudflare (Configuration and Bindings).
ทุก lab ต้องยอมรับเกณฑ์ต่อไปนี้ก่อนส่งขึ้น production:
| ด้าน | เกณฑ์ที่ตรวจได้ | วิธีตรวจในบทเรียน |
|---|---|---|
| การเข้าถึง | ใช้คีย์บอร์ดได้, focus มองเห็น, label/error ของ form ชัด, alt ที่มีความหมาย | Tab/Shift+Tab, เปิด DevTools accessibility tree, ทดลอง reader-friendly copy |
| pointer | เป้าหมายสัมผัสอย่างน้อย 24×24 CSS px หรือมีข้อยกเว้นตาม WCAG | ตรวจ computed box ของปุ่ม/ไอคอน |
| motion | ใช้ prefers-reduced-motion; motion ที่ไม่จำเป็นหยุด/ลดได้ |
เปิด Reduce Motion ของ OS แล้ว reload |
| ความเร็ว | field data ที่ p75: LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1 | PageSpeed Insights/CrUX เมื่อมี traffic และ Lighthouse เป็น lab signal |
| server | ตรวจ schema, authorization และ business rule ที่ Worker; bind parameter ทุก SQL | curl payload ผิดรูปและทดสอบ duplicate/conflict |
| commerce | เบราว์เซอร์ไม่เป็นผู้ตัดสินราคา, stock, หรือ payment สำเร็จ | Worker คำนวณ demo quote ใหม่; เปลี่ยนราคาใน DevTools แล้วส่งซ้ำ |
WCAG 2.2 เป็น W3C Recommendation ตั้งแต่ 5 ตุลาคม 2023; เกณฑ์ใหม่ระดับ AA ที่เกี่ยวข้องโดยตรงคือ Target Size (Minimum) และ Dragging Movements (W3C: WCAG 2.2, What’s new). การลากจึงต้องมีปุ่ม/stepper หรือ field เป็นทางเลือก ไม่ใช่บังคับลากอย่างเดียว.
Core Web Vitals ใช้ข้อมูลผู้ใช้จริงที่ percentile 75 แยก mobile/desktop. LCP วัดเวลาจน image/text block ที่ใหญ่สุดใน viewport render และเกณฑ์ดีคือ ≤2.5 s; INP วัด responsiveness ของ interaction ตลอด visit และเกณฑ์ดี ≤200 ms; CLS วัดการเลื่อนของ layout และเกณฑ์ดี ≤0.1 (LCP, INP, CLS). FCP และ TTFB เป็น diagnostic metrics จึงอย่าเรียกว่า Core Web Vitals.
วิธีใช้ AI/vibe coding โดยไม่ยกความรับผิดชอบให้ AI
Vibe coding มีประโยชน์เมื่อแบ่งงานให้ AI เป็นชิ้นที่ตรวจได้: ให้ออกแบบหน้าเดียว, เขียน test case, อธิบาย diff, หรือปรับ error state. ห้ามยอมรับโค้ดเพียงเพราะหน้าตาสวย. ผู้เรียนต้องระบุ acceptance criteria, อ่าน diff, run test, ทดสอบ form/keyboard/mobile และตรวจ secret ก่อน merge ทุกครั้ง. Prompt ที่ดีระบุ ผู้ใช้และเป้าหมาย, ขอบเขตไฟล์, state/data contract, ข้อห้าม, acceptance checks.
วงจรการทำงานในหลักสูตร:
- เขียน brief และ UI states (loading, empty, error, success) ก่อนสร้าง code.
- ขอ AI ให้เสนอแผนและรายชื่อไฟล์; ตัดงานให้เหลือหนึ่ง vertical slice.
- ให้ AI สร้าง แล้วอ่าน diff เพื่อหา hard-coded secret, client-trusted price, invalid HTML และ dependency ที่ไม่ได้ขอ.
- รัน build/typecheck/test และ manual checklist; ให้ AI แก้จาก output จริงเท่านั้น.
- Deploy preview ก่อน production และทดสอบ URL จริง,
/api/*, headers และ form error.
ความปลอดภัยและข้อมูล
รับ input จาก URL, form, cookie และ API เป็น untrusted เสมอ. OWASP แนะนำให้ validate ตั้งแต่ต้นทางทั้ง syntactic (รูปแบบ date/email/enum) และ semantic (วันเริ่มก่อนวันจบ, จำนวนไม่เกิน stock, price อยู่ใน product catalog) (Input Validation Cheat Sheet). Validation ไม่ได้แทนการป้องกัน SQL injection: D1 query ต้องใช้ prepared statement และ .bind(...); OWASP ให้ parameterized query เป็นการป้องกันหลัก เพราะแยก SQL code ออกจาก data (SQL Injection Prevention Cheat Sheet, D1 Worker Binding API).
อย่าส่ง API secret, D1 credential, webhook secret หรือ private customer data ไป browser, git หรือ prompt. ใช้ Worker secret/environment binding และ log เฉพาะ request id กับ error category. สำหรับ form รับ inquiry ให้ rate limit/anti-abuse ตามบริบทก่อนเปิดรับ traffic จริง และตอบข้อความเดียวกันสำหรับกรณีที่ไม่ควรเปิดเผยข้อมูล.
ขอบเขต demo และ payment ที่ปลอดภัย
สิ่งที่ current demo ทำจริง: wrangler.jsonc ตั้ง DEMO_MODE=true. POST /api/contact, /api/rentals และ /api/quotes ตรวจ input, Same-Origin, honeypot และ idempotency แล้วเขียน local D1 โดย redacts name/email/message ก่อน persist. Rental อ่าน equipment/price/stock จาก D1, สร้าง reserved-demo และใช้ rental_days trigger เพื่อนับ capacity; quote อ่าน product price จาก D1, สร้าง quote-demo และ quote_items. เมื่อ D1 binding พร้อม /api/catalog คืน catalog จาก D1 และต้องตอบข้อผิดพลาดเมื่อ binding ไม่มี. ใช้ข้อมูลสมมติเท่านั้น; demo ไม่มี payment, authentication, notification หรือ commercial fulfilment.
เปิดแผนภาพ quote authority แบบเต็มหน้า เพื่อใช้ trace trust boundary ก่อนอ่านรายละเอียด payment extension ด้านล่าง
Cart อยู่ใน browser เพื่อ UX แต่ Worker รับ productId และ quantity แล้วอ่าน product price จาก D1 เพื่อคำนวณ totalPrice integer satang และ snapshot unit_price ลง D1. หน้า “สร้างใบเสนอราคาสาธิตแล้ว” ไม่ใช่ใบเสนอราคา, order, payment หรือ stock commitment ทางธุรกิจ. ห้ามเก็บเลขบัตร/CVC หรือประกาศว่า checkout ใช้งานจริงจนกว่าจะออกแบบและเปิดใช้ provider เป็นงานใหม่.
เมื่อเลือกทำ production ภายหลัง: ออกแบบ source of truth ของ catalog, state quote/order/hold/cancel, staff authorization, privacy/retention, tax/stock และ fulfillment ก่อนนำแนวคิดไปใช้. สิ่งเหล่านี้เป็น conceptual extension ไม่ใช่ requirement ของ lab ปัจจุบัน.
ถ้าต่อ Stripe ภายหลัง ให้ Worker สร้าง Checkout Session บน server และส่ง URL กลับ browser; Checkout Sessions จัดการ state ของ checkout และมี Stripe-hosted/embedded UI (Checkout Sessions, prebuilt Checkout). success_url เป็นเพียง navigation ของลูกค้า ไม่ใช่หลักฐาน fulfillment. Worker webhook ต้อง verify raw event payload, Stripe-Signature และ endpoint secret ก่อนเปลี่ยนสถานะ order; Stripe ระบุสามค่านี้เป็นส่วนของการตรวจสอบ (Receive Stripe events). ฝั่ง server ควร map internal order id ผ่าน metadata และทำ fulfillment แบบ idempotent จาก verified event.
Source inventory
Official platform and payment docs
- Cloudflare Workers Static Assets — routing, asset binding และ caching; ตรวจวันที่ 2026-09-09.
- Cloudflare Assets configuration and bindings —
run_worker_firstสำหรับ/api/*; ตรวจวันที่ 2026-09-09. - Cloudflare D1 Worker Binding API — prepare/bind/run flow; ตรวจวันที่ 2026-09-09.
- Stripe Checkout Sessions API และ Webhook verification — boundary ระหว่าง browser/server/payment event; ตรวจวันที่ 2026-09-09.
Web quality and accessibility
- W3C WCAG 2.2 และ WAI WCAG overview — standard และ quick reference.
- web.dev LCP, INP, CLS — current metric definitions/thresholds, last updated 2025.
- MDN
prefers-reduced-motion— widely available since January 2020 and its accessibility purpose.
Security
- OWASP Input Validation and OWASP SQL Injection Prevention — validation and SQL defenses.
Motion documentation
- GSAP
context(), GSAPmatchMedia(), ScrollTrigger andScrollTrigger.refresh()— behavior verified against current v3 documentation on 2026-09-09.