Skip to main content

ฐานข้อมูลสมาชิก (Member Database)

ภาพรวม

Member Database (ฝั่ง backend ใช้ชื่อ customer-database) คือคลังข้อมูลสมาชิกที่ผู้ดูแลระบบอัปโหลดขึ้นมาเองในรูปแบบไฟล์ CSV เพื่อใช้เป็น "ตารางอ้างอิง" ให้ฟีเจอร์อื่นนำไปตรวจสอบสิทธิ์หรือยืนยันตัวตนของผู้ใช้

ผู้ใช้หลักคือผู้ดูแล CMS ที่มีรายชื่อสมาชิกเดิมอยู่ในระบบ CRM หรือไฟล์ Excel แล้วต้องการนำเข้ามาให้ระบบ LINE ใช้งานได้ ปลายทางหลักคือ Form Builder ซึ่งจะผูก (map) ฐานข้อมูลนี้เข้ากับฟอร์ม เพื่อตรวจสอบว่าผู้กรอกฟอร์มเป็นสมาชิกจริงหรือไม่

ข้อแตกต่างจาก Import Mapping — Member Database ไม่ได้เขียนทับข้อมูลโปรไฟล์ของผู้ใช้ LINE แต่เก็บ CSV ไว้เป็นชุดข้อมูลแยกต่างหาก แล้วให้ฟีเจอร์อื่นเรียกใช้เมื่อต้องการตรวจสอบ ส่วน Import Mapping เป็นการอัปเดตค่าลงในโปรไฟล์เพื่อนโดยตรง

ข้อมูล 1 รายการประกอบด้วย

ข้อมูลคำอธิบาย
ชื่อชื่อฐานข้อมูลที่ใช้อ้างอิง บังคับกรอก ไม่เกิน 255 ตัวอักษร
คำอธิบายรายละเอียดเพิ่มเติม ไม่เกิน 1,000 ตัวอักษร
คอลัมน์รายชื่อคอลัมน์ที่ระบบอ่านได้จากไฟล์ CSV
จำนวนแถวจำนวนข้อมูลสมาชิกในไฟล์
ฟอร์มที่ผูกอยู่รายการฟอร์มที่กำลังใช้ฐานข้อมูลนี้ตรวจสอบสมาชิก
วันที่สร้างวันที่อัปโหลดฐานข้อมูลนี้

ข้อจำกัดที่ควรทราบ

  • รองรับเฉพาะไฟล์ .csv และอัปโหลดได้ครั้งละ 1 ไฟล์
  • ไม่มีหน้ารายละเอียดแยก ผู้ใช้ดูข้อมูลได้จากตารางและ popover รายชื่อคอลัมน์เท่านั้น
  • ไม่มีฟังก์ชันส่งออกข้อมูลกลับเป็น CSV
  • ตัวกรองมีเฉพาะช่องค้นหา ไม่มีการกรองตามสถานะหรือฟอร์มที่ผูก และไม่มีการเรียงลำดับคอลัมน์
  • การตรวจสอบความถูกต้องของไฟล์ทำที่ฝั่ง backend ทั้งหมด ผลลัพธ์จะกลับมาแสดงในขั้นตอนพรีวิว

Business Flow

ดูรายการฐานข้อมูล

  1. เข้าหน้า /member-database ระบบตรวจสิทธิ์การเข้าถึงก่อน หากไม่ผ่านจะไม่แสดงเนื้อหา
  2. ระบบตั้ง breadcrumb และไฮไลต์เมนูด้านข้าง แล้วโหลดรายการฐานข้อมูลตามหน้าและคำค้นปัจจุบัน
  3. ตารางแสดงชื่อพร้อมคำอธิบายเป็นบรรทัดรอง จำนวนคอลัมน์ จำนวนแถว ฟอร์มที่ผูกอยู่ วันที่สร้าง และปุ่มดำเนินการ
  4. คลิกหรือชี้ที่จำนวนคอลัมน์เพื่อเปิด popover แสดงชื่อคอลัมน์ทั้งหมดของไฟล์นั้น
  5. คอลัมน์ฟอร์มที่ผูกอยู่จะแสดงชื่อฟอร์มเป็นป้ายกำกับ หากยังไม่มีฟอร์มใดใช้งานจะแสดงป้าย "not mapped"
  6. ช่องค้นหาใช้ค้นตามชื่อ เมื่อกดค้นหาระบบจะกลับไปหน้าแรกเสมอ และมีปุ่มล้างค่าสำหรับรีเซ็ตเงื่อนไข

อัปโหลดฐานข้อมูลใหม่ (wizard 3 ขั้น)

  1. กดปุ่ม "Upload Database" ที่หัวข้อหน้าเพื่อเปิดหน้าต่างอัปโหลดแบบ 3 ขั้นตอน
  2. ขั้นที่ 1 — เลือกไฟล์ ลากไฟล์ CSV มาวางหรือกดเลือกไฟล์ ระบบจะไม่อัปโหลดทันที แต่ส่งไฟล์ไปให้ backend อ่านพรีวิวก่อน
  3. หากอ่านไฟล์สำเร็จ ระบบจะเก็บผลลัพธ์ (รายชื่อคอลัมน์ จำนวนแถว ตัวอย่างข้อมูล และข้อผิดพลาดที่พบ) แล้วพาไปขั้นถัดไป หากไม่สำเร็จจะแจ้งข้อความผิดพลาดที่ backend ส่งกลับมา
  4. ขั้นที่ 2 — ตรวจสอบข้อมูล แสดงแถบแจ้งเตือนหากพบข้อผิดพลาดในไฟล์ พร้อมบรรทัดสรุปจำนวนคอลัมน์และแถว รายชื่อคอลัมน์ในรูปแบบป้ายกำกับ และตารางตัวอย่างข้อมูลบางแถว
  5. หากไฟล์มีข้อผิดพลาด ปุ่มถัดไปจะถูกปิด ผู้ใช้ต้องย้อนกลับไปเลือกไฟล์ใหม่ การกดย้อนกลับจะล้างไฟล์และผลพรีวิวเดิมทิ้งทั้งหมด
  6. ขั้นที่ 3 — กรอกรายละเอียด กรอกชื่อฐานข้อมูล (บังคับ) และคำอธิบาย
  7. กด Create ระบบจะตรวจความถูกต้องของฟอร์ม แล้วส่งชื่อ คำอธิบาย และไฟล์ไปสร้างฐานข้อมูลใหม่ เมื่อสำเร็จจะปิดหน้าต่าง ล้างสถานะ และรีเฟรชตาราง

แก้ไขหรือแทนที่ไฟล์

  1. กดปุ่มแก้ไขในตารางเพื่อเปิดหน้าต่างแก้ไข ระบบจะเติมชื่อและคำอธิบายเดิมลงฟอร์มให้อัตโนมัติ
  2. หากฐานข้อมูลนี้มีฟอร์มผูกอยู่ ระบบจะแสดงแถบเตือนพร้อมจำนวนและชื่อฟอร์มทั้งหมด เพื่อให้ผู้ใช้รู้ผลกระทบก่อนแก้ไข
  3. หากต้องการเปลี่ยนข้อมูล ให้เลือกไฟล์ CSV ใหม่ ระบบจะพรีวิวไฟล์ใหม่ให้ตรวจสอบเช่นเดียวกับตอนอัปโหลด พร้อมปุ่มยกเลิกการแทนที่ไฟล์
  4. กด Save เพื่อบันทึก หากไม่ได้เลือกไฟล์ใหม่ ระบบจะแก้เฉพาะชื่อและคำอธิบายโดยไม่แตะข้อมูลเดิม
  5. ปุ่มบันทึกจะถูกปิดหากไฟล์ใหม่ที่เลือกมีข้อผิดพลาด

ลบฐานข้อมูล

  1. กดปุ่มลบในตารางเพื่อเปิดกล่องยืนยัน โดยหัวข้อจะระบุชื่อฐานข้อมูลที่กำลังจะลบ
  2. เมื่อยืนยัน ระบบจะส่งคำสั่งลบและแจ้งผลสำเร็จพร้อมรีเฟรชตาราง
  3. หาก backend ปฏิเสธคำขอ เช่น กรณีฐานข้อมูลยังถูกฟอร์มผูกอยู่ ระบบจะแสดงข้อความผิดพลาดที่ได้รับกลับมาแล้วปิดกล่องยืนยัน

การนำฐานข้อมูลไปใช้ใน Form Builder

  1. เมื่อเปิดหน้าตั้งค่าฟอร์ม ระบบจะโหลดรายการฐานข้อมูลสมาชิกมาเตรียมไว้ล่วงหน้า (สูงสุด 100 รายการ)
  2. ในส่วนตั้งค่า Profile Mapping ผู้ใช้เลือกฐานข้อมูลที่ต้องการ แล้วระบบจะแสดงรายชื่อคอลัมน์ของฐานข้อมูลนั้นให้จับคู่กับฟิลด์ในฟอร์ม พร้อมนับจำนวนคู่ที่จับแล้ว
  3. การจับคู่นี้เองคือที่มาของข้อมูล "ฟอร์มที่ผูกอยู่" ที่กลับมาแสดงในตารางหน้า Member Database และเป็นเหตุผลที่การแก้ไขหรือลบฐานข้อมูลจะมีคำเตือน

หน้าจอและองค์ประกอบหลัก

ฟีเจอร์นี้มีหน้าจอเดียวคือ /member-database การสร้างและแก้ไขทั้งหมดทำผ่านหน้าต่าง modal ไม่มีหน้าฟอร์มแยก

หน้ารายการ

  • หัวข้อหน้าและปุ่มอัปโหลด — ใช้ส่วนหัวมาตรฐานของ CMS พร้อมปุ่ม Upload Database
  • แถบค้นหา — ช่องค้นหาชื่อเพียงช่องเดียว พร้อมปุ่มค้นหาและล้างค่า
  • ตารางรายการ — ชื่อพร้อมคำอธิบาย จำนวนคอลัมน์ (มี popover แสดงชื่อคอลัมน์) จำนวนแถว ป้ายฟอร์มที่ผูกอยู่ วันที่สร้าง และปุ่มแก้ไข/ลบ

ไฟล์อ้างอิงหลัก: src/app/member-database/page.tsx, src/components/member-database/member-database.container.tsx, src/components/member-database/member-database-table.tsx, src/components/member-database/member-database-filter.tsx

หน้าต่างอัปโหลด

  • แถบขั้นตอน — แสดงความคืบหน้า 3 ขั้น ได้แก่ เลือกไฟล์ ตรวจสอบข้อมูล และกรอกรายละเอียด
  • พื้นที่ลากวางไฟล์ — รับไฟล์ .csv ทีละ 1 ไฟล์ พร้อมข้อความแนะนำขนาดไฟล์
  • ส่วนแสดงผลพรีวิว — ใช้คอมโพเนนต์ร่วมกับหน้าต่างแก้ไข ประกอบด้วยแถบแจ้งข้อผิดพลาด บรรทัดสรุป ป้ายรายชื่อคอลัมน์ และตารางตัวอย่าง

ไฟล์อ้างอิงหลัก: src/components/member-database/upload-database-modal.tsx, src/components/member-database/csv-preview-detail.tsx

หน้าต่างแก้ไข

  • ฟอร์มข้อมูลพื้นฐาน — ชื่อและคำอธิบาย เติมค่าเดิมให้อัตโนมัติทุกครั้งที่เปิด
  • แถบเตือนฟอร์มที่ผูกอยู่ — แสดงเมื่อฐานข้อมูลถูกฟอร์มใช้งานอยู่ พร้อมรายชื่อฟอร์ม
  • ส่วนแทนที่ไฟล์ — เลือกไฟล์ CSV ใหม่พร้อมพรีวิว และปุ่มยกเลิกการแทนที่

ไฟล์อ้างอิงหลัก: src/components/member-database/edit-database-modal.tsx

บริการฝั่ง API

รวมอยู่ที่ src/services/customer-database.service.ts ภายใต้ path หลัก customer-database โดยคำสั่งที่มีการแนบไฟล์จะส่งเป็น multipart/form-data

ความสามารถEndpoint
ดึงรายการฐานข้อมูลGET /customer-database
ดึงข้อมูลรายตัวGET /customer-database/{id}
พรีวิวไฟล์ CSV ก่อนบันทึกPOST /customer-database/preview
สร้างฐานข้อมูลใหม่POST /customer-database
แก้ไขข้อมูลหรือแทนที่ไฟล์PUT /customer-database/{id}
ลบฐานข้อมูลDELETE /customer-database/{id}

จุดเชื่อมต่อกับฟีเจอร์อื่น

  • สิทธิ์การใช้งาน — หน้าจอถูกควบคุมด้วยสิทธิ์ดูข้อมูลของโมดูล customer-database ซึ่งแมปกับเมนู member-database เมนูด้านข้างจะแสดงเมื่อผู้ใช้มีสิทธิ์ และมีทางลัดใน Quick Access ด้วย
  • Form Builder — เป็นผู้บริโภคหลักของฟีเจอร์นี้ ส่วนตั้งค่า Profile Mapping ใช้ฐานข้อมูลสมาชิกเป็นแหล่งตรวจสอบสิทธิ์ผู้กรอกฟอร์ม และมีลิงก์กลับมายังหน้า Member Database เพื่อจัดการข้อมูล
  • Import Mapping — เป็นฟีเจอร์คนละตัว ใช้สำหรับอัปเดตโปรไฟล์เพื่อนโดยตรง ไม่ได้ใช้ฐานข้อมูลชุดนี้
  • คอมโพเนนต์กลางของ CMS — ใช้ส่วนหัวหน้า กล่องยืนยันมาตรฐาน และพื้นที่เลื่อนตารางร่วมกับหน้ารายการอื่นในระบบ
  • โครงสร้างพื้นฐานร่วม — ใช้ระบบยืนยันตัวตนและ HTTP client กลางของ CMS (แนบ token อัตโนมัติและออกจากระบบเมื่อ token หมดอายุ) ระบบ breadcrumb และเมนูด้านข้าง

รายละเอียดฝั่ง Backend (CMS API)

โค้ดฝั่ง backend อยู่ที่ internal/modules/customerdatabase/ โดยมีส่วนที่แยกออกมาเป็นไฟล์เฉพาะทาง ได้แก่ ตัวอ่าน CSV และ ตัวรักษาลำดับคอลัมน์ เพื่อให้ลำดับคอลัมน์ในผลลัพธ์ตรงกับลำดับในไฟล์ต้นฉบับเสมอ

สิทธิ์ที่ต้องมี

  • ทุก route ถูกครอบด้วย module gate ของโมดูล customer-database
  • policy แยกตามการกระทำ: readAll สำหรับดึงรายการ, read สำหรับดูรายตัว, create สำหรับสร้าง, update และ delete ตามการกระทำ
  • ข้อสังเกต — endpoint พรีวิวไฟล์ CSV ใช้ policy create ไม่ใช่ read เพราะถือเป็นขั้นตอนหนึ่งของการสร้าง ผู้ที่มีสิทธิ์เพียงดูข้อมูลจึงไม่สามารถลากไฟล์มาพรีวิวได้

ตัวอ่าน CSV และพฤติกรรมที่ต้องรู้

ตัวอ่าน CSV ของโมดูลนี้ถูกเขียนขึ้นให้เลียนแบบไลบรารีอ่าน CSV ฝั่ง JavaScript แบบเป๊ะทุกรายละเอียด เพื่อให้ผลลัพธ์ตรงกับระบบเดิม ซึ่งหมายความว่ามันสืบทอด "พฤติกรรมแปลก" ของไลบรารีนั้นมาด้วย

  • ไฟล์ CSV ที่มีคอลัมน์เดียวจะถูกปฏิเสธ ด้วยข้อผิดพลาดว่าหาตัวคั่นคอลัมน์ไม่ได้ ทั้งที่ตัวไฟล์อาจถูกต้องสมบูรณ์ในสายตาผู้ใช้ ถ้าจำเป็นต้องนำเข้าข้อมูลคอลัมน์เดียว ให้เพิ่มคอลัมน์หลอกอีกหนึ่งคอลัมน์
  • เมื่อพบข้อผิดพลาด รายการแถวข้อมูลที่คืนกลับมาจะกลายเป็นค่าว่างทั้งหมด ไม่ใช่คืนเฉพาะแถวที่อ่านได้ ดังนั้นหน้าจอพรีวิวที่แสดงข้อผิดพลาดจะไม่มีตัวอย่างข้อมูลให้ดูควบคู่กัน
  • การตรวจไฟล์เกิดขึ้นที่ backend ทั้งหมด หน้าจอเป็นเพียงผู้แสดงผลที่ backend รายงานกลับมา

สิ่งที่บันทึกและผลข้างเคียง (Side Effect)

  • ข้อมูลสรุปของฐานข้อมูล (ชื่อ คำอธิบาย รายชื่อคอลัมน์ จำนวนแถว) เก็บในตาราง customer_database ส่วนข้อมูลรายแถวเก็บแยกในตาราง customer_database_row
  • การสร้างแทรกข้อมูลแบบเป็นชุด ครั้งละ 1,000 แถว ภายใน transaction เดียว ทั้งหมด ถ้าล้มเหลวกลางทางจะถูกยกเลิกทั้งก้อน ไม่ทิ้งข้อมูลค้างครึ่ง ๆ กลาง ๆ
  • การแก้ไขที่แนบไฟล์ใหม่คือการแทนที่แถวข้อมูลทั้งหมด ไม่ใช่การผสานข้อมูล แถวเดิมทั้งชุดถูกลบแล้วเขียนใหม่ใน transaction เดียวกัน
  • ไฟล์ CSV ต้นฉบับถูกเก็บไว้บน object storage ควบคู่กับข้อมูลในตาราง
  • คอลัมน์ "ฟอร์มที่ผูกอยู่" ไม่ได้เก็บเป็นความสัมพันธ์ในฐานข้อมูล แต่ คำนวณสด ๆ ตอนดึงรายการ โดยค้นเข้าไปในค่าการตั้งค่า profile mapping ของตาราง form_builder ว่ามีฟอร์มใดอ้างถึงรหัสฐานข้อมูลนี้อยู่บ้าง

Edge Case และข้อสังเกตที่ควรรู้

  • การลบเป็น soft delete แบบอิงสถานะ โดยเปลี่ยนค่าสถานะของแถวเป็น "ลบแล้ว" ไม่ใช่การประทับเวลาลบในคอลัมน์แยกแบบโมดูลอื่น การดึงรายการจึงต้องกรองสถานะนี้ออกเองทุกครั้ง
  • เพราะความสัมพันธ์กับฟอร์มถูกคำนวณจากฝั่ง form_builder ไม่ใช่เก็บเป็นความสัมพันธ์จริง การเปลี่ยนแปลงที่ฝั่งฐานข้อมูลนี้จึงไม่ได้แจ้งกลับไปที่ฟอร์มโดยอัตโนมัติ ฟอร์มที่ผูกไว้อาจชี้ไปยังชุดข้อมูลที่เนื้อหาเปลี่ยนไปแล้วโดยไม่รู้ตัว
  • ทุก query ถูกจำกัดขอบเขตตาม LINE OA ที่เลือกอยู่ ฐานข้อมูลของ OA อื่นจะไม่ถูกดึงมาแม้จะระบุรหัสตรง ๆ
  • ลำดับของคอลัมน์เป็นสิ่งที่โมดูลนี้ตั้งใจรักษาไว้ เพราะการจับคู่คอลัมน์ใน Form Builder อาศัยลำดับและชื่อคอลัมน์ที่ตรงกับไฟล์ต้นฉบับ
  • โมดูลนี้ไม่ได้ส่งงานเข้าคิวและไม่มีการประมวลผลเบื้องหลัง การอัปโหลดไฟล์ใหญ่จึงใช้เวลาอยู่ในคำขอเดียวจนกว่าจะแทรกข้อมูลครบทุกชุด