Skip to main content

ที่เก็บไฟล์และรูปภาพ (Storage / S3-MinIO)

ภาพรวม

ไฟล์ทุกชิ้นที่ผู้ใช้อัปโหลดผ่าน CMS ผ่าน service ตัวเดียวกันคือ internal/storage.Service ซึ่งเป็นชั้นห่อของ S3/MinIO ครอบคลุมตั้งแต่รูป rich message, รูป rich menu, รูป hero ของ template, รูปในหน้า content page, ไฟล์ CSV ของ audience / customer database / import mapping ไปจนถึง avatar ของผู้ใช้

โมดูล internal/modules/storage ไม่มี route ของตัวเอง (RegisterRoutes เป็น no-op) เพราะใน NestJS เดิมเป็น @Global provider แบบไม่มี controller โมดูลนี้จึงเป็นเพียง type alias ที่ชี้ไปยัง service ที่แชร์ผ่าน Deps.Storage

Business Flow

  1. controller ที่รับ multipart/form-data แปลงไฟล์ที่อัปโหลดเป็น storage.File ซึ่งมีฟิลด์ originalName, extension, mimetype และ buffer เลียนแบบ MemoryStoredFile ของ nestjs-form-data
  2. เรียก method ตามชนิดของงาน
    • PutTemp / PutTempBuffer — เก็บชั่วคราวก่อนผู้ใช้ยืนยัน
    • PutImage / PutImageBuffer — เก็บรูปลงโฟลเดอร์ตาม FolderName
    • PutFile — เก็บไฟล์ทั่วไป เช่น CSV
  3. ไฟล์ถูกจัดเก็บแยกโฟลเดอร์ตาม root folder ของแต่ละ tenant ผ่าน GetRootFolder
  4. เมื่อต้องอ่านกลับ
    • GetPublicUrl / GetPublicFileUrl — URL สาธารณะ ใช้กับไฟล์ที่ต้องส่งเข้า LINE ซึ่งต้องเข้าถึงได้จากภายนอก
    • GeneratePresignedUrl — URL แบบมีวันหมดอายุ สำหรับไฟล์ที่ไม่ควรเปิดสาธารณะ
    • GetImage / GetPathUrl — ดึงไฟล์และแปลง path
  5. งานอื่น ๆ ได้แก่ DeleteObject, IsFileExist และ CopyObjectFromPublicUrl โดยตัวสุดท้ายใช้ตอน duplicate content หรือ clone rich menu ซึ่งต้องคัดลอกรูปจาก URL เดิม
  6. ไฟล์ CSV ที่เก็บไว้จะถูกอ่านต่อโดย CSV Engine เมื่อต้องแบ่งหน้ารายชื่อ LINE user

ไฟล์และฟังก์ชันหลัก

ไฟล์บทบาท
internal/storage/storage.goService ตัวจริง — port ของ src/storage/storage.service.ts
internal/storage/image.goจัดการรูปภาพ เช่น validate ชนิดไฟล์และแปลงชื่อไฟล์
internal/modules/storage/service.gotype alias ของ Service, File, StorageType, FolderName, ImageFileType, RootFolder
internal/modules/storage/controller.goRegisterRoutes เป็น no-op

Method ทั้งชุด: GetPublicUrl, GetPathUrl, GetImage, PutTemp, PutImage, PutTempBuffer, PutImageBuffer, DeleteObject, CopyObjectFromPublicUrl, IsFileExist, GetRootFolder, PutFile, GetPublicFileUrl, GeneratePresignedUrl

Endpoint ที่อัปโหลดไฟล์จริง — อยู่ในโมดูลอื่น แต่ปลายทางลงมาที่ service นี้ทั้งหมด

Routeโมดูล
POST /api/content-pages/upload-imageContent Page
POST /api/menu-builder/upload-imageMenu Builder
POST /api/template-message/upload-imageTemplate Message
POST /api/rich-message (form-data)Rich Message
POST /api/rich-menu (form-data)Rich Menu
POST /api/friend-track/:id/refs/uploadFriend Track
POST /api/customer-database และ /previewCustomer Database
POST /api/import-mapping/uploadImport Mapping
POST /api/line-users/import-all-friendsLINE User Management
POST /api/user (avatar)User Management

จุดเชื่อมต่อกับ Service อื่น

  • Permission — ไม่มี route ของตัวเอง สิทธิ์จึงถูกบังคับที่ endpoint ของโมดูลผู้เรียก
  • Infrastructure — ใช้ S3 หรือ MinIO ตามค่า StorageType ซึ่งตั้งจาก environment ใน internal/config/config.go
  • ผู้บริโภคDeps.Storage ถูก inject ให้ทุกโมดูล และ Deps.CSVEngine ก็รับ storage ตัวนี้เข้าไปด้วย