Skip to content

11.5 · Scorecard — data-model debt ที่รวมจากทั้งแพลตฟอร์ม

Debt ID ในบทนี้ใช้ prefix CORR-DATA-/QUAL-DATA- เพื่อไม่ชนกับ ID เฉพาะ repo ที่มีอยู่แล้วใน Volume 3-9 (เช่น CORR-BENEFIT-01) — รายการนี้คือ debt ที่เกิดจากการรวมหลาย repo เข้าด้วยกัน ไม่ใช่ debt ของ repo เดียว ถ้าเป็น debt เฉพาะ repo ให้ดูที่ scorecard ของ volume นั้นแทน

Severity: Critical

CORR-DATA-01 · ไม่มี transaction ข้าม physical database ในทั้งแพลตฟอร์ม

ทุกจุดที่พบใน 11.2 ที่ service หนึ่งเขียนเข้าหลาย database พร้อมกัน (vtrc-api เขียน db+db2, workflow-api เขียน benefit_write+อีก 3 connection, pms-api เขียน dbWorkforce+ตัวเอง) ไม่มีที่ไหนมี distributed transaction/saga pattern — ทุกจุดเป็น sequential write ที่ fail กลางทางแล้วเหลือ orphan data ได้ ดู Volume 3 vtrc-api/05-persistence สำหรับตัวอย่างที่ยืนยันแล้วในโค้ดจริง (cross-database write ที่ db สำเร็จแต่ db2 fail)

ผลกระทบขยายวง — เพราะ pattern นี้ซ้ำใน ≥ 5 repo ไม่ใช่แค่ vtrc-api ตัวเดียวเหมือนที่ v1 Volume 8.11 เคยบันทึกไว้ ความเสี่ยง data inconsistency จึงเป็น platform-wide ไม่ใช่ legacy-only

CORR-DATA-02 · synchronize: true ของ chat-center-api เขียนทับ schema ที่ 2way-api เป็นเจ้าของ

รายละเอียดเต็มที่ 11.2 #9 — นี่คือ debt เดียวในบทนี้ที่มีโอกาสทำลายข้อมูลของอีก service โดยไม่ตั้งใจในทุกครั้งที่ deploy ไม่ใช่แค่ความเสี่ยง — ถ้า chat-center-api เพิ่ม/ลบ column ใน entity ที่ชื่อชนกับ column ของ 2way-api โดยบังเอิญ TypeORM auto-migrate จะ execute DDL จริงบน production database ของอีกทีม

Severity: High

CORR-DATA-03 · recruitment-api/ai-recruitment-api เขียน jobReqPosition คู่ขนานไม่มี sync mechanism

รายละเอียดที่ 11.2 #12 — สอง record คนละ database ของ "ตำแหน่งงานเดียวกัน" ไม่มี job/event ที่ reconcile กัน ต่างจาก benefit-api's wdHospitals (ดูข้อถัดไป) ที่อย่างน้อยยังมี manual sync บางจุด กรณีนี้ไม่พบ sync แม้แต่ manual — เสี่ยง drift สูงกว่า

CORR-DATA-04 · vtrc-api อยู่ใน JWT secret cluster เดียวกับ 4 domain microservice — ไม่ถูกบันทึกไว้ใน canonical-truths.md

รายละเอียดที่ 11.4 Cluster 1 — เป็น debt เชิง documentation/data-model ที่ทำให้ risk assessment เดิม (ที่นับ blast radius แค่ 4 domain microservice) นับ scope ผิดพลาด ควร reconcile เข้า canonical-truths.md เป็น priority เพราะกระทบการประเมิน severity ของ incident ในอนาคต — ถ้า secret รั่ว impact จริงคือ 5 service ไม่ใช่ 4

CORR-DATA-05 · benefit.dbo.wdHospitalsvtrc.dbo.WDHospitals มีข้อมูลซ้ำ ไม่มี job reconcile แบบ periodic

ยืนยันจาก Volume 6 benefit-api/06-scorecard (CORR-BENEFIT-01) — sync ทำผ่าน raw SQL แบบ manual เฉพาะบาง flow (cancel, update bank detail) เท่านั้น ยกมารวมไว้ที่นี่เพราะเป็นตัวอย่างชัดเจนของ pattern "ชื่อตารางคล้ายกันข้าม schema แต่ capitalization ต่างกัน" (wdHospitals vs WDHospitals) ที่ควรเป็นสัญญาณเตือนเวลา search schema ข้าม repo

CORR-DATA-06 · ไม่มี cascade delete ข้าม physical database ที่ใดในแพลตฟอร์มเลย

ขยายจาก v1 Volume 8.9 (ที่พบใน legacy 3 service) — v2 ยืนยันว่า pattern เดียวกันเกิดกับทุกเส้น cross-service coupling ใน 11.2 โดยไม่มีข้อยกเว้น: workflow-api (4 database), pms-api (dbWorkforce), 2way-api (pms schema) — ทุกจุดต้อง manual cleanup เอง ไม่มี foreign key ข้าม engine ให้พึ่งได้

CORR-DATA-07 · meeting-vtrc-api ตั้ง constraints: false ทุก Sequelize association

ยืนยันจาก Volume 7 meeting-vtrc-api/03-persistence-integrations — ไม่มี foreign key constraint ระดับ database เลยแม้จะเป็น database เดียว (ไม่ใช่ cross-service) หมายความว่า referential integrity ทั้งหมดพึ่ง application logic 100% ถ้ามี bug ใน service layer ข้อมูล orphan จะเกิดขึ้นได้โดยไม่มี database เตือน

Severity: Medium

QUAL-DATA-01 · 3 PK strategy ที่ไม่สอดคล้องกันข้าม engine

ขยายจาก v1 Volume 8.9 "3 PK strategies" — v2 ยืนยันว่า pattern นี้ยังคงอยู่และขยายไปอีก 2 รูปแบบใหม่ที่ v1 ไม่เคยเห็น: (1) native UUID (MariaDB vtrc-api), (2) UUID-as-string (MSSQL centralize-api), (3) business code empCode (HRMI + ทุก domain microservice), (4) LINE userId (external string ID ที่ไม่ใช่ UUID เลย ใน 2way/chat-center-api), (5) SSO external account ID (sso-api) — ดู 11.3 สำหรับรายละเอียดครบ

QUAL-DATA-02 · dbHRMI_Center.dbo.temp_pee_na_table กลายเป็น production identity bridge ที่ไม่มี owner ชัดเจน

รายละเอียดที่ 11.3 — ตารางชื่อขึ้นต้นด้วย temp_ ถูกใช้จาก 2 repo คนละกลุ่ม (chat-center-api, sso-api) เป็น production dependency จริง ไม่มี schema versioning หรือ contract document ที่ยืนยันได้ ควรพิจารณา promote เป็นตารางที่มีชื่อและ owner ชัดเจน หรือแทนที่ด้วย API call

QUAL-DATA-03 · sourceDb/SourceDB เป็น open string ไม่ใช่ enum ปิด

ยืนยันซ้ำจาก v1 Volume 8.9 — field นี้ยังเป็น STRING ที่รับค่าอะไรก็ได้ทั้งฝั่ง vtrc-centralize.Users.sourceDb (MariaDB) และ centralize-api's SourceDB column (MSSQL) ไม่มีการ validate ว่าค่าที่ใส่ต้องเป็นชื่อ SourceDB ของ HRMI ที่มีอยู่จริง (เช่น dbHRMI_CU_SC_rep) — เสี่ยง typo ทำให้ query ข้ามระบบไม่เจอข้อมูลแบบเงียบ ๆ (ไม่ throw error แต่ได้ผลลัพธ์ว่าง)

Severity: Low

OBS-DATA-01 · Connection pool sizing ของ vtrc-api เสี่ยง exhaust MariaDB max_connections

ยืนยันจาก v1 Volume 8.1 (ยังไม่เปลี่ยนใน v2) — pool.max: 100 × 2 connection (db+db2) × 4 replica = 800 connection สูงสุด เทียบกับ MariaDB default max_connections: 151 — ไม่ใช่ bug ที่เกิดบ่อยเพราะ traffic ไม่พุ่งพร้อมกันสุดขีด แต่เป็นความเสี่ยงแฝงที่ scale งานเพิ่ม replica ในอนาคตอาจชนขึ้นมาได้


Scorecard สรุป

Dimensionสถานะหมายเหตุ
Cross-database transaction integrity🔴ไม่มี saga/2-phase-commit ที่จุดใดในระบบ
Schema ownership boundary🔴chat-center-api auto-migrate เข้า database ของ 2way-api
Identity model consistency🔴5 รูปแบบ PK/ID ต่างกันไม่ map กันแบบ enforced
Data duplication reconciliation🟡มี manual sync บางจุด (wdHospitals) แต่ไม่มี periodic job
Cascade/cleanup ข้าม service🔴ไม่มี mechanism ใดเลยในทั้งแพลตฟอร์ม
Documentation ↔ reality gap (secret blast radius)🟡พบ 1 จุดที่ canonical-truths.md นับ scope ไม่ครบ (CORR-DATA-04)

คะแนนรวม: 0 🟢 / 2 🟡 / 8 🔴 (นับจาก 10 debt item ในบทนี้)


รายการ Critical security finding ที่เกี่ยวข้อง (ไม่ใช่ data-model ล้วน ๆ) ถูกรวมแยกไว้ที่ Volume 12 · 03-critical-findings-summary แทน เพื่อไม่ให้ปนกันระหว่าง "data integrity debt" กับ "security vulnerability"

กลับไป Volume 11 · index หรือไปที่ Volume 12 · Security & Authentication