Skip to content

19.2 · 6-month correctness & data integrity

ขอบฟ้า เดือน 3–6 (ทับซ้อนท้ายของ 90 วันสำหรับงานที่เริ่มแล้ว) — แก้ bug ที่ทำให้ข้อมูลผิด / ส่งแจ้งเตือนผิด / auth flow พัง โดยที่ security emergency ใน 19.1 ต้องปิดพื้นผิว Critical ไปก่อนแล้ว

/ Months 3–6 — fix correctness and integrity defects after the 90-day emergency surface is closed. Wrong data and broken auth flows are in scope; framework rewrites are not.

แหล่งหลัก: vtrc-api/10 (CORR-VTRC-API-*), pms-api/06 (cron / notification), benefit-api/06 (dual hospital schema), Vol 12.5 (CORR-SSO-01)


ทำไมต้องแยกจาก security emergency

Security 90 วันCorrectness 6 เดือน
ผู้โจมตีภายนอก / credential leakผู้ใช้ภายในเจอข้อมูลผิด / email ซ้ำ / leave ค้าง
ปิดได้ด้วยลบโค้ด / rotateต้อง regression test + เข้าใจ business rule
Coordination หลัก = secret ownershipCoordination หลัก = HR / finance / PMS ops

การแก้ transaction pattern ผิดทั้ง vtrc-api โดยไม่มี test จะสร้าง regression ที่มองว่าเป็น "security incident" ทั้งที่รากเป็น correctness — แยกขอบฟ้าเพื่อบังคับให้มี test plan ก่อน sweep


Track A — vtrc-api transaction & session correctness

A1 · CORR-VTRC-API-01transaction: t อยู่ผิด argument position

ที่: กระจายใน vtrc-api/api/src/lib/controllers/ (~20+ จุด) — vtrc-api/10

Sequelize คาดหวัง:

javascript
await Model.create({ ...fields }, { transaction: t })
await Model.update({ ...fields }, { where: {...}, transaction: t })

แต่โค้ดจำนวนมากส่งเป็น arg ที่ 3 ซึ่งถูก discard:

javascript
await Model.create({ ...fields }, { where: {...} }, { transaction: t })  // arg 3 discarded

Impact: ไม่มี atomicity จริง — partial write เมื่อ error กลางทาง; race ไม่ manifest ชัดเพราะ rollback ไม่เคยทำงาน

แผน 6 เดือน:

Phaseงานประมาณ
A1.1rg "transaction:\s*t" + จัดตาราง call site ตาม domain (leave / claim / auth)2–3 วัน
A1.2แก้ทีละ domain พร้อม integration test ที่ force error กลาง transaction2–4 สัปดาห์
A1.3ห้าม merge PR ใหม่ที่ยังใช้ arg-3 pattern — lint / codeowner rule1 วัน

ตรง vtrc-api/10 ROI #7 และคำเตือน "หนึ่ง change ต่อ PR"

A2 · CORR-VTRC-API-02getCurrentRoleUser signature mismatch

แก้ signature ให้ตรง caller — effort S แต่กระทบ RBAC จริง (คู่กับ auth pipeline ที่แดงใน health scorecard)

A3 · CORR-VTRC-API-03clouse.js limit cap ไม่ทำงาน

ไฟล์ชื่อ typo clouse (จาก clause) เป็น public contract ของ import path — แก้ logic ของ limit โดย ห้าม rename ไฟล์ใน PR เดียวกัน (ดู 19.4)

A4 · CORR-VTRC-API-04getCurrentProfileSession fallback ข้าม user

Medium severity แต่กระทบ session ที่ผูก user ผิดคน — วางในเดือน 4–5 พร้อม test login/refresh

A5 · Migration runner แทน syncModelToTable

vtrc-api/10 ROI #6: เพิ่ม goose / atlas / Sequelize migration runner — ลด schema drift ตอน boot

อย่าเปิด sync ใน production ระหว่าง migration นี้


Track B — PMS cron / notification integrity

จาก pms-api/06 ROI #2, #4, #5 และ regression checklist

B1 · CORR-PMS-01 — notification date gate ถูกปิด

คืน isSameDate gate ใน notification cron + await ที่หาย — effort ชั่วโมง แต่ impact = อาจส่งอีเมลทุกประเภททุกวัน

Regression:

  • วันที่ไม่ตรง settingGoalStart → ต้อง ไม่ ส่ง notiGoalStart
  • วันตรง → ส่งได้ครั้งเดียวต่อวันต่อประเภท

B2 · CORR-PMS-02 — cron 1 นาที overlap

เพิ่ม in-process + distributed lock — effort 0.5–2 วัน (ROI #4)

Regression: จำลอง getEmployeeTriggerQeue ช้า > 60s → job ที่สองต้อง skip

B3 · OBS-PMS-01 — silent cron errors

Alert เมื่อ cron fail + metric last-success — ROI #5 (~1 วัน)

อย่าพึ่ง console.error อย่างเดียว (prod มี no-op pattern ในหลาย frontend/API)

B4 · QUAL-PMS-01 — docs ไม่ตรงโค้ด

อัปเดตหรือลบ PMS-Period-Notification-System.md — กัน ops ทำตามเอกสารผิด

สิ่งที่ทำได้ดีแล้วใน pms-api (อย่าทำพัง)

จาก pms-api/06 § สิ่งที่ทำได้ดีแล้ว:

  1. *History audit trail สม่ำเสมอ
  2. Parameterized stored procedures (sp_get_employeeSalary_orgUnit, …) — ไม่ใช่ string SQLi
  3. ThrottlerGuard global
  4. NODE_ENV double-guard บน migrate / notification manual
  5. ValidationPipe เข้ม (forbidNonWhitelisted: true)
  6. Period cycle แยกสถานะด้วยวันที่

PR correctness ต้องไม่ทำลายข้อเหล่านี้เพื่อ "cleanup"


Track C — benefit dual-schema & batch correctness

C1 · CORR-BENEFIT-01 / ROI #8 — reconcile benefit.wdHospitals vs vtrc.WDHospitals

benefit-api/06 Public contract ระบุ casing คนละแบบเป็นสัญญา — ห้าม unify ชื่อโดยไม่ migrate

งาน 6 เดือน:

  1. ตัดสินใจ source of truth (benefit schema vs vtrc schema)
  2. เขียน sync job หรือ API facade ที่อ่านจากเจ้าของข้อมูล
  3. ตรวจ diff รายวันจนกว่า drift = 0
  4. ค่อย deprecate ตารางซ้ำ

C2 · Distributed lock ให้ cron (ROI #7)

ถ้า deploy >1 replica โดยไม่มี lock — batch ซ้ำ = เบิก/โอนซ้ำได้

C3 · หลังปิด @Public() แล้ว — ตรวจ batch ที่เคยพึ่ง public path

ยืนยันว่า scheduler เรียกด้วย service credential ไม่ใช่เปิดเปล่า — คู่กับ 19.1 SEC-BENEFIT-04/05


Track D — SSO / workflow / cross-service auth correctness

D1 · CORR-SSO-01 — JWT sign พัง

Vol 12.5: sign() commented + JwtService not injected

ทางเลือก (ตัดสินใจในเดือน 3):

ทางเมื่อไหร่ใช้
ซ่อมให้ sso-api ออก JWT จริงยังต้องการ SSO เป็น issuer
ลบ/bypass guard ที่พึ่ง sso-api ผิดสัญญาถ้า sso-api เป็น dead path

ห้ามปล่อย "guard ที่ verify ไม่ได้แต่ยัง mount" — ทำให้ 2FA / login ดูผ่านทั้งที่ token ไร้ความหมาย

D2 · SEC-WORKFLOW-01 spillover

ถ้าไม่จบใน 90 วัน — เดือน 4–6 ต้องมี JWT verify จริง และเลิก derive role จาก sourceDB อย่างเดียว

D3 · CORR-WORKFLOW-01 — direct cross-DB (distributed monolith)

TypeORM ตรงไปยัง schema ของ service อื่น — เริ่ม inventory + ห้ามเพิ่ม connection ใหม่; แทนที่ด้วย API ค่อยเป็นค่อยไป (งานใหญ่ต่อใน 19.3)


Track E — Frontend correctness ที่กระทบข้อมูล

IDRepoปัญหางาน
CORR-BO-02 / CORR-BONEW-01backoffice / backoffice-newisRemember hardcode = 1แก้ทั้งคู่พร้อมกัน — fork ซ้ำ
CORR-MOBILE-01vtrc-mobiledata integrity ฝั่ง clientตาม scorecard mobile
GraphQL cache-first stalevtrc-webstale UI หลัง mutationเปลี่ยน fetchPolicy เฉพาะ operation ที่เขียนข้อมูล — vtrc-web/07

อย่าใช้โอกาสนี้ rename from/ หรือ TheamCss19.4


Track F — Observability ที่จำเป็นต่อ correctness

Correctness ที่ไม่มีสัญญาณ = แก้แล้วไม่รู้ว่าพัง

งานRepoSource
/healthz + readinessvtrc-apiROI #2 — vtrc-api/10
Structured logging (pino) + trace idvtrc-api + Nest servicesROI #9
เลิกพึ่ง sync wlog อย่างเดียวvtrc-apiOBS-VTRC-API-*
Cron last-success metricpms-api, 2way-api (07:00 jobs)pms ROI #5; 2way-api cron table

2way-api มี cron announce/survey/complaint ทุกวัน 07:00 ที่พึ่ง raw SQL + LINE — หลัง parameterized ใน 90 วัน ต้อง monitor ว่าแจ้งเตือนถูกกลุ่ม (2way-api/04)


ลำดับเดือนแบบแนะนำ

Month 3 (ทับ 90-day ท้าย)
├── ปิด spillover: SEC-WORKFLOW-01 spike, SSO decision
├── CORR-PMS-01 / -02 / OBS-PMS-01
└── เริ่ม A1.1 inventory transaction sites

Month 4
├── A1.2 leave/claim transaction fixes + tests
├── CORR-VTRC-API-02 / -03
├── benefit dual-schema decision doc
└── healthz บน vtrc-api

Month 5
├── A1.2 ต่อ (auth/session controllers)
├── C1 sync job เฟสแรก
├── CORR-BO-02 + CORR-BONEW-01 พร้อมกัน
└── structured logging pilot

Month 6
├── A1.3 lint gate + A5 migration runner spike
├── D3 inventory cross-DB (ห้ามเพิ่ม)
├── regression pack เต็มตาม checklist ด้านล่าง
└── handoff ไป 12-month platform track

Regression pack (ขั้นต่ำก่อนปิดขอบฟ้า 6 เดือน)

vtrc-api

  1. Force error กลาง leave/create transaction → ไม่มี orphan row
  2. Role resolution หลังแก้ getCurrentRoleUser ตรงกับเมนูที่เห็น
  3. Profile session ไม่สลับ user หลัง refresh

pms-api

ใช้ pms-api/06 Regression checklist ข้อ 2–6 ครบ (ข้อ 1 ควรผ่านตั้งแต่ 90 วัน)

benefit-api

  1. สร้าง/อัปเดต wdHospitals ต้องมี JWT
  2. Diff wdHospitals vs WDHospitals ลดลงตามเป้าที่ตั้งใน decision doc
  3. Approver list ไม่คืนทั้งตารางเมื่อส่ง approverEmpCode แปลก ๆ (หลัง SQLi fix)

2way-api

  1. Login ปกติผ่าน SSO ยังได้
  2. Backdoor ยังปิด
  3. Cron 07:00 ไม่ยิงซ้ำผิดกลุ่มหลัง SQL parameterize

สิ่งที่ยัง UNVERIFIED (อย่า claim ในสถานะ Done)

จาก pms-api/06 และ 2way-api/04:

หัวข้อทำไมยังไม่ยืนยัน
จำนวน replica จริงตอน deployไม่มี k8s/helm ในหลาย repo
timezone container = Asia/Bangkokcron 07:00 พึ่งสมมติฐานนี้
WAF/gateway บังคับ JWT ด้านหน้าอาจลด severity ปฏิบัติ แต่โค้ดยังเป็น bypass
mDropdown แชร์ DB กับ benefit หรือไม่ชื่อตารางเหมือน คนละ schema
ความสัมพันธ์ workflow-api ↔ pms-ai-apiมี docs ใน workflow ยังไม่ verify

บันทึก UNVERIFIED ไว้ใน ticket — อย่าใส่ใน "ปิดแล้ว" ของ Vol 19 โดยไม่มีหลักฐานใหม่

ไป 19.3 · 12-month platform