ผู้สอน: Assessment, เฉลย และ rubric capstone
วิธีใช้ assessment
ข้อ 1–12 เป็นคลัง assessment เต็ม สำหรับ workshop 2 วัน ให้ผู้สอนเลือก 4 ข้อ ทำ diagnostic 10–15 นาทีต้นวัน 1 และเลือก 4 ข้อคู่ขนานทำ posttest 10 นาทีท้ายวัน 2 โดยสลับชื่อธุรกิจ/ตัวเลข/route ที่ไม่เปลี่ยน principle. หากใช้ครบ 12 ข้อเป็นงานศึกษาต่อ ให้เวลา 20–25 นาที, ไม่เปิดเอกสาร, 1 คะแนนต่อคำตอบหลัก + 1 คะแนนสำหรับเหตุผล/หลักฐาน (24 คะแนน). เป้าหมายไม่ใช่ท่อง Cloudflare แต่ตัดสินใจได้ว่าควรหยุด, ตรวจ, หรือทำต่ออย่างไร.
ข้อสอบสถานการณ์ (พร้อมเฉลยและเหตุผล)
Prompt: ผู้เรียนพิมพ์ “ทำเว็บให้เช่ากล้องสวย ๆ พร้อมจ่ายเงินวันนี้” โดยไม่มีราคา/เงื่อนไข/ผู้อนุมัติ. คำตอบแรกของ agent ควรเป็นอะไร?
เฉลย: ให้ agent ทำ plan-only และถาม/บันทึก facts ที่ขาด: audience, content owner, pricing source, payment scope, form destination, acceptance criteria; ใช้
[TODO]แทนการแต่งข้อมูล. เหตุผล: ราคาและ payment เป็น business/security decisions; UI ที่ดูดีไม่พิสูจน์ความจริงหรือความพร้อม production.Context: กติกา
npm run build, “ห้ามส่ง secret”, และ “deploy preview only” ถูกใช้ทุก task. ควรเก็บที่ใด?เฉลย:
AGENTS.mdของ repository แบบสั้น. เหตุผล: เป็น context ถาวร. คู่มือ deploy ยาวหรือ workflow review ที่ใช้บางครั้งควรเป็น skill/reference เพื่อไม่บวมทุก session.Skill: ต้องการ procedure ตรวจ marketing page ก่อนส่ง preview โดยมี checklist ยาวและ brand guide. ควรวาง brand guide ทุกบรรทัดใน
AGENTS.mdไหม?เฉลย: ไม่ควร; สร้าง skill ที่มี
name/descriptionชัดและให้ body ลิงก์references/brand-guide.mdเมื่อจำเป็น. เหตุผล: progressive disclosure โหลดเฉพาะเมื่อ task match. ตรวจ syntax invocation ตาม host; portable core ไม่รับประกัน$skillหรือ/skillทุกเครื่อง.API: Frontend cart ส่ง
{ productId, quantity, totalPrice: 1 }แต่สินค้าแท้ราคา 459000. Worker ควรทำอย่างไร?เฉลย: ignore/reject client
totalPrice, validate product/quantity แล้วใช้ catalog server-side คำนวณใหม่. ใน repo นี้POST /api/quotesรับitems(1–10 unique) และ Worker สร้างtotalPrice. เหตุผล: browser state เป็น UX state ไม่ใช่ authority ของเงิน.Rental: ผู้ใช้ A และ B เห็น
available: trueจาก GET พร้อมกัน. ทั้งคู่กดจองกล้องที่เหลือชุดสุดท้าย. ทำไม GET check อย่างเดียวพอไม่ได้ และ repository ป้องกันอย่างไร?เฉลย: เกิด race ระหว่าง read และ write.
POST /api/rentalsinsertrentals/rental_daysเป็น batch และ D1 triggerrental_days_capacity_before_insertabort เมื่อเกิน capacity; Worker แปลงเป็น 409UNAVAILABLE. เหตุผล: constraint ต้องตรวจที่ write point.Idempotency: network timeout หลัง browser ส่ง
/api/contact, ผู้ใช้กดซ้ำ. Frontend ใน repository ส่ง header ใด และ server behaviour ที่ถูกต้องคืออะไร?เฉลย:
Idempotency-Key; same key + same payload ต้อง replay response เดิม (201 และIdempotent-Replayed: trueใน implementation), key เดิมกับ payload ต่างกันตอบ 409IDEMPOTENCY_CONFLICT. เหตุผล: ป้องกัน mutation ซ้ำโดยไม่ต้องอาศัย UI button disabled อย่างเดียว.Accessibility/motion: reduced motion เปิดอยู่ แต่ animation
gsap.from({ opacity: 0 })ยังคง execute แล้ว animation ถูกยกเลิก. เกิดอะไรและแก้อย่างไร?เฉลย: content อาจค้าง invisible. ให้ DOM/CSS เริ่ม final readable state และสร้าง GSAP tween เฉพาะ
prefers-reduced-motion: no-preference; ใน store example ใช้gsap.matchMedia()ตาม pattern นี้. เหตุผล: reduced motion ต้องเป็น usable experience ไม่ใช่ “animation เร็วมาก”.Form: learner เพิ่ม field
phoneใน form แต่ APIallowOnlyKeysไม่อนุญาต. ควรคาดหวังอะไรและทำอย่างไร?เฉลย: HTTP 400
UNKNOWN_FIELD; ตัดสิน privacy/data contract ก่อน แล้วจึงเปลี่ยน form + Worker validation + schema/migration + evidence พร้อมกันหากอนุมัติ. เหตุผล: strict allow-list ตั้งใจป้องกัน field ที่ frontend แอบเพิ่มหรือ typo.Deploy:
npm run deployใช้ได้บนเครื่องผู้สอน แต่ user ยังไม่ review preview และ D1 migration. action ที่ถูกต้องถัดไปคือ?เฉลย: ไม่ deploy production. รัน/อ่านผล
npm run deploy:check, ระบุ environment, review migration, deploy preview/staging ตาม workflow ที่อนุมัติ, smoke test URL, สร้าง release packet และรอ human sign-off. เหตุผล: command สำเร็จไม่พิสูจน์ business correctness หรือ rollback readiness.Testing claim: agent พูด “tests passed” แต่ report ไม่มี command/output และ
tests/อาจไม่มีไฟล์. reviewer ทำอย่างไร?เฉลย: label เป็น
not verified, run/inspect commands ที่ package ประกาศก่อนจึงสรุป.npm run testมี script แต่ไม่ใช่หลักฐานว่ามี/ผ่าน test ใน environment ปัจจุบัน. เหตุผล: evidence ต้องผูก command, output, scope และเวลา.Security: ผู้เรียนจะ paste Cloudflare token ลง
SKILL.mdเพื่อให้ deploy ง่าย. คำตอบที่ถูกต้องคือ?เฉลย: ห้าม; remove token, rotate หากเคยเผย, ใช้ Cloudflare secret/environment binding หรือ credential store และอ้างเฉพาะชื่อ binding ใน docs. review scripts/MCP/plugin ก่อน execute และใช้ preview least privilege. เหตุผล: skill เป็น instruction/package ไม่ใช่ secret manager; Git/history/prompt อาจเผย credential.
Endpoint mapping: ผู้เรียนใช้
POST /api/rental-requestsตาม blog ข้างนอก แล้วได้ 404. ให้อธิบาย correction โดยใช้ repo เป็น source of truth.เฉลย: อ่าน
src/worker.ts: routes จริงคือGET /api/health,GET /api/catalog,GET /api/availability,POST /api/contact,POST /api/rentals,POST /api/quotes. Rental ต้องส่ง fields ที่ Worker allow-list ไม่ใช่ route/shape จาก tutorial. เหตุผล: external example เป็น reference ได้ แต่ implementation contract ของ repo เป็น authority.
เกณฑ์แปลผล
| คะแนน / 24 | ความหมาย | การสอนต่อ |
|---|---|---|
| 0–10 | ยังมอง AI เป็นเครื่องสร้าง code โดยไม่เห็น boundary | pair lab, ใช้ prompt plan-only และ evidence log ทุก task |
| 11–17 | เข้าใจหลักบางส่วน แต่ยังสับสน authority/production | review endpoint/race/deploy scenarios ซ้ำ |
| 18–21 | พร้อมทำ capstone ภายใต้ checkpoint | ให้รับบท reviewer เพิ่มหนึ่งรอบ |
| 22–24 | reasoning มีหลักฐานและชี้ risk ได้ | ให้ช่วย peer facilitation โดยไม่แก้แทนเพื่อน |
Reference-solution checklists สำหรับ lab
แบบตรวจเสริม: การติดตั้งและ design handoff
กิจกรรมนี้อยู่นอกคลังข้อสอบ 24 คะแนนเดิม ใช้ตรวจ prework และงานศึกษาต่อ:
| สถานการณ์ | คำตอบ/หลักฐานที่คาดหวัง |
|---|---|
เปิด ChatGPT Desktop ได้ แต่ codex ไม่พบ |
แยกการติดตั้งแอปกับ CLI; ตรวจ channel, PATH และ codex --version |
| ลงชื่อเข้าใช้แอปแล้วจึงคิดว่าใช้ Figma ได้ | ต้อง authorize Figma และมีสิทธิ์ file; ลองอ่าน frame จริง |
| ส่ง screenshot แล้ว agent บอกว่า MCP ผ่าน | ระบุว่าเป็น file handoff; MCP ต้องมี tool call/result ที่ตรวจย้อนกลับได้ |
| Figma remote อ่านคนละหน้ากับที่ต้องการ | ใช้ Copy link to selection ของ frame เดียวและเทียบชื่อ/ขนาด |
| มี local MCP default port แต่เครื่องใช้ร่วมกัน | อ่าน shared-infra ตรวจ listener/จองก่อนเปิด; ใช้ remote ถ้าชน |
| แบบสวยใน Dark แต่ Light อ่านปุ่มไม่ออก | ตรวจ semantic colors/contrast ทั้งคู่; Light เป็น default ของ course web |
รับงานเมื่อมี prompt ฉบับเต็ม, แบบที่เลือก, mapping ที่ตรวจได้ และผลตรวจ 390px/1440px/keyboard ตาม Lab Design Tools/MCP หากไม่มี account ให้รับ file handoff ที่ระบุข้อจำกัดตรงตามจริง ไม่ลดคะแนนเพียงเพราะผู้เรียนไม่ได้สมัครทุกบริการ
สิ่งต่อไปนี้เป็นเฉลยแนวตรวจ ไม่ใช่คำสั่งให้ copy/overwrite code; ก่อนตรวจต้องใช้ working tree และ output ปัจจุบัน
Lab บริษัท: contact flow
Expected contract: เปิด /examples/company/; form JS posts name, email, message, boolean consent, website to /api/contact, adds JSON content type and Idempotency-Key. Worker returns 201 onlyหลัง validation/DB mutation. DEMO_MODE: "true" ใน wrangler.jsonc ทำให้ bypass Turnstile และ redacts stored personal fields, แต่ไม่เปลี่ยน rule ที่ต้อง validate consent/honeypot/origin.
Instructor checks:
-
/api/healthแสดง JSON (ไม่ต้องอ้าง storage ready หาก D1 ยังไม่ตั้ง) - valid demo submit แสดง message + id หรือบันทึก failure output ที่แท้จริง
- blank/invalid email/consent missing มี state ที่ user เข้าใจ
- keyboard focus ไปถึง form/status; ห้ามส่งข้อมูลลูกค้าจริง
- repeated same request/key เข้าใจว่า idempotency server-side ไม่ใช่ browser magic
Lab เช่า: availability/reservation
Expected contract: examples/rental/main.js fetch /api/catalog, then request /api/availability with equipmentId,start,end,quantity; POST /api/rentals with equipmentId,start,end,quantity,name,email,consent,website. start/end ใช้ YYYY-MM-DD, end ต้องหลัง start 1–30 วันและไม่ย้อนหลัง; valid id เช่น camera, light, audio ไม่ใช่ invented id. totalPrice ใน response เป็น satang and UI divides by 100 for Thai formatting.
Instructor checks:
- unknown query field / id / invalid date ถูก reject ตาม API response
-
/api/availabilityเป็น preview; POST เป็น authority ที่มี D1 capacity trigger - UI สามารถสื่อ 409 ไม่ใช่บอก “จองสำเร็จ”
- request field ไม่เกิน allow-list และ form applies idempotency key
- learner รู้ว่า
reserved-demoไม่มีผลทางการค้า
Lab store: motion/cart/quote
Expected contract: examples/store/main.js imports gsap and ScrollTrigger, creates animation only for no-preference media query, and cart uses Map. Cart submit sends items as {productId,quantity} with contact/consent/honeypot, no price/total. Worker validates and returns quote-demo, not paid/order confirmed.
Instructor checks:
- reduced motion leaves hero/story/product content readable
- Escape/close control works and focus treatment is reviewed
- empty cart prevents quote submit; max quantity UI aligns with API limit 10
- modifying browser total cannot alter Worker computed total (show API response)
- copy says quote demo, no credit-card/payment claim
Rubric capstone (100 คะแนน)
ให้คะแนนจาก artifact, live demo และ evidence record. “หน้าสวย” ไม่มีคะแนนแทน criterion ที่ขาด. หากมี hard-stop ด้านล่าง ให้ cap final score แม้คะแนนส่วนอื่นสูง.
เปิดแผนภาพ release gates แบบเต็มหน้า แล้วให้ผู้เรียนชี้ว่า evidence ของตนหยุดอยู่ที่ gate ใดก่อนให้คะแนนหมวด Preview/release readiness ตาราง rubric ด้านล่างยังเหมาะกับการให้คะแนนหลายมิติ จึงคงเป็นตาราง ไม่แปลงเป็นรูป
| หมวด | คะแนน | หลักฐานที่ต้องเห็น |
|---|---|---|
| Problem, brief และ content truth | 12 | audience/action, approved facts/assets, TODO owner, explicit out-of-scope |
| Spec/prompt discipline | 10 | SPEC.md, assumption log, plan-first prompt, small slice history |
| Information architecture และ UX | 12 | routes/sections/empty-error-success states, responsive demo 320px+desktop, CTA truthfully describes effect |
| Accessibility | 12 | semantic/labels/error/status, keyboard/focus, alt rationale, reduced-motion evidence where motion exists |
| Implementation quality | 10 | small coherent diff, no needless dependency, readable data/state boundary, no obvious code copied blindly |
| Server/data authority (as applicable) | 12 | form/catalog contract; server validates/reprices; D1 migration or explicit static-only rationale; no client trusted price |
| Security/privacy | 10 | no secret/real PII, allow-list/validation/origin boundary where API used, preview-only credentials and human gates |
| Validation and quality evidence | 10 | exact commands/output, manual smoke flow, not-run gaps stated; no unsupported “passed” claim |
| Preview/release readiness | 6 | preview URL or documented blocker, environment/commit, deployment check, rollback/known gaps |
| Communication/demo | 6 | 5–7 minute demo explains user outcome, one technical boundary, one risk and next action |
Hard stops / score caps
| Condition | Maximum total until fixed |
|---|---|
| Secret/token committed or pasted into deliverable | 0 and incident/rotation exercise required |
| Claims payment, reservation, testimonial, price, or compliance that is not true | 59 |
| Deploys/changes production without explicit authorized checkpoint | 59 |
| No working artifact or no evidence record | 49 |
| API accepts client-authoritative price/total for quote/commerce flow | 69 |
Capstone solution outline
A passing company capstone can remain static plus contact demo: cite source of copy, make CTA/form honest, show form states and evidence. A rental capstone must not say “confirmed booking” unless it implements real staff/payment workflow; use request/reserved-demo language and derive price/capacity server-side. A storefront capstone can use GSAP only as progressive enhancement and must call the flow a quote request. For all tracks, the instructor awards full deployment points only for the actual preview evidence or a correctly documented blocker—not for a fabricated URL.