สร้างเมนูหน้าเว็บ
ภาพรวม
Menu Builder ใช้สร้าง "หน้าเมนู" ในลักษณะ mini-site ที่เปิดจาก LINE ได้ผ่าน LIFF หรือ in-app browser เมนูแต่ละตัวมี public token ประจำตัว ทำให้ผู้ใช้ปลายทางเปิดดูได้ โดยไม่ต้องล็อกอิน
โมดูลรองรับการอัปโหลดรูปประกอบ การคัดลอกเมนูเดิมทั้งชุด และการออก token ใหม่ เมื่อลิงก์เดิมหลุดออกไปสู่บุคคลที่ไม่ควรเข้าถึง
มีจุดที่ควรทราบคือ policy metadata ของโมดูลนี้ใช้ PolicyModuleSystemModule
แทนที่จะเป็นโมดูลของตัวเอง ซึ่งเป็นการรักษาพฤติกรรมให้ตรงกับ NestJS เวอร์ชันเดิม
Business Flow
ฝั่งผู้ดูแลระบบ
GET /api/menu-builderลิสต์เมนูแบบแบ่งหน้า พร้อมตัวกรองตามQueryParamsMenuBuilderDtoPOST /api/menu-builderสร้างเมนูใหม่ โดยระบบจะ generate public token ให้อัตโนมัติPOST /api/menu-builder/upload-imageอัปโหลดรูปประกอบเมนู พร้อมตรวจสอบว่าไฟล์เป็นรูปภาพจริงGET /api/menu-builder/:idและPUT /api/menu-builder/:idสำหรับดูและแก้ไขโครงเมนูPOST /api/menu-builder/:id/cloneคัดลอกเมนูทั้งชุดพร้อมออก token ใหม่ เหมาะกับการทำ A/B testing หรือเวอร์ชันตามเทศกาลPOST /api/menu-builder/:id/regenerate-tokenออก token ใหม่ ทำให้ลิงก์เดิมใช้ไม่ได้ทันทีDELETE /api/menu-builder/:idเป็น soft delete โดยประทับค่าลงคอลัมน์deleted_at
ฝั่งผู้ใช้ปลายทาง
- ผู้ใช้เปิดลิงก์จาก LINE ระบบเรียก
GET /api/menu-builder/public/:tokenซึ่งไม่มี JWT guard และคืนโครงเมนูให้ client-web นำไป render - ยังมีเส้นทางสาธารณะอีกชุดที่ทำงานคล้ายกันในโมดูล publicmod คือ
GET /api/public/menu/:token
หมายเหตุเรื่อง soft delete: entity มีคอลัมน์ deleted_at แต่ไม่ได้ประกาศเป็น gorm.DeletedAt
จึงต้องเติมเงื่อนไข deleted_at IS NULL เองในทุก read เพื่อให้ตรงกับพฤติกรรมของ TypeORM เดิม
ส่วนการ soft delete จะประทับ deleted_at = now() โดยไม่ใส่ filter จึงต้องใช้ Unscoped()
ไฟล์และฟังก์ชันหลัก
โค้ดหลักอยู่ที่ internal/modules/menubuilder/ ประกอบด้วย controller.go, service.go
และ dto.go
| Method | Route | Handler | Guard / Policy |
|---|---|---|---|
| GET | /api/menu-builder/public/:token | h.findByPublicToken | public (ไม่มี guard) |
| GET | /api/menu-builder | h.findAll | read system_module |
| GET | /api/menu-builder/:id | h.findOne | read system_module |
| POST | /api/menu-builder | h.create | create system_module |
| POST | /api/menu-builder/:id/clone | h.clone | create system_module |
| POST | /api/menu-builder/:id/regenerate-token | h.regenerateToken | update system_module |
| POST | /api/menu-builder/upload-image | h.uploadImage | create system_module |
| PUT | /api/menu-builder/:id | h.update | update system_module |
| DELETE | /api/menu-builder/:id | h.delete | delete system_module |
route ทั้งหมดยกเว้นเส้นทางสาธารณะถูก register บน group authed.Group("/menu-builder")
จุดเชื่อมต่อกับ Service อื่น
- สิทธิ์การเข้าถึง — route ฝั่งผู้ดูแลต้องผ่าน global
JwtAuthโดยมี policy metadata เป็นPolicyModuleSystemModuleซึ่งยังไม่บังคับใช้ ส่วน route สาธารณะไม่มี guard - ตารางที่เกี่ยวข้อง —
menu_builder,line_oa - Storage Service — เก็บรูปประกอบเมนูที่อัปโหลด
- โมดูลที่เกี่ยวข้อง — Public API (เส้นทางสาธารณะอีกชุด), Content Page (mini-site อีกรูปแบบ) และ Content Link