Supabase Waitlist Playbook สำหรับ Non-Coder | Vibe Coding สำหรับคนไม่ใช่โปรแกรมเมอร์ | Vibe Coding Thailand
$ cat appendix-e-supabase-waitlist-playbook.md
Supabase Waitlist Playbook สำหรับ Non-Coder ใช้ appendix นี้เมื่อไหร่
ใช้เมื่อคุณมี landing page แล้วอยากเพิ่ม form เก็บ email เช่น:
waitlist
lead capture
early access
newsletter signup
contact interest form คัดลอก
เป้าหมายคือทำ database flow ที่เล็ก ปลอดภัย และ test ได้:
form → validate → insert into Supabase → success/error state → test local → deploy → test production คัดลอก
ไม่ใช่สอน Supabase ทั้งหมด
เราจะทำเฉพาะ waitlist version แรกที่ non-coder คุมความเสี่ยงได้
ภาพรวมแบบภาษาคน
Supabase ใน playbook นี้มี 4 ชิ้นที่ต้องรู้:
ชิ้น แปลแบบง่าย Project พื้นที่หนึ่งสำหรับ database/app ของคุณ Table ตารางเก็บข้อมูล คล้าย sheet API key key ให้ app ต่อกับ Supabase RLS / Policy กฎว่าใครทำอะไรกับข้อมูลได้บ้าง
สำหรับ waitlist ที่ปลอดภัยแบบพื้นฐาน:
public user กรอก form ได้
public user insert row ได้
public userอ่านรายชื่อทั้งหมดไม่ได้
public userแก้/ลบข้อมูลไม่ได้
admin/owner ดูข้อมูลใน Supabase dashboard ได้ คัดลอก
ก่อนเริ่ม: ลด scope ให้เล็กที่สุด อย่าเริ่มจาก “ระบบสมาชิก + dashboard + email automation + payment” พร้อมกัน
email
name optional
use_case optional
created_at automatic คัดลอก ไม่ควรเก็บตอนแรกถ้าไม่จำเป็น:
เบอร์โทร
ที่อยู่
วันเกิด
เลขบัตร
password
ข้อมูลสุขภาพ/การเงิน/กฎหมาย คัดลอก ช่วย review waitlist fields ของ app นี้
แยกเป็น:
1. จำเป็นจริง ๆ
2. optional
3. ไม่ควรเก็บตอนนี้
อธิบายความเสี่ยงด้าน privacy/security แบบ non-coder
อย่าเพิ่งสร้าง table คัดลอก
Step 1 — สร้าง Supabase project ไปที่ Supabase Dashboard แล้วสร้าง project ใหม่
สิ่งที่ต้องจดไว้ใน note ส่วนตัว:
Project name:
Organization:
Region:
Project URL:
Date created:
Owner: คัดลอก อย่าจด database password หรือ secret key ลงใน manuscript, README, หรือ chat prompt ถ้าไม่จำเป็น
หลังสร้าง project แล้ว ให้เข้าใจว่า Supabase project มี Postgres database ให้คุณใช้
Supabase docs ระบุว่า Table Editor ช่วยให้ใช้งาน database ได้คล้าย spreadsheet ซึ่งเหมาะกับมือใหม่
Step 2 — เลือกวิธีสร้าง table
วิธี A: Table Editor เหมาะกับ non-coder เพราะเห็นหน้าตาเป็นตาราง
table ง่าย
field น้อย
ยังไม่มั่นใจ SQL
วิธี B: SQL Editor เหมาะเมื่ออยากให้ setup ทำซ้ำได้ และให้ Claude review ได้ชัด
ต้องการสร้าง table + RLS + policy เป็นชุดเดียว
ต้องการเก็บ script ไว้ใน docs
มี developer ช่วย review ได้
สำหรับหนังสือเล่มนี้ แนะนำให้ Claude สร้าง SQL แล้วให้คุณ review ก่อนรัน
ไม่ใช่ให้ Claude กดหรือรันใน dashboard แทนคุณโดยไม่เข้าใจ
Step 3 — Table schema สำหรับ waitlist v1 Schema เริ่มต้นที่พอสำหรับ waitlist:
Field Type แบบเข้าใจง่าย จำเป็นไหม ใช้ทำอะไร idauto number yes id ของ row emailtext yes ติดต่อกลับ nametext no เรียกชื่อ use_casetext no รู้ว่า user สนใจอะไร created_attimestamp yes รู้ว่าสมัครเมื่อไหร่
waitlist ไม่ใช่ระบบ account
Step 4 — SQL starter สำหรับ waitlist insert-only ตัวอย่างนี้เป็น starter สำหรับ waitlist ที่ public user insert ได้ แต่ไม่มี policy ให้ public select/update/delete
ให้ใช้เป็นจุดเริ่มต้น ไม่ใช่กฎหมายตายตัว
-- Waitlist table: public can submit, but cannot read all rows
create table if not exists public.waitlist_leads (
id bigint generated always as identity primary key ,
email text not null ,
name text ,
use_case text ,
created_at timestamptz not null default now ()
);
-- Optional: prevent exact duplicate emails.
-- This is simple and case-sensitive. If you need case-insensitive uniqueness,
-- ask a developer to review the best approach.
create unique index if not exists waitlist_leads_email_unique
on public.waitlist_leads (email);
-- Enable Row Level Security.
alter table public.waitlist_leads enable row level security ;
-- Allow anonymous/public clients to insert only.
grant insert on public.waitlist_leads to anon;
-- RLS policy: public can submit a row that passes basic checks.
create policy "Public can submit waitlist"
on public.waitlist_leads
for insert
to anon
with check (
email is not null
and length (email) <= 320
and ( name is null or length ( name ) <= 120 )
and (use_case is null or length (use_case) <= 1000 )
); คัดลอก สิ่งที่ intentionally ไม่มี:
ไม่มี select policy สำหรับ anon
ไม่มี update policy สำหรับ anon
ไม่มี delete policy สำหรับ anon คัดลอก แปลว่า public user ไม่ควรอ่าน/แก้/ลบข้อมูลคนอื่นผ่าน API ได้
ก่อนรัน SQL ให้ใช้ prompt นี้:
ช่วย review SQL waitlist นี้ก่อนรันใน Supabase
ฉันเป็น non-coder
ตรวจว่า:
1. table เก็บข้อมูลเท่าที่จำเป็นไหม
2. RLS เปิดไหม
3. anon ทำได้เฉพาะ insert ใช่ไหม
4. anon select/update/delete ได้ไหม
5. มี secret หรือ admin key เกี่ยวข้องไหม
6. มี risk อะไรที่ต้องรู้ก่อนใช้จริง
อย่าเสนอปิด RLS คัดลอก
Step 5 — หา Supabase URL และ publishable key Supabase docs ระบุว่าส่วนใหญ่เอา key ได้จาก Connect dialog หรือ Settings > API Keys
สำหรับ waitlist frontend ทั่วไป คุณต้องใช้:
Project URL
Publishable key คัดลอก ใน legacy project อาจเห็นชื่อ anon key
Key ใช้ตรงไหน ปลอดภัยใน browser ไหม Publishable key frontend/public app ใช้ได้ ถ้ามี RLS/policy anon key legacy frontend/public app ใช้ได้ ถ้ามี RLS/policy Secret key backend/server เท่านั้น ห้าม browser service_role legacy backend/server/admin เท่านั้น ห้าม browser
publishable key ไม่ใช่ password สำหรับป้องกัน data
RLS/policy ต่างหากที่ป้องกัน data คัดลอก ถ้า Claude เสนอให้ใช้ service_role เพื่อให้ insert ผ่าน ให้หยุดทันที
Step 6 — ใส่ค่าใน .env.local สำหรับ local development ให้สร้าง .env.local
NEXT_PUBLIC_SUPABASE_URL = your-project-url
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY = your-publishable-key คัดลอก ควรมี .env.example แบบ placeholder:
NEXT_PUBLIC_SUPABASE_URL = your-supabase-project-url
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY = your-supabase-publishable-key คัดลอก ช่วยตรวจ env setup สำหรับ Supabase waitlist
กติกา:
- อย่า print ค่า key จริง
- ตรวจว่าควรมี variable ชื่ออะไร
- ตรวจว่า .env.local ไม่ควรถูก commit
- ตรวจว่า .env.example มีแต่ placeholder
- บอกว่า variable ไหน public และ variable ไหนห้ามอยู่ frontend คัดลอก
ก่อนให้ Claude แก้ code ให้สั่งวาง plan
ช่วยวาง plan เพื่อต่อ waitlist form เข้ากับ Supabase
Context:
- table: waitlist_leads
- fields: email, name, use_case
- env vars: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
กติกา:
- อย่าเพิ่งแก้ไฟล์
- ใช้ publishable key เท่านั้นใน frontend
- ห้ามใช้ secret/service_role ใน frontend
- ต้องมี validation
- ต้องมี success/error state
- ต้องไม่ log key หรือข้อมูลส่วนตัวเกินจำเป็น
- ระบุไฟล์ที่จะเปลี่ยน
- ระบุ manual test หลังแก้ คัดลอก หลัง plan ผ่าน ค่อยให้แก้:
โอเค ทำตาม plan ได้
เปลี่ยนเฉพาะ waitlist form และ Supabase client ที่จำเป็น
หลังแก้ให้สรุป diff และ manual test checklist คัดลอก
Step 8 — Validation ที่ควรมี email ต้องไม่ว่าง
email ต้องหน้าตาคล้าย email
email ยาวไม่เกิน 320 ตัวอักษร
name optional แต่ถ้ามีต้องไม่ยาวเกิน
use_case optional แต่ถ้ามีต้องไม่ยาวเกิน คัดลอก อย่า rely เฉพาะ placeholder ใน form
ช่วย review waitlist form validation
ตรวจทั้ง frontend และ database/RLS policy
บอกว่า:
- ตอนนี้ validate อะไรแล้ว
- ยังขาดอะไร
- error message user อ่านเข้าใจไหม
- มี input ที่ทำให้ app พังได้ไหม
อย่าเพิ่งแก้ code คัดลอก
Step 9 — Test local เมื่อ Claude ต่อ form แล้ว ให้ test ในเครื่องก่อน
[ ] เปิด local URL ได้
[ ] submit email ที่ถูกต้องแล้ว success
[ ] row เข้า Supabase table
[ ] email ว่างแล้ว error
[ ] email ไม่ถูก format แล้ว error
[ ] submit ซ้ำแล้ว behavior ชัดเจน
[ ] name/use_case ยาวมากไม่ทำให้ app พัง
[ ] error message ไม่โชว์ technical secret
[ ] console ไม่ log key หรือข้อมูลเกินจำเป็น คัดลอก ถ้ามี duplicate email แล้ว error ให้ตัดสินใจว่าจะให้ user เห็นข้อความแบบไหน
อีเมลนี้อยู่ใน waitlist แล้ว คัดลอก duplicate key value violates unique constraint waitlist_leads_email_unique คัดลอก
Step 10 — ตรวจว่า public อ่าน data ไม่ได้ จุดสำคัญที่สุดของ waitlist คือ public submit ได้ แต่ไม่ควรอ่าน email ทุกคนได้
ให้ Claude ช่วยตรวจด้วย prompt:
ช่วยตรวจว่า public/anon user อ่านข้อมูล waitlist ทั้งหมดไม่ได้
กติกา:
- อย่าใช้ service_role ในการ test ฝั่ง public
- อธิบายว่าจะ test อย่างไร
- ตรวจ RLS policies
- ตรวจว่าไม่มี frontend page/API route ที่ expose list ทั้งหมด
- ถ้าต้องรัน command ให้บอกก่อนว่าทำอะไร คัดลอก ถ้า Claude บอกว่า “สร้าง select policy ให้ anon เพื่อ debug” ให้หยุด
สำหรับ waitlist public ไม่จำเป็นต้องให้ anon select รายชื่อทั้งหมด
Step 11 — ตรวจ secret ก่อน commit [ ] ไม่มี .env.local ถูก track
[ ] ไม่มี key จริงใน source code
[ ] ไม่มี service_role ใน frontend
[ ] ไม่มี screenshot ที่มี key จริง
[ ] .env.example มี placeholder เท่านั้น
[ ] README ไม่ใส่ key จริง คัดลอก ช่วย review changes ก่อน commit สำหรับ Supabase waitlist
ตรวจว่า:
1. เปลี่ยนไฟล์อะไร
2. มี secret/key จริงหลุดไหม
3. มี service_role หรือ secret key ใน frontend ไหม
4. RLS/policy ยังปลอดภัยไหม
5. manual test ที่ต้องทำก่อน deploy คืออะไร
6. commit message ควรเป็นอะไร
อย่า print ค่า secret จริง คัดลอก
Step 12 — ใส่ env vars ใน Vercel ถ้า deploy ไป Vercel ต้องใส่ env vars ใน Vercel ด้วย
สำหรับ waitlist frontend-only:
Variable Vercel Environment Public/Secret หมายเหตุ NEXT_PUBLIC_SUPABASE_URLPreview + Production Public Supabase project URL NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYPreview + Production Public ต้องมี RLS/policy
ถ้ามี server-side function จริง ๆ อาจมี secret key แต่สำหรับ waitlist v1 ไม่ควรต้องใช้
ถ้า Claude บอกว่าต้องใช้ secret key ให้ถาม:
ทำไม waitlist v1 ต้องใช้ secret key
มีวิธีใช้ publishable key + RLS policy แทนไหม
ถ้าต้องใช้ secret จริง ๆ มันอยู่ server-side เท่านั้นใช่ไหม คัดลอก หลังเพิ่ม env var ใน Vercel ต้อง redeploy เพื่อให้ deployment ใหม่ใช้ค่าใหม่
Step 13 — Test production หลัง deploy ผ่าน ให้ test production URL จริง
[ ] production page เปิดได้
[ ] form submit ได้
[ ] row เข้า Supabase table
[ ] invalid email แสดง error
[ ] duplicate email แสดงข้อความที่เข้าใจได้
[ ] mobile ใช้ได้
[ ] ไม่มี technical error โผล่ให้ user เห็น
[ ] ไม่มี key/secret โผล่ในหน้าเว็บ/log/error
[ ] ลบหรือ mark test row หลัง test คัดลอก ถ้า production ไม่เข้า Supabase แต่ local เข้า ให้ดู 5 จุดนี้:
1. Vercel env var ตั้งครบไหม
2. env var อยู่ใน Production environment ไหม
3. redeploy หลังตั้ง env var แล้วไหม
4. Supabase URL/key ถูก project เดียวกันไหม
5. RLS policy allow insert ให้ anon/publishable path ไหม คัดลอก production waitlist submit ไม่เข้า Supabase แต่ local ใช้ได้
ช่วย debug แบบ non-coder
ข้อมูล:
- production URL:
- env var names ที่ตั้งใน Vercel:
- table name:
- RLS policies:
- error message/log:
กติกา:
- อย่าเพิ่งแก้ไฟล์
- อย่า print ค่า key จริง
- แยกสาเหตุ env / RLS / table schema / validation / network
- เสนอวิธีตรวจทีละข้อ คัดลอก
Step 14 — ดูข้อมูล lead อย่างไร สำหรับ version แรก เจ้าของ project ดู lead ผ่าน Supabase Dashboard ได้
อย่าเพิ่งสร้าง public dashboard ถ้ายังไม่มี auth/permission ชัด
export เฉพาะข้อมูลที่จำเป็น
เก็บไฟล์ export ให้ปลอดภัย
ลบไฟล์ export ที่ไม่ใช้
อย่าส่ง CSV ที่มี email ผ่านช่องทางไม่ปลอดภัย คัดลอก ถ้าจะสร้าง admin dashboard ให้กลับไปใช้บท Internal Dashboard และ Security Checklist ก่อน
Common problems สำหรับ waitlist
Problem 1: Submit แล้วขึ้น error เรื่อง RLS
RLS เปิด แต่ยังไม่มี insert policy
policy ใช้ role ผิด
grant insert ให้ anon ยังไม่ถูก
field ไม่ผ่าน with check
Supabase insert ถูก RLS block
ช่วยอ่าน error นี้และ policy ปัจจุบัน
อธิบายว่า block เพราะอะไร
อย่าเสนอปิด RLS
เสนอ fix ที่ทำให้ public insert ได้เฉพาะ waitlist row เท่านั้น คัดลอก
Problem 2: Duplicate email error อ่านไม่รู้เรื่อง ควรแปลงเป็นข้อความ user-friendly
อีเมลนี้อยู่ใน waitlist แล้ว คัดลอก ช่วยปรับ duplicate email error ให้ user อ่านเข้าใจ
อย่าเปลี่ยน database schema ถ้าไม่จำเป็น
อย่าเปิดเผย constraint name หรือ SQL error ให้ user เห็น คัดลอก
Problem 3: Production ใช้ key ผิด project
local เข้า project A
production เข้า project B
ดู table แล้วไม่เห็น row
[ ] URL/key ใน .env.local และ Vercel เป็น project เดียวกันไหม
[ ] table มีอยู่ใน project production ไหม
[ ] Vercel redeploy แล้วไหม คัดลอก
Problem 4: Claude เสนอ service_role ใน frontend หยุดก่อน
service_role/secret key ห้ามอยู่ frontend ใช่ไหม
ช่วยเสนอ architecture ที่ไม่ expose secret
สำหรับ waitlist v1 ใช้ publishable key + RLS insert policy ได้ไหม คัดลอก
Problem 5: User submit ได้ แต่คุณไม่เห็น row
ดูผิด Supabase project
ดูผิด table
insert fail แต่ UI แสดง success ผิด
production ใช้ env var ผิด
duplicate error ถูกกลืนไว้
UI แสดง success แต่ฉันไม่เห็น row ใน Supabase
ช่วยทำ debug checklist
ตรวจทั้ง frontend response, Supabase project/table, env var, error handling
อย่าเพิ่งแก้ code คัดลอก
Waitlist launch checklist ก่อนเปิดให้คนอื่นกรอกจริง:
Data
[ ] เก็บเฉพาะ email/name/use_case หรือ field ที่จำเป็น
[ ] ไม่มี sensitive data ที่ไม่จำเป็น
Supabase
[ ] table ถูกต้อง
[ ] RLS enabled
[ ] anon insert ได้
[ ] anon select/update/delete ไม่ได้
[ ] Security Advisor ไม่มี issue สำคัญที่เกี่ยวกับ table นี้
Keys/env
[ ] ใช้ publishable key ใน frontend
[ ] ไม่มี secret/service_role ใน frontend
[ ] .env.local ไม่ถูก commit
[ ] Vercel env vars ตั้งครบใน Production
[ ] redeploy หลังแก้ env var แล้ว
App
[ ] validation ทำงาน
[ ] success/error state ชัด
[ ] duplicate email handled
[ ] mobile ใช้ได้
[ ] production submit แล้ว row เข้า
Ops
[ ] รู้ว่าจะดู lead ที่ไหน
[ ] test data ถูกลบ/mark แล้ว
[ ] มี launch note
[ ] มีวิธีปิด form ชั่วคราวถ้า spam หรือ error คัดลอก
Launch note template สำหรับ waitlist # Waitlist Launch Note
## Date/time
[ date/time ]
## URL
[production URL]
## Supabase project
[project name only, no keys]
## Table
waitlist_leads
## Data collected
- email
- name optional
- use_case optional
## RLS summary
- public/anon can insert
- public/anon cannot select/update/delete
## Env vars used
- NEXT_PUBLIC_SUPABASE_URL
- NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
## Production test
- [ ] submit valid email
- [ ] invalid email rejected
- [ ] duplicate handled
- [ ] row visible in dashboard
- [ ] mobile checked
## Known limitations
- [ TODO ]
## Owner
[ name ] คัดลอก
Prompt รวมท้าย appendix ใช้ prompt นี้ก่อนเปิด waitlist ให้คนอื่นใช้
ช่วยเป็น Supabase waitlist launch reviewer
ฉันเป็น non-coder
ตรวจ project นี้ตั้งแต่ form ถึง database:
1. data fields
2. Supabase table schema
3. RLS enabled หรือไม่
4. policies: anon insert / no anon select-update-delete
5. publishable vs secret/service_role keys
6. .env.local / .env.example / Vercel env vars
7. validation
8. success/error states
9. local test
10. production test
11. launch note
กติกา:
- อย่า print ค่า key จริง
- อย่าเสนอปิด RLS
- ถ้าเจอ secret/service_role ใน frontend ให้บอกเป็น Critical
- แยกผลเป็น Green / Yellow / Red
- เสนอ next steps ไม่เกิน 5 ข้อ คัดลอก อัปเดตล่าสุด: 25 พ.ค. 2569
ความคิดเห็น
ยังไม่มีความคิดเห็น
เป็นคนแรกได้เลย