Volume 17 · Technical Debt Register
รวบรวมทุก debt item จากทุก *scorecard*.md ใน Volume 3-9 (29 ไฟล์ scorecard ครอบคลุม 29 repo — interns_playground ไม่มี scorecard เพราะยังไม่มี business logic ให้ตรวจ, centralize-api ไม่มี scorecard แยกเพราะ debt ของมันถูกรวมในการเปรียบเทียบของ cu-central-api) เข้าเป็นทะเบียนกลาง (register) เดียวที่ตรวจสอบย้อนกลับได้ทุกรายการ
- 1 · Master register — ตารางรวมทุกรายการ เรียงตาม category แล้ว severity
- 2 · จัดกลุ่มตาม Category — SEC/PERF/CORR/LEG/QUAL/OBS พร้อมจำนวนต่อ category
- 3 · จัดกลุ่มตาม Severity — Critical/High/Medium/Low, Critical แสดงรายละเอียดเต็ม
- 4 · Addendum (Deep Redo) — Critical IDs ใหม่หลัง V1-depth scorecard; ใช้ร่วมกับตัวเลขด้านล่าง
ตัวเลขรวม
275 รายการ จาก shallow pass เดิม (29 repo) — ยังไม่รวม Deep Redo Critical ใหม่ ที่ 17.4 และ Vol 12.5 — ต้อง reconcile หลัง mobile/OCR เสร็จ
แบ่งตาม Category
| Category | จำนวน | % |
|---|---|---|
| QUAL — Code quality | 99 | 36.0% |
| SEC — Security | 89 | 32.4% |
| CORR — Correctness/data integrity | 30 | 10.9% |
| OBS — Observability | 24 | 8.7% |
| LEG — Legacy/EOL/dependency | 22 | 8.0% |
| PERF — Performance | 11 | 4.0% |
| รวม | 275 | 100% |
แบ่งตาม Severity
| Severity | จำนวน | % |
|---|---|---|
| Critical | 46 | 16.7% |
| High | 69 | 25.1% |
| Medium | 149 | 54.2% |
| Low | 11 | 4.0% |
| รวม | 275 | 100% |
44 จาก 46 Critical เป็น SEC — แทบทั้งหมดของงาน "ต้องแก้ก่อนอย่างอื่น" คืองาน security ดูรายละเอียดที่ Volume 18
แบ่งตาม Repo (เรียงจากมากไปน้อย)
| Repo | จำนวน debt item |
|---|---|
| vtrc-api | 22 |
| cu-central-api | 19 |
| vtrc-web | 15 |
| meeting-vtrc-api | 14 |
| vtrc-rc-backoffice | 12 |
| benefit-api | 12 |
| 2way-api | 12 |
| vtrc-mobile | 12 |
| 2way-vtrc-api | 11 |
| vtrc-backoffice | 11 |
| pms-api | 11 |
| recruitment-web | 10 |
| vtrc-backoffice-new | 9 |
| ai-recruitment-api | 9 |
| chat-center-api | 9 |
| recruitment-api | 9 |
| meeting-backoffice | 9 |
| workflow-api | 8 |
| vtrc-ocr-api | 8 |
| 2way-meeting-backoffice | 8 |
| new-vtrc-mobile | 7 |
| vtrc-common | 6 |
| sso-api | 5 |
| job-scheduler-api | 5 |
| report-log | 5 |
| 2way-line-service | 5 |
| meeting-backoffice-new | 5 |
| 2way-batch | 4 |
| vtrc-application-front | 3 |
vtrc-api (legacy core, 68KB routes.js, อายุยาวนานที่สุดในระบบ) และ cu-central-api (LDAP+MSSQL integration เก่าแก่พอกัน) ครองอันดับ 1-2 อย่างชัดเจน — สอดคล้องกับสมมติฐานว่า debt สะสมตามอายุของโค้ดและจำนวน integration ที่ต้องดูแล ไม่ใช่ตามขนาด codebase เพียงอย่างเดียว (vtrc-web ที่มีแค่ 1 scorecard ก็ยังติดอันดับ 3 เพราะเป็น SPA เก่าที่ไม่มีการ refactor มานาน)
รูปแบบที่พบซ้ำข้าม repo (systemic patterns)
การอ่าน scorecard ทั้ง 29 ไฟล์ต่อเนื่องทำให้เห็น pattern ที่ไม่ใช่เรื่องบังเอิญของ repo เดียว แต่เป็นนิสัยการเขียนโค้ด/deploy ที่ทำซ้ำกันทั่วทั้งแพลตฟอร์ม:
.envที่มี secret จริง commit เข้า git — พบใน 13 repo (cu-central-api,vtrc-rc-backoffice,pms-api,ai-recruitment-api,workflow-api,vtrc-common,job-scheduler-api,chat-center-api,recruitment-web,recruitment-api,benefit-api,meeting-vtrc-api,meeting-backoffice) — นี่คือ pattern เดี่ยวที่ใหญ่ที่สุดในทั้ง register เพราะทุกจุดคือ Critical และ credential ส่วนใหญ่ยังใช้งานได้จริงในวันที่ตรวจ (ไม่ได้ rotate ภายหลัง commit)SQL injection ผ่าน raw string interpolation — พบใน 6 repo (
vtrc-api,chat-center-api,recruitment-api,benefit-api,2way-api,vtrc-common) ทุกจุดเป็นการต่อ string ตรงจาก request param เข้ากับ query แทนการใช้ parameterized query/ORM ที่มีอยู่แล้วในโปรเจกต์เดียวกัน@Public()ครอบ endpoint ที่ควรมี auth (NestJS) — พบใน 5 repo (vtrc-common,2way-line-service,2way-api,workflow-api,benefit-api) ส่วนใหญ่เกิดจากการ scaffold ด่วนแล้วไม่ย้อนมาปิด decorator ทำให้ controller ทั้งไฟล์เปิดสาธารณะโดยไม่ตั้งใจToken เก็บใน localStorage/URL แทน httpOnly cookie — พบใน 7 repo (
vtrc-rc-backoffice,vtrc-backoffice-new,vtrc-backoffice,vtrc-web,2way-meeting-backoffice,new-vtrc-mobile,recruitment-web) เป็นผลจากการ scaffold frontend ทุกเจนเนอเรชันตาม pattern เดียวกันโดยไม่มี security review ระหว่างทางJWT secret hardcode/มี default fallback โดยไม่มีระบบ secret-management กลาง — พบใน 7 repo (
vtrc-api,cu-central-api,pms-api,vtrc-common,job-scheduler-api,2way-vtrc-api,2way-api) หลายจุด secret ซ้ำกันข้าม repo (เช่นpms-apishare secret กับ 3 service อื่น) แปลว่า token ที่ forge จาก repo หนึ่งอาจ valid ในอีก repoRSA private key hardcode ในซอร์ส mobile app — พบใน 2 repo (
vtrc-mobile,new-vtrc-mobileที่ copy key เดียวกันมาซ้ำ) — เนื่องจากคอมไพล์เข้า JS bundle ของแอปที่แจกจ่ายจริง key นี้ถือว่า "รั่ว" แล้วในทุก build ที่ปล่อยไปแล้ว ไม่ใช่แค่ในซอร์สBackdoor/bypass login endpoint ที่ตั้งใจสร้างไว้และยัง live ใน production — พบใน 4 repo (
cu-central-api—/auth/signinbypass,2way-vtrc-api— master bypass token,2way-api— hardcoded admin login,recruitment-web— OTP คงที่) ทั้งหมดดูเหมือนถูกสร้างไว้เพื่อ debug/QA แล้วไม่ถูกถอดออกก่อน deploy จริงconsole.logปนกับ structured logger ที่มีอยู่แล้ว รวม PII หลุดสู่ stdout — พบใน 7 repo (vtrc-api,pms-api,ai-recruitment-api,chat-center-api,recruitment-api,benefit-api,2way-api) สะท้อนว่าการติดตั้ง logger กลางไม่เพียงพอ ต้องมี lint rule (เช่นno-console) บังคับด้วยจึงจะปิดช่องได้จริงMulti-table write ไม่มี transaction wrapping — พบใน 3 repo (
vtrc-api— pattern ที่ใช้ผิดทั้งระบบ,2way-vtrc-api,meeting-vtrc-api) เสี่ยงข้อมูลไม่ครบ (partial write) เมื่อ request ล้มเหลวกลางทางRuntime/framework ที่ EOL แล้วยังใช้งานจริงใน production — พบใน 7 repo (Node 12 ใน
cu-central-api, CRA 3.4.3 + AntD v4.15.4 ในvtrc-backoffice/vtrc-backoffice-new, RN 0.63.2 + React 16.13.1 ในvtrc-mobile, Node 16 ใน2way-batch, Next.js 12 + React 17 ใน2way-meeting-backoffice, Node 18 ในai-recruitment-api) — ไม่มี patch security ใหม่สำหรับ dependency เหล่านี้อีกแล้ว
ทั้ง 10 pattern นี้คือเหตุผลที่ Volume 19 · Modernization Roadmap แนะนำให้แก้แบบ "ข้าม repo ในรอบเดียว" (เช่น หมุน secret ทั้งหมดพร้อมกัน) แทนที่จะไล่แก้ repo ต่อ repo — เพราะรากของปัญหาคือนิสัยร่วม ไม่ใช่ความผิดพลาดเฉพาะจุด