# สรุปปัญหา ข้อผิดพลาด และ Checklist การสร้าง Tenant / Subdomain ใหม่ (Tenant Provisioning Post-Mortem & Standard Operating Procedure) บันทึกข้อผิดพลาดจากการสร้าง Showcase Subdomains (`wellness`, `fashion`, `beauty`, `moto`) บน `kittisak.com` เมื่อวันที่ 24 กันยายน 2026 เพื่อใช้เป็น Checklist ป้องกันการทำผิดพลาดซ้ำในอนาคต --- ## 1. ปัญหาและข้อผิดพลาดที่เกิดขึ้น (What Went Wrong) ### ข้อผิดพลาดหลักที่ 1: ลืมรันคำสั่ง Seed ฐานข้อมูล (ตกหล่นขั้นตอนที่ 8 ของ DEPLOYMENT_GUIDE.md) * **สิ่งที่เกิดขึ้น:** หลังจากสร้างฐานข้อมูล PostgreSQL ใหม่ทั้ง 4 ตัว (`wellness_db`, `fashion_db`, `beauty_db`, `moto_db`) ได้ทำการรัน `bunx prisma db push` เพื่อสร้าง Table โครงสร้างเสร็จสิ้น **แต่ไม่ได้รันคำสั่ง `bun run prisma/seed.cjs`** * **ผลกระทบ:** ตาราง `User` ในฐานข้อมูลใหม่ทั้งหมดมีข้อมูล **0 คน** เมื่อผู้ใช้พยายามล็อกอินเข้าหลังบ้าน (`admin..kittisak.com`) ระบบ Backend จึงหาชื่อผู้ใช้ไม่พบ และส่ง Error `401 Unauthorized` ทันที นอกจากนี้ข้อมูลตั้งต้น เช่น เมนู, หมวดหมู่ และสินค้าตัวอย่างก็ไม่มีในระบบ * **สาเหตุที่พลาด:** สรุปจบงานเร็วเกินไปหลังจากเช็ค HTTP 200 ของหน้าเว็บและหน้า API พื้นฐาน โดยไม่ได้ทำการทดสอบ Smoke Test ในส่วนของการ **Login ด้วยบัญชี Admin จริง** ### ข้อผิดพลาดหลักที่ 2: วิเคราะห์ปัญหาออกนอกลู่นอกทาง (Over-complicating Troubleshooting) * **สิ่งที่เกิดขึ้น:** เมื่อเกิดปัญหา Login ไม่ได้ แทนที่จะกลับมาเปิดอ่าน `DEPLOYMENT_GUIDE.md` ที่ระบุขั้นตอนการ Seed และ User Admin ไว้อย่างชัดเจน กลับไปไล่แกะ Hash Password ใน Database และตั้งข้อสงสัยเรื่อง `onParse` ในโค้ด Backend * **สาเหตุที่พลาด:** ไม่ได้ยึดตาม Runbook ขั้นตอนการ Deploy มาตรฐานเป็น First Priority ในการตรวจสอบความสมบูรณ์ของระบบที่เพิ่งสร้างใหม่ --- ## 2. Checklist การสร้าง Subdomain / Tenant ใหม่ (ห้ามข้ามขั้นตอนเด็ดขาด) ทุกครั้งที่มีการสร้าง Domain หรือ Subdomain ใหม่ ต้องปฏิบัติตามลำดับขั้นตอนดังนี้: ### Step 1: DNS & Port Allocation - [ ] กำหนดพอร์ตที่ไม่ซ้ำกับโปรเจกต์เดิม: - Backend API Port (เช่น `3055`, `3056`, ...) - Website SSR Port (เช่น `3006`, `3007`, ...) - [ ] ผูก DNS Records หรือ Wildcard A Record ชี้มาที่ IP เซิร์ฟเวอร์ให้เรียบร้อย ### Step 2: Database Provisioning - [ ] สร้างฐานข้อมูลใหม่ใน PostgreSQL: ```bash docker exec -i arokro_postgres psql -U postgres -c "CREATE DATABASE _db;" ``` - [ ] Push Schema ตารางเข้าฐานข้อมูลใหม่: ```bash cd /home/ti/projects/-api/apps/backend bunx prisma db push ``` ### Step 3: Database Seeding (จุดที่เคยลืม - บังคับทำทันที!) - [ ] รันคำสั่ง Seed ข้อมูลเริ่มต้นและบัญชี Admin: ```bash cd /home/ti/projects/-api/apps/backend bun run prisma/seed.cjs ``` - [ ] ตรวจสอบว่ามี Admin User ในตารางจริง: ```bash docker exec -i arokro_postgres psql -U postgres -d _db -c "SELECT id, username, role FROM \"User\";" ``` *(ต้องเห็น user `admin` / role `ADMIN` จำนวน 1 แถว)* ### Step 4: Firewall & Network - [ ] เปิดพอร์ต Backend และ SSR ใน UFW: ```bash sudo ufw allow /tcp sudo ufw allow /tcp ``` - [ ] ตรวจสอบว่ากฎ `ufw-user-input` ไม่บล็อกพอร์ตภายในเครื่อง ### Step 5: Nginx & SSL Certbot - [ ] สร้าง Nginx Config สำหรับ 4 ส่วน: - `main` (SSR Website & Reverse Proxy ไปที่ SSR Port) - `api` (Reverse Proxy ไปที่ Backend Port) - `spa` (Static Web Root `/usr/share/nginx/html//spa`) - `admin` (Static Web Root `/usr/share/nginx/html//admin`) - [ ] ขอใบรับรอง SSL (Let's Encrypt Certbot) ให้ครบทุก Subdomain - [ ] Reload Nginx: `docker exec -it nginx nginx -s reload` ### Step 6: Automated Post-Receive Hook & Git Remote - [ ] สร้าง Bare Git Repo: `/home/ti/git/.git` - [ ] ตั้งค่า Hook `hooks/post-receive` พร้อมสิทธิ์ `chmod +x` - [ ] เพิ่ม Git Remote ที่เครื่อง Local: ```bash git remote add demo- ti@kittisak.com:/home/ti/git/.git ``` --- ## 3. Smoke Test Verification (ต้องผ่านครบทุกข้อก่อนส่งมอบงาน) ห้ามประกาศว่าเสร็จงานจนกว่าจะรันคำสั่งทดสอบครบทั้ง 5 ข้อนี้: 1. **ทดสอบ Website SSR:** ```bash curl -I https://.kittisak.com/th # ต้องได้ HTTP 200 OK ``` 2. **ทดสอบ Backend API Status:** ```bash curl -I https://api..kittisak.com/api/categories # ต้องได้ HTTP 200 OK ``` 3. **ทดสอบ Static SPA & Admin:** ```bash curl -I https://spa..kittisak.com curl -I https://admin..kittisak.com # ต้องได้ HTTP 200 OK ``` 4. **ทดสอบ Admin Login API (CRITICAL):** ```bash curl -X POST https://api..kittisak.com/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"homaroma123"}' # ผลลัพธ์ต้องเป็น: {"success":true,"token":"...","user":{"username":"admin"}} ``` 5. **ตรวจสอบตาราง User ในฐานข้อมูล:** - ตาราง `User` ต้องมีอย่างน้อย 1 คน - ข้อมูลสินค้าในตาราง `Product` ต้องมากกว่า 0