AMLO Screening — Open Concerns (ความเสี่ยงที่ยังเปิดอยู่)
รายการความเสี่ยงที่ยังไม่ปิด ณ วันส่งมอบ data tier — อะไรบล็อก deploy, อะไรบล็อกงานชิ้นถัดไป, อะไรเป็นหนี้ที่รู้ตัวแล้วยอมรับไว้ พร้อมเงื่อนไขปิดของแต่ละข้อ
อัปเดต: 2026-08-21
หน้านี้ไม่ใช่ TODO list — เป็นรายการของที่ “รู้ว่าเสี่ยง แต่ยังไม่ปิด” พร้อมเหตุผลว่าทำไมถึงยังไม่ปิด และต้องเห็นอะไรถึงจะปิดได้ สถานะของที่ลงไปแล้ว → Data Tier Handoff
สรุปตาราง
| # | เรื่อง | ระดับ | บล็อกอะไร | เจ้าของ |
|---|---|---|---|---|
| 1 | SSH.NET 2026.0.0 ยังไม่เคยรันจริง | 🔴 สูง | deploy | dev ที่ deploy service |
| 2 | migration ไม่เคยถูก test suite รัน | 🟡 กลาง | ความมั่นใจของ migration รอบถัดไป | dev |
| 3 | ไม่มี pipeline ไหนรัน migration | 🟡 กลาง | ทุก deploy (manual step) | DevOps / dev |
| 4 | คีย์จัดกลุ่มยังไม่มีมติจาก Compliance | 🟡 กลาง | งานชิ้นถัดไป (ตัวสร้าง generation) | Compliance |
| 5 | read path เดิมยังเทียบ CustCode ดิบ | 🟢 หนี้ที่รู้ตัว | ไม่บล็อก | dev (แก้ตอนแตะ endpoint) |
| 6 | ไม่มีทางสร้าง fingerprint เวอร์ชันเก่า | 🟢 หนี้ที่รู้ตัว | ไม่บล็อก จนกว่าจะต้อง backfill | dev |
| 7 | SIT ช้ากว่า 3 migration | 🟢 รับทราบ | ไม่บล็อก (เลิกใช้แล้ว) | ทีม |
| 8 | DB ล้ำหน้า code ที่ deploy | 🟢 รับทราบ | ไม่บล็อก (migration เพิ่มอย่างเดียว) | — |
| 9 | PII / retention ของ snapshot_detail | 🟡 กลาง | Phase 2 | Compliance / Security |
1. 🔴 SSH.NET 2026.0.0 ยังไม่เคยรันกับ SFTP จริง — บล็อก deploy
อัปจาก 2024.2.0 → 2026.0.0 เพื่อปิด CVE-2026-48798 (path traversal ใน ScpClient) ปัญหาคือ ไม่มี test สักตัวที่แตะ Sftp / SSH / Renci และผู้ใช้เดียวคือ src/Centralized02.Infrastructure/Sftp/SshNetSftpFileSource.cs ⇒ build ผ่านและ test 851 ตัวผ่าน ไม่ได้พิสูจน์อะไรเลยเกี่ยวกับ SFTP
CVE ตัวที่แก้อยู่ที่ ScpClient ซึ่งเราไม่ได้ใช้ (เราใช้ SftpClient) — แต่ระหว่างทางมี behaviour change ที่เห็นได้เฉพาะตอน runtime 2 เรื่อง:
| เวอร์ชัน | เปลี่ยนอะไร | กระทบเราตรงไหน |
|---|---|---|
| 2025.0.0 | ตัด DSA ออก | ถ้า host key ของฝั่ง server หรือ private key ใน Key Vault เป็น DSA → พังที่ client.Connect() (~บรรทัด 28) |
| 2025.1.0 | ”Fix SftpFileAttributes file type detection” | กระทบ f.IsRegularFile (~บรรทัด 32–33) — เปลี่ยนได้ว่าไฟล์ไหนถูก ingest โดยไม่มี error ให้เห็น |
| 2025.1.0 | เพิ่มการตรวจ host key algorithm, แยก PrivateKeyFile ตามรูปแบบ key | อาจ reject key ที่เคยรับได้ |
2025.1.0 → 2026.0.0 ต้นทางระบุว่า breaking change “None known”
เงื่อนไขปิด — smoke test กับ endpoint จริงของ dev/uat ด้วย key จริงจาก Key Vault:
-
Connect()ผ่าน -
ListDirectoryคืนรายการไฟล์เท่าเดิมกับที่ 2024.2.0 เคยคืน (ข้อนี้สำคัญที่สุด — ถ้าไฟล์หายไปเงียบๆ จะกลายเป็น “ไม่มีไฟล์ใหม่” ซึ่งระบบถือว่าปกติ) -
ReadAllTextอ่านไฟล์ได้ครบ - ยืนยันว่า host key และ client key ไม่ใช่ DSA
ℹ️ ข้อนี้ไม่เกี่ยวกับ migration ที่ลง DEV/UAT ไปแล้ว — ตารางเปล่ายังไม่มีใครเขียน จะ rollback หรือรอได้โดยไม่กระทบอะไร
2. 🟡 migration ไม่เคยถูก test suite รัน
tests/Centralized05.Tests/TestSupport/SqliteAuthDbContext.cs ใช้ EnsureCreated() ซึ่ง สร้าง schema จาก model ตรงๆ ข้าม migration ทั้งหมด ⇒ test 851 ตัวพิสูจน์ว่า model ถูก ไม่ได้พิสูจน์ว่า migration ถูก
has-pending-model-changes = none ก็ตอบแค่ว่า model กับ migration ล่าสุดตรงกัน ไม่ได้ตอบว่า migration รันผ่าน
รอบนี้ชดเชยด้วยการรันกับ Postgres จริงบน DEV/UAT แล้วยิงทดสอบพฤติกรรม 10 ข้อ (Handoff §5) — แต่เป็นการทำมือ ไม่ได้อยู่ใน CI
เงื่อนไขปิด: มี integration test ที่รัน Database.Migrate() กับ Postgres จริง (Testcontainers) อย่างน้อย 1 ตัว — หรือยอมรับว่าทุก migration ต้องทำ manual verification แล้วเขียนไว้ใน definition of done
ℹ️ ผลข้างเคียงที่แก้ไปแล้วระหว่างทาง: connection string ของ SQLite เดิมไม่ได้ระบุ Foreign Keys=True ⇒ test เรื่อง cascade เคยผ่านแบบไร้ความหมาย ตอนนี้เปิดแล้ว
3. 🟡 ไม่มี pipeline ไหนรัน migration
ตรวจแล้วทั้ง ci.yml, ci-sit.yml, ci-orchestrate.yml — ไม่มี step รัน migration ทุก env ต้องมีคนรัน script เอง
ผลที่ตามมาคือ env drift แบบที่เห็นอยู่ตอนนี้: DEV/UAT อยู่ที่ migration ล่าสุด ส่วน SIT ช้ากว่า 3 ตัว (ข้อ 7)
เงื่อนไขปิด: ตัดสินใจอย่างใดอย่างหนึ่ง — เพิ่ม step ลง pipeline หรือประกาศให้ชัดว่าเป็น manual runbook แล้วเขียน runbook ไว้ (ตอนนี้อยู่ที่ Handoff §7 ซึ่งเป็นเอกสาร sprint ไม่ใช่ runbook ถาวร)
4. 🟡 คีย์จัดกลุ่มยังไม่มีมติ — บล็อกงานชิ้นถัดไป
ตัวสร้าง generation เขียนไม่ได้จนกว่าจะรู้ว่าจัดกลุ่มด้วยคีย์อะไร ข้อเสนอจากฝั่ง dev คือ (CustCode, RecordGuid) พร้อมหลักฐานวัดจากไฟล์จริงแล้วที่ Phase 1 §3.2 แต่เป็นคำถามของ Compliance ไม่ใช่ของ dev
schema รองรับได้ทุกทางเลือกแล้ว (เก็บ RecordGuid, SubjectId, CtlId ครบ) จึงไม่บล็อก data tier — บล็อกเฉพาะโค้ดที่จัดกลุ่ม
คำถามพ่วงที่ต้องถามพร้อมกัน: การเปลี่ยนบทบาท (CustTypeDesc) ถือเป็นหลักฐานใหม่ที่ต้องทบทวนหรือไม่ — มีผลกับ EvidenceFingerprint โดยตรง ซึ่งแปลว่ามีผลกับการ revoke สิ่งที่อนุมัติไปแล้ว
เงื่อนไขปิด: Compliance ยืนยันคีย์เป็นลายลักษณ์อักษร → บันทึกเป็น ADR → เก็บคีย์ไว้เป็น constant/config จุดเดียว ห้าม hardcode กระจาย
5. 🟢 read path เดิมยังเทียบ CustCode ดิบ
AmloScreeningMatchRepository (~บรรทัด 36) ยังเทียบ x.CustCode == custCode ตรงๆ ⇒ GET /v1/amlo-screening/{custCode} ตอบ NotFound ให้ " abc123 " ทั้งที่ amlo_screened_company จับคู่ได้
ทำไมยังไม่แก้: ตารางนั้นคือ staging ซึ่งอยู่คนละชั้นกับ ADR 0007 และการแก้จะเปลี่ยนพฤติกรรมของ endpoint ที่มีคนใช้อยู่ — ควรแก้พร้อม test เทียบก่อน/หลัง ไม่ใช่แถมมากับ migration
เงื่อนไขปิด: แก้ตอนแตะ endpoint นั้นรอบหน้า พร้อม test ว่า " abc123 " กับ ABC123 ให้ผลเดียวกัน · บันทึกไว้แล้วที่ Phase 1 §7 และใน ADR 0007
6. 🟢 สร้าง fingerprint เวอร์ชันเก่าไม่ได้แล้ว
ADR 0008 บังคับให้ Create ปั๊ม FingerprintVersion จาก CurrentVersion เสมอ — โดยตั้งใจ เพื่อกันแถวที่ label ไม่ตรงสูตร
ผลข้างเคียงคือ backfill หรือการคำนวณย้อนหลังทำผ่าน Create ไม่ได้ ห้ามแก้โดยเปิดให้ Create รับ version กลับมา (จะย้อนกลับไปหาปัญหาที่ ADR 0008 ปิดไปทันที) ต้องทำเป็นทางเข้าแยกที่มีเจตนาชัดเจน
เงื่อนไขปิด: เมื่อมี requirement backfill จริง — ยังไม่มี
7. 🟢 SIT ช้ากว่า 3 migration
SIT_CentralizedDb อยู่ที่ 20260608112601_RenameDocumentNumberTables ทีมยืนยันว่าเลิกใช้ SIT แล้ว จึงไม่ migrate ให้
บันทึกไว้เพื่อกันคนกลับมาเปิด SIT ใหม่แล้วคิดว่ามันพร้อมใช้ — ต้องไล่ migration 3 ตัวก่อน ไม่ใช่แค่ deploy service
8. 🟢 DB ล้ำหน้า code ที่ deploy อยู่
DEV/UAT มีตาราง 3 ตัวแล้วแต่ยังไม่มี service เวอร์ชันที่รู้จักมัน — ปลอดภัยเพราะ migration เพิ่มอย่างเดียว ไม่มี ALTER/DROP ของเดิม และตารางว่างเปล่า
บันทึกไว้เพราะเวลาไล่ปัญหาแล้วเจอตารางที่ code ไม่ได้ใช้ จะได้ไม่คิดว่าเป็นขยะที่ลบทิ้งได้
9. 🟡 PII และ retention ของ snapshot_detail
snapshot_detail เก็บ ชื่อบุคคลที่สาม (ไทย/อังกฤษ) เป็น text ธรรมดา ไม่เข้ารหัส และยังไม่มี retention policy
ADR 0006 ตั้งใจให้ snapshot เป็นที่เดียวที่ต้องคุยเรื่อง retention (staging ลบได้) แต่ยังไม่มีใครตอบว่า เก็บนานเท่าไหร่ และ ต้องเข้ารหัสไหม
กฎที่บังคับไว้แล้วระหว่างที่ยังไม่มีคำตอบ: คอลัมน์ชื่อ ห้ามโผล่ใน API response หรือ log ใดๆ — เป็นเงื่อนไขรับงานข้อหนึ่งของ Phase 1
เงื่อนไขปิด: Compliance/Security ตอบ retention + การเข้ารหัส → ทำเป็น ADR