Skip to main content

นำเข้าข้อมูลและ Mapping ฟิลด์ (Import Mapping)

ภาพรวม

Import Mapping คือฟีเจอร์สำหรับ นำเข้าไฟล์ CSV เพื่ออัปเดตข้อมูลโปรไฟล์ของเพื่อน (LINE friend) ที่มีอยู่แล้วในระบบ เหมาะกับผู้ดูแล CMS ที่ถือข้อมูลลูกค้าจากระบบภายนอก แล้วต้องการ sync ค่าลงมาที่โปรไฟล์เพื่อนหรือ custom attribute

หลักการสำคัญที่ต้องเข้าใจก่อนใช้งาน

  • การนำเข้านี้เป็นแบบ update-only ระบบจะไม่สร้างผู้ใช้ใหม่จากไฟล์ CSV
  • ต้องเลือก match key เสมอ ซึ่งเป็นการจับคู่ระหว่างฟิลด์ในโปรไฟล์กับคอลัมน์ใน CSV เพื่อระบุว่าข้อมูลแต่ละแถวตรงกับเพื่อนคนใด
  • แถวที่หาเพื่อนไม่เจอจะถูกนับเป็น "no match" และถูกข้ามไป ไม่ทำให้ทั้งไฟล์ล้มเหลว
  • การนำเข้าทำงานเป็น งานเบื้องหลัง (asynchronous job) เมื่อสั่งแล้วผู้ใช้จะกลับมาที่หน้ารายการเพื่อติดตามสถานะ

ฟีเจอร์นี้มี 2 หน้าจอ คือหน้ารายการประวัติการนำเข้า (/import-mapping) และหน้า wizard 4 ขั้นตอนสำหรับสร้างงานนำเข้าใหม่ (/import-mapping/import)

สถานะของงานนำเข้ามี 5 แบบ

สถานะความหมายที่แสดงบนหน้าจอ
pendingรอคิวประมวลผล
processingกำลังประมวลผล
successเสร็จสมบูรณ์
partialเสร็จแล้วแต่มีบางแถวผิดพลาด
failedล้มเหลว

ฟิลด์ปลายทางที่เลือกได้มาจากฝั่ง backend และแบ่งเป็น 2 กลุ่ม คือฟิลด์ที่ใช้เป็น match key ได้ และฟิลด์ที่ใช้เป็นปลายทางในการเขียนค่า โดยฟิลด์ปลายทางที่ขึ้นต้นด้วย custom. จะถูกจัดกลุ่มแยกเป็น "Custom attributes" ซึ่งก็คือ custom attribute ที่ประกาศไว้ในหน้า Attribute Setup

Business Flow

หน้ารายการประวัติการนำเข้า (/import-mapping)

  1. เข้าหน้า ระบบตรวจสิทธิ์การเข้าถึงก่อน แล้วตั้ง breadcrumb และไฮไลต์เมนูด้านข้าง
  2. ระบบโหลดประวัติงานนำเข้าตามหน้าปัจจุบัน หน้านี้ไม่มีตัวกรองหรือการค้นหา มีเฉพาะการแบ่งหน้าเท่านั้น
  3. ระบบตรวจว่ามีงานที่สถานะ pending หรือ processing อยู่ในหน้าที่แสดงหรือไม่ ถ้ามีจะดึงข้อมูลใหม่อัตโนมัติทุก 10 วินาที และหยุดดึงเมื่อไม่มีงานค้างแล้ว
  4. ตารางแสดงชื่อไฟล์ (ตัดข้อความยาวพร้อม tooltip แสดงชื่อเต็ม) สถานะเป็นป้ายกำกับสี จำนวนเรคคอร์ด วันที่สร้าง และลิงก์ดาวน์โหลด log
  5. คอลัมน์จำนวนเรคคอร์ดปรับตามสถานะ งานที่จบแล้วจะแสดงจำนวนแถวที่อัปเดตสำเร็จและที่ถูกข้าม ส่วนงานที่ยังทำงานอยู่จะแสดงจำนวนแถวทั้งหมดที่รอประมวลผล
  6. หากงานสร้างไฟล์ log ไว้ คอลัมน์ Import log จะเป็นลิงก์ดาวน์โหลดที่เปิดในแท็บใหม่ หากไม่มีจะแสดงเครื่องหมายขีด
  7. เมื่อยังไม่มีประวัติใด ๆ ตารางจะแสดงสถานะว่างพร้อมคำอธิบายและปุ่ม "Import CSV" ให้เริ่มใช้งานได้ทันที
  8. กดปุ่ม "Import CSV" เพื่อเข้าสู่ wizard สร้างงานนำเข้าใหม่

Wizard นำเข้าข้อมูล (/import-mapping/import)

ขั้นที่ 1 — อัปโหลดไฟล์

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

ขั้นที่ 2 — ดูตัวอย่างข้อมูล

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

ขั้นที่ 3 — จับคู่ฟิลด์

  1. การ์ด Match key — เลือกฟิลด์ในโปรไฟล์ทางซ้ายและคอลัมน์ใน CSV ทางขวา เพื่อกำหนดว่าจะใช้อะไรจับคู่หาเพื่อน โดยตัวเลือกฝั่งโปรไฟล์แบ่งกลุ่มเป็นฟิลด์โปรไฟล์และ custom attribute
  2. คอลัมน์ที่ถูกเลือกเป็น match key จะถูกถอดออกจากรายการคอลัมน์ที่จะเขียนค่าโดยอัตโนมัติ เพราะทำหน้าที่เป็นกุญแจค้นหาแล้ว
  3. การ์ด Column mapping — แสดงทุกคอลัมน์ใน CSV เป็นแถว โดยแต่ละแถวมีชื่อคอลัมน์พร้อมค่าตัวอย่างแรกที่ไม่ว่าง ตามด้วยลูกศรและตัวเลือกฟิลด์ปลายทาง
  4. คอลัมน์ที่เป็น match key จะไม่มีตัวเลือกปลายทาง แต่แสดงป้าย "match key" แทน
  5. ตัวเลือกฟิลด์ปลายทางมีตัวเลือกแรกคือ "Don't import" สำหรับคอลัมน์ที่ไม่ต้องการนำเข้า และรองรับการพิมพ์ค้นหาชื่อฟิลด์
  6. ฟิลด์ปลายทางที่ถูกคอลัมน์อื่นเลือกไปแล้วจะถูกปิดไม่ให้เลือกซ้ำ เพื่อบังคับความสัมพันธ์แบบ 1 คอลัมน์ต่อ 1 ฟิลด์
  7. หน้าจอใช้สีแยกที่มาของข้อมูลให้ชัดเจน ฝั่งคอลัมน์จากไฟล์ผู้ใช้เป็นสีกลาง ส่วนฝั่งฟิลด์ของระบบเป็นสีฟ้าตามสีแบรนด์
  8. ปุ่มถัดไปจะเปิดใช้งานเมื่อเลือก match key ครบทั้งสองฝั่ง และมีคอลัมน์อย่างน้อย 1 คอลัมน์ที่จับคู่ปลายทางไว้แล้ว
  9. เมื่อกดถัดไป ระบบจะส่งข้อมูลการจับคู่ไปให้ backend ตรวจสอบล่วงหน้า แล้วนำผลลัพธ์ไปแสดงในขั้นสุดท้าย

ขั้นที่ 4 — ตรวจทานและสั่งนำเข้า

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

ความหมายของตัวเลขในผลตรวจสอบ

ตัวเลขความหมาย
Total rowsจำนวนแถวทั้งหมดในไฟล์ที่ถูกตรวจสอบ
Will updateจำนวนแถวที่จับคู่กับเพื่อนได้และจะถูกอัปเดตจริง
No matchแถวที่หาเพื่อนตาม match key ไม่พบ จะถูกข้าม
Invalidแถวที่ข้อมูลผิดรูปแบบ จะถูกข้าม
Skip reasonsสรุปเหตุผลของการข้ามพร้อมจำนวนแถวของแต่ละเหตุผล

ตัวเลขชุดเดียวกันนี้ถูกส่งไปพร้อมกับการสร้างงาน และใช้แสดงจำนวนแถวที่รอประมวลผลในหน้ารายการ ก่อนจะถูกแทนที่ด้วยผลจริงเมื่องานทำงานเสร็จ

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

หน้ารายการ (/import-mapping)

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

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

หน้า wizard (/import-mapping/import)

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

ไฟล์อ้างอิงหลัก: src/app/import-mapping/import/page.tsx, src/components/import-mapping/import-wizard.container.tsx, src/components/import-mapping/steps/upload-step.tsx, src/components/import-mapping/steps/preview-step.tsx, src/components/import-mapping/steps/mapping-step.tsx, src/components/import-mapping/steps/review-step.tsx

บริการฝั่ง API

รวมอยู่ที่ src/services/import-mapping.service.ts ภายใต้ path หลัก import-mapping

ความสามารถEndpointใช้ที่
อัปโหลดไฟล์ CSVPOST /import-mapping/uploadขั้นที่ 1
ดึงรายการฟิลด์ปลายทางและ match keyGET /import-mapping/fieldsโหลดตอนเข้า wizard
ตรวจสอบข้อมูลก่อนนำเข้าPOST /import-mapping/validateขั้นที่ 3 ก่อนไปขั้นที่ 4
สร้างงานนำเข้าPOST /import-mappingขั้นที่ 4
ดึงประวัติงานนำเข้าGET /import-mappingหน้ารายการและการติดตามสถานะ

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

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

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

  • สิทธิ์การใช้งาน — ทั้งหน้ารายการและ wizard ใช้สิทธิ์ดูข้อมูลของโมดูล import-mapping ร่วมกัน ผู้ที่เข้าดูหน้ารายการได้จึงสั่งนำเข้าได้ด้วย
  • Attribute Setup — ฟิลด์ปลายทางที่ขึ้นต้นด้วย custom. คือ custom attribute ที่ประกาศไว้ในหน้า Attribute Setup การเพิ่มฟิลด์ใหม่ที่นั่นจึงทำให้มีปลายทางใหม่ให้เลือกที่นี่
  • โปรไฟล์เพื่อน (Friend profile) — เป็นปลายทางของการอัปเดต ค่าที่นำเข้าจะไปปรากฏในรายงาน All Friends และใช้เป็นเงื่อนไขใน Audience ได้ตามการตั้งค่าของ attribute นั้น
  • ระบบงานเบื้องหลัง — การประมวลผลจริงทำที่ฝั่ง server หน้าจอรับรู้ความคืบหน้าผ่านสถานะ ตัวเลขสรุป และไฟล์ log เท่านั้น
  • Member Database — เป็นฟีเจอร์คนละตัว ใช้เก็บ CSV เป็นชุดข้อมูลอ้างอิงแยกต่างหาก ไม่ได้เขียนทับโปรไฟล์เพื่อนแบบฟีเจอร์นี้
  • โครงสร้างพื้นฐานร่วม — ใช้ระบบยืนยันตัวตนและ HTTP client กลางของ CMS ระบบ breadcrumb และเมนูด้านข้าง รวมถึงส่วนหัวหน้าและพื้นที่เลื่อนตารางมาตรฐานเช่นเดียวกับหน้ารายการอื่นในระบบ

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

โค้ดฝั่ง backend อยู่ที่ internal/modules/importmapping/ โมดูลนี้เป็น ผู้เตรียมงานและรับคำสั่ง เท่านั้น การอัปเดตข้อมูลโปรไฟล์จริงเกิดที่ line-management-worker-go ซึ่งเป็นคนละ service

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

  • ทุก route ถูกครอบด้วย module gate ของโมดูล import-mapping
  • policy ที่ประกาศไว้ต่างกันตาม endpoint: readAll สำหรับดึงประวัติงาน, read สำหรับดึงรายการฟิลด์ปลายทาง ส่วน การอัปโหลดไฟล์ การตรวจสอบล่วงหน้า และการสร้างงานนำเข้า ล้วนใช้ policy ระดับ create
  • ข้อสังเกต — ฝั่งหน้าจอควบคุมทั้งหน้ารายการและ wizard ด้วยสิทธิ์ดูข้อมูลชุดเดียวกัน แต่ฝั่ง backend แยกระดับสิทธิ์ของการอ่านออกจากการสั่งนำเข้าไว้ชัดเจนกว่านั้น

แหล่งที่มาของฟิลด์ปลายทาง

  • รายการฟิลด์ที่เลือกได้ (GET /api/import-mapping/fields) ประกอบขึ้นจากสองแหล่งรวมกัน คือฟิลด์มาตรฐานของตาราง line_user และ custom attribute ที่ประกาศไว้ในตาราง attribute_master
  • ดังนั้นการเพิ่ม attribute ใหม่ในหน้า Attribute Setup จะทำให้มีปลายทางใหม่ให้เลือกที่นี่ทันที โดยไม่ต้องแก้อะไรที่โมดูลนำเข้า

Validation และ Business Rule ที่ backend ตรวจ

  • ขั้นตอนอัปโหลด (POST /api/import-mapping/upload) เก็บไฟล์ลง object storage ก่อน แล้วคืนเฉพาะหัวคอลัมน์ที่อ่านได้กลับมา ตัวไฟล์ไม่ได้ถูกส่งซ้ำในขั้นตอนถัดไป
  • ขั้นตอนตรวจสอบล่วงหน้า (POST /api/import-mapping/validate) ไล่เทียบข้อมูลกับตาราง line_user ของ LINE OA ปัจจุบันจริง ๆ ไม่ใช่การตรวจเพียงรูปแบบข้อมูล ตัวเลข "จะอัปเดตกี่แถว" และ "หาไม่เจอกี่แถว" ที่เห็นในขั้นตรวจทาน จึงเป็นผลจากการค้นข้อมูลจริงในเวลานั้น
  • ทุก query ถูกจำกัดขอบเขตตาม LINE OA และองค์กรที่กำลังใช้งานอยู่ ข้อมูลจึงไม่ข้ามไปแตะเพื่อนของ OA อื่น
  • การนำเข้าเป็นแบบอัปเดตเท่านั้น backend ไม่สร้างผู้ใช้ใหม่จากไฟล์ แถวที่จับคู่ไม่ได้จะถูกนับและข้าม ไม่ทำให้ทั้งงานล้มเหลว

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

  • การกด "Start import" ไม่ได้อัปเดตข้อมูลทันที แต่สร้างแถวงานในตาราง import_mapping_job ด้วยสถานะรอประมวลผล แล้ว ส่งรหัสงานเข้าคิวข้อความ ให้ worker รับไปทำ
  • worker เป็นผู้เขียนค่าลงตาราง line_user จริง และเป็นผู้ปรับสถานะของงานตามความคืบหน้า สถานะที่หน้าจอ poll เห็นจึงมาจาก worker ไม่ใช่จาก cms-api
  • ผลลัพธ์การตรวจสอบล่วงหน้าถูกส่งไปเก็บพร้อมกับตอนสร้างงานด้วย เพื่อให้เป็นภาพรวมของสิ่งที่ตรวจไว้ ณ เวลานั้น ก่อนที่ผลจริงจะเข้ามาแทน
  • ไฟล์ CSV ต้นฉบับยังคงอยู่บน object storage หลังงานเสร็จ

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

  • ผลการตรวจสอบล่วงหน้าเป็นภาพ ณ เวลาที่ตรวจ ไม่ใช่การจอง ถ้ามีเพื่อนถูกเพิ่มหรือถูกลบระหว่างที่รอคิว จำนวนแถวที่อัปเดตได้จริงอาจต่างจากตัวเลขในขั้นตรวจทาน
  • ถ้า worker ไม่ทำงานหรือคิวติดขัด งานจะค้างอยู่ในสถานะรอประมวลผลไปเรื่อย ๆ โดยฝั่ง CMS ไม่มีสัญญาณผิดพลาดใด ๆ และไม่มี endpoint สำหรับยกเลิกงาน
  • ไฟล์ log ที่ดาวน์โหลดได้เป็นไฟล์ที่ worker สร้างไว้บน storage ลิงก์ที่ได้จึงเป็นการเข้าถึงไฟล์ตรง ไม่ได้ผ่านการตรวจสิทธิ์ของ CMS อีกชั้น — ควรถือว่าใครที่ได้ลิงก์ไปก็เปิดดูได้
  • โมดูลนี้ไม่มี endpoint สำหรับดูรายละเอียดงานรายตัว ข้อมูลทั้งหมดที่หน้าจอมีจึงมาจากรายการแบบแบ่งหน้าและไฟล์ log เท่านั้น