7.10 · Scorecard + known issues
บทสุดท้ายสรุปสุขภาพของ vtrc-web แบบ scorecard พร้อมลำดับปัญหาที่ควรแก้ไข
ถ้ามีเวลาจำกัดและต้องเลือกแก้ — บทนี้คือแผนงาน
Scorecard รวม
| มิติ | คะแนน | ความเห็น |
|---|---|---|
| Maintainability | 5/10 | pattern สม่ำเสมอ แต่มี legacy 50+ ไฟล์ + bundle ใหญ่ |
| Security | 4/10 | token ใน localStorage + AES key hardcoded + ไม่มี HTML sanitizer |
| Performance | 4/10 | bundle ~12 MB + no-cache ทุก query + ไม่มี code splitting |
| Developer Experience | 5/10 | pattern ชัดเจน แต่ console ถูกปิด + bundle build ช้า |
| Documentation | 3/10 | แทบไม่มี inline comment อธิบาย intent |
| Test coverage | 1/10 | ไม่มี unit test, integration test |
| Type safety | 1/10 | JavaScript ล้วน ไม่มี TypeScript |
| Accessibility | 3/10 | ใช้ AntD v3 ที่มี a11y พื้นฐาน แต่ไม่มี ARIA เพิ่มเติม |
| รวม | 3.5/10 | ทำงานได้จริง แต่มีหนี้เทคนิคสะสมสูง |
จุดแข็ง
- pattern สม่ำเสมอ — class component + withApollo ทั้งระบบ ทำให้นักพัฒนาใหม่เข้าใจได้เร็ว
- GraphQL operations รวมในไฟล์เดียว — ค้นหาง่าย ไม่กระจาย
- runtime env resolver — bundle ตัวเดียวใช้ได้หลาย env ลดความซับซ้อนตอน deploy
- error handling รวมศูนย์ — errorLink จัดการทุก GraphQL error ที่เดียว
- route table ชัดเจน —
routes.jsเป็นแหล่งความจริงเรื่อง route + menu
จุดอ่อนหลัก
W-1 · Legacy/backup ไฟล์มากกว่า 50 ไฟล์
ดู บท 6.1 — _bk, _prd, _pentest, _table, _gql กระจายทั่วระบบ
ผลกระทบ: ทำให้สับสนว่าไฟล์ไหนคือไฟล์จริง เพิ่มเวลาอ่านโค้ด
แนวทางแก้: ย้าย legacy ทั้งหมดไปโฟลเดอร์ _archive/ หรือลบทิ้งหลังตรวจสอบ git history
W-2 · Bundle ใหญ่ ~12 MB
ดู บท 6.9 — ไม่มี code splitting ระดับ route
ผลกระทบ: เวลาโหลดหน้าแรกช้า
แนวทางแก้: เริ่มจาก babel-plugin-import สำหรับ AntD ก่อน ลดขนาดได้เยอะที่สุดด้วย effort น้อยที่สุด
W-3 · ไม่มี unit test / integration test
ไม่มี test file เดียวใน repo — scripts/test.js มีอยู่แต่ไม่ได้ใช้จริง
ผลกระทบ: ทุกการแก้โค้ดมีความเสี่ยงสูง ไม่มี safety net
แนวทางแก้: เริ่มจาก test ของ helper ใน utils/ (pure function) ก่อน — คุ้มค่าที่สุด
W-4 · Console override ปิดการ debug
App/index.js:15 ปิด console.log/warn/error ทั้งหมด
ผลกระทบ: debug ฝั่ง production ได้ยาก
แนวทางแก้: ใช้ terser drop_console แทน — strip ตอน build ไม่ใช่ override ตอน runtime
W-5 · AES key hardcoded สำหรับ "remember password"
utils/auth.js:38 — key "6A45soD%9eB#" เปิดเผยใน bundle
ผลกระทบ: ถ้าเครื่องผู้ใช้ถูกขโมย localStorage ผู้โจมตีถอดรหัส password ได้ทันที
แนวทางแก้: เลิกใช้ "remember password" ในรูปแบบนี้ ใช้ refresh token + autologin แทน
W-6 · Typos ที่ติดอยู่ใน GraphQL schema
fetchListDocumen, fetchLeaveDocumentDetailDraf, detchProfileListDetail — เปลี่ยนไม่ได้เพราะเป็น public API
ผลกระทบ: อ่านโค้ดแล้วสับสน เผลอแก้ชื่อทำให้ request fail
แนวทางแก้: ยอมรับว่าเปลี่ยนไม่ได้ — เพิ่ม comment ใน queries.js อธิบายว่าเป็นชื่อเดิมที่คงไว้
W-7 · โฟลเดอร์ components/user/from/ สะกดผิด
from (f เล็ก) แทน Form (F ใหญ่) — เป็นชื่อจริงที่ห้ามแก้
ผลกระทบ: เพิ่ม cognitive load ตอน import
แนวทางแก้: ยอมรับ — ถ้าจะแก้ต้องแก้ import path ทั้งระบบ (high risk)
W-8 · moment.js + manual +543 กระจายอยู่หลายที่
ดู บท 6.8 — helper 22 ตัวใน formatdate.js ซ้ำซ้อน
ผลกระทบ: ถ้าจะเปลี่ยน logic ต้องแก้หลายจุด
แนวทางแก้: รวม mapping เดือนเป็น constant กลาง แล้วให้ทุก helper import ใช้
W-9 · toGqlTypes/Args/Fields ใน utils/string.js ไม่ได้ใช้
helper ที่วางแผนไว้สำหรับ refactor แต่ไม่เคยใช้จริง
ผลกระทบ: ทำให้สับสนว่ามี helper ใช้ แต่จริง ๆ ทุก query เขียนด้วยมือ
แนวทางแก้: ลบทิ้ง หรือใส่ comment ว่า deprecated
W-10 · ไม่มี <ErrorBoundary> ระดับ root
runtime error ใน component ลูกจะทำให้หน้าขาวทันที
ผลกระทบ: UX แย่เวลาเกิด error
แนวทางแก้: เพิ่ม <ErrorBoundary> ครอบ <App /> ใน index.js
ลำดับการแก้ไข (ถ้าจะลงมือทำจริง)
Phase 1 — Quick win (1-2 วัน)
| ปัญหา | การแก้ | Effort |
|---|---|---|
| W-4 console override | เปลี่ยนเป็น terser drop_console | 0.5 วัน |
| W-9 helper ไม่ใช้ | ลบ toGqlTypes/Args/Fields | 0.5 วัน |
| W-10 ไม่มี ErrorBoundary | เพิ่ม <ErrorBoundary> ครอบ <App> | 0.5 วัน |
| S-3 AES key | เลิกใช้ remember password หรือเปลี่ยน approach | 1 วัน |
Phase 2 — Security (1 สัปดาห์)
| ปัญหา | การแก้ | Effort |
|---|---|---|
| S-4 ไม่มี sanitizer | เพิ่ม DOMPurify ก่อน dangerouslySetInnerHTML | 2 วัน |
| S-8 ไม่มี CSP | เพิ่ม CSP header ใน nginx | 1 วัน |
| S-2 apiKey ใน bundle | ย้ายไป server-side proxy | 3 วัน |
Phase 3 — Performance (2-4 สัปดาห์)
| ปัญหา | การแก้ | Effort |
|---|---|---|
| P-1 bundle ใหญ่ | babel-plugin-import สำหรับ AntD | 1 สัปดาห์ |
| P-2 no-cache | เปลี่ยน fetchPolicy ของ dropdown query | 2 วัน |
| W-8 helper ซ้ำ | รวม constant กลาง | 1 วัน |
Phase 4 — Long-term (1-3 เดือน)
| ปัญหา | การแก้ | Effort |
|---|---|---|
| W-1 legacy 50+ ไฟล์ | archive + ลบ | 1 สัปดาห์ |
| W-3 ไม่มี test | setup jest + เขียน test ของ utils ก่อน | 1 เดือน |
| ย้ายไป TypeScript | ค่อย ๆ เพิ่ม types | 3+ เดือน |
| ย้ายไป React 17/18 + hooks | breaking change ใหญ่ | 2+ เดือน |
เกณฑ์การประเมินเมื่อจะแก้ไขโค้ด
ก่อนแก้ไฟล์ใดใน vtrc-web ให้ตรวจสอบ:
- ไฟล์นี้เป็นของจริงไหม — ดูใน
routes.jsก่อนว่า import ไฟล์ไหน - pattern ตรงไหม — class component + withApollo + Form.create (ถ้ามี form)
- endpoint ตรงไหม — ใช้
checkLinkURL()อย่าแก้ hardcode - error handling รวมศูนย์ไหม — ใช้ errorLink อย่า catch เอง
- state จัดการยังไง —
this.state+ localStorage (ผ่าน helper) อย่าใช้ Redux/Context - locale ถูกไหม — ใช้ helper ใน
utils/formatdate.jsอย่า +543 ตรง ๆ
สรุป Volume 7
vtrc-web เป็น employee portal ที่ใช้งานจริงใน production ทำงานได้ แต่มีหนี้เทคนิคสะสมสูง pattern สม่ำเสมอทำให้ maintain ได้ แต่ legacy 50+ ไฟล์ + bundle ใหญ่ + ปัญหา security หลายจุดเป็นสิ่งที่ต้องจัดการในระยะกลางถึงยาว
ถ้าจะแก้ฟีเจอร์ — Volume นี้ให้แผนที่เพียงพอที่จะหาไฟล์เจอ เข้าใจ pattern และหลีกเลี่ยงกับดักที่ทราบ
ถ้าจะทำ modernization — ลำดับการแก้ใน Phase 1-4 คือแนวทางที่แนะนำ เริ่มจาก quick win ก่อน แล้วค่อยขยายไป security และ performance
อ่านต่อ
- Volume 8 · vtrc-rc-backoffice Deep Dive — sibling frontend ฝั่ง HR (AntD v4 + Recoil + MUI v5)
- Volume 3 · vtrc-api Deep Dive — backend ที่ vtrc-web คุยด้วย
- Volume 10 · Security — security analysis เชิงลึกของทั้งระบบ