Skip to content

15.8 Build & reproducibility debt

บทนี้รวบรวม debt ที่กระทบความสามารถในการ build ซ้ำได้ผลลัพธ์เดิม (reproducibility) และความน่าเชื่อถือของ build process

รายการทั้งหมด

LEG-15 · centralize-api ไม่มี lockfile

ข้อมูลรายละเอียด
Evidencecentralize-api/ — ไม่มี yarn.lock commit, ทั้งที่ Dockerfile ใช้ yarn install
ปัญหาbuild ไม่ reproducible — yarn install ในแต่ละครั้งอาจได้ dependency version ต่างกัน
Impactbuild ใน dev อาจไม่เหมือน production การ debug ปัญหายาก
Mitigation ระยะสั้นcommit yarn.lock ที่ generate จาก yarn install ครั้งแรก
แนวทางระยะยาวCI ตรวจ lockfile drift — ถ้า yarn install เปลี่ยน lockfile ให้ fail

LEG-16 · vtrc-web มีทั้ง yarn.lock และ package-lock.json

ข้อมูลรายละเอียด
Evidencevtrc-web/ — มีทั้ง yarn.lock และ package-lock.json
ปัญหาdual-resolver state — นักพัฒนาคนหนึ่งใช้ yarn อีกคนใช้ npm แต่ละคน lock คนละ file ผลลัพธ์การ install อาจต่างกัน
Impactbuild ไม่ consistent ระหว่างเครื่อง ความสับสนในการ add dependency
Mitigation ระยะสั้นเลือกตัวจัดการ dependency ตัวเดียว (yarn classic ตามที่เคยใช้) ลบอีกอัน
แนวทางระยะยาวpolicy: 1 package manager ต่อ repo

LEG-17 · TypeScript safety ปิดอยู่

ข้อมูลรายละเอียด
Evidencecentralize-api/tsconfig.json:15-19strictNullChecks: false, noImplicitAny: false, forceConsistentCasingInFileNames: false
ปัญหาsafety net ของ TypeScript ถูกปิด — เขียน TS แต่ไม่ได้ประโยชน์จาก type safety
Impactbug ที่ type ช่วยตรวจไม่ได้ เช่น null reference, implicit any
Mitigation ระยะสั้นเปิด strictNullChecks ก่อน (ตามด้วยการแก้ type error ที่เกิด)
แนวทางระยะยาวstrict: true ในทุก tsconfig

LEG-18 · ไม่มี engines field ทุก package.json

ข้อมูลรายละเอียด
Evidencerg '"engines"' → 0 matches ในทุก package.json
ปัญหาไม่จำกัด version ของ Node ที่ใช้ install/run — Node version ใดก็ได้
Impactนักพัฒนาใช้ Node version ต่างกัน อาจเจอ bug ที่เกิดจากความแตกต่างของ version
Mitigation ระยะสั้นเพิ่ม "engines": { "node": ">=20.0.0" } ในทุก package.json
แนวทางระยะยาวCI ตรวจ engines field ใช้ .nvmrc หรือ volta

LEG-19 · In-process node-schedule สำหรับ cron

ข้อมูลรายละเอียด
Evidencevtrc-api/api/src/crons.js (72 LOC) + cu-central-api/main-api/src/cron.js
ปัญหาnode-schedule รัน in-process — ไม่มี high availability, ไม่มี retry, ไม่มี visibility ถ้า replica ที่ถือ job restart ระหว่างรัน job จะหาย กับ 4 replica แต่ละ replica อาจรันซ้อน
Impactcron job ที่หายไปไม่มีใครรู้ cron ที่รันซ้อนอาจทำให้ข้อมูลซ้ำ
Mitigation ระยะสั้นใช้ APP_NO=1 gate (ทำอยู่แล้ว) + log ทุก job ที่รัน + การตรวจสอบ
แนวทางระยะยาวdistributed scheduler — BullMQ + Redis (Node) หรือ asynq/robfig/cron (Go) กับ distributed lock

LEG-20 · axios instances 16+ ตัวใน backoffice

ข้อมูลรายละเอียด
Evidencevtrc-rc-backoffice/src/config/axios-*.js — 16+ ไฟล์ (PMS, Recruitment, Meeting, WorkForce, Payments, Benefit, AI, ...)
ปัญหาaxios instance แยก 16+ ตัว — แต่ละตัวมี config + interceptor + token-refresh path ของตัวเอง
Impactการ maintain ใช้เวลานาน, ความเสี่ยง token-refresh path ต่างกันในแต่ละ instance
Mitigation ระยะสั้นรวม instance ที่ config เหมือนกัน
แนวทางระยะยาวใช้ typed API client หนึ่งตัวต่อ bounded context

ปัญหาที่ไม่มี ID แต่สำคัญ

ไม่มี health check endpoint

ไม่มี service ใดที่มี /health หรือ /healthz — Dockerfile ไม่ได้กำหนด HEALTHCHECK การตรวจสอบสถานะ service ต้องทำผ่าน URL อื่น ๆ (เช่น GraphQL playground) ที่ไม่ได้ออกแบบมาสำหรับ monitoring

ไม่มี CI/CD สำหรับ 3 repos

มี pipeline เฉพาะ vtrc-api และ vtrc-web — cu-central-api, centralize-api, vtrc-rc-backoffice deploy ด้วยมือทั้งหมด

Docker image ไม่ pin version

หลาย Dockerfile ใช้ FROM node:12 ไม่ใช่ FROM node:12.18.3-alpine3.11 — image ที่ได้จาก build แต่ละครั้งอาจต่างกัน

ไม่มี SBOM (Software Bill of Materials)

ไม่มีการ generate SBOM ของ dependency ทำให้การตอบสนองต่อ CVE ใหม่ ๆ ช้า — ไม่รู้ว่าแพ็กเกจที่มี CVE อยู่ใน image ใดบ้าง

สรุป

IDรายการSeverityEffort ระยะสั้น
LEG-15centralize ไม่มี lockfileHigh30 นาที
LEG-16vtrc-web สอง lockfileMed30 นาที
LEG-17TS safety ปิดHigh1-2 สัปดาห์ (incremental)
LEG-18ไม่มี enginesMed30 นาที
LEG-19in-process cronHigh(architectural — Wave 2)
LEG-20axios 16+ instancesMed1 สัปดาห์

ไม่มี ID

รายการEffort
เพิ่ม /health endpoint ทุก service1-2 วัน
สร้าง CI/CD สำหรับ 3 repos ที่เหลือ1 สัปดาห์
Pin Docker image version30 นาทีต่อ Dockerfile
Generate SBOM1-2 วัน

บทถัดไปจะรวบรวมทุกรายการเป็น heat-map เพื่อช่วยตัดสินใจจัดลำดับ