Ecommerce Template
Modern ecommerce template built with Next.js 16, React 19, Drizzle, Better Auth, Supabase, and Stripe.
Find your address, order food and household items from local shops through Bawor Thai, with community news and ways to register merchants, riders, and village representatives.
AI translation
ค้นหาตำบลของคุณ สั่งอาหารและของใช้จากร้านในชุมชนผ่านบวรไทย พร้อมข่าวชุมชนและช่องทางสมัครร้านค้า ไรเดอร์ และตัวแทนตำบล
CommerceTypeScript · PLpgSQLGitHub @bhiddayaOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
ระบบสั่งอาหาร ส่งของ และเรียกรถ ภายในตำบลเดียวกัน โดยคนในตำบล ค่าส่งถูกกว่า ถึงเร็วกว่า และเงินหมุนอยู่ในชุมชน ออกแบบให้รองรับได้ถึงระดับ ~7,000 ตำบลทั่วประเทศ โดยแยกข้อมูลแต่ละตำบลที่ชั้นฐานข้อมูล (tambon_id) ไม่ใช่ที่ URL — เว็บเดียวจึงเสิร์ฟได้ทุกตำบล ⚠️ ตัวแปรที่ขึ้นต้น NEXT_PUBLIC_ ต้องตั้ง Type เป็น Config ใน Vercel ถ้าตั้งเป็น Secret จะไRead the full README ↗
ระบบสั่งอาหาร ส่งของ และเรียกรถ ภายในตำบลเดียวกัน โดยคนในตำบล ค่าส่งถูกกว่า ถึงเร็วกว่า และเงินหมุนอยู่ในชุมชน
ออกแบบให้รองรับได้ถึงระดับ ~7,000 ตำบลทั่วประเทศ โดยแยกข้อมูลแต่ละตำบลที่ชั้นฐานข้อมูล
(tambon_id) ไม่ใช่ที่ URL — เว็บเดียวจึงเสิร์ฟได้ทุกตำบล
| ส่วน | ใช้ |
|---|---|
| Frontend + API | Next.js 16 (App Router) · React 19 · TypeScript |
| Styling | Tailwind CSS v4 |
| ฐานข้อมูล + Auth | Supabase (PostgreSQL + Row Level Security) |
| Hosting | Vercel |
| ช่องทางผู้ใช้ | PWA + LINE OA / LIFF |
src/
├── app/
│ ├── customer/ ลูกค้า — สั่งอาหาร ส่งของ เรียกรถ ติดตามออร์เดอร์
│ ├── driver/ ไรเดอร์ — รับงาน ดูรายได้
│ ├── merchant/ ร้านค้า — คิวออร์เดอร์ เมนู
│ ├── admin/ ตัวแทนตำบล — อนุมัติสมาชิก ตั้งค่า
│ ├── t/[slug]/ หน้าสาธารณะของตำบล (ไม่ต้องล็อกอิน แชร์ลิงก์ได้)
│ └── api/line/ LINE Messaging API webhook
├── components/ UI ที่ใช้ร่วมกัน + LiffProvider
├── lib/
│ ├── supabase/ client (เบราว์เซอร์) · server (session) · admin (service role)
│ ├── auth-guard.ts ตรวจบทบาทก่อนเข้าหน้า
│ └── line.ts ตรวจลายเซ็น webhook · ส่งข้อความ · สร้างลิงก์ LIFF
├── proxy.ts middleware — รีเฟรช session cookie
└── services/ เรียก API ฝั่ง client
supabase/migrations/ migration ของฐานข้อมูล
wip/ โค้ดที่พักไว้ ยังไม่พร้อมใช้ (ดู wip/api-shops/README.md)
| ตัวแปร | จำเป็น | หมายเหตุ |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | ✅ | Supabase → Settings → API |
NEXT_PUBLIC_SUPABASE_ANON_KEY | ✅ | ใส่ publishable key (sb_publishable_…) — เปิดเผยได้ ความปลอดภัยอยู่ที่ RLS |
LINE_CHANNEL_SECRET | เฉพาะ LINE OA | ใช้ตรวจว่า request มาจาก LINE จริง |
LINE_CHANNEL_ACCESS_TOKEN | เฉพาะ LINE OA | ใช้ส่งข้อความกลับ |
NEXT_PUBLIC_LIFF_ID | เฉพาะ LINE OA | รหัส LIFF app |
SUPABASE_SERVICE_ROLE_KEY | ❌ | ไม่มีโค้ดส่วนไหนใช้แล้ว — ทุกหน้าใช้สิทธิ์ผู้ใช้/สาธารณะผ่าน RLS |
⚠️ ตัวแปรที่ขึ้นต้น
NEXT_PUBLIC_ต้องตั้ง Type เป็น Config ใน Vercel ถ้าตั้งเป็น Secret จะไม่ถูกส่งให้ build ค่าจึงไม่ถูกฝังลงโค้ด แล้วแอปจะต่อฐานข้อมูลไม่ได้
🔑 legacy key ถูกปิดถาวรแล้ว (4 ก.ย. 2569) — anon/service_role แบบ JWT ใช้ไม่ได้อีก โปรเจกต์นี้ใช้ระบบ key แบบใหม่เท่านั้น (
sb_publishable_…/sb_secret_…) ซึ่งหมุนแยกกันได้ ต่างจาก legacy ที่หมุนทีเดียวโดนทั้งคู่และทำให้เว็บล่ม
Authentication → Sign In / Providers → User Signups → Confirm email ต้อง "ปิด"
ผู้ใช้ที่สมัครด้วยเบอร์โทรจะได้อีเมลแฝงที่ส่งจริงไม่ได้ (ดู src/lib/identifier.ts)
ถ้าเปิด Confirm email ระบบจะพยายามส่งเมลยืนยันไปยังอีเมลแฝงนั้น แล้ว
การสมัครด้วยเบอร์โทรจะพังทั้งระบบ — พังแบบเงียบ ๆ ไม่มี error ให้เห็นบนหน้าเว็บ
ผู้ใช้แค่สมัครไม่ผ่านเฉย ๆ และจะโดน rate limit ของผู้ให้บริการเมลตามมา
การยืนยันตัวตนจริงของระบบนี้คือ ตัวแทนตำบลกดอนุมัติ (profiles.approved)
ไม่ใช่การยืนยันอีเมล จึงไม่ได้สูญเสียอะไรจากการปิดสวิตช์นี้
npm install
cp .env.example .env.local # แล้วเติมค่า Supabase
npm run dev
ก่อน deploy ควรทดสอบแบบไม่มี env vars ด้วย เพื่อจำลองสภาพ deploy ครั้งแรก:
mv .env.local .env.local.bak && npm run build && mv .env.local.bak .env.local
build ต้องผ่าน — โค้ดถูกออกแบบให้สร้าง Supabase client ตอนเรียกใช้จริง ไม่ใช่ตอน import
เพราะ next build จะ evaluate ทุก route module
next buildผ่านไม่ได้แปลว่าเว็บใช้ได้ — บั๊กบางแบบ (เช่นชื่อ dynamic segment ชนกัน) โผล่ตอนรันเซิร์ฟเวอร์เท่านั้น ควรnpm startแล้วลองเปิดสักหน้าก่อนเสมอ
migration อยู่ใน supabase/migrations/ เรียงตามวันที่
RLS เปิดครบทุกตาราง การเข้าถึงคุมที่ policy ไม่ใช่ที่โค้ด:
order_events เขียนได้เฉพาะ trigger ของระบบ ผู้ใช้อ่านได้เท่าที่เห็นออร์เดอร์แม่/t/<slug> อ่านด้วยสิทธิ์ anon และจำกัดคอลัมน์ด้วย GRANTเอกสารสถาปัตยกรรม แผนพัฒนา และคู่มือตัวแทนตำบล อยู่ใน Claude Project "โครงการ Delivery" ไม่ได้อยู่ใน repo นี้