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.wdHospitals ↔ vtrc.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 →