รายงานเพื่อนทั้งหมด
ภาพรวม
รายงานเพื่อนทั้งหมด (All Friends Report) คือหน้าฐานข้อมูลผู้ใช้ LINE ทั้งหมดของ OA ใช้สำหรับค้นหาและกรองรายชื่อ ดูรายละเอียดรายบุคคล แก้ไขข้อมูลโปรไฟล์และคุณสมบัติเพิ่มเติม (custom attribute) สั่งซิงก์รายชื่อผู้ติดตามจาก LINE ส่งออกข้อมูลเป็นไฟล์ CSV และนำเข้ารายชื่อ LINE User ID จากไฟล์ CSV
เหมาะกับทีมที่ต้องการภาพรวมของฐานผู้ติดตาม ตรวจสอบข้อมูลรายคนก่อนทำแคมเปญ หรือแก้ไขข้อมูลลูกค้าที่ได้จากช่องทางอื่นให้ตรงกับระบบ
โครงสร้างของโมดูลแบ่งเป็น 3 หน้า ได้แก่ หน้ารายการที่มี 2 แท็บ (รายชื่อในระบบ และประวัติการนำเข้า), หน้ารายละเอียดแบบเต็ม และหน้าฟอร์มนำเข้าไฟล์ CSV
Business Flow
รายชื่อในระบบ
- เปิดหน้ารายงาน ระบบตรวจสิทธิ์การเข้าถึงก่อน แล้วจึงโหลดรายชื่อผู้ใช้พร้อมข้อมูลประกอบอีก 2 ชุด คือ สถานะการซิงก์ผู้ติดตามล่าสุด และรายการคุณสมบัติที่ตั้งค่าให้แสดงในรายงานได้
- แท็บปัจจุบันอ่านจาก query string ทำให้ผู้ใช้บันทึกหรือแชร์ลิงก์ไปยังแท็บที่ต้องการได้ การสลับแท็บจะรีเซ็ตการแบ่งหน้าเสมอ
- ตัวกรองใช้รูปแบบ "กรอกแล้วกดค้นหา" คือค่าที่พิมพ์หรือเลือกจะพักไว้ในตัวตารางก่อน แล้วส่งขึ้นไปยิงคำขอเมื่อกดปุ่มค้นหาหรือกด Enter เท่านั้น จึงไม่ยิงคำขอทุกครั้งที่พิมพ์
- ตัวกรองที่ใช้ได้ในแท็บนี้มี 3 ตัว คือ ประเภทผู้ใช้ (สมาชิก / ผู้เยี่ยมชม), สถานะการใช้งาน (ใช้งานอยู่ / ไม่ได้ใช้งาน) และช่วงการใช้งานล่าสุดเป็นจำนวนวัน (7 / 30 / 90 / 180 / 365) ซึ่งระบบจะแปลงเป็นช่วงวันที่ก่อนส่งไปยังเซิร์ฟเวอร์
- คอลัมน์มาตรฐานประกอบด้วย ลำดับ, ผู้ใช้ (รูปโปรไฟล์ ชื่อที่แสดง และ user ID แบบย่อที่คัดลอกได้), ประเภท, สถานะ, สถานะการติดตาม, วันที่ใช้งานล่าสุด และวันที่ลงทะเบียน
- คอลัมน์คุณสมบัติเพิ่มเติมถูกสร้างขึ้นอัตโนมัติ จากรายการคุณสมบัติที่ถูกตั้งค่าให้แสดงในรายงาน โดยการแสดงผลปรับตามชนิดข้อมูล เช่น ค่าตรรกะแสดงเป็นป้าย ค่าวันที่จัดรูปแบบให้อ่านง่าย ค่าที่เป็นรายการหรือวัตถุแสดงแบบย่อ และค่าว่างแสดงเป็นขีด
- ปุ่มท้ายแถวเปิดหน้าต่างรายละเอียดผู้ใช้ ส่วนแถบเครื่องมือด้านขวาแสดงจำนวนเพื่อนทั้งหมด เวลาซิงก์ล่าสุด และปุ่มซิงก์กับปุ่มส่งออก
การซิงก์ผู้ติดตาม
- กดปุ่มซิงก์เพื่อสั่งงานดึงรายชื่อผู้ติดตามจาก LINE ซึ่งเป็นงานที่ทำงานเบื้องหลัง
- เมื่อสั่งสำเร็จ ระบบจะโหลดตารางและสถานะการซิงก์ใหม่
- หากสั่งไม่สำเร็จเพราะมีงานซิงก์ค้างอยู่ ระบบจะแสดงคำเตือนพร้อมข้อความจากเซิร์ฟเวอร์แทนที่จะแสดงเป็นข้อผิดพลาดทั่วไป
- เมื่อเข้าหน้ามาแล้วพบว่าสถานะการซิงก์ยังอยู่ระหว่างประมวลผล ปุ่มจะขึ้นสถานะกำลังทำงานให้เองโดยไม่ต้องกดใหม่
การส่งออกข้อมูล
ปุ่มส่งออกจะเรียกคำสั่งสร้างรายงาน ซึ่งฝั่งเซิร์ฟเวอร์จะประกอบเนื้อหา CSV เป็นข้อความพร้อมชื่อไฟล์ส่งกลับมา แล้วเบราว์เซอร์จึงบันทึกเป็นไฟล์ให้ผู้ใช้ โครงสร้าง endpoint ถูกออกแบบให้รองรับรายงานประเภทอื่นในอนาคตด้วยรูปแบบเดียวกัน
รายละเอียดผู้ใช้
- หน้าต่างรายละเอียดที่เปิดจากตารางเป็นเส้นทางหลักที่ผู้ใช้ส่วนใหญ่ใช้งาน โดยโหลดข้อมูลผู้ใช้รายคนพร้อมรายการกลุ่มผู้ชมและโครงสร้างคุณสมบัติเพิ่มเติม
- ส่วนหัวแสดงรูปโปรไฟล์ ชื่อ และป้ายบอกประเภท สถานะ และการติดตาม
- บล็อกข้อมูลส่วนตัว แก้ไขได้ในตัว ประกอบด้วยชื่อ-นามสกุล อีเมล และเบอร์มือถือ โดยมีการตรวจรูปแบบอีเมลและตรวจว่าเบอร์มือถือมี 9 ถึง 10 หลักหลังตัดช่องว่างและขีดออก
- บล็อกข้อมูล LINE OA แสดง user ID แบบคัดลอกได้ กลุ่มผู้ชมที่ผู้ใช้สังกัด (แปลงจากรหัสเป็นชื่อ) และวันที่เลิกติดตามหากมี
- บล็อกคุณสมบัติเพิ่มเติม อ่านโครงสร้างจากการตั้งค่าคุณสมบัติแล้วคลี่ออกมาเป็นรายการ ค่าที่เป็นวัตถุหรือรายการจะแสดงแบบอ่านอย่างเดียว ส่วนคีย์ที่ผู้ใช้มีข้อมูลอยู่แต่ไม่พบในโครงสร้างจะถูกนำมาแสดงเพิ่มแบบอ่านอย่างเดียวเช่นกัน เพื่อไม่ให้ข้อมูลหายไปจากสายตา
- โหมดแก้ไขจะเลือกชนิดของช่องกรอกตามชนิดข้อมูลของคุณสมบัตินั้น เมื่อบันทึกสำเร็จจะโหลดข้อมูลใหม่ทั้งในหน้าต่างและในตารางหลัก
- หน้ารายละเอียดแบบเต็ม เป็นอีกเส้นทางหนึ่ง แบ่งเป็น 2 แท็บ คือ โปรไฟล์ (การ์ดสรุป สถิติย่อ และข้อมูลติดต่อที่แก้ไขได้) และเส้นทางการใช้งานเว็บไซต์ ปัจจุบันลิงก์เข้าหน้านี้มาจากโมดูลกลุ่มผู้ชมเป็นหลัก และหน้านี้ไม่มีบล็อกคุณสมบัติเพิ่มเติม
เส้นทางการใช้งานเว็บไซต์
ดึงข้อมูลพฤติกรรมจาก Google Analytics ของผู้ใช้รายนั้น เลือกช่วงเวลาได้ 7 / 14 / 30 / 90 วัน แล้วแสดงเป็นไทม์ไลน์แยกตาม session พร้อมไอคอนประจำชนิดเหตุการณ์ เช่น การเปิดหน้า การเริ่ม session การเลื่อนหน้า การซื้อ และการคลิก หากยังไม่ได้ตั้งค่า GA ฝั่งเซิร์ฟเวอร์ หน้าจอจะแสดงสถานะว่างพร้อมคำอธิบาย
การนำเข้าไฟล์ CSV
- แท็บประวัติการนำเข้าแสดงรายการงานที่เคยสั่ง พร้อมชื่อไฟล์ต้นฉบับ สถานะ (ใหม่ / กำลังประมวลผล / ล้มเหลว / เสร็จสิ้น) และเวลาตามเขตเวลากรุงเทพฯ ปุ่มดาวน์โหลดไฟล์ผลลัพธ์จะเปิดใช้ได้ต่อเมื่องานเสร็จสิ้นแล้ว
- หน้าฟอร์มนำเข้าประกอบด้วยชื่องาน พื้นที่ลากวางไฟล์ที่รับเฉพาะ CSV และคำแนะนำการเตรียมไฟล์พร้อมรูปตัวอย่างและปุ่มดาวน์โหลดเทมเพลต
- การตรวจไฟล์ทำหลายชั้นตั้งแต่ฝั่งหน้าเว็บ เริ่มจากตรวจนามสกุลและชนิดไฟล์ ตรวจว่าจำนวนระเบียนไม่เกิน 10,000 รายการ ตรวจว่ามีคอลัมน์ LINE User ID และมีข้อมูลอย่างน้อยหนึ่งแถว จากนั้นจึงไล่ตรวจทีละแถวว่าไม่มีค่าว่าง ไม่มีค่าซ้ำ และรูปแบบ LINE User ID ถูกต้อง ข้อผิดพลาดทั้งหมดจะถูกรวบรวมพร้อมเลขแถวแล้วแสดงในหน้าต่างสรุป
- เมื่อยืนยันการนำเข้า ระบบจะส่งไฟล์พร้อมข้อมูลประกอบไปยังเซิร์ฟเวอร์ แล้วพาผู้ใช้กลับไปยังแท็บประวัติเพื่อติดตามสถานะ
- รหัสข้อผิดพลาดจากเซิร์ฟเวอร์ถูกจับแยกตามความหมาย เช่น รหัสที่บอกว่า user ID ในไฟล์ไม่ถูกต้องจะถูกแตกออกเป็นรายการข้อผิดพลาดรายแถว ส่วนรหัสที่เกี่ยวกับสิทธิ์จะแสดงเป็นข้อผิดพลาด และรหัสที่แม็ปกลับเข้าฟิลด์ได้จะถูกแสดงใต้ฟิลด์นั้นโดยตรง
หน้าจอและองค์ประกอบหลัก
Route ทั้งสาม — หน้ารายการ (src/app/report/all-friends/page.tsx), หน้ารายละเอียดแบบเต็ม (.../detail/page.tsx) และหน้าฟอร์มนำเข้า (.../form/page.tsx) โดยสองหน้าแรกถูกห่อด้วยตัวตรวจสิทธิ์ ส่วนหน้าฟอร์มไม่ได้ห่อไว้
ตัวควบคุมของรายการ (src/components/report/report-all-friends-table.container.tsx) — รวมตรรกะทั้งหมดของหน้ารายการ ทั้งการสลับแท็บ การกรอง การซิงก์ การส่งออก และการสร้างคอลัมน์คุณสมบัติแบบอัตโนมัติ ส่วนตัวตาราง (report-all-friends-table.tsx) ดูแลแถบเครื่องมือและตัวกรองแบบพักค่า
หน้าต่างรายละเอียด (src/components/report/all-friends-detail-modal.tsx) — เส้นทางหลักในการดูและแก้ไขข้อมูลรายบุคคล รวมถึงการคลี่โครงสร้างคุณสมบัติแบบซ้อนชั้นออกมาแสดง
ไทม์ไลน์ GA (src/components/report/user-ga-journey.tsx) — จัดกลุ่มเหตุการณ์ตาม session และแสดงจุดที่จับคู่ตัวตนบนเว็บกับผู้ใช้ LINE ได้
ตัวควบคุมการนำเข้า (src/components/report/csv-form.container.tsx) — รวมการตรวจไฟล์ทุกชั้นและการจัดการรหัสข้อผิดพลาดจากเซิร์ฟเวอร์ โดยใช้หน้าต่างยืนยันและหน้าต่างสรุปข้อผิดพลาดร่วมกับโมดูลกลุ่มผู้ชม
Endpoint สำคัญ — รายชื่อผู้ใช้และประวัติการนำเข้าอยู่ใต้กลุ่ม /report/* ส่วนข้อมูลรายบุคคล การแก้โปรไฟล์ การแก้คุณสมบัติ การซิงก์ผู้ติดตาม และเส้นทาง GA อยู่ใต้กลุ่ม /line-users/* ซึ่งใช้ร่วมกับโมดูลฐานข้อมูลสมาชิก
จุดเชื่อมต่อกับฟีเจอร์อื่น
- สิทธิ์การเข้าถึง — ใช้ subject
report/all-friendsซึ่งแม็ปจากโมดูลreport-all-friendsฝั่งหลังบ้าน โดยการกระทำที่ตรวจจริงในหน้าเว็บคือการดูข้อมูล ส่วนการควบคุมสิทธิ์การส่งออกอยู่ที่ฝั่งเซิร์ฟเวอร์ - ตั้งค่าคุณสมบัติผู้ใช้ (Attribute Master) — เป็นแหล่งของทั้งคอลัมน์แบบอัตโนมัติในตารางและโครงสร้างฟอร์มคุณสมบัติในหน้าต่างรายละเอียด หากยังไม่มีคุณสมบัติใดถูกตั้งให้แสดงในรายงาน ตารางจะไม่มีคอลัมน์เพิ่ม
- กลุ่มผู้ชม (Audience) — ใช้แปลงรหัสกลุ่มผู้ชมเป็นชื่อในหน้าต่างรายละเอียด และเป็นต้นทางของลิงก์เข้าหน้ารายละเอียดแบบเต็ม นอกจากนี้ยังใช้หน้าต่างประกอบการนำเข้าไฟล์ร่วมกัน
- Google Analytics — ต้องตั้งค่าฝั่งเซิร์ฟเวอร์ก่อน มิฉะนั้นแท็บเส้นทางการใช้งานเว็บไซต์จะแสดงสถานะว่าง
- งานเบื้องหลัง — ทั้งการซิงก์ผู้ติดตามและการนำเข้า CSV เป็นงานที่ประมวลผลแบบไม่พร้อมกันที่ฝั่ง worker หน้าเว็บทำหน้าที่สั่งงานแล้วติดตามสถานะผ่านสถานะการซิงก์และตารางประวัติการนำเข้าตามลำดับ
- ค่ามาตรฐานร่วม — ขนาดหน้าตาราง รูปแบบวันที่ และสไตล์ของ control ในแถบตัวกรอง ใช้ค่ากลางเดียวกับหน้ารายการอื่นของ CMS
รายละเอียดฝั่ง Backend (CMS API)
โมดูลนี้อยู่ที่ internal/modules/report/ ลงทะเบียนใต้กลุ่ม /api/report
สิทธิ์ที่ต้องมี
- โมดูลนี้มี
ModuleGate("report-all-friends")คุมอยู่จริง ต่างจากหลายโมดูลในระบบที่ประกาศ policy ไว้แต่ยังไม่บังคับ กล่าวคือถ้าองค์กรไม่ได้เปิดโมดูลreport-all-friendsไว้ คำขอจะถูกปฏิเสธที่ระดับ gate ก่อนถึง handler เลย - นอกจาก gate แล้วยังต้องผ่าน
JwtAuthระดับ global - การส่งออกใช้สิทธิ์คนละตัวกับการดู —
GET /api/report/all-friendประกาศ policyreadAllแต่GET /api/report/all-friend/exportประกาศ policyexportแยกต่างหาก เจตนาคือให้ตัดสิทธิ์คนที่ดูรายงานได้แต่ไม่ควรดึงข้อมูลทั้งฐานออกไปได้ (หน้าเว็บตรวจแค่สิทธิ์ "ดูข้อมูล" การแยกจึงเกิดที่ฝั่งเซิร์ฟเวอร์)
เงื่อนไขการกรองมาจากที่เดียวกับหน้าค้นหาเพื่อน
backend นำตัวสร้าง query ของโมดูลจัดการผู้ใช้ LINE มาใช้ซ้ำ ไม่ได้เขียนเงื่อนไขชุดใหม่ ผลที่ได้คือ:
- ตัวกรองของ
GET /api/report/all-friendตรงกับGET /api/line-users/searchทุกประการ พฤติกรรมการกรองในสองหน้านี้จึงตรงกัน 100% โดยไม่ต้องดูแลสองที่ - เมื่อมีการเพิ่มหรือแก้เงื่อนไขกรองในโมดูลผู้ใช้ LINE รายงานนี้จะได้ตามไปด้วยโดยอัตโนมัติ
- คอลัมน์ attribute ที่แสดงได้มาจาก
GET /api/attribute-master/reportableถ้าไม่มี attribute ใดถูกตั้งให้แสดงในรายงาน ตารางก็จะไม่มีคอลัมน์เพิ่ม
การส่งออก CSV
GET /api/report/all-friend/export ใช้เงื่อนไขกรองชุดเดียวกับการดูรายการ แต่ ไม่มีการแบ่งหน้า และเขียนผลลัพธ์ลง response แบบสตรีมโดยตรง ไม่ได้ประกอบไฟล์ทั้งก้อนไว้ในหน่วยความจำก่อน กลไกเดียวกับการส่งออกของโมดูลกลุ่มผู้ชม ข้อควรรู้:
- ยิ่งเงื่อนไขกว้าง ไฟล์ยิ่งใหญ่และคำขอยิ่งค้างนาน เพราะปริมาณถูกกำหนดโดยตัวกรองล้วน ๆ
- เนื่องจากเป็นการสตรีม การล้มเหลวกลางทางอาจได้ไฟล์ที่ไม่สมบูรณ์แทนที่จะเป็นข้อความ error
ประวัติการนำเข้า
GET /api/report/import-history อ่านจาก line_user_import คู่กับ line_user_import_detail จึงเห็นผลของทุกรอบการนำเข้า ไม่ว่าจะสั่งจากหน้าจัดการผู้ใช้ LINE หรือจากหน้านำเข้าแบบจับคู่คอลัมน์ ถ้าอ่านข้อมูลไม่สำเร็จ backend จะตอบเป็นสถานะ 500 พร้อมข้อความว่านำเข้าไม่สำเร็จ ไม่ได้ตอบเป็นรายการว่าง หน้าจอจึงควรแยกแยะระหว่าง "ไม่มีประวัติ" กับ "อ่านประวัติไม่ได้"
ตารางที่เกี่ยวข้อง
line_user, line_user_import, line_user_import_detail, attribute_master, system_attribute และ line_oa