AMLO Screening — Overview & What You Get
สรุปภาพรวมทั้งระบบเป็นภาษาง่ายๆ สำหรับคนที่เพิ่งเริ่มอ่าน — หลังจาก implement เสร็จจะได้อะไรบ้าง ทั้งหน้าบ้าน หลังบ้าน และ flow หลักที่ต้องรู้
อัปเดต: 2026-08-19
หน้านี้สรุปภาพรวมเป็นภาษาง่ายๆ สำหรับคนที่ยังไม่เคยอ่านชุดเอกสารนี้มาก่อน — อ่านจบแล้วถ้าอยากรู้รายละเอียดเชิงลึกไปต่อที่ Architecture & Scenarios · สิ่งที่ยังไม่ตัดสินใจ → Open Items · หลักฐานจากโค้ดจริง → Code Baseline
1. สรุปสั้นๆ ก่อน (TL;DR)
AMLO screening คือฟีเจอร์ตรวจว่า “บริษัทลูกค้า” ติดบัญชีดำฟอกเงิน (AMLO watchlist) หรือไม่ ถ้าติด ระบบต้อง บล็อกไม่ให้ทำธุรกรรมในนามบริษัทนั้นได้จริง ไม่ใช่แค่ขึ้นข้อความเตือนเฉยๆ
Implement เสร็จแล้วจะได้ 2 อย่างที่ทำงานคู่กันเสมอ แต่เป็นคนละกลไก ไม่พึ่งกัน:
- แจ้งผู้ใช้ทันที (UX) — ถ้าผู้ใช้ค้างอยู่หน้าจอ จะเห็น modal เด้งขึ้นมาบอกว่าบริษัทติด AMLO พร้อมทางออก
- บล็อกจริงที่ server (Enforcement) — ต่อให้ผู้ใช้ปิดเบราว์เซอร์ทิ้งไว้ ไม่เคยเห็น modal เลย พอพยายามทำรายการ ระบบก็ปฏิเสธคำขอนั้นอยู่ดี
ข้อ 2 คือหัวใจของฟีเจอร์นี้ — modal เป็นแค่คำอธิบายให้ผู้ใช้เข้าใจ ไม่ใช่ตัวที่กันไม่ให้ทำรายการ ถ้าเข้าใจผิดตรงนี้แล้วออกแบบให้ modal เป็นตัวกั้นเอง ฟีเจอร์นี้จะพังแบบไม่มีใครรู้ตัว เพราะคนที่ไม่เห็น modal (ปิดเบราว์เซอร์, เน็ตหลุด, ยิง API ตรง) จะยังทำรายการผ่านได้
2. ศัพท์ที่ต้องรู้ก่อนอ่านต่อ
| คำ | แปลว่าอะไร |
|---|---|
| AMLO | หน่วยงานรัฐที่ดูแลเรื่องการฟอกเงิน มีบัญชีรายชื่อ (watchlist) ที่ธนาคารต้องตรวจสอบลูกค้า |
| บริษัทติด AMLO / Flagged | บริษัทนั้นมีผลตรวจอยู่ในไฟล์ AMLO ล่าสุด |
| Clearance (การปลดบล็อก) | เจ้าหน้าที่ Compliance ตรวจสอบแล้วบันทึกว่า “ปลดบล็อกบริษัทนี้แล้ว” พร้อมเหตุผล/หลักฐาน — เป็นทางเดียวที่ทำให้บริษัทกลับมาใช้งานได้ |
| Session | การ login ค้างไว้ของผู้ใช้ 1 คนบนเบราว์เซอร์ 1 อัน (มี cookie เป็นตัวอ้างอิง) |
| APIM facade | ด่านหน้าสุดที่ request จากเว็บทุกตัวต้องผ่าน เป็นคนตัดสินใจปฏิเสธ (403) ก่อนถึงบริการปลายทาง |
| Sentinel | ระบบที่รู้ว่า session ไหนคือใคร กำลังใช้บริษัทไหนอยู่ และบริษัทนั้นสถานะ AMLO อะไร แล้วบอกต่อให้ APIM ตัดสินใจ |
| UserService | เจ้าของข้อมูลจริงว่าใครสังกัดบริษัทไหน และเป็นคนคำนวณ/เก็บสถานะ AMLO ที่ระบบใช้บล็อกจริง |
| Redis (cache) | ที่พักข้อมูลความเร็วสูง เก็บสถานะล่าสุดไว้ให้ APIM/Sentinel เช็คได้เร็ว โดยไม่ต้องถามฐานข้อมูลทุก request |
3. ภาพรวม — ใครทำหน้าที่อะไร
flowchart LR
SFTP[/"ไฟล์ AMLO รายวัน"/] --> CEN["Centralized<br/>เก็บผลตรวจ"]
CEN --> US["UserService<br/>คำนวณสถานะ + เจ้าของกฎบล็อก"]
US --> REDIS[("Redis<br/>สถานะล่าสุด")]
US --> NS["NotificationService"]
NS --> FE["หน้าเว็บลูกค้า"]
FE --> APIM["APIM facade<br/>ตัดสินใจปฏิเสธ/ปล่อยผ่าน"]
APIM --> SEN["Sentinel"]
SEN --> REDIS
APIM --> SVC["บริการปลายทาง<br/>เช่น โอนเงิน"]
| ส่วน | ทำหน้าที่อะไร |
|---|---|
| Centralized | รับไฟล์ AMLO รายวันมาเก็บ แล้วตอบได้ว่า “บริษัทนี้ติดไหม” |
| UserService | รู้ว่าใครอยู่บริษัทไหน คำนวณสถานะ AMLO ของทุกบริษัท และเก็บสถานะที่ระบบใช้บล็อกจริง |
| Sentinel + APIM facade | ด่านหน้าที่เช็คทุก request แล้วปฏิเสธก่อนถึงบริการปลายทาง ถ้าบริษัทติด AMLO |
| NotificationService | ส่งสัญญาณเตือนแบบ real-time ให้คนที่ค้างหน้าจออยู่ (แค่กระตุ้น ไม่ได้ส่งสถานะจริงมาด้วย) |
| Frontend (หน้าเว็บลูกค้า) | แสดง modal และให้ทางออก (สลับบริษัท / ติดต่อธนาคาร) |
| Admin Portal | หน้าจอให้ Ops/Compliance ทำงาน + หน้าทดสอบสำหรับ non-production |
4. สถานะ AMLO มี 4 แบบ ไม่ใช่แค่ “ติด/ไม่ติด”
| สถานะ | ความหมาย | ผู้ใช้เจออะไร |
|---|---|---|
| 🔴 Flagged | บริษัทติด AMLO จริง (มีผลตรวจ) | บล็อกทำรายการ — ต้องสลับบริษัทหรือติดต่อธนาคาร |
| 🟢 Clear | ตรวจแล้วไม่พบ | ทำงานได้ตามปกติ |
| 🟡 NotScreenable | ตรวจไม่ได้ — ข้อมูล custCode ไม่ครบหรือรูปแบบไม่ตรง | ไม่ใช่ Clear — ต้องติดต่อธนาคาร เหมือนกรณีติดจริง |
| ⚪ Unknown | ระบบยืนยันสถานะไม่ได้ (ปัญหาทางเทคนิค ไม่ใช่ผลตรวจ) | งานที่มีมูลค่าถูกกันไว้ชั่วคราว (503) แต่ยัง logout/สลับบริษัทได้ |
⚠️ ทำไมต้องมี 4 แบบไม่ใช่ 2 — ถ้ามีแค่ “ติด/ไม่ติด” บริษัทที่ข้อมูลไม่ครบ (เช่นยังไม่ผูก custCode) จะถูกนับเป็น “ไม่ติด” ไปเงียบๆ ทั้งที่จริงๆ ยังไม่เคยถูกตรวจเลย และถ้าระบบเช็คสถานะไม่ได้ชั่วคราว (Unknown) ก็ต้องไม่เดาว่าปลอดภัยแล้วปล่อยผ่านไปเฉยๆ
5. หน้าบ้าน — สิ่งที่ผู้ใช้จะเห็น
5.1 ฝั่งลูกค้า (Customer App)
| ผู้ใช้เจออะไร | เกิดตอนไหน | ทำอะไรได้ |
|---|---|---|
| กำลังตรวจสอบ… | ระบบกำลังยืนยันสถานะ | รอสักครู่ — ยังกดอะไรไม่ได้ยกเว้น logout |
| บริษัทนี้ติด AMLO — เลือกบริษัทอื่น | ยังมีบริษัทสะอาดให้เลือกสลับ | เลือกบริษัทแล้วกดยืนยัน |
| บริษัทนี้ติด AMLO — ไม่มีบริษัทอื่นให้เลือก | ทุกบริษัทที่สังกัดติดหมด | ติดต่อธนาคาร หรือ logout เท่านั้น |
| ตรวจสอบบริษัทนี้ไม่ได้ | ข้อมูลบริษัทไม่ครบ (NotScreenable) | ติดต่อธนาคาร / สลับบริษัท / logout |
| ระบบขัดข้องชั่วคราว | ปัญหาทางเทคนิค (Unknown) ไม่ใช่ผลตรวจจริง | ลองใหม่ หรือ logout |
ตัวอย่าง flow จริง — ผู้ใช้ถูกบล็อกกลางทางแล้วสลับบริษัท:
sequenceDiagram
autonumber
actor U as ผู้ใช้
participant FE as หน้าเว็บลูกค้า
participant US as UserService
Note over FE: ได้รับสัญญาณแจ้งเตือนจาก NotificationService
FE->>US: ขอสถานะบริษัททั้งหมดจาก /users/me
US-->>FE: บริษัท A = Flagged (ติด) · บริษัท B = Clear (สะอาด)
FE->>U: เปิด modal แจ้งว่าบริษัท A ติด AMLO ให้เลือกสลับไปบริษัท B
U->>FE: เลือกบริษัท B แล้วกดยืนยัน
FE->>US: ขอสลับบริษัท default เป็น B
US->>US: เช็คว่า B ยังสะอาดจริง และผู้ใช้เป็นสมาชิก B จริง
US-->>FE: สลับสำเร็จ
FE->>US: ขอสถานะล่าสุดอีกครั้งเพื่อยืนยัน
US-->>FE: บริษัทที่ใช้งานตอนนี้ = B (Clear)
FE->>FE: ปิด modal — กลับไปทำงานได้ตามปกติในนามบริษัท B
สังเกตว่า modal ไม่ได้ปิดตัวเองทันทีที่กดสลับ — ต้องรอให้ระบบยืนยันสถานะใหม่จริงๆ ก่อน เพื่อกันกรณีสลับไม่สำเร็จแล้ว modal หายไปทั้งที่ยังใช้บริษัทเดิมอยู่
สิ่งที่ผู้ใช้ที่ถูกบล็อกยังทำได้เสมอ (ตั้งใจเปิดไว้):
- ดูข้อมูลบริษัทตัวเอง + สลับบริษัท (ทางออกหลัก)
- login / logout
- รับการแจ้งเตือนแบบ real-time
เหตุผล: ถ้าปิดหมดเลย ผู้ใช้จะติดอยู่ในจอที่ทำอะไรไม่ได้เลยแม้แต่ออกจากระบบ — กลายเป็นปัญหาที่เราสร้างขึ้นเอง
5.2 ฝั่ง Admin (Admin Portal)
เมนู AMLO Management มี 3 หน้า แยกสิทธิ์กันชัดเจน:
| หน้า | ใครใช้ | ทำอะไร |
|---|---|---|
| Operations | Ops | ดูประวัติการตรวจ + กด “ตรวจ AMLO เดี๋ยวนี้” แทนรอรอบอัตโนมัติ |
| Compliance Cases | Compliance | ดูรายชื่อบริษัทที่ติด + กดปลดบล็อกพร้อมกรอกเหตุผล/แนบหลักฐาน |
| Test Simulation | ทีมทดสอบ/dev — เฉพาะ non-production | จำลองบริษัทติด AMLO เพื่อทดสอบ โดยไม่แตะข้อมูลจริง |
6. หลังบ้าน — เกิดอะไรขึ้นที่มองไม่เห็น
ทุกวันตอนตี 5 (หรือ Admin กดสั่งตรวจเอง):
sequenceDiagram
autonumber
participant CEN as Centralized
participant US as UserService
participant Redis
participant NS as NotificationService
participant FE as หน้าเว็บลูกค้า
participant APIM as APIM facade
participant SEN as Sentinel
participant SVC as บริการปลายทาง เช่น โอนเงิน
Note over CEN: ทุกวันตี 5 (หรือ Admin กดสั่งตรวจเอง)
CEN->>CEN: อ่านไฟล์ AMLO ใหม่ + บันทึกผลตรวจ
CEN-->>US: แจ้งว่าตรวจเสร็จแล้ว
US->>US: คำนวณสถานะทุกบริษัทใหม่ทั้งหมด
US->>Redis: บันทึกสถานะล่าสุด (Flagged / Clear / NotScreenable)
US->>NS: ส่งสัญญาณแจ้งเตือน (best-effort — ส่งไม่ถึงก็ได้)
NS-->>FE: กระตุ้นว่ามีอะไรเปลี่ยน
FE->>US: ขอสถานะจริงจาก /users/me
US-->>FE: สถานะล่าสุดของทุกบริษัทที่ผู้ใช้สังกัด
FE->>FE: เปิด modal ถ้าบริษัทที่ใช้งานอยู่ติด AMLO
Note over FE,SVC: ต่อให้ผู้ใช้ปิดเบราว์เซอร์อยู่ ไม่เห็นการแจ้งเตือนเลย ระบบก็ยังบล็อกอยู่ดี
FE->>APIM: ผู้ใช้พยายามทำรายการ (เช่น โอนเงิน)
APIM->>SEN: ขอสถานะ session และบริษัทที่กำลังใช้งาน
SEN->>Redis: อ่านสถานะที่ UserService เตรียมไว้
Redis-->>SEN: สถานะล่าสุด
SEN-->>APIM: ส่งสถานะกลับมา
alt บริษัทติด AMLO
APIM-->>FE: ปฏิเสธทันที (403) — ไม่ถึงบริการปลายทางเลย
else บริษัทไม่ติด
APIM->>SVC: ส่งรายการต่อไปตามปกติ
end
ทำไมด่านปฏิเสธถึงอยู่ที่ APIM facade ไม่ใช่ให้แต่ละบริการ (โอนเงิน, workflow ฯลฯ) เช็คเอง — เพราะ request จากเว็บลูกค้าทุกตัวต้องผ่าน APIM facade อยู่แล้ว จุดเดียวนี้เลยครอบคลุมทุกบริการโดยที่บริการปลายทางไม่ต้องรู้ business logic ของ AMLO เลย ถ้าปล่อยให้แต่ละบริการเขียนเช็คเอง มีความเสี่ยงสูงที่จะมีบางบริการลืมเช็คแล้วหลุดออกไป
เจ้าหน้าที่ Compliance ปลดบล็อก:
sequenceDiagram
autonumber
actor C as เจ้าหน้าที่ Compliance
participant ADM as Admin Portal
participant US as UserService
participant NS as NotificationService
participant FE as หน้าเว็บลูกค้า
C->>ADM: เปิดบริษัทที่ Flagged แล้วกด "ปลดบล็อก"
C->>ADM: กรอกเหตุผล + แนบหลักฐาน แล้วยืนยัน
ADM->>US: บันทึกการปลดบล็อก (clearance)
US->>US: ตรวจว่ายังติดอยู่จริง + หลักฐานครบ แล้วบันทึกเป็น Clear
US-->>ADM: บันทึกสำเร็จ — กำลังกระจายผลไปยังผู้ใช้ในบริษัทนี้
US->>NS: ส่งสัญญาณแจ้งเตือนหลังกระจายผลเสร็จ (best-effort)
NS-->>FE: กระตุ้นให้โหลดสถานะใหม่
FE->>FE: modal หายไปเมื่อสถานะยืนยันว่า Clear แล้ว
🔴 บริษัทหายไปจากไฟล์ตรวจรอบใหม่ ไม่ได้ปลดบล็อกให้อัตโนมัติ — ต้องมีเจ้าหน้าที่กดปลดบล็อกและบันทึกเหตุผล/หลักฐานเสมอ (ระบบยังพิสูจน์ไม่ได้ว่า “หายจากไฟล์” แปลว่าพ้นจริงหรือแค่ไฟล์รอบนั้นไม่ได้ส่งซ้ำ — ปลดอัตโนมัติเป็นงานเฟส 2)
Audit — ทุกอย่างต้องมีบันทึกไว้ 5 เรื่อง (เพราะนี่คือ compliance control ที่ต้องอธิบายกับผู้ตรวจสอบได้):
- ทุกรอบตรวจ (แม้ตรวจแล้วไม่พบอะไรเปลี่ยนเลย)
- การเปลี่ยนสถานะของแต่ละบริษัท
- ทุกครั้งที่ปฏิเสธรายการจริง — หลักฐานว่าระบบทำงาน
- ใครสั่งตรวจเอง เมื่อไหร่ ผลอะไร
- ใครปลดบล็อก ด้วยหลักฐานอะไร
7. ทดสอบได้จริง โดยไม่ต้องรอข้อมูลจริง
หน้า Test Simulation (non-production เท่านั้น) ให้ทีมทดสอบ/dev เลือกบริษัททดสอบที่เตรียมไว้ล่วงหน้า (ไม่มีผลตรวจ AMLO จริง) แล้วสั่งให้กลายเป็น “Flagged” ชั่วคราว — มีเวลาหมดอายุ (TTL) และมีบันทึกว่าใครสั่ง เพื่อดู modal และทดสอบ flow ทั้งหมดได้จริง โดยไม่ต้องรอไฟล์ AMLO จริง ไม่ต้องแก้ฐานข้อมูล
ข้อจำกัดสำคัญ:
- ใช้ได้เฉพาะบริษัททดสอบที่ไม่มีผลตรวจจริงเท่านั้น — บริษัทที่ติดจริงจะไม่ถูกจำลองทับ
- สั่งให้ “ติด” ได้อย่างเดียว (ไม่มีปุ่มสั่งให้ “สะอาด” ปลอมๆ)
- Production ไม่มีหน้านี้เลย ไม่มีเมนู ไม่มี route ไม่มี code ส่วนนี้ติดไปด้วยซ้ำ
8. สิ่งที่ยังไม่ได้ในรอบแรกนี้ (เฟส 2)
รอบแรก (เฟส 1) ครอบคลุมทุกอย่างข้างบนแล้วครบ แต่มีของที่ตั้งใจเลื่อนไปเฟส 2 เพราะยังรอคำตอบจาก Owner/Compliance ก่อน:
- ปลดบล็อกอัตโนมัติเมื่อบริษัทหายจากไฟล์ (ตอนนี้ต้องมีคนกดปลดเสมอ)
- การแจ้งเตือนแบบส่งเฉพาะรายการที่เปลี่ยน (ตอนนี้คำนวณใหม่ทั้งชุดทุกรอบ — ช้ากว่าแต่ซ่อมตัวเองได้ถ้า event หาย)
- endpoint แยกเล็กๆ สำหรับดูสถานะ AMLO อย่างเดียว (ตอนนี้รวมอยู่ใน
/users/meเส้นเดียว)
รายละเอียดเหตุผลและของที่ต้องปิดก่อน go-live จริง (performance, permission, ช่องโหว่ที่ยังไม่ปิด ฯลฯ) → Open Items
9. อยากรู้ลึกกว่านี้ ไปอ่านที่ไหน
| อยากรู้เรื่องอะไร | ไปอ่านที่ |
|---|---|
| กลไกเบื้องหลังแบบละเอียด, APIM policy design, ทุก scenario/edge case | Architecture & Scenarios |
| สิ่งที่ยังไม่ตัดสินใจ, ช่องโหว่ที่ต้องปิดก่อน go-live, แผนแบ่งเฟส | Open Items |
| จะลงมือเขียนโค้ด ต้องแก้ไฟล์ไหนของ repo ไหนบ้าง | Code Baseline |