Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证register program
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
ระบบเว็บที่ดูแลผู้เข้าร่วมงานครบวงจร ตั้งแต่ฟอร์มลงทะเบียนออนไลน์และอีเมลยืนยันพร้อม QR Code ไปจนถึงการสแกนเช็คอินหน้างานที่ทำงานได้แม้เน็ตหลุด และรายงานสรุปผลหลังจบงาน 📍 สถานะปัจจุบัน: เฟส 6 เสร็จแล้ว — ความปลอดภัยและ PDPA Rate limiting · Security headers · หน้านโยบาย · ลบข้อมูลอัตโนมัติตามกำหนด · ผ่าน WCAG AA เฟสถัดไปคือเฟส 7 — ทดสอบ · คู่มือ · ส่งมอบ สิ่งที่ต้องมีก่อน • Node.js 22 ขึ้นไป (ดาวน์โหลด) • ฐานข้อมูล PostgreSQL — แนะนำสมัคร Supabase ฟรี แล้วเลือก region Singapore查看完整 README ↗
ระบบเว็บที่ดูแลผู้เข้าร่วมงานครบวงจร ตั้งแต่ฟอร์มลงทะเบียนออนไลน์และอีเมลยืนยันพร้อม QR Code ไปจนถึงการสแกนเช็คอินหน้างานที่ทำงานได้แม้เน็ตหลุด และรายงานสรุปผลหลังจบงาน
📍 สถานะปัจจุบัน: เฟส 6 เสร็จแล้ว — ความปลอดภัยและ PDPA Rate limiting · Security headers · หน้านโยบาย · ลบข้อมูลอัตโนมัติตามกำหนด · ผ่าน WCAG AA เฟสถัดไปคือเฟส 7 — ทดสอบ · คู่มือ · ส่งมอบ
| เอกสาร | เนื้อหา |
|---|---|
docs/00-กระบวนการทำงานทั้งหมด.md | เอกสารหลัก — workflow 40 ขั้นตอน · คู่มือผู้ใช้ 3 กลุ่ม · โครงสร้างข้อมูล 20 ตาราง · แผนงาน 8 เฟส |
docs/UAT-checklist.md | เช็กลิสต์ทดสอบก่อนใช้งานจริง — รวมทุกข้อที่ต้องทดสอบจากทุกเฟสไว้ที่เดียว 202 ข้อ พร้อมช่องกรอกผล |
docs/DEPLOY.md | คู่มือ Deploy ขึ้นเครื่องจริง — Vercel + Supabase + Resend + Cloudflare R2 ทีละขั้นตอน |
| ส่วน | เทคโนโลยี | เหตุผล |
|---|---|---|
| Frontend + Backend | Next.js 15 (App Router) + TypeScript | ภาษาเดียวทั้งระบบ พัฒนาเร็ว หาคนดูแลต่อง่าย |
| สไตล์ | Tailwind CSS v4 + CSS Variables | เปลี่ยนธีมได้จากที่เดียว |
| ฐานข้อมูล | PostgreSQL (Supabase · region Singapore) | รองรับ transaction + row lock สำหรับตัดโควตาที่นั่ง |
| ORM | Drizzle ORM + drizzle-kit | type-safe และ migration ตรงไปตรงมา |
| ตรวจสอบข้อมูล | Zod | ใช้กฎเดียวกันทั้งฝั่ง client และ server |
| ฟอนต์ | IBM Plex Sans Thai + Sarabun | รองรับภาษาไทย อ่านง่าย self-host ผ่าน next/font |
| Hosting | Vercel (sin1) + Cloudflare + Resend | auto-scale ตอน spike · latency ต่ำสำหรับผู้ใช้ในไทย |
# 1. ดึงโค้ดลงเครื่อง
git clone https://github.com/Tikkieteddy/register.git
cd register
# 2. ติดตั้ง dependencies
npm install
# 3. คัดลอกไฟล์ตั้งค่า แล้วเปิดแก้ค่าจริง
cp .env.example .env.local # Windows PowerShell: Copy-Item .env.example .env.local
# 4. สร้างตารางในฐานข้อมูล
npm run db:migrate
# 5. ใส่ข้อมูลตัวอย่างสำหรับทดสอบ
npm run db:seed
# 6. เริ่มเซิร์ฟเวอร์
npm run dev
เปิดเบราว์เซอร์ที่ http://localhost:3000
💡 บน Windows: ถ้า path มีเว้นวรรค (เช่น
ai project) ต้องใส่เครื่องหมายคำพูดครอบเสมอ เช่นcd "C:\Users\TIKKIE\Desktop\ai project\register"
ดูคำอธิบายทุกตัวแปรพร้อมวิธีหาค่าได้ในไฟล์ .env.example
| ตัวแปร | จำเป็นเมื่อไร | คำอธิบายสั้น |
|---|---|---|
DATABASE_URL | ตั้งแต่แรก | Connection string ของ PostgreSQL |
NEXT_PUBLIC_SITE_URL | ตั้งแต่แรก | URL เต็มของเว็บ ใช้สร้างลิงก์ในอีเมลและ QR |
HASH_SALT | ก่อนขึ้น production | ใช้แฮช IP ก่อนบันทึก — ห้ามเก็บ IP ดิบตาม PDPA |
RESEND_API_KEY · EMAIL_FROM | เฟส 3 | ส่งอีเมลยืนยันพร้อม QR |
RECAPTCHA_SECRET_KEY · NEXT_PUBLIC_RECAPTCHA_SITE_KEY | เฟส 2 | ป้องกัน bot ที่หน้าฟอร์ม |
SESSION_SECRET | เฟส 4 | ใช้เซ็น session ของเจ้าหน้าที่และผู้ดูแล (ยาว ≥ 32 ตัวอักษร) |
R2_ACCOUNT_ID · R2_BUCKET · R2_ACCESS_KEY_ID · R2_SECRET_ACCESS_KEY · R2_PUBLIC_BASE_URL | ก่อน deploy | ที่เก็บไฟล์ภาพ — ถ้าไม่ใส่ ตอนพัฒนาจะเขียนลง public/uploads แทน แต่บนเครื่องจริงไฟล์จะหายทุกครั้งที่ deploy |
⚠️ ห้าม commit ไฟล์
.envหรือ.env.localเข้า git เด็ดขาด —.gitignoreกันไว้ให้แล้ว
| คำสั่ง | ทำอะไร |
|---|---|
npm run dev | เริ่มเซิร์ฟเวอร์สำหรับพัฒนา |
npm run build | build สำหรับขึ้น production |
npm run start | รันเวอร์ชัน production ที่ build แล้ว |
npm run typecheck | ตรวจชนิดข้อมูลด้วย TypeScript |
npm run lint | ตรวจคุณภาพโค้ดด้วย ESLint |
npm run db:generate | สร้างไฟล์ migration จาก schema ที่แก้ไข |
npm run db:migrate | รัน migration ที่ยังไม่ได้รันเข้าฐานข้อมูล |
npm run db:push | ดันโครงสร้างเข้าฐานข้อมูลตรง ๆ (ใช้เฉพาะตอนพัฒนา) |
npm run db:studio | เปิดหน้าเว็บดูและแก้ข้อมูลในฐานข้อมูล |
npm run db:seed | ใส่ข้อมูลตัวอย่างสำหรับทดสอบ (งาน · ช่วงเวลา · คำถาม · ลิงก์ · บัญชีผู้ใช้) |
npm run db:demo | สร้างผู้ลงทะเบียนสมมติ 120 คน เพื่อดูหน้า Dashboard ว่ามีข้อมูลจริงแล้วหน้าตาเป็นอย่างไร |
npm run db:reset-demo | ล้างข้อมูลผู้ลงทะเบียนทั้งหมด (ใช้เฉพาะเครื่องพัฒนา) |
npm run test:quota | ทดสอบว่าการตัดโควตาที่นั่งทนต่อการกดพร้อมกัน |
npm run test:e2e | ทดสอบ flow ลงทะเบียนจริงบนเบราว์เซอร์ (ต้องเปิดเซิร์ฟเวอร์ที่พอร์ต 3100 ก่อน) |
npm run email:preview | เรนเดอร์อีเมลยืนยันออกมาเป็นไฟล์ HTML ไว้ตรวจหน้าตาโดยไม่ต้องส่งจริง |
npm run user:password <อีเมล> <รหัสผ่าน> | ตั้งรหัสผ่านให้บัญชีเจ้าหน้าที่หรือผู้ดูแล |
npm run check:deploy | ตรวจความพร้อมก่อน deploy — env ครบไหม ต่อฐานข้อมูลได้ไหม migration ครบหรือยัง |
register/
├── docs/ เอกสารกระบวนการทำงาน
├── drizzle/ ไฟล์ migration SQL (สร้างอัตโนมัติ ห้ามแก้ด้วยมือ)
├── public/ ไฟล์สาธารณะ เช่น รูปภาพ
├── src/
│ ├── app/ หน้าเว็บและ API (Next.js App Router)
│ │ ├── globals.css Design Token — สีธีมและตัวแปรทั้งหมดอยู่ที่นี่
│ │ ├── layout.tsx โครงหลักของทุกหน้า + ฟอนต์ไทย
│ │ ├── e/[slug]/ หน้ารายละเอียดงาน และฟอร์มลงทะเบียน
│ │ ├── ticket/[token]/ หน้าเสร็จสิ้น บัตรออนไลน์ ตั๋วพิมพ์ และไฟล์ปฏิทิน
│ │ ├── r/[code]/ ลิงก์สั้นติดตามผล
│ │ ├── staff/ ระบบหน้างาน: สแกน QR ค้นหา walk-in และพิมพ์บัตร
│ │ ├── admin/ หลังบ้าน: Dashboard 11 กราฟ · รายชื่อ · อีเมล · ลิงก์ · สื่อ · ตั้งค่า
│ │ ├── actions/ Server Actions (จองที่นั่ง บันทึกลงทะเบียน จัดการหลังบ้าน)
│ │ └── api/ ส่งอีเมลซ้ำ บันทึกการแชร์ คืนที่นั่ง Export QR ของลิงก์
│ ├── components/ ส่วนประกอบหน้าจอ แยกตาม form / ui / landing / ticket / admin / charts
│ ├── i18n/ ข้อความ 2 ภาษา (ค่าเริ่มต้นภาษาไทย)
│ ├── db/
│ │ ├── schema/ โครงสร้างฐานข้อมูล 20 ตาราง
│ │ ├── index.ts การเชื่อมต่อฐานข้อมูล
│ │ └── seed.ts ข้อมูลตัวอย่าง
│ ├── lib/
│ │ ├── env.ts ตรวจสอบ environment variables
│ │ ├── quota.ts ⭐ ตรรกะตัดโควตาที่นั่ง (จุดสำคัญที่สุดของระบบ)
│ │ ├── hash.ts แฮช IP ก่อนบันทึกตามข้อกำหนด PDPA
│ │ ├── codes.ts สร้างรหัสผู้ลงทะเบียนและโค้ดตั๋ว
│ │ ├── validation.ts กฎตรวจข้อมูล ใช้ร่วมกันทั้ง client และ server
│ │ ├── qr.ts สร้าง QR Code (PNG / SVG / data URI)
│ │ ├── calendar.ts ลิงก์ Google Calendar และไฟล์ .ics
│ │ ├── ticket.ts query ตั๋วที่ทุกหน้าใช้ร่วมกัน
│ │ ├── tracking.ts บันทึกคลิกและการแชร์ลิงก์
│ │ ├── storage.ts ชั้นเก็บไฟล์ — เลือก R2 หรือดิสก์ในเครื่องอัตโนมัติ
│ │ ├── storage/ ตัวเชื่อม Cloudflare R2 และดิสก์ในเครื่อง
│ │ ├── audit.ts บันทึกทุกการเข้าถึงและแก้ไขข้อมูลตาม PDPA
│ │ ├── admin/ query ของ Dashboard · รายชื่อ · Export xlsx/CSV · ประมวลผลภาพ
│ │ ├── auth/ เข้าสู่ระบบและ session ของเจ้าหน้าที่
│ │ ├── offline/ IndexedDB คิวเช็คอิน และเสียงแจ้งผลสแกน
│ │ └── email/ เทมเพลตอีเมล และระบบส่งพร้อม retry
│ └── types/ ประกาศชนิดข้อมูลเพิ่มเติม
├── scripts/ สคริปต์ทดสอบและเครื่องมือช่วยพัฒนา
├── tests/ ทดสอบ flow จริงบนเบราว์เซอร์
├── .env.example ตัวอย่างการตั้งค่า
└── .github/workflows/ci.yml ตรวจโค้ดอัตโนมัติทุกครั้งที่ push
| กลุ่ม | ตาราง |
|---|---|
| งานและฟอร์ม | events · event_sessions · form_questions · form_options · settings |
| ผู้ลงทะเบียน | registrations · registration_sessions · registration_answers · seat_holds · consents |
| ตั๋วและเช็คอิน | tickets · check_ins · badge_prints |
| ผู้ใช้ระบบ | users |
| ภาพและการตลาด | media_assets · share_links · link_events |
| ระบบเบื้องหลัง | email_logs · audit_logs · calendar_syncs |
การตัดโควตาที่นั่ง (src/lib/quota.ts)
ต้องทำใน transaction พร้อม SELECT ... FOR UPDATE เสมอ
ถ้าเขียนแบบอ่านมาบวกแล้วเขียนกลับธรรมดา จะรับลงทะเบียนเกินโควตาตอนคนกดพร้อมกัน
QR token (tickets.qrToken)
ต้องเป็น UUID สุ่มเท่านั้น ห้ามใส่ชื่อ อีเมล หรือเบอร์โทรลงใน QR โดยตรง
และต้องตรวจสอบฝั่งเซิร์ฟเวอร์ทุกครั้ง ห้ามเชื่อข้อมูลจากฝั่ง client
IP address (ipHash · visitorHash)
ต้องผ่าน hashIdentifier() ใน src/lib/hash.ts ก่อนบันทึกเสมอ
ห้ามเขียน IP ดิบลงฐานข้อมูล ตามข้อกำหนด PDPA
พารามิเตอร์ติดตามผล (ref · utm_*)
ต้องส่งต่อจากหน้า Landing ไปหน้าฟอร์มเสมอ ไม่งั้นจะวัดไม่ได้ว่าคนที่ลงทะเบียนสำเร็จ
มาจากลิงก์ไหน — ข้อมูลนี้เก็บย้อนหลังไม่ได้
กล้องและ Service Worker ต้องใช้ HTTPS
เบราว์เซอร์อนุญาตให้ใช้กล้องและ Service Worker เฉพาะเว็บที่เป็น HTTPS เท่านั้น
(ยกเว้น localhost) — ถ้าเจ้าหน้าที่เข้าผ่าน http จะสแกนไม่ได้และใช้ออฟไลน์ไม่ได้ทั้งคู่
ต้องกด "ดาวน์โหลดรายชื่อ" ก่อนวันงาน ถ้าไม่ได้ดาวน์โหลดลงเครื่องไว้ล่วงหน้า เมื่อ Wi-Fi ในงานล่มจะสแกนไม่ได้เลย
ห้ามเชื่อ navigator.onLine อย่างเดียว (src/components/staff/)
เน็ตในงานอีเวนต์มักเป็นแบบ ต่อ Wi-Fi ติดแต่ออกอินเทอร์เน็ตไม่ได้ ซึ่งเบราว์เซอร์
ยังรายงานว่าออนไลน์อยู่ ทุกจุดที่เรียกเซิร์ฟเวอร์จึงต้องมี try/catch
แล้วตกไปใช้ข้อมูลในเครื่องเสมอ พร้อมรายงานผลผ่าน reportServerReachable()
ถ้าไม่ทำ การค้นหาจะขึ้นว่า "ไม่พบผู้ลงทะเบียน" ทั้งที่คนนั้นลงทะเบียนไว้แล้ว
และการเช็คอินจะหายไปทั้งรายการ
/admin)เข้าได้เฉพาะบัญชีที่มีสิทธิ์ admin เท่านั้น · ทุกการกระทำถูกบันทึกลง audit_logs ตามข้อกำหนด PDPA
| หน้า | ทำอะไรได้ |
|---|---|
| Dashboard | ตัวเลขสรุป 6 ค่า + กราฟ 11 ชุด · คลิกที่แท่งกราฟเพื่อดูรายชื่อเบื้องหลังตัวเลขนั้น |
| ผู้ลงทะเบียน | ค้นหาคำเดียวครอบ ชื่อ/อีเมล/เบอร์/รหัส · กรอง 7 แบบ · แก้ไข · ยกเลิกแล้วคืนที่นั่งทันที · ส่งอีเมลซ้ำทีละหลายคน · เพิ่มด้วยมือ · ลบข้อมูลส่วนบุคคลตามคำขอ PDPA |
| Export | Excel (.xlsx) และ CSV UTF-8 with BOM · ใช้ตัวกรองเดียวกับที่ตั้งไว้บนหน้าจอ · รายงานสรุป PDF พร้อมกราฟ |
| จัดการอีเมล | ดูสถานะทุกฉบับ · ปุ่ม ส่งอีเมลทดสอบหาตัวเอง · ปุ่มส่งซ้ำทั้งหมดที่ล้มเหลว |
| ลิงก์ติดตามผล | สร้างลิงก์สั้นแยกช่องทาง · ดาวน์โหลด QR (PNG/SVG) · ดูคลิก · ลงทะเบียน · อัตราแปลง · มาจริง รายลิงก์ |
| ภาพและสื่อ | อัปโหลดภาพ 8 ประเภท · แปลง WebP/AVIF และย่อหลายขนาดอัตโนมัติ · เตือนเมื่อผิดสัดส่วน · ลบสคริปต์ที่ฝังในไฟล์ SVG |
| ตั้งค่างาน | ข้อมูลงาน · ที่นั่งและโควตา · คำถามในฟอร์ม · ผู้ใช้งาน · ความเป็นส่วนตัว |
| บันทึกการใช้งาน | ดู audit log ย้อนหลัง — ใครเข้าถึง แก้ไข หรือส่งออกข้อมูลอะไร เมื่อไร (อ่านอย่างเดียว แก้ไม่ได้) |
| กฎ | เหตุผล |
|---|---|
| ลดโควตาต่ำกว่าจำนวนที่จองไปแล้วไม่ได้ | ไม่งั้นระบบจะค้างในสถานะ "รับเกิน" ที่แก้ไม่ได้ และหน้าเว็บจะโชว์ที่นั่งติดลบ |
| ไม่มีปุ่มลบลิงก์ติดตามผล | การลบทำให้ผู้ลงทะเบียนที่มาจากลิงก์นั้นกลายเป็น "ไม่ทราบที่มา" ทั้งหมด — ใช้ปุ่ม "ปิด" แทน |
| ไม่มีปุ่มลบตัวเลือกในฟอร์ม | คำตอบของคนที่เคยเลือกจะหายจากกราฟ — ให้ติ๊ก "แสดง" ออกแทน |
| ไม่มีปุ่มลบบัญชีผู้ใช้ | audit log อ้างถึงบัญชีอยู่ — ให้ใช้การระงับแทน |
| ผู้ดูแลถอดสิทธิ์หรือปิดบัญชีตัวเองไม่ได้ | กันกรณีเผลอทำแล้วไม่มีใครเข้าหลังบ้านได้อีกเลย |
| ลบข้อมูลส่วนบุคคลแต่เก็บสถิติไว้ | คำขอลบตาม PDPA ต้องทำได้ แต่รายงานย้อนหลังต้องไม่เพี้ยน |
| ทุกครั้งที่ Export ต้องบันทึกว่าใครดึงอะไรออกไปกี่รายการ | ข้อกำหนดของ PDPA |
สีทั้งหมดถูกกำหนดเป็น CSS Variables ที่ src/app/globals.css
ห้าม hard-code ค่าสีกระจายทั่วโค้ด ให้เรียกใช้ผ่านตัวแปรเสมอ เพื่อให้เปลี่ยนธีมได้จากที่เดียว
| ตัวแปร | ค่า | ใช้กับ |
|---|---|---|
--color-primary | #EC5F27 | ปุ่มหลัก · หัวข้อสำคัญ · ลิงก์ · กราฟ |
--color-primary-dark | #C94A18 | hover / active |
--color-primary-light | #FFF1EA | พื้นหลังอ่อน |
--color-primary-contrast | #FFFFFF | ตัวอักษรบนพื้นสีหลัก |
--color-danger | #D32F2F | ข้อความ error — ตั้งใจแยกจากสีส้ม CI ไม่ให้ปนกัน |
ทุกครั้งที่ push ขึ้น GitHub ระบบจะรันอัตโนมัติ (.github/workflows/ci.yml):
npm audit)รันเองก่อน commit ได้ด้วย:
npm run typecheck && npm run lint && npm run build
| เฟส | ชื่อ | สถานะ |
|---|---|---|
| 0 | เอกสารกระบวนการทำงาน | ✅ เสร็จ |
| 1 | วางรากฐานโปรเจกต์ | ✅ เสร็จ |
| 2 | หน้า Public + ฟอร์มลงทะเบียน | ✅ เสร็จ |
| 3 | QR + อีเมล + หน้าเสร็จสิ้น | ✅ เสร็จ |
| 4 | ระบบหน้างาน (Staff PWA) | ✅ เสร็จ |
| 5 | ระบบหลังบ้าน (Admin) | ✅ เสร็จ |
| 5.5 | หน้าแรกรวมงาน + รองรับหลายอีเวนต์ | ✅ เสร็จ |
| 6 | ความปลอดภัยและ PDPA | ✅ เสร็จ |
| 7 | ทดสอบ · Deploy · ส่งมอบ | ⏭️ ถัดไป |