Claude Camps Koh Phangan · Method เกาะพะงัน · คู่มือ
Ko Pha-ngan seen from the air, jungle meeting the sea
Claude Camps · Koh Phangan, from above
Claude Camps · เกาะพะงัน มองจากมุมสูง

Ship itin a day.The method.

สร้างจริงจบใน 1 วันนี่คือวิธีทำ

How a real booking website — landing page, database, live payments, deployed — gets built with Claude Code in a single working session. Written from one that happened.

เว็บจองที่นั่งจริง ๆ หน้าเว็บ ฐานข้อมูล ระบบรับเงิน ขึ้นออนไลน์ครบ สร้างด้วย Claude Code จบในการทำงานรอบเดียว เขียนจากงานที่เกิดขึ้นจริง

What was builtสิ่งที่สร้างclaude-camp-site
Stackเครื่องมือClaude Code · Supabase · Stripe · Vercel
Shippedที่ได้ออกมา4 pages · 5 API functions · 4 migrations4 หน้า · 5 ฟังก์ชัน API · 4 ไฟล์ migration
Tests writtenเทสต์ที่เขียน40, all passing40 ตัว ผ่านหมด
Build stepขั้นตอน buildNoneไม่มี
Before we start
ก่อนเริ่ม

How to read this.

คู่มือนี้อ่านยังไง

This is a method, not a tutorial. Tutorials go stale the week the API changes. A method survives, because it is about how you spend your attention.

นี่คือวิธีการ ไม่ใช่บทเรียนสอนทำตามทีละขั้น บทเรียนหมดอายุตั้งแต่ API เปลี่ยนสัปดาห์ถัดมา แต่วิธีการอยู่ได้ เพราะมันว่าด้วยการใช้สมาธิของคุณ

Everything here comes from building one specific thing: a seven-day bootcamp website with a booking system that takes real money. Claude Code did the building, Supabase held the data, Stripe took the payments, Vercel served it. Nothing about that combination is precious. Swap any piece and the method holds.

ทุกอย่างในนี้มาจากการสร้างของจริงชิ้นเดียว เว็บค่าย 7 วัน พร้อมระบบจองที่รับเงินได้จริง Claude Code เป็นคนสร้าง Supabase เก็บข้อมูล Stripe รับเงิน Vercel เอาขึ้นเว็บ ชุดเครื่องมือนี้ไม่ได้ศักดิ์สิทธิ์ เปลี่ยนตัวไหนก็ได้ วิธีการยังใช้ได้เหมือนเดิม

What is precious is the sequence, and the discipline of checking your work inside the same breath as doing it. That is the whole lesson. The rest is detail.

ที่สำคัญคือลำดับ กับวินัยในการตรวจงานตัวเองในลมหายใจเดียวกับตอนที่ทำ นั่นแหละคือบทเรียนทั้งหมด ที่เหลือเป็นรายละเอียด

Track markers

สัญลักษณ์สายการเรียน

TRACK A Beginner. You have an idea and little or no code. These sections cover talking to the model well, knowing when to trust an answer, and building the habit of verifying. You can ship a real product without writing a line yourself. สายเริ่มต้น มีไอเดีย แต่เขียนโค้ดไม่เป็นหรือเป็นนิดหน่อย ส่วนนี้ว่าด้วยการคุยกับโมเดลให้เป็น รู้ว่าเมื่อไหร่ควรเชื่อคำตอบ และสร้างนิสัยตรวจงาน คุณปล่อยของจริงได้โดยไม่ต้องพิมพ์โค้ดเองสักบรรทัด
TRACK B Builder. You already ship software. These are the engineering sections: concurrency under load, security posture, idempotent payment handling, and what is worth testing when a model wrote the code. สายบิลด์เดอร์ ปล่อยซอฟต์แวร์เป็นอยู่แล้ว ส่วนนี้คือเรื่องวิศวกรรม การชนกันของคำสั่งพร้อมกัน ท่าตั้งรับด้านความปลอดภัย การรับ webhook แบบซ้ำแล้วไม่พัง และอะไรที่ควรเทสต์เมื่อโมเดลเป็นคนเขียนโค้ด
BOTH Everyone. The method chapters and the economics at the end. ทุกคน บทว่าด้วยวิธีการ กับบทต้นทุนตอนท้าย
The one sentence
ถ้าจำได้ประโยคเดียว

The model is fast at producing and slow at knowing. Your job is not to type less — it is to close the gap between what was produced and what is true, as early and as cheaply as possible.

โมเดลผลิตเร็ว แต่รู้ช้า หน้าที่คุณไม่ใช่พิมพ์ให้น้อยลง แต่คือปิดช่องว่างระหว่างสิ่งที่มันผลิตออกมา กับสิ่งที่จริง ให้เร็วที่สุดและถูกที่สุด

Contents

สารบัญ

01Where the time actually goesเวลาหมดไปกับอะไรกันแน่bothทุกสาย
02The loopวงจรการทำงานbothทุกสาย
03Before you type anythingก่อนพิมพ์อะไรสักตัวbothทุกสาย
04Stage one — the pageขั้นที่หนึ่ง หน้าเว็บA
05Stage two — the dataขั้นที่สอง ข้อมูลB
06Stage three — the moneyขั้นที่สาม เงินB
07Stage four — ship itขั้นที่สี่ ปล่อยขึ้นจริงbothทุกสาย
08The economics of attentionต้นทุนของสมาธิbothทุกสาย
09The prompt sequenceลำดับพร้อมต์bothทุกสาย
The rocky shoreline of Ko Pha-ngan from above
18:40

The sun lands in front of the house. Everyone stops. Nobody planned that part.

ดวงอาทิตย์ตกตรงหน้าบ้านพอดี ทุกคนหยุดมือ ไม่มีใครวางแผนตรงนี้ไว้

01 · Both tracks
01 · ทุกสาย

Where the time actually goes.

เวลาหมดไปกับอะไรกันแน่

Beginners assume the bottleneck is typing speed. It never is. The bottleneck is rework — building the wrong thing, then building it again.

มือใหม่มักคิดว่าคอขวดคือความเร็วในการพิมพ์ ไม่เคยใช่เลย คอขวดคือการทำซ้ำ สร้างผิด แล้วสร้างใหม่

Watch anyone build with an AI assistant for an hour and the shape is always the same. A burst of production. A pause. Then a correction that throws away most of the burst. The generated code was never the expensive part. The expensive part was that nobody established what "right" meant before the generating started.

ลองนั่งดูใครสักคนใช้ AI ทำงานสักชั่วโมง รูปแบบจะเหมือนกันทุกครั้ง พุ่งออกมาชุดใหญ่ หยุด แล้วแก้ทีเดียวทิ้งของที่พุ่งออกมาเกือบหมด โค้ดที่โมเดลเขียนไม่เคยเป็นส่วนที่แพง ส่วนที่แพงคือไม่มีใครตกลงกันก่อนว่า "ถูก" แปลว่าอะไร

Three things cause almost all rework:

สามอย่างนี้คือต้นเหตุของการทำซ้ำเกือบทั้งหมด

01
Unstated requirements. ไม่ได้บอกความต้องการ You asked for "a landing page." The model guessed at audience, length, tone and structure. Every guess it got wrong is a rebuild — not a tweak, because tone runs through every sentence. คุณสั่งว่า "ทำหน้าแลนดิ้ง" โมเดลก็เดาเอาว่ากลุ่มคนอ่านคือใคร ยาวแค่ไหน โทนแบบไหน โครงยังไง เดาผิดข้อไหนก็ต้องสร้างใหม่ ไม่ใช่แค่แก้ เพราะโทนมันวิ่งอยู่ในทุกประโยค
02
Unstated standards. ไม่ได้บอกมาตรฐาน You didn't say what good looks like, so you got the average of everything the model has seen. Then you say "make it look more premium" and the whole design is redone. That round trip was avoidable with sixty seconds up front. ไม่ได้บอกว่าดีหน้าตาเป็นยังไง ก็เลยได้ค่าเฉลี่ยของทุกอย่างที่โมเดลเคยเห็น แล้วคุณก็บอกว่า "ทำให้ดูพรีเมียมกว่านี้" ดีไซน์ทั้งชุดก็ต้องรื้อทำใหม่ รอบนั้นเลี่ยงได้ด้วยการใช้เวลาหกสิบวินาทีตอนต้น
03
Unverified output. ไม่ได้ตรวจของที่ได้มา Something plausible came out, you accepted it, and forty minutes later it failed — by which point three other things were built on top. The cost of a wrong answer compounds with how long it survives. ของที่ออกมาดูน่าเชื่อ คุณรับไว้ อีกสี่สิบนาทีมันพัง ตอนนั้นมีของอีกสามอย่างสร้างทับไปแล้ว ต้นทุนของคำตอบผิดทบต้นตามเวลาที่มันรอดอยู่
Every one of these is fixed before generation starts, not after.
ทั้งสามข้อแก้ก่อนเริ่มสร้าง ไม่ใช่หลังจากนั้น

A concrete example from the build

ตัวอย่างจริงจากงานนี้

Partway through, a deployment failed with an error about function runtimes. The instinct is to guess — try a different value, redeploy, wait, guess again. Each cycle costs minutes and a deploy.

ระหว่างทาง การดีพลอยพังพร้อมข้อความว่าด้วย function runtime สัญชาตญาณคือเดา ลองค่าอื่น ดีพลอยใหม่ รอ แล้วเดาอีก แต่ละรอบกินเวลาหลายนาทีบวกอีกหนึ่งดีพลอย

What actually happened: the platform's own configuration schema was fetched and read. It defined the field as "the npm package name of a Runtime, including its version." The value in the file wasn't an npm package name. One read, one fix — and the fix came with a reason that made it obvious why guessing would never have worked.

สิ่งที่เกิดขึ้นจริงคือ ไปดึง schema ของแพลตฟอร์มมาอ่าน มันนิยามฟิลด์นั้นว่า "ชื่อ npm package ของ Runtime พร้อมเวอร์ชัน" ค่าที่อยู่ในไฟล์ไม่ใช่ชื่อ npm package อ่านครั้งเดียว แก้ครั้งเดียว แล้วยังได้เหตุผลที่ทำให้เห็นชัดว่าเดายังไงก็ไม่มีทางถูก

Reading the spec took less time than one wrong guess. That is the discipline in miniature.

อ่านสเปกใช้เวลาน้อยกว่าเดาผิดหนึ่งครั้ง นี่คือวินัยทั้งหมดในรูปย่อ

Classroom exercise
แบบฝึกหัดในห้อง

Take your last AI-assisted project. Count the times you said "no, actually…" and had output thrown away. For each one, write the single sentence that, said earlier, would have prevented it. That list is your personal brief template.

หยิบโปรเจกต์ล่าสุดที่ใช้ AI ช่วยขึ้นมา นับดูว่าพูดคำว่า "ไม่ใช่ เอาจริง ๆ คือ…" กี่ครั้ง แล้วต้องทิ้งของที่ทำไปแล้วกี่ครั้ง แต่ละครั้งเขียนประโยคเดียวที่ถ้าพูดตั้งแต่แรกจะไม่เกิดเรื่องนี้ รายการนั้นแหละคือเทมเพลตบรีฟส่วนตัวของคุณ

Looking up through coconut palms on Ko Pha-ngan
16:20

Nothing is being built in this photograph. That is rather the point.

ในรูปนี้ไม่มีใครสร้างอะไรเลย และนั่นแหละคือประเด็น

02 · Both tracks
02 · ทุกสาย

The loop.

วงจรการทำงาน

One cycle, repeated at every scale — from a whole feature down to a single function. Skipping any step is what costs you the day.

วงจรเดียว ใช้ซ้ำได้ทุกขนาด ตั้งแต่ทั้งฟีเจอร์ลงมาถึงฟังก์ชันเดียว ข้ามขั้นไหนก็ตาม นั่นแหละที่กินเวลาทั้งวันของคุณ

1 · Frame
State the goal, the constraints, and what "done" looks like
บอกเป้าหมาย ข้อจำกัด และ "เสร็จ" หน้าตาเป็นยังไง
2 · Load
Give the model your standards and any real reference material
ป้อนมาตรฐานของคุณ กับของอ้างอิงจริง ๆ ให้โมเดล
3 · Build
Let it produce the whole thing without interrupting
ปล่อยให้มันทำจนจบ อย่าไปขัดกลางทาง
4 · Verify
Run it, test it, or read the spec — in the same turn
รัน เทสต์ หรืออ่านสเปก ในรอบเดียวกันนั้น
5 · Name gaps
Write down what is fake, missing or unproven
จดไว้ว่าอะไรปลอม อะไรขาด อะไรยังไม่พิสูจน์
6 · Commit
Small commit, honest message, then next cycle
commit ก้อนเล็ก ข้อความตรงไปตรงมา แล้วเริ่มรอบใหม่

Why the order matters

ทำไมลำดับถึงสำคัญ

Frame before Load. If you don't know what you're building, no amount of style guidance helps. Framing is one minute and it is the highest-leverage minute of the session.

กรอบมาก่อนมาตรฐาน ถ้ายังไม่รู้ว่ากำลังสร้างอะไร ให้แนวทางสไตล์ไปเท่าไหร่ก็ไม่ช่วย การตั้งกรอบใช้เวลานาทีเดียว และเป็นนาทีที่คุ้มที่สุดของทั้งรอบ

Load before Build. Standards given after the fact mean a rewrite. Standards given before cost nothing extra — they simply shape the first draft.

มาตรฐานมาก่อนลงมือ ให้มาตรฐานทีหลังเท่ากับเขียนใหม่ ให้ก่อนไม่มีค่าใช้จ่ายเพิ่ม มันแค่ไปกำหนดร่างแรกเท่านั้น

Verify before you move on. This is the step people skip and the one that pays. A wrong answer caught in the same turn costs one correction. Caught three features later, it costs four.

ตรวจก่อนไปต่อ ขั้นนี้คนข้ามบ่อยที่สุด และเป็นขั้นที่คุ้มที่สุด จับคำตอบผิดได้ในรอบเดียวกัน เสียแค่การแก้หนึ่งครั้ง ไปจับได้ตอนทำฟีเจอร์ที่สามแล้ว เสียสี่ครั้ง

Name the gaps out loud. Anything invented, stubbed or untested gets written down the moment it's created. In the build this manual describes, the page contained several plausible-sounding facts — internet speeds, distances, a cohort count — that were pure invention. They were listed in the README on the day they were written, so they could not quietly become true by repetition.

พูดออกมาเลยว่าอะไรยังโหว่ อะไรที่แต่งขึ้น ยังเป็นของหลอก หรือยังไม่ได้เทสต์ จดไว้ทันทีที่สร้างมัน ในงานที่คู่มือนี้เล่าถึง หน้าเว็บมีข้อเท็จจริงที่ฟังดูน่าเชื่ออยู่หลายจุด ความเร็วเน็ต ระยะทาง จำนวนรุ่นที่จัดไปแล้ว ทั้งหมดแต่งขึ้นล้วน ๆ ของพวกนี้จดลง README ตั้งแต่วันเดียวกับที่เขียน มันจะได้ไม่ค่อย ๆ กลายเป็นเรื่องจริงเพราะพูดซ้ำไปเรื่อย ๆ

Rule
กฎ

A fabricated fact that nobody wrote down is indistinguishable from a real one within an hour. Write it down when you make it.

ข้อมูลที่แต่งขึ้นแล้วไม่มีใครจด ภายในชั่วโมงเดียวจะแยกไม่ออกจากของจริง แต่งเมื่อไหร่ จดเมื่อนั้น

What "verify" means at each level

คำว่า "ตรวจ" หมายถึงอะไรในแต่ละระดับ

You builtสิ่งที่สร้าง Verify byตรวจด้วย Costใช้เวลา
A pageหน้าเว็บ Count opening and closing tags; check every link resolvesนับแท็กเปิดกับแท็กปิด เช็กว่าทุกลิงก์ไปถึงไฟล์จริง Secondsไม่กี่วินาที
A database schemaโครงฐานข้อมูล Run the migrations against a real databaseรัน migration กับฐานข้อมูลจริง A minuteราวหนึ่งนาที
A logic ruleกฎทางตรรกะ Write the test that tries to break itเขียนเทสต์ที่พยายามทำให้มันพัง Minutesไม่กี่นาที
A config fileไฟล์คอนฟิก Fetch the platform's schema and check each fieldดึง schema ของแพลตฟอร์มมาเทียบทีละฟิลด์ A minuteราวหนึ่งนาที
A factual claimข้อมูลที่อ้าง Find the source, or mark it unverifiedหาแหล่งอ้างอิง ถ้าไม่มีก็ระบุว่ายังไม่ได้ตรวจ Secondsไม่กี่วินาที

Every row costs less than the rework it prevents. That asymmetry is the whole argument.

ทุกแถวราคาถูกกว่างานที่ต้องทำซ้ำถ้าไม่ตรวจ ความไม่สมมาตรตรงนี้คือเหตุผลทั้งหมด

A wooden boat dock on the shoreline of Ko Pha-ngan
09:00

The boat comes twice a day. Everything else you decide yourself.

เรือเข้าวันละสองรอบ นอกนั้นคุณตัดสินใจเองทั้งหมด

03 · Both tracks
03 · ทุกสาย

Before you type anything.

ก่อนพิมพ์อะไรสักตัว

Sixty seconds of setup that removes most of the rework from the rest of the day.

ตั้งต้นหกสิบวินาที ตัดงานทำซ้ำออกไปเกือบหมดตลอดทั้งวันที่เหลือ

The four-line brief

บรีฟสี่บรรทัด

Write these four lines before your first prompt. Not in your head — written down.

เขียนสี่บรรทัดนี้ก่อนพิมพ์พร้อมต์แรก อย่าคิดในหัว เขียนลงจริง ๆ

WHO One reader. A person, not a segment. "A developer with a half-finished side project" beats "our target audience." คนอ่านคนเดียว คนจริง ๆ ไม่ใช่กลุ่มเป้าหมาย "นักพัฒนาที่มีโปรเจกต์ข้างค้างอยู่ครึ่งทาง" ดีกว่า "กลุ่มลูกค้าของเรา"
WHAT What is different after they use this. A belief changed, an action taken, a thing bought. อะไรเปลี่ยนไปหลังเขาใช้ ความเชื่อเปลี่ยน ลงมือทำอะไรสักอย่าง หรือซื้อของ
SHAPE The deliverable, concretely. One HTML file. A Postgres schema. A deck of twelve slides. ของที่ส่งมอบ ให้ชัดเป็นรูปธรรม ไฟล์ HTML หนึ่งไฟล์ โครง Postgres สไลด์สิบสองหน้า
DONE The test you'd run to prove it works. If you can't name one, you don't know what you're building. เทสต์ที่จะใช้พิสูจน์ว่ามันทำงาน ถ้าบอกไม่ได้สักอัน แปลว่ายังไม่รู้ว่ากำลังสร้างอะไร
Worked example — the build in this manual
ตัวอย่างจริง งานที่คู่มือนี้เล่าถึง

WHO — an indie developer with a project they keep not finishing, browsing on a phone at night.
WHAT — they book a seat, or they message us. Nothing else counts.
SHAPE — one landing page, one booking form, real payments. Static files, no framework.
DONE — a stranger can pick a week, pay with a real card, and the seat count drops by one.

WHO — นักพัฒนาอิสระที่มีโปรเจกต์ทำไม่จบสักที นั่งเลื่อนดูในมือถือตอนกลางคืน
WHAT — เขาจองที่นั่ง หรือทักมาหาเรา นอกนั้นไม่นับ
SHAPE — หน้าแลนดิ้งหนึ่งหน้า ฟอร์มจองหนึ่งอัน รับเงินได้จริง ไฟล์นิ่ง ไม่ใช้เฟรมเวิร์ก
DONE — คนแปลกหน้าเลือกสัปดาห์ได้ จ่ายด้วยบัตรจริงได้ แล้วจำนวนที่นั่งลดลงหนึ่ง

That last line drove every technical decision that followed.

บรรทัดสุดท้ายนั่นแหละที่กำหนดการตัดสินใจทางเทคนิคทุกอย่างที่ตามมา

Ask the model to ask you TRACK A

ให้โมเดลถามคุณกลับ TRACK A

If you're not sure what to specify, hand the problem back:

ถ้าไม่แน่ใจว่าต้องระบุอะไรบ้าง โยนโจทย์กลับไป

Before you build anything, ask me the three or four questions
whose answers would most change what you build. Wait for my answers.
ก่อนจะเริ่มสร้างอะไร ถามฉันมาสามสี่ข้อ
เอาเฉพาะข้อที่ถ้าได้คำตอบแล้วจะเปลี่ยนสิ่งที่คุณสร้างมากที่สุด
แล้วรอคำตอบก่อน อย่าเพิ่งลงมือ

You'll get better questions than you would have thought to answer, and you'll get them before anything is produced. The questions are often the most useful output of the session.

คุณจะได้คำถามที่ดีกว่าที่ตัวเองนึกออก และได้มาก่อนที่จะมีอะไรออกมาสักชิ้น หลายครั้งคำถามพวกนี้คือผลลัพธ์ที่มีประโยชน์ที่สุดของทั้งรอบ

Load your standards once

ป้อนมาตรฐานครั้งเดียว

Anything you'd say twice belongs in a reusable instruction set. Design rules, writing voice, testing conventions, security posture. Load them at the start and every later output inherits them.

อะไรที่ต้องพูดสองรอบ ควรไปอยู่ในชุดคำสั่งที่ใช้ซ้ำได้ กฎดีไซน์ น้ำเสียงการเขียน ธรรมเนียมการเทสต์ ท่าตั้งรับด้านความปลอดภัย ป้อนตอนเริ่ม แล้วผลลัพธ์ทุกชิ้นหลังจากนั้นรับไปเอง

In this build, three sets were loaded before the first line of HTML: a design system with concrete values, a writing standard for the copy, and an animation reference for the motion. The result is that "make it look more premium" was never said, because premium was the starting definition rather than a later correction.

ในงานนี้ ป้อนไปสามชุดก่อนเขียน HTML บรรทัดแรก ระบบดีไซน์ที่มีค่าตัวเลขชัด มาตรฐานการเขียนสำหรับคอปปี้ และตัวอ้างอิงเรื่องแอนิเมชัน ผลคือไม่เคยต้องพูดคำว่า "ทำให้ดูพรีเมียมกว่านี้" เลย เพราะพรีเมียมเป็นนิยามตั้งต้น ไม่ใช่คำสั่งแก้ทีหลัง

Rule
กฎ

Standards stated after the output are a rewrite. Standards stated before are free.

บอกมาตรฐานหลังได้ของ เท่ากับเขียนใหม่ บอกก่อน ไม่เสียอะไรเลย

Give it the real artifact BOTH

ส่งของจริงให้มันดู BOTH

Describing a reference in words is lossy and expensive. Handing over the actual thing is cheap and exact. A screenshot carries the palette, type scale, density and spacing in one shot. A pasted error carries the exact failure. A link to real documentation ends an argument about what a field means.

อธิบายตัวอย่างอ้างอิงด้วยคำพูด ข้อมูลหายและเปลืองด้วย ส่งของจริงไปเลยถูกกว่าและตรงกว่า ภาพหน้าจอหนึ่งภาพพาชุดสี ขนาดตัวอักษร ความแน่น และระยะห่างไปพร้อมกันหมด ข้อความ error ที่วางไปพาความพังที่แท้จริงไป ลิงก์เอกสารจริงจบการเถียงว่าฟิลด์นั้นแปลว่าอะไร

Instead ofแทนที่จะบอกว่า Do thisให้ทำแบบนี้
"Make it look like a premium retreat site""ทำให้เหมือนเว็บรีทรีตหรู ๆ" Paste a screenshot of oneวางภาพหน้าจอของเว็บนั้นไปเลย
"The build is failing somehow""มัน build ไม่ผ่าน ไม่รู้ทำไม" Paste the exact error textวางข้อความ error ตัวเต็มไป
"Use the standard config for this""ใช้คอนฟิกมาตรฐานของอันนี้" Link the platform's own schemaส่งลิงก์ schema ของแพลตฟอร์มไป
"Match our brand voice""ให้เข้ากับน้ำเสียงแบรนด์เรา" Paste three paragraphs you've writtenวางงานเขียนของคุณเองไปสามย่อหน้า
Palm trees along the water on a Ko Pha-ngan beach
The brief

Four lines, written by hand, before a single prompt is typed.

สี่บรรทัด เขียนด้วยมือ ก่อนพิมพ์พร้อมต์แรกสักตัว

04 · Track A — Beginner
04 · สายเริ่มต้น

Stage one — the page.

ขั้นที่หนึ่ง หน้าเว็บ

A landing page that doesn't look generated, built as a single file, verified before anyone looks at it.

หน้าแลนดิ้งที่ไม่ดูเหมือนของที่ AI ปั๊มออกมา ทำเป็นไฟล์เดียว ตรวจให้เรียบร้อยก่อนใครจะเห็น

Why one file, and no framework

ทำไมไฟล์เดียว ไม่ใช้เฟรมเวิร์ก

The site in this manual is plain HTML with the CSS and JavaScript inside it. No build step, no bundler, no dependencies for the pages themselves. This is not nostalgia. It is a deliberate reduction of the surface where things go wrong.

เว็บในคู่มือนี้คือ HTML ล้วน ๆ มี CSS กับ JavaScript อยู่ในไฟล์เดียวกัน ไม่มีขั้นตอน build ไม่มี bundler ตัวหน้าเว็บเองไม่มี dependency นี่ไม่ใช่การโหยหาของเก่า แต่เป็นการจงใจลดพื้นที่ที่อะไร ๆ จะพังได้

Choiceตัวเลือก What it removesตัดอะไรออกไป
No build stepไม่มีขั้นตอน build Build failures. There is nothing to build.build พัง เพราะไม่มีอะไรให้ build
No frameworkไม่ใช้เฟรมเวิร์ก Version conflicts, breaking upgrades, framework-shaped bugsเวอร์ชันชนกัน อัปเกรดแล้วพัง บั๊กที่มาจากตัวเฟรมเวิร์กเอง
Inline CSS and JSCSS กับ JS อยู่ในไฟล์ Broken relative paths, missing assets, load-order bugsพาธเพี้ยน ไฟล์หาย ลำดับการโหลดผิด

The design decisions that stop it looking generated

การตัดสินใจด้านดีไซน์ที่ทำให้มันไม่ดูเหมือนของ AI

Generated design has a signature: pure white background, one particular blue, a single sans-serif everywhere, uniform rounded corners, everything centred. Avoiding it is a small number of concrete decisions.

ดีไซน์ที่ AI ปั๊มออกมามีลายเซ็นของมัน พื้นขาวสนิท สีน้ำเงินเฉดหนึ่งที่เห็นบ่อย ฟอนต์ sans-serif ตัวเดียวทั้งหน้า มุมโค้งเท่ากันหมด แล้วจัดกึ่งกลางทุกอย่าง เลี่ยงได้ด้วยการตัดสินใจไม่กี่ข้อ

01
Two typefaces, and a real size jump. ฟอนต์สองตัว กับการกระโดดขนาดที่ชัดจริง One characterful face for headlines, one quiet face for body. The headline at least two and a half times the body size. Large text wants tight line spacing; body text wants the opposite. ตัวหนึ่งมีคาแรกเตอร์ไว้ทำหัวเรื่อง อีกตัวเงียบ ๆ ไว้ทำเนื้อความ หัวเรื่องใหญ่กว่าเนื้อความอย่างน้อยสองเท่าครึ่ง ตัวใหญ่ต้องการระยะบรรทัดแน่น เนื้อความต้องการตรงข้าม
02
One spacing scale, no arbitrary values. สเกลระยะห่างชุดเดียว ห้ามใส่ตัวเลขมั่ว Powers of eight: 8, 16, 24, 32, 48, 64, 96, 128. Define them once and use nothing else. Inconsistent spacing is the loudest amateur signal, and it is invisible as a cause — you only see the effect. คูณแปดไปเรื่อย 8, 16, 24, 32, 48, 64, 96, 128 ตั้งไว้ครั้งเดียวแล้วห้ามใช้ค่าอื่น ระยะห่างที่ไม่สม่ำเสมอคือสัญญาณมือสมัครเล่นที่ดังที่สุด และมองไม่เห็นว่าเป็นสาเหตุ เห็นแต่ผลลัพธ์
03
One accent colour, used sparingly. สีเน้นสีเดียว ใช้ให้น้อย Roughly sixty percent one background tone, thirty percent neutrals, ten percent accent — and the accent only where the eye should land. If two things are colourful, neither is important. คร่าว ๆ คือพื้นหลังโทนเดียวหกสิบเปอร์เซ็นต์ สีกลางสามสิบ สีเน้นสิบ และสีเน้นใส่เฉพาะจุดที่อยากให้สายตาไปหยุด ถ้ามีของสองอย่างที่สีจัด แปลว่าไม่มีอันไหนสำคัญเลย
04
Off-white, not white. Near-black, not black. ขาวนวล ไม่ใช่ขาวสนิท ดำเกือบสนิท ไม่ใช่ดำสนิท A warm off-white background and a near-black text colour read as considered. Pure white with pure black reads as a default nobody chose. พื้นขาวนวลอุ่น ๆ กับตัวหนังสือดำเกือบสนิท อ่านแล้วรู้สึกว่ามีคนคิดมา ขาวสนิทคู่ดำสนิท อ่านแล้วรู้สึกว่าเป็นค่าตั้งต้นที่ไม่มีใครเลือก

Copy that sounds like a person

คอปปี้ที่อ่านแล้วเหมือนคนเขียน

The failure mode of generated copy is not bad grammar. It is the absence of anything specific enough to be wrong.

จุดพังของคอปปี้ที่ AI เขียน ไม่ใช่ไวยากรณ์ผิด แต่คือไม่มีอะไรเฉพาะเจาะจงพอที่จะผิดได้เลยสักอย่าง

Be specific or cut it. Every abstract noun should become something you could photograph or count. "Fast loading" becomes "it loads in 200ms; it used to hang for three seconds." If a sentence would survive being pasted into a different company's website, it is saying nothing.

เจาะจง หรือตัดทิ้ง คำนามนามธรรมทุกคำควรกลายเป็นของที่ถ่ายรูปได้หรือนับได้ "โหลดเร็ว" กลายเป็น "โหลดใน 200ms เมื่อก่อนค้างสามวินาที" ถ้าประโยคไหนย้ายไปวางในเว็บของบริษัทอื่นแล้วยังใช้ได้ แปลว่าประโยคนั้นไม่ได้พูดอะไรเลย

Break the rhythm. Uniform sentence length is the deepest tell, felt before it can be named. Follow a long sentence with a short one. Read it aloud — one speed throughout reads as machine-made.

อย่าให้จังหวะเท่ากันหมด ประโยคยาวเท่ากันทุกประโยคคือสัญญาณที่ลึกที่สุด คนรู้สึกได้ก่อนที่จะบอกถูกว่ามันคืออะไร ประโยคยาวแล้วต่อด้วยประโยคสั้น ลองอ่านออกเสียง ถ้าความเร็วเท่ากันตลอด แปลว่าอ่านแล้วเหมือนเครื่องเขียน

Verify before anyone looks

ตรวจก่อนใครจะเห็น

# 1. do the tags balance?
grep -o '<div' index.html | wc -l
grep -o '</div>' index.html | wc -l

# 2. does every internal link point at a file that exists?
grep -o 'href="/[^"]*"' index.html | sort -u

# 3. does every image have alt text?
grep -c '<img' index.html
# 1. แท็กเปิดกับแท็กปิดเท่ากันไหม
grep -o '<div' index.html | wc -l
grep -o '</div>' index.html | wc -l

# 2. ลิงก์ภายในทุกอันชี้ไปที่ไฟล์ที่มีอยู่จริงไหม
grep -o 'href="/[^"]*"' index.html | sort -u

# 3. รูปทุกรูปมี alt text ไหม
grep -c '<img' index.html

In this build the three checks ran after each rewrite. The link check caught six dead placeholder links that would otherwise have shipped.

ในงานนี้ สามข้อนี้รันทุกครั้งหลังเขียนใหม่ ข้อเช็กลิงก์จับลิงก์หลอกที่ตายแล้วได้หกอัน ไม่งั้นก็หลุดขึ้นเว็บไปหมดแล้ว

Habit
นิสัยที่ควรมี

Ask for the check in the same message as the work. "Build the page, then confirm the tags balance and every link resolves." One turn, not two.

สั่งตรวจไปในข้อความเดียวกับสั่งงาน "ทำหน้านี้ แล้วยืนยันว่าแท็กครบและทุกลิงก์ไปถึงจริง" หนึ่งรอบ ไม่ใช่สองรอบ

A coconut palm on a hillside above the sea, Ko Pha-ngan
Ten

Ten beds. The rule that must never break.

เตียงสิบเตียง กฎที่ห้ามพังเด็ดขาด

05 · Track B — Builder
05 · สายบิลด์เดอร์

Stage two — the data.

ขั้นที่สอง ข้อมูล

Where the real thinking happens. Get this wrong and no amount of application code saves you.

ตรงนี้คือจุดที่ต้องคิดจริง ๆ ถ้าพลาดตรงนี้ เขียนโค้ดฝั่งแอปเท่าไหร่ก็ช่วยไม่ได้

Model the invariant, not the feature

ออกแบบจากกฎที่ห้ามผิด ไม่ใช่จากฟีเจอร์

The product had ten beds per cohort. That is not a display detail — it is a rule the system must never violate, no matter how many people click at once.

สินค้านี้มีเตียงสิบเตียงต่อหนึ่งรุ่น นั่นไม่ใช่แค่ตัวเลขที่เอาไว้โชว์ แต่เป็นกฎที่ระบบห้ามละเมิด ไม่ว่าจะมีคนกดพร้อมกันกี่คนก็ตาม

Ask what must never be true. Then make the database itself refuse it. Application logic is a request; a constraint is a guarantee.

ถามตัวเองว่าอะไรที่ห้ามเป็นจริงเด็ดขาด แล้วให้ฐานข้อมูลเป็นคนปฏิเสธเอง ตรรกะฝั่งแอปคือการขอ แต่ constraint คือการรับประกัน

constraint inventory_no_oversell check (beds_taken <= beds_total)

That one line means overselling is physically impossible. Not unlikely — impossible. You could delete the entire application layer, connect directly with a database client, and still fail to oversell a cohort.

บรรทัดเดียวนั้นทำให้การขายเกินเป็นไปไม่ได้ในทางกายภาพ ไม่ใช่แค่โอกาสน้อย แต่เป็นไปไม่ได้ ต่อให้ลบโค้ดฝั่งแอปทิ้งทั้งชั้น แล้วต่อเข้าฐานข้อมูลตรง ๆ ก็ยังขายเกินไม่ได้อยู่ดี

The one statement that matters

คำสั่งเดียวที่สำคัญที่สุด

Seat inventory is the classic race. Two people click "book" on the last bed at the same instant. The naive approach reads the count, decides, then writes — and there is a gap between the read and the write where both requests see one bed free.

จำนวนที่นั่งคือเคสคลาสสิกของการชนกัน สองคนกด "จอง" เตียงสุดท้ายพร้อมกันเป๊ะ วิธีที่คิดง่าย ๆ คืออ่านจำนวน ตัดสินใจ แล้วเขียนกลับ แต่ระหว่างอ่านกับเขียนมีช่องว่างอยู่ ตรงช่องนั้นทั้งสองคำขอเห็นเตียงว่างเหมือนกัน

update cohort_inventory
   set beds_taken = beds_taken + 1
 where cohort_id = $1
   and track     = $2
   and beds_taken < beds_total;

-- zero rows updated means sold out
update cohort_inventory
   set beds_taken = beds_taken + 1
 where cohort_id = $1
   and track     = $2
   and beds_taken < beds_total;

-- ไม่มีแถวไหนถูกอัปเดต แปลว่าเต็มแล้ว

Under Postgres's default isolation level, when two transactions update the same row the second blocks until the first commits, then re-evaluates its WHERE clause against the row as it now stands. If that pushed it to capacity, the condition no longer matches, zero rows update, and you return "sold out." No advisory locks. No retry loop. One statement, correct under any amount of concurrency.

ที่ระดับ isolation ค่าเริ่มต้นของ Postgres เมื่อสอง transaction อัปเดตแถวเดียวกัน ตัวที่สองจะถูกบล็อกไว้จนตัวแรก commit เสร็จ แล้วค่อยประเมินเงื่อนไข WHERE กับแถวในสภาพล่าสุดอีกที ถ้าตอนนั้นเต็มพอดี เงื่อนไขก็ไม่ตรงแล้ว ไม่มีแถวไหนถูกอัปเดต แล้วคุณก็ตอบกลับไปว่า "เต็มแล้ว" ไม่ต้องใช้ advisory lock ไม่ต้องวนลูป retry คำสั่งเดียว ถูกต้องไม่ว่าจะมีคนพร้อมกันเท่าไหร่

Teaching point
จุดที่ต้องสอน

When a model hands you a correct-looking solution to a concurrency problem, that is exactly when to slow down. Ask it to explain why it is correct at the isolation level you are actually running. If the explanation is vague, the code is probably wrong.

เวลาโมเดลยื่นทางแก้ปัญหาการชนกันที่ดูถูกต้องมาให้ นั่นแหละคือจังหวะที่ต้องช้าลง ให้มันอธิบายว่าทำไมถึงถูกต้อง ที่ระดับ isolation ที่คุณใช้อยู่จริง ถ้าคำอธิบายคลุมเครือ โค้ดนั้นน่าจะผิด

Row Level Security is not optional

Row Level Security ไม่ใช่ของเสริม

Managed Postgres services hand your browser a public key. That key ships in your JavaScript; anyone can read it out of developer tools. This is by design. What stops a stranger downloading your entire bookings table with it is row-level security, and nothing else.

บริการ Postgres แบบ managed จะยื่น public key ให้เบราว์เซอร์ของคุณ คีย์นั้นติดไปกับ JavaScript ใครก็เปิด developer tools อ่านได้ และตั้งใจให้เป็นแบบนั้นตั้งแต่แรก สิ่งเดียวที่กันไม่ให้คนแปลกหน้าโหลดตาราง bookings ทั้งตารางไปด้วยคีย์นั้น คือ row-level security ไม่มีอย่างอื่น

Tableตาราง Public role canสิทธิ์ของ public
cohortsread open onesอ่านรุ่นที่ยังเปิดอยู่
availabilityread remaining seat countsอ่านจำนวนที่นั่งที่เหลือ
pricesread active pricesอ่านราคาที่ใช้งานอยู่
bookingsnothing at allไม่ได้เลยสักอย่าง
payment eventsnothing at allไม่ได้เลยสักอย่าง
The check people skip
ข้อที่คนชอบข้าม

Connect with the public key and try to read your bookings table. If anything comes back, you have a data breach waiting for its first customer. Make this a step in your launch checklist, not a thing you assume.

ลองต่อด้วย public key แล้วอ่านตาราง bookings ดู ถ้ามีอะไรกลับมา แปลว่าคุณมีข้อมูลรั่วรออยู่แล้ว รอแค่ลูกค้าคนแรก ใส่ข้อนี้ลงเช็กลิสต์ก่อนเปิดจริง อย่าเดาเอาเอง

Honesty note
หมายเหตุที่ต้องพูดตรง ๆ

Single-process Postgres cannot demonstrate true parallel connections. The blocking behaviour above is documented semantics, not something the tests observed. The constraint was tested; the isolation behaviour was reasoned about. Those are different kinds of confidence and students should learn to tell them apart.

Postgres ที่รันโปรเซสเดียวสาธิตการเชื่อมต่อพร้อมกันจริง ๆ ไม่ได้ พฤติกรรมการบล็อกข้างบนเป็นสิ่งที่เอกสารระบุไว้ ไม่ใช่สิ่งที่เทสต์เห็นกับตา ตัว constraint ถูกเทสต์จริง ส่วนพฤติกรรม isolation เป็นการให้เหตุผล ความมั่นใจสองแบบนี้ไม่เหมือนกัน และผู้เรียนควรแยกให้ออก

Still water ringed by trees on Ko Pha-ngan
Money

You can see straight to the bottom here. Your payment code should read the same way.

น้ำตรงนี้ใสจนมองเห็นพื้น โค้ดรับเงินของคุณควรอ่านแล้วรู้สึกแบบเดียวกัน

06 · Track B — Builder
06 · สายบิลด์เดอร์

Stage three — the money.

ขั้นที่สาม เงิน

Payments are where sloppiness stops being embarrassing and starts being expensive. Four rules cover almost everything.

ระบบเงินคือจุดที่ความมักง่ายเลิกเป็นแค่เรื่องน่าอาย แล้วกลายเป็นเรื่องแพง สี่กฎนี้ครอบคลุมเกือบทั้งหมด

Rule one — the order of operations

กฎข้อหนึ่ง ลำดับการทำงาน

1. validate the request
2. reserve the seat in your database    ← before the payment provider
3. create the checkout session
4. record the session id on the booking
1. ตรวจความถูกต้องของคำขอ
2. กันที่นั่งไว้ในฐานข้อมูล    ← ก่อนติดต่อผู้ให้บริการรับเงิน
3. สร้าง checkout session
4. บันทึก session id ลงในรายการจอง

Reserving before you contact the payment provider means two people cannot both reach checkout for the last seat. If step three fails, the reservation expires by itself after thirty minutes and the seat returns. No compensating transaction, no cleanup job.

กันที่นั่งไว้ก่อนติดต่อผู้ให้บริการรับเงิน แปลว่าสองคนจะไปถึงหน้าจ่ายเงินของที่นั่งสุดท้ายพร้อมกันไม่ได้ ถ้าขั้นที่สามพัง การกันที่จะหมดอายุเองใน 30 นาที แล้วที่นั่งก็กลับคืนมา ไม่ต้องมี transaction ชดเชย ไม่ต้องมีงานตามเก็บกวาด

Rule two — the price never comes from the browser

กฎข้อสอง ราคาห้ามมาจากเบราว์เซอร์

The client sends a cohort, a track and a tier. It never sends an amount. The server looks the price up in its own table and charges that. This is the difference between a payment system and a donation box, and it is the most common serious flaw in tutorial payment code.

ฝั่งไคลเอนต์ส่งมาแค่รุ่น สาย และระดับแพ็กเกจ ไม่เคยส่งจำนวนเงินมา เซิร์ฟเวอร์ไปเปิดราคาจากตารางของตัวเองแล้วเรียกเก็บตามนั้น นี่คือเส้นแบ่งระหว่างระบบรับเงินกับกล่องรับบริจาค และเป็นช่องโหว่ร้ายแรงที่พบบ่อยที่สุดในโค้ดสอนทำระบบจ่ายเงิน

Rule three — the webhook is the truth

กฎข้อสาม webhook คือความจริง

The success page is a redirect the customer's browser performs. Browsers get closed, tabs crash, phones die on hotel wifi, and anyone can type your success URL directly into the address bar. None of that is a payment.

หน้า success คือการ redirect ที่เบราว์เซอร์ลูกค้าเป็นคนทำ เบราว์เซอร์ปิดเมื่อไหร่ก็ได้ แท็บแครชได้ มือถือดับคาไวไฟโรงแรมได้ และใครก็พิมพ์ URL หน้า success ลงช่องที่อยู่เองได้ ไม่มีอันไหนคือการจ่ายเงิน

Verify the signature against the raw request body. Parse the JSON first and the signature will never match, because verification runs over the exact bytes that were sent. This detail costs more lost hours than any other part of payment integration.

ตรวจลายเซ็นกับ เนื้อคำขอดิบ ถ้าแปลง JSON ก่อน ลายเซ็นจะไม่มีวันตรง เพราะการตรวจทำบนไบต์ชุดเดิมเป๊ะ ๆ ที่ส่งมา รายละเอียดข้อนี้กินเวลาคนไปมากกว่าส่วนอื่นของงานเชื่อมระบบจ่ายเงินทั้งหมด

Rule four — duplicates are normal

กฎข้อสี่ ของซ้ำเป็นเรื่องปกติ

Payment providers guarantee at-least-once delivery. Receiving the same event twice is ordinary operation, not an error. Design for it in two layers.

ผู้ให้บริการรับเงินรับประกันการส่งแบบอย่างน้อยหนึ่งครั้ง การได้รับ event เดิมสองรอบคือการทำงานปกติ ไม่ใช่ข้อผิดพลาด ออกแบบรับไว้สองชั้น

-- layer one: a ledger with a primary key on the provider's event id
insert into payment_events (id, type) values ($1, $2);
-- a duplicate raises a unique violation; return 200 and stop

-- layer two: make the update itself idempotent
update bookings set status = 'paid'
 where session_id = $1
   and status = 'held';    ← re-running matches zero rows
-- ชั้นที่หนึ่ง สมุดบัญชีที่ใช้ event id ของผู้ให้บริการเป็น primary key
insert into payment_events (id, type) values ($1, $2);
-- ถ้าซ้ำจะเกิด unique violation ให้ตอบ 200 แล้วจบ

-- ชั้นที่สอง ทำให้ตัวอัปเดตเองรันซ้ำได้
update bookings set status = 'paid'
 where session_id = $1
   and status = 'held';    ← รันซ้ำจะไม่ตรงกับแถวไหนเลย

Then test it: fire the identical event twice and assert the paid timestamp did not move.

แล้วเทสต์จริง ยิง event เดิมสองรอบ แล้วยืนยันว่าเวลาที่บันทึกว่าจ่ายแล้วไม่ขยับ

Test keys until the rehearsal is done
ใช้คีย์ทดสอบจนกว่าจะซ้อมครบ

Build the entire thing on test keys. Switch to live only after a complete run-through, and expect to update the webhook signing secret when you do — test and live have different secrets, and the resulting signature failures look exactly like an attack.

สร้างทั้งหมดบนคีย์ทดสอบ เปลี่ยนไปคีย์จริงหลังซ้อมครบวงจรแล้วเท่านั้น และเตรียมใจว่าต้องเปลี่ยน secret ของ webhook ด้วย เพราะโหมดทดสอบกับโหมดจริงใช้ secret คนละตัว แล้วอาการลายเซ็นไม่ตรงที่ตามมา หน้าตาเหมือนถูกโจมตีเป๊ะ

A motorcycle on the coast road above the sea, Ko Pha-ngan
Day seven

The part nobody photographs: it works, and then you leave it running.

ตอนที่ไม่มีใครถ่ายรูปเก็บไว้ มันใช้งานได้แล้ว แล้วคุณก็ปล่อยให้มันวิ่งต่อไป

07 · Both tracks
07 · ทุกสาย

Stage four — ship it.

ขั้นที่สี่ ปล่อยขึ้นจริง

Deployment should be boring. If it is exciting, something is configured wrong.

การดีพลอยควรน่าเบื่อ ถ้ามันตื่นเต้น แปลว่ามีอะไรตั้งค่าผิด

Read the schema, don't guess the config

อ่าน schema อย่าเดาคอนฟิก

Deployment configuration is where guessing is most tempting and least effective. The field names look obvious and frequently are not. In this build a config field was set to a value that looked entirely reasonable and was rejected. Fetching the platform's published JSON schema settled it in one read: the field expected an npm package identifier, not a version label. The correct answer was to omit the field entirely.

คอนฟิกตอนดีพลอยคือจุดที่อยากเดาที่สุด และเดาแล้วได้ผลน้อยที่สุด ชื่อฟิลด์ดูเหมือนเดาได้ แต่บ่อยครั้งไม่ใช่ ในงานนี้มีฟิลด์หนึ่งที่ใส่ค่าดูสมเหตุสมผลมากลงไป แล้วโดนปฏิเสธ พอไปดึง JSON schema ที่แพลตฟอร์มเผยแพร่ไว้มาอ่าน ก็จบในการอ่านครั้งเดียว ฟิลด์นั้นต้องการชื่อ npm package ไม่ใช่ป้ายเวอร์ชัน คำตอบที่ถูกคือไม่ต้องใส่ฟิลด์นั้นเลย

Environment variables are read at boot

ตัวแปรสภาพแวดล้อมอ่านค่าตอนบูต

Serverless functions read their configuration when the instance starts. Changing a variable without redeploying changes nothing. Set every variable before the first deploy, or the functions will boot and immediately throw on every request.

ฟังก์ชัน serverless อ่านค่าคอนฟิกตอนอินสแตนซ์เริ่มทำงาน เปลี่ยนค่าแล้วไม่ดีพลอยใหม่ เท่ากับไม่ได้เปลี่ยนอะไรเลย ตั้งค่าให้ครบ ก่อน ดีพลอยครั้งแรก ไม่งั้นฟังก์ชันจะบูตแล้วพังทุกคำขอทันที

Git, and the one rule that matters

Git กับกฎข้อเดียวที่สำคัญจริง

Initialise the repository inside the project folder. Then prove your ignore rules work rather than trusting them:

สร้าง repository ในโฟลเดอร์โปรเจกต์ แล้วพิสูจน์ว่ากฎ ignore ทำงานจริง อย่าเชื่อไปเอง

git check-ignore -v .env.local node_modules/ .vercel
git add -A
git status --porcelain     # read this list before committing
git check-ignore -v .env.local node_modules/ .vercel
git add -A
git status --porcelain     # อ่านรายการนี้ก่อน commit ทุกครั้ง

If a real key ever does reach a commit: rotate the key first. Rewriting history does not help. Public repositories are scraped within minutes and the key is compromised from the moment it lands.

ถ้าคีย์จริงหลุดเข้า commit ไปแล้ว เปลี่ยนคีย์ก่อนเป็นอันดับแรก การเขียนประวัติใหม่ไม่ช่วยอะไร repository สาธารณะโดนกวาดข้อมูลภายในไม่กี่นาที คีย์นั้นถือว่าหลุดตั้งแต่วินาทีที่มันลงไป

Palms on the shoreline of Ko Pha-ngan at golden hour
Friday

Ship in the morning. The afternoon takes care of itself.

ปล่อยขึ้นจริงตอนเช้า ตอนบ่ายไม่ต้องจัดการอะไรแล้ว

08 · Both tracks
08 · ทุกสาย

The economics of attention.

ต้นทุนของสมาธิ

Time, tokens and energy are the same currency spent three ways. Here is where they go.

เวลา โทเคน และแรง คือเงินสกุลเดียวกันที่จ่ายออกไปสามทาง นี่คือที่ที่มันหมดไป

Expensiveแพง Whyเพราะอะไร
Rebuilding after a wrong assumptionสร้างใหม่เพราะสมมติผิด The whole output is discarded, and often the things built on top of itทิ้งผลลัพธ์ทั้งก้อน แถมของที่สร้างทับไว้ด้วย
Long back-and-forth about tasteโต้กันไปมาเรื่องรสนิยม Every round re-sends the entire context and produces a fresh draftทุกรอบส่งบริบททั้งหมดใหม่ แล้วผลิตร่างใหม่ทั้งชุด
Debugging by guessingแก้บั๊กด้วยการเดา Each guess is a full cycle: change, deploy, wait, read, guess againเดาหนึ่งครั้งคือหนึ่งรอบเต็ม แก้ ดีพลอย รอ อ่าน แล้วเดาใหม่
Re-explaining the same standardsอธิบายมาตรฐานเดิมซ้ำ Paid again in every single sessionจ่ายใหม่ทุกครั้งที่เปิดงาน
Cheapถูก Whyเพราะอะไร
Clarifying questions before buildingถามให้ชัดก่อนลงมือ A few sentences that prevent a full rebuildไม่กี่ประโยค แลกกับการไม่ต้องสร้างใหม่ทั้งชุด
Pasting the real artifactวางของจริงไปเลย An image or an error carries more than a paragraph describing itภาพหนึ่งภาพหรือ error หนึ่งชุด บอกได้มากกว่าคำอธิบายทั้งย่อหน้า
Running the check in the same turnตรวจในรอบเดียวกัน No context re-send; the model already has everything loadedไม่ต้องส่งบริบทใหม่ โมเดลถืออยู่ครบแล้ว
Loading standards onceป้อนมาตรฐานครั้งเดียว Every later output inherits them at no extra costผลลัพธ์ทุกชิ้นหลังจากนั้นรับไปเอง ไม่มีค่าใช้จ่ายเพิ่ม

What to verify and what to trust

อะไรต้องตรวจ อะไรเชื่อได้

Verifying everything is its own waste. The distinction that matters is whether the claim is checkable and whether being wrong is expensive.

ตรวจทุกอย่างก็เป็นการเปลืองอีกแบบ เส้นแบ่งที่สำคัญคือ สิ่งนั้น ตรวจได้ไหม และถ้าผิดแล้ว แพงไหม

Always verifyต้องตรวจเสมอ Usually trustปกติเชื่อได้
Anything that moves moneyอะไรก็ตามที่ทำให้เงินเคลื่อน Layout and spacing — you can see itเลย์เอาต์กับระยะห่าง เพราะมองเห็นเอง
Anything about who can read whatเรื่องใครอ่านอะไรได้บ้าง Copy phrasing — you can read itถ้อยคำในคอปปี้ เพราะอ่านเองได้
Config field names and valuesชื่อและค่าของฟิลด์คอนฟิก Standard library usageการใช้ไลบรารีมาตรฐาน
Statistics, dates, names, pricesสถิติ วันที่ ชื่อ ราคา Common syntaxไวยากรณ์ทั่วไป
Concurrency and ordering claimsข้ออ้างเรื่องการทำงานพร้อมกันและลำดับ Formatting conventionsธรรมเนียมการจัดรูปแบบ
The right column is visible when it's wrong. The left column is invisible until a customer finds it.
คอลัมน์ขวาผิดแล้วเห็นเลย คอลัมน์ซ้ายผิดแล้วมองไม่เห็น จนกว่าลูกค้าจะเจอ
Rocks and trees along a beach on Ko Pha-ngan
17:15

Nobody down here is talking about tokens.

ตรงนี้ไม่มีใครคุยเรื่องโทเคนกันแล้ว

09 · Both tracks
09 · ทุกสาย

The prompt sequence.

ลำดับพร้อมต์

The shape of the actual session, reduced to its load-bearing moments. Adapt the words; keep the order.

โครงของการทำงานจริง เหลือไว้เฉพาะจังหวะที่รับน้ำหนัก ปรับคำได้ แต่รักษาลำดับไว้

1 · Frame and reference

1 · ตั้งกรอบและให้ตัวอย่าง

Here's a screenshot of a site whose feel I want [attach].
Build a landing page for [product] aimed at [one reader].
Success is [one measurable outcome].
One HTML file, no framework, no build step.
Before you start, ask me anything that would change what you build.
นี่คือภาพหน้าจอของเว็บที่ฉันอยากได้ฟีลแบบนี้ [แนบไฟล์]
ทำหน้าแลนดิ้งให้ [สินค้า] สำหรับ [คนอ่านคนเดียว]
ถือว่าสำเร็จเมื่อ [ผลลัพธ์ที่วัดได้หนึ่งอย่าง]
ไฟล์ HTML เดียว ไม่ใช้เฟรมเวิร์ก ไม่มีขั้นตอน build
ก่อนเริ่ม ถามมาก่อนถ้ามีอะไรที่จะเปลี่ยนสิ่งที่คุณสร้าง

2 · Build with verification attached

2 · สั่งงานพร้อมสั่งตรวจ

Build the page. Then, in the same turn, confirm the tags balance,
every internal link resolves to a file that exists, and every
image has alt text. Show me the output of those checks.
ทำหน้านี้ แล้วในรอบเดียวกันนั้น ยืนยันว่าแท็กเปิดปิดครบ
ลิงก์ภายในทุกอันไปถึงไฟล์ที่มีอยู่จริง และรูปทุกรูปมี alt text
แล้วโชว์ผลการตรวจให้ดูด้วย

3 · Model the data TRACK B

3 · ออกแบบข้อมูล TRACK B

Design the schema. The rule that must never break is [invariant].
Enforce it with a database constraint, not application logic.
Then run the migrations against a real database and show me it works.
ออกแบบโครงฐานข้อมูล กฎที่ห้ามพังเด็ดขาดคือ [กฎ]
บังคับด้วย constraint ในฐานข้อมูล ไม่ใช่ตรรกะฝั่งแอป
แล้วรัน migration กับฐานข้อมูลจริง แล้วให้เห็นว่ามันทำงาน

4 · Prove the hard part

4 · พิสูจน์ส่วนที่ยาก

Write the tests that try to break the [invariant], including one
that bypasses the application layer entirely. Run them.
Tell me plainly which guarantees are tested and which are reasoned about.
เขียนเทสต์ที่พยายามทำให้ [กฎ] พัง รวมถึงตัวที่ข้ามชั้นแอปไปเลย
รันให้ดู แล้วบอกตรง ๆ ว่าข้อรับประกันไหนถูกเทสต์จริง
ข้อไหนแค่ให้เหตุผลไว้เฉย ๆ

5 · Payments

5 · ระบบเงิน

Wire up checkout. The price must come from the database, never
the request body. Confirm payment only in the signed webhook,
verified against the raw body, and make it idempotent.
Then test: send a forged amount, and replay the same event twice.
ต่อระบบ checkout ราคาต้องมาจากฐานข้อมูล ห้ามมาจาก request body
ยืนยันการจ่ายเงินใน webhook ที่ตรวจลายเซ็นกับ raw body เท่านั้น
และทำให้รันซ้ำแล้วไม่พัง
แล้วเทสต์ ส่งจำนวนเงินปลอมมาหนึ่งครั้ง แล้วยิง event เดิมซ้ำอีกรอบ

6 · Ship

6 · ปล่อยขึ้นจริง

Prepare it for deployment. Validate the config against the
platform's published schema rather than assuming field names.
List every placeholder, stub and invented fact still in the project.
เตรียมสำหรับดีพลอย ตรวจคอนฟิกกับ schema ที่แพลตฟอร์มเผยแพร่ไว้
อย่าเดาชื่อฟิลด์เอง
แล้วลิสต์ทุกอย่างที่ยังค้างอยู่ในโปรเจกต์ ทั้งของหลอก stub
และข้อมูลที่แต่งขึ้น
The last prompt is the important one
พร้อมต์สุดท้ายคือตัวที่สำคัญที่สุด

Asking for the list of what is still fake, at the end of every session, is the single highest-value habit in this document. It costs one sentence. It is the difference between a demo and a product.

การขอรายการว่ายังมีอะไรปลอมอยู่บ้าง ตอนจบทุกรอบการทำงาน คือนิสัยที่คุ้มที่สุดในเอกสารทั้งฉบับ ราคาแค่หนึ่งประโยค และมันคือเส้นแบ่งระหว่างเดโมกับสินค้าจริง

The one-page checklist

เช็กลิสต์หน้าเดียว

Four-line brief written down before the first promptเขียนบรีฟสี่บรรทัดก่อนพร้อมต์แรก
Standards loaded at the start of the sessionป้อนมาตรฐานตั้งแต่เริ่มรอบ
Real reference material pasted, not describedวางของอ้างอิงจริง ไม่ใช่อธิบายเอา
Every build request carries its verificationทุกคำสั่งสร้างมีคำสั่งตรวจติดไปด้วย
Invariants enforced by database constraintsบังคับกฎที่ห้ามผิดด้วย constraint ในฐานข้อมูล
Prices read server-side, never from the requestราคาอ่านฝั่งเซิร์ฟเวอร์ ไม่เอาจากคำขอ
Payment confirmed only in the signed webhookยืนยันการจ่ายเงินใน webhook ที่มีลายเซ็นเท่านั้น
Duplicate events proven harmless by testพิสูจน์ด้วยเทสต์ว่า event ซ้ำไม่ทำให้พัง
Public key confirmed unable to read private tablesยืนยันว่า public key อ่านตารางส่วนตัวไม่ได้
Ignore rules tested with a planted fake secretทดสอบกฎ ignore ด้วยการวางคีย์ปลอมไว้จริง
Config validated against the published schemaตรวจคอนฟิกกับ schema ที่เผยแพร่ไว้
Every placeholder and invented fact written downจดของหลอกและข้อมูลที่แต่งขึ้นไว้ครบทุกจุด
A wooden boat on the sea off Ko Pha-ngan
Claude Camps

Bring the project you keep not finishing. Leave with it live.

เอาโปรเจกต์ที่ทำไม่จบสักทีมา แล้วกลับไปพร้อมของที่ขึ้นจริงแล้ว