ฐานข้อมูลลูกค้าจาก CSV (Customer Database)
ภาพรวม
Customer Database เปิดให้ลูกค้าอัปโหลดข้อมูลลูกค้าของตัวเองในรูปแบบ CSV เข้ามาเก็บเป็น ตารางอ้างอิงแยกต่างหาก ในระบบ ข้อมูลชุดนี้ถูกนำไปใช้สองทางหลัก คือใช้เป็นแหล่งข้อมูล สำหรับ profile mapping ตอนผู้ใช้กรอกฟอร์ม และใช้เทียบข้อมูลลูกค้าเดิมกับเพื่อน LINE ที่มีอยู่
มีสองประเด็นทางเทคนิคที่ควรทราบ:
- การ parse CSV เลียนแบบ papaparse ของ JavaScript อย่างเคร่งครัด รวมถึงพฤติกรรมเฉพาะตัว
เช่น CSV ที่มีคอลัมน์เดียวจะได้ error
UndetectableDelimiterและเมื่อเกิด error ผลลัพธ์ rows จะกลายเป็น array ว่าง - Soft delete ของโมดูลนี้เป็นแบบ status-based คือตั้งค่า
status = 'delete'ไม่ได้ใช้คอลัมน์deleted_dateเหมือนโมดูลอื่น
Business Flow
- ดูตัวอย่างก่อน —
POST /api/customer-database/previewรับไฟล์แบบ multipart/form-data ระบบ parse หัวคอลัมน์และแถวตัวอย่างกลับไปให้ผู้ใช้ตรวจความถูกต้อง หาก CSV มีคอลัมน์เดียวจะได้ errorUndetectableDelimiterตามพฤติกรรมเดิมของ papaparse - สร้างฐานข้อมูลจริง —
POST /api/customer-databaseบันทึก metadata ลงตารางcustomer_databaseแล้วแทรกแถวข้อมูลลงcustomer_database_rowแบบ bulk ครั้งละ 1,000 แถวภายใน transaction เดียว - ดูรายการ —
GET /api/customer-databaseคืนรายการแบบแบ่งหน้า scope ตามlineOaIdและตัดแถวที่status = 'delete'ออก พร้อมแสดงว่าฐานข้อมูลนี้ถูกฟอร์มใดใช้อยู่ ซึ่งหาได้จาก raw query บนคอลัมน์ JSONprofile_mapping ->> 'databaseId'ของตารางform_builder - ดูรายละเอียด —
GET /api/customer-database/:idคืนทั้ง metadata และข้อมูลในตาราง - แก้ไข —
PUT /api/customer-database/:idรับ form-data และ แทนที่แถวข้อมูลทั้งหมด ภายใน transaction เดียว - ลบ —
DELETE /api/customer-database/:idเปลี่ยนค่าstatusเป็นdelete - เมื่อผู้ใช้ปลายทางกรอกฟอร์มที่ผูกกับฐานข้อมูลนี้ ฝั่ง client-api จะค้นแถวที่ตรงกัน มาเติมข้อมูลอัตโนมัติหรือใช้ตรวจสอบสิทธิ์
ไฟล์และฟังก์ชันหลัก
โค้ดอยู่ที่ internal/modules/customerdatabase/
| ไฟล์ | บทบาท |
|---|---|
controller.go | ลงทะเบียน route |
service.go | logic หลัก ได้แก่ _getOwnedDatabase, _getMappedFormsMap และการ create/update ใน transaction |
papaparse.go, papaparse_config.go | ตัว parse CSV ที่เลียนแบบ papaparse |
orderedmap.go, orderedrow.go | รักษาลำดับคอลัมน์ให้ JSON output ตรงกับระบบเดิม |
dto.go | นิยาม DTO |
| Method | Route | Handler | Policy |
|---|---|---|---|
| GET | /api/customer-database | ct.findAll | readAll customer-database |
| GET | /api/customer-database/:id | ct.findOne | read customer-database |
| POST | /api/customer-database | ct.create | create customer-database |
| POST | /api/customer-database/preview | ct.previewCsv | create customer-database |
| PUT | /api/customer-database/:id | ct.update | update customer-database |
| DELETE | /api/customer-database/:id | ct.remove | delete customer-database |
ทุก route ครอบด้วย modulegate.ModuleGate(d, "customer-database")
จุดเชื่อมต่อกับ Service อื่น
- Permission — ต้องผ่าน
ModuleGate("customer-database")ซึ่งหมายความว่าองค์กรต้องเปิดใช้ โมดูลนี้ก่อน และมีPolicyModuleCustomerDatabaseเป็น metadata - ตารางที่เกี่ยวข้อง —
customer_database,customer_database_row,form_builder(สำหรับ mapping) และline_oa - Storage — เก็บไฟล์ CSV ต้นฉบับไว้บน object storage
- CLS — ใช้
lineOaIdจาก context ในการ scope ทุก query - โมดูลที่เกี่ยวข้อง — Form Builder ในฐานะผู้ใช้ข้อมูล และ Import Mapping
ซึ่งเป็นการนำเข้าอีกรูปแบบที่ map ข้อมูลเข้าตาราง
line_userโดยตรง