1 · Master register
ตารางนี้รวมทุก debt item ที่พบในทุก *scorecard*.md ของ Volume 3-9 (29 ไฟล์ scorecard จาก 30 repo ที่มีโค้ด — interns_playground ไม่มี scorecard เพราะเป็น playground ที่ยังไม่มี business logic ให้ตรวจ, centralize-api ไม่มี scorecard แยกเพราะเนื้อหา debt ของมันถูกรวมไว้ในการเปรียบเทียบของ cu-central-api/04-integrations-scorecard.md) ID คงตามต้นฉบับทุกตัว ไม่มีการเปลี่ยนแปลง — บาง repo (vtrc-web, vtrc-rc-backoffice) เขียน scorecard ก่อนที่ debt ID scheme ของ v2 จะ finalize จึงใช้ ID รูปแบบอื่น (S-1, C1, H1, M1, P-1) แทน SEC-XXX-01 — เก็บไว้ตามต้นฉบับและระบุ repo ในคอลัมน์ Repo เพื่อไม่ให้กำกวม
เรียงตาม Category (ตามลำดับใน style guide: SEC → PERF → CORR → LEG → QUAL → OBS) จากนั้นเรียงตาม Severity (Critical → High → Medium → Low)
รวมทั้งหมด 275 รายการ — ดูสรุปตัวเลขที่ index
SEC — Security (89 รายการ: Critical 44, High 30, Medium 14, Low 1)
| ID | Repo | Severity | คำอธิบาย | file:line | Source |
|---|---|---|---|---|---|
| SEC-VTRC-API-01 | vtrc-api | Critical | Command injection ผ่าน execSync ใน PDF pipeline (qpdf) 5 จุด | vtrc-api/api/src/routes.js:73,120,227,277,355 | Vol 3 · vtrc-api |
| SEC-VTRC-API-02 | vtrc-api | Critical | Default JWT_SECRET = 'secret' — forge token ได้ถ้า env ไม่ override | vtrc-api/api/src/config.js:12 | Vol 3 · vtrc-api |
| SEC-VTRC-API-03 | vtrc-api | Critical | /webdeployment รัน shell binary โดยไม่มี auth | vtrc-api/api/src/routes.js:975-984 | Vol 3 · vtrc-api |
| SEC-VTRC-API-04 | vtrc-api | Critical | /file/:id/download ไม่มี apiKey check | vtrc-api/api/src/routes.js:464 | Vol 3 · vtrc-api |
| SEC-CU-01 | cu-central-api | Critical | JWT_SECRET default เป็น empty string | cu-central-api/main-api/src/config.js, jwtToken.js | Vol 3 · cu-central-api |
| SEC-CU-02 | cu-central-api | Critical | apiKeys hardcoded ในโค้ด 2 keys | cu-central-api/main-api/src/lib/auth/auth.controller.js | Vol 3 · cu-central-api |
| SEC-CU-03 | cu-central-api | Critical | .env.develop-test (UAT secrets) commit อยู่ในโค้ด | repo root | Vol 3 · cu-central-api |
| SEC-CU-04 | cu-central-api | Critical | /auth/signinbypass passwordless signin live ใน production | cu-central-api/main-api/src/routes.js | Vol 3 · cu-central-api |
| SEC-CU-05 | cu-central-api | Critical | ignoreAuth bypass — apiKey อย่างเดียวพอผ่าน auth | cu-central-api/main-api/src/directives/auth.js, searchProfile.js | Vol 3 · cu-central-api |
| SEC-CU-06 | cu-central-api | Critical | rejectUnauthorized: false ใน LDAP connection | cu-central-api/main-api/src/activeDirectory.connector.js | Vol 3 · cu-central-api |
| C1 | vtrc-rc-backoffice | Critical | .env committed ลง git มี secret จริง (AES key, MSSQL connection string) | vtrc-rc-backoffice/.env | Vol 4 · vtrc-rc-backoffice |
| C2 | vtrc-rc-backoffice | Critical | REACT_APP_STIMUL_CONN_STRING (MSSQL conn string) ฝังใน bundle ที่ browser โหลดได้ | CRA env inlining | Vol 4 · vtrc-rc-backoffice |
| C3 | vtrc-rc-backoffice | Critical | SSO bypass /pathLogin/:token/:refreshToken รับ token ใน URL | vtrc-rc-backoffice/src/containers/App/index.js:24 | Vol 4 · vtrc-rc-backoffice |
| SEC-BONEW-01 | vtrc-backoffice-new | Critical | Login ส่ง access+refresh token เป็น URL path segment ข้าม origin | vtrc-backoffice-new/src/pages/Login/index.js:93-103 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| SEC-PMS-01 | pms-api | Critical | GET /budget/getEmployeeSalary เป็น @Public() คืนเงินเดือนพนักงาน | pms-api/src/modules/budget/budget.controller.ts:49-53 (branch: uat) | Vol 6 · pms-api |
| SEC-PMS-02 | pms-api | Critical | Credential (UAT) + JWT secret ที่ share กับ prod ของ 3 service อื่น หลุดเข้า git | pms-api/.env:12,19,26,33,41,45, vtrc-gcp-sa-key.json (branch: uat) | Vol 6 · pms-api |
| SEC-AIRECRUIT-01 | ai-recruitment-api | Critical | Production credential + OpenAI/remove.bg/HCTI API key ที่มีค่าใช้จ่ายจริง หลุดเข้า git | ai-recruitment-api/.env:2,5,7,9-10,11 (branch: prod) | Vol 6 · ai-recruitment-api |
| SEC-AIRECRUIT-02 | ai-recruitment-api | Critical | ไม่มี authorization ระดับ role/scope — JWT ที่ verify ผ่านเรียก AI generation ได้ไม่จำกัด | ai-recruitment-api/middleware/verifyJWT.js:7-40 (branch: prod) | Vol 6 · ai-recruitment-api |
| SEC-WORKFLOW-01 | workflow-api | Critical | ไม่มี JWT guard ระดับ global/module ใดเลย role ถูกอนุมานจาก payload ที่ปลอมได้ | workflow-api/src/main.ts:9-82, jwt-actor.util.ts:1-4,33-47, ipd-user.util.ts:20-65 (branch: uat) | Vol 6 · workflow-api |
| SEC-WORKFLOW-02 | workflow-api | Critical | .env.example มีรหัสผ่านจริงฝังอยู่ | workflow-api/.env.example:11,31,44 (branch: uat) | Vol 6 · workflow-api |
| SEC-COMMON-01 | vtrc-common | Critical | ทุก controller ที่มีจริงถูก mark @Public() — file/address/bank เข้าถึงได้ไม่ต้อง auth | vtrc-common/src/modules/file/file.controller.ts:18,24, address.controller.ts, bank.controller.ts, .env:12 | Vol 6 · vtrc-common |
| SEC-COMMON-03 | vtrc-common | Critical | .env commit เข้า git พร้อมรหัสผ่าน MSSQL sa จริง + SECRET_KEY ที่ share กับ repo อื่น | vtrc-common/.env:11,17 | Vol 6 · vtrc-common |
| SEC-JOBSCHED-01 | job-scheduler-api | Critical | .env commit เข้า git พร้อมรหัสผ่าน MSSQL sa จริง + RSA secret key ที่ share ข้าม repo | job-scheduler-api/.env:9-11,18 | Vol 6 · job-scheduler-api |
| SEC-CHAT-01 | chat-center-api | Critical | Raw SQL string interpolation จาก query param ผู้ใช้ตรง — SQL injection | chat-center-api/src/modules/chat/chat.service.ts:103-157, tags.service.ts:55-61 (branch: prod) | Vol 6 · chat-center-api |
| SEC-CHAT-04 | chat-center-api | Critical | .env commit เข้า git พร้อมรหัสผ่านจริง (MSSQL, MongoDB, LINE secret) | chat-center-api/.env:10-11,26,28-29 (branch: prod) | Vol 6 · chat-center-api |
| SEC-RCWEB-01 | recruitment-web | Critical | .env/.env.dev/.env.uat track ใน git มี AES key จริงสำหรับเข้ารหัส PII | recruitment-web/.env:2,9, .env.uat:2,7, cryptoJs.js:1-32 (branch: prod) | Vol 9 · recruitment-web |
| SEC-REPORTLOG-01 | report-log | Critical | ไฟล์ request_*.log commit จริง 50 ไฟล์ มี citizenId/birthDate/empCode plaintext | report-log/request_2023-02-17.log และอื่น ๆ | Vol 9 · report-log |
| SEC-RECRUIT-01 | recruitment-api | Critical | Production credential หลุดเข้า git (MSSQL, JWT×2, SMTP, reCAPTCHA, GCP key) | recruitment-api/.env:11,18,25,32,44,45,52,55, vtrc-gcp-sa-key.json (branch: prod) | Vol 6 · recruitment-api |
| SEC-RECRUIT-02 | recruitment-api | Critical | SQL injection ผ่าน dynamic EXEC stored procedure string | recruitment-api/src/modules/candidate/candidate.repositories.ts:1324-1338 (branch: prod) | Vol 6 · recruitment-api |
| SEC-BENEFIT-01 | benefit-api | Critical | Production credential หลุดเข้า git (MSSQL×3, JWT, SFTP) | benefit-api/.env:18,25,32,64, exportpaymentreport.service.ts:5271,5824,6151 (branch: prod) | Vol 6 · benefit-api |
| SEC-BENEFIT-02 | benefit-api | Critical | Raw SQL string interpolation ข้าม 2 database — SQL injection surface ขนาดใหญ่ | benefit-api/src/modules/payments/payments.service.ts:415-573,640-720,1032-1183,1185-1435, approvedisaster.service.ts:415-417 (branch: prod) | Vol 6 · benefit-api |
| SEC-2WAYVTRC-01 | 2way-vtrc-api | Critical | Master bypass token static string "testnaja" ข้าม auth ทั้งหมด | 2way-vtrc-api/middleware/checkbypasstoken.ts:24 (branch: prod) | Vol 5 · 2way-vtrc-api |
| SEC-2WAYVTRC-02 | 2way-vtrc-api | Critical | POST /2way/getProfile ไม่มี middleware คืน PII จาก lineID ตรง | 2way-vtrc-api/routes/TwoWayAPI/userLine/getProfile.ts:34-63,79-134 (branch: prod) | Vol 5 · 2way-vtrc-api |
| SEC-2WAYVTRC-03 | 2way-vtrc-api | Critical | Credential MongoDB production commit ตรงในซอร์ส | 2way-vtrc-api/util/mongo.config.ts:8 (branch: prod) | Vol 5 · 2way-vtrc-api |
| SEC-2WAYLINE-01 | 2way-line-service | Critical | ทุก endpoint ของ LineController เป็น @Public() | 2way-line-service/src/modules/line/line.controller.ts:13,19,25,31 | Vol 5 · 2way-line-service |
| SEC-2WAYAPI-01 | 2way-api | Critical | Backdoor login hardcode i3admin/aA123456! ออก JWT admin 48 ชม. | 2way-api/src/modules/auth/auth.service.ts:184-240 (branch: prod) | Vol 5 · 2way-api |
| SEC-2WAYAPI-02 | 2way-api | Critical | SSO/JWT secret มี default fallback ฝังในซอร์ส | 2way-api/src/modules/auth/auth.service.ts:20-26 (branch: prod) | Vol 5 · 2way-api |
| SEC-2WAYAPI-03 | 2way-api | Critical | SQL injection จาก string interpolation หลายโมดูล | 2way-api/src/modules/announces/announces.service.ts:164-296,297-463, surveys.service.ts, complaints.service.ts (branch: prod) | Vol 5 · 2way-api |
| SEC-2WAYAPI-04 | 2way-api | Critical | Global JwtAuthGuard ถูก bypass ด้วย @Public() บนแทบทุก endpoint เขียนข้อมูล | 2way-api/src/modules/announces/announces.controller.ts:45,56,79,85, line.controller.ts (branch: prod) | Vol 5 · 2way-api |
| SEC-MOBILE-01 | vtrc-mobile | Critical | RSA private key เต็ม hardcode ในซอร์ส compile เข้า JS bundle | vtrc-mobile/src/utils/login.js:16-42 | Vol 8 · vtrc-mobile |
| SEC-MOBILE-02 | vtrc-mobile | Critical | Android release keystore path + password plaintext commit เข้า git | vtrc-mobile/android/app/build.gradle:174-179 | Vol 8 · vtrc-mobile |
| SEC-NEW-01 | new-vtrc-mobile | Critical | RSA private key เดียวกับ vtrc-mobile ถูก copy มา hardcode ซ้ำ | new-vtrc-mobile/src/constants/RSAKey.ts:11-38 | Vol 8 · new-vtrc-mobile |
| SEC-MTVTRC-01 | meeting-vtrc-api | Critical | .envdev/.envuat/.envprod commit plaintext มี secret จริง | meeting-vtrc-api/.envprod:1-9 (branch: prod-meeting-vtrc-api) | Vol 7 · meeting-vtrc-api |
| SEC-MTVTRC-02 | meeting-vtrc-api | Critical | /meeting/mockuser/one ไม่มี auth คืน PII hardcode | meeting-vtrc-api/routes/mockdelatlast/mockuser.ts:29-60 (branch: prod-meeting-vtrc-api) | Vol 7 · meeting-vtrc-api |
| SEC-VTRC-API-05 | vtrc-api | High | checkMenuAuth อ่าน role ผิดตัว เปิดช่อง cross-role escalation ในทางทฤษฎี | vtrc-api/api/src/session/session.js:50-70 | Vol 3 · vtrc-api |
| SEC-VTRC-API-06 | vtrc-api | High | CORS misconfiguration — typo corss ทำให้ allowlist ไม่ทำงาน, เปิดทุก origin | vtrc-api/api/src/index.js:76-91 | Vol 3 · vtrc-api |
| SEC-VTRC-API-07 | vtrc-api | High | SQL injection ผ่าน string concat ใน statLog cron | vtrc-api/api/src/lib/controllers/statLog/statLog.js | Vol 3 · vtrc-api |
| SEC-BO-01 | vtrc-backoffice | High | Token ไม่มีวันหมดอายุใน localStorage + XSS surface 20 ไฟล์ dangerouslySetInnerHTML | vtrc-backoffice/src/utils/auth.js:1-17 | Vol 4 · vtrc-backoffice |
| H1 | vtrc-rc-backoffice | High | dangerouslySetInnerHTML 30 ไฟล์ ไม่มี sanitizer | — | Vol 4 · vtrc-rc-backoffice |
| H2 | vtrc-rc-backoffice | High | AES key จาก REACT_APP_PRIVATE_KEY expose ใน bundle | utils/cryptoJs.js | Vol 4 · vtrc-rc-backoffice |
| H3 | vtrc-rc-backoffice | High | Token เก็บใน localStorage/sessionStorage ทั้งหมด | — | Vol 4 · vtrc-rc-backoffice |
| H4 | vtrc-rc-backoffice | High | apiKeyNews() hardcode UUID ตาม origin (prod/UAT) | utils/apiKey.js | Vol 4 · vtrc-rc-backoffice |
| S-1 | vtrc-web | High | Token เก็บใน localStorage/sessionStorage | utils/auth.js:4-35 | Vol 4 · vtrc-web |
| S-3 | vtrc-web | High | AES key+IV เดียวกัน hardcoded สำหรับ "remember password" | utils/auth.js:37-47 | Vol 4 · vtrc-web |
| S-4 | vtrc-web | High | dangerouslySetInnerHTML ไม่มี sanitizer 20+ ไฟล์ | — | Vol 4 · vtrc-web |
| SEC-COMMON-02 | vtrc-common | High | SQL injection ผ่าน string interpolation ใน AddressRepository | vtrc-common/src/modules/address/address.repository.ts:82-94,117-130 | Vol 6 · vtrc-common |
| SEC-CHAT-02 | chat-center-api | High | WebSocket chat event ไม่มี guard, flag fromline เชื่อจาก client ตรง | chat-center-api/src/modules/chat/chat.gateway.ts:19-26,49-67 | Vol 6 · chat-center-api |
| SEC-CHAT-03 | chat-center-api | High | POST /webhook (LINE) เป็น @Public() ไม่ verify signature | chat-center-api/src/app.controller.ts:18-22 | Vol 6 · chat-center-api |
| SEC-RCWEB-02 | recruitment-web | High | PII ที่ decrypt แล้วเก็บใน localStorage ไม่มีวันหมดอายุ (expiry ถูก comment ปิด) | recruitment-web/src/utils/localStorage.js:1-28 | Vol 9 · recruitment-web |
| SEC-RCWEB-03 | recruitment-web | High | handleLogin bypass OTP ด้วยค่าคงที่ 111111 — check ผูกกับ prod bundle | recruitment-web/src/components/header/index.js:230-231 | Vol 9 · recruitment-web |
| SEC-REPORTLOG-02 | report-log | High | .gitignore *.log ถูก comment ปิดโดยตั้งใจ — อนุญาตให้ commit log ซ้ำได้ | report-log/.gitignore:16-17 | Vol 9 · report-log |
| SEC-BENEFIT-03 | benefit-api | High | Endpoint เบิกค่ารักษาพยาบาลเป็น @Public() ทั้งชุด | benefit-api/src/modules/wdhospitals/wdhospitals.controller.ts:24-40 (branch: prod) | Vol 6 · benefit-api |
| SEC-2WAYVTRC-04 | 2way-vtrc-api | High | JWT secret hardcoded ไม่มี env override, มี secret 2 ตัวไม่ตรงกันในระบบเดียว | 2way-vtrc-api/util/jwt.config.ts:2, checkbypasstoken.ts:65 | Vol 5 · 2way-vtrc-api |
| SEC-2WAYVTRC-05 | 2way-vtrc-api | High | Sequelize dialect ตั้ง encrypt: false — เชื่อมต่อ MSSQL แบบไม่เข้ารหัส | 2way-vtrc-api/util/db.config.ts:8-11 | Vol 5 · 2way-vtrc-api |
| SEC-2WAYMTBO-01 | 2way-meeting-backoffice | High | JWT เก็บที่ localStorage ไม่ใช่ httpOnly cookie | src/utils/fetchApiWithAxios.tsx:8, src/HOC/withAuth.tsx:22 | Vol 5 · 2way-meeting-backoffice |
| SEC-2WAYMTBO-02 | 2way-meeting-backoffice | High | Route guard เป็น client-side check ล้วน ไม่ป้องกันก่อน bundle โหลด | src/HOC/withAuth.tsx:19-73 | Vol 5 · 2way-meeting-backoffice |
| SEC-2WAYLINE-02 | 2way-line-service | High | Service ถูกเรียกจาก 2way-api ผ่าน hardcoded IP ไม่มี TLS/service discovery | .env.example:5 (เทียบ 2way-api/src/modules/line/line.service.ts:76,86) | Vol 5 · 2way-line-service |
| SEC-2WAYAPI-05 | 2way-api | High | verifyJwt() ตั้ง ignoreExpiration: true เสมอ — token ไม่หมดอายุจริงในการตรวจสอบ | 2way-api/src/modules/auth/auth.service.ts:31-40,339-357,290 (branch: prod) | Vol 5 · 2way-api |
| SEC-2WAYAPI-06 | 2way-api | High | MSSQL connection ตั้ง encrypt: false | 2way-api/src/app.module.ts:39-42 (branch: prod) | Vol 5 · 2way-api |
| SEC-MOBILE-03 | vtrc-mobile | High | apiKey (device key) production hardcode ซ้ำ 3 จุดในซอร์ส พร้อม apiKey UAT ที่ comment ทิ้งไว้ | src/utils/fetch.js:43-45, src/constants/Authen.js:1-5, src/utils/login.js:49-52 | Vol 8 · vtrc-mobile |
| SEC-NEW-02 | new-vtrc-mobile | High | accessToken/refreshToken เก็บผ่าน AsyncStorage แบบ plain — regression จาก encrypted storage ของ vtrc-mobile | src/redux/store.ts:13,20-25 | Vol 8 · new-vtrc-mobile |
| SEC-MTVTRC-03 | meeting-vtrc-api | High | /meeting/secure/health-check/email อยู่ใต้ path "secure" แต่ไม่มี auth ส่งอีเมลจริง | routes/secure/meeting/health-check.ts:9-17 | Vol 7 · meeting-vtrc-api |
| SEC-MTBO-01 | meeting-backoffice | High | X-API-Key hardcode ในซอร์ส frontend ที่ browser โหลดได้ | pages/[token].tsx:14-21 | Vol 7 · meeting-backoffice |
| SEC-MTBO-02 | meeting-backoffice | High | .env (URL จริงของ UAT backend) commit เข้า git | .env:1-16 | Vol 7 · meeting-backoffice |
| SEC-VTRC-API-08 | vtrc-api | Medium | JWT verify ไม่ระบุ algorithms — เปิดช่อง alg-confusion attack | vtrc-api/api/src/lib/repositories/auth/auth.js:259-285 | Vol 3 · vtrc-api |
| M1 | vtrc-rc-backoffice | Medium | checkLinkURL() ใช้ .includes() แทนการ parse origin จริง | — | Vol 4 · vtrc-rc-backoffice |
| M2 | vtrc-rc-backoffice | Medium | errorLink (Apollo) ไม่มี queue/singleton สำหรับ token refresh | — | Vol 4 · vtrc-rc-backoffice |
| M3 | vtrc-rc-backoffice | Medium | ไม่มี Content-Security-Policy meta/header | — | Vol 4 · vtrc-rc-backoffice |
| M4 | vtrc-rc-backoffice | Medium | ไม่มี CSRF token | — | Vol 4 · vtrc-rc-backoffice |
| M5 | vtrc-rc-backoffice | Medium | ไม่มี Subresource Integrity (SRI) สำหรับสคริปต์ CDN ภายนอก | — | Vol 4 · vtrc-rc-backoffice |
| S-2 | vtrc-web | Medium | apiKey เข้ารหัส base64 ในบันเดิล ถอดได้ทันทีด้วย atob() | utils/apiKey.js:1-12 | Vol 4 · vtrc-web |
| S-5 | vtrc-web | Medium | isShow เป็นเพียง UI flag ไม่ใช่ auth gate จริง | config/routes.js | Vol 4 · vtrc-web |
| S-6 | vtrc-web | Medium | Console override ปิดการ debug production | containers/App/index.js:15 | Vol 4 · vtrc-web |
| S-8 | vtrc-web | Medium | ไม่มี Content Security Policy | nginx-config/default.conf | Vol 4 · vtrc-web |
| SEC-RCWEB-04 | recruitment-web | Medium | Email/OTP ส่งผ่าน query string ของ GET request — ค่าถูก log ใน access log | form-otp.js:51-52, header/index.js:74,232,266 | Vol 9 · recruitment-web |
| SEC-2WAYVTRC-06 | 2way-vtrc-api | Medium | CORS wildcard * พร้อม Access-Control-Allow-Credentials: true ขัดแย้งกันในตัว | 2way-vtrc-api/app.ts:87-99 | Vol 5 · 2way-vtrc-api |
| SEC-OCRAPI-01 | vtrc-ocr-api | Medium | CORS เปิดกว้างด้วยค่า default — config.cors ไม่ถูกใช้จริง | vtrc-ocr-api/app.js:16 | Vol 9 · vtrc-ocr-api |
| SEC-MTVTRC-04 | meeting-vtrc-api | Medium | Tinify API key hardcode ในซอร์ส (จุดเรียกใช้ถูก comment) | lib/Uploadimage.class.ts:5,29-30 | Vol 7 · meeting-vtrc-api |
| S-7 | vtrc-web | Low | Google Analytics ID เปิดเผยใน public HTML | public/index.html:33-38 | Vol 4 · vtrc-web |
PERF — Performance (11 รายการ: High 1, Medium 10)
| ID | Repo | Severity | คำอธิบาย | file:line | Source |
|---|---|---|---|---|---|
| PERF-2WAYBATCH-01 | 2way-batch | High | Cron ทุก 10 วินาทีทำงานจริงแค่ log ข้อความเปล่า logic แจ้งเตือนจริงถูก comment ปิด | src/crontab/survey/survey.task.service.ts:32-41 | Vol 5 · 2way-batch |
| PERF-VTRC-API-01 | vtrc-api | Medium | execSync block event loop ระหว่างสร้าง PDF | vtrc-api/api/src/routes.js (5 call sites) | Vol 3 · vtrc-api |
| PERF-CU-01 | cu-central-api | Medium | ไม่มี timeout/retry/circuit breaker ในทุก external integration | ทุกไฟล์ integration | Vol 3 · cu-central-api |
| PERF-BO-01 | vtrc-backoffice | Medium | ไม่พบการใช้ React.lazy/route-level code splitting ที่ใดใน src/ | vtrc-backoffice/src | Vol 4 · vtrc-backoffice |
| P-1 | vtrc-web | Medium | Bundle ~12MB ไม่มี code splitting, PDF library ซ้อนกัน 4 ตัว | — | Vol 4 · vtrc-web |
| P-2 | vtrc-web | Medium | fetchPolicy: 'no-cache' เป็น default ทุก query | — | Vol 4 · vtrc-web |
| P-3 | vtrc-web | Medium | SiderLayout query profile ทุกครั้งที่ reload | — | Vol 4 · vtrc-web |
| P-4 | vtrc-web | Medium | ไม่มี lazy loading รูปภาพ | — | Vol 4 · vtrc-web |
| P-5 | vtrc-web | Medium | Webpack 4 (ไม่มี webpack 5 features) | — | Vol 4 · vtrc-web |
| P-6 | vtrc-web | Medium | console.log กระจายหลายสิบจุดเพิ่มขนาดบันเดิล | — | Vol 4 · vtrc-web |
| P-7 | vtrc-web | Medium | PDF.js โหลด worker แยกเพิ่ม 1 request | — | Vol 4 · vtrc-web |
CORR — Correctness / data integrity (30 รายการ: Critical 1, High 20, Medium 8, Low 1)
| ID | Repo | Severity | คำอธิบาย | file:line | Source |
|---|---|---|---|---|---|
| CORR-CU-01 | cu-central-api | Critical | lib/httpRequest.js import axios จริงแต่ package.json มีแต่ axois (typo) — crash ถ้า code path ถึง | cu-central-api/main-api/src/lib/httpRequest.js | Vol 3 · cu-central-api |
| CORR-VTRC-API-01 | vtrc-api | High | Transaction pattern ทั่วระบบไม่ทำงานจริง — {transaction: t} เป็น arg ที่ 3 ที่ Sequelize ไม่รับ (ซ้ำ 20+ ที่) | vtrc-api/api/src/session/session.js:101-124 | Vol 3 · vtrc-api |
| CORR-VTRC-API-02 | vtrc-api | High | getCurrentRoleUser signature mismatch — device argument ถูก drop | vtrc-api/api/src/session/session.js:126 | Vol 3 · vtrc-api |
| CORR-VTRC-API-03 | vtrc-api | High | limit cap ใน clouse.js ไม่ทำงาน (let limit ไม่มีค่าเริ่มต้น) — เปิดช่อง DoS | vtrc-api/api/src/clouse.js:21-27 | Vol 3 · vtrc-api |
| CORR-CU-02 | cu-central-api | High | OTP inconsistency — hrAddress ปิด OTP, hrPhoneNumber ยังเปิด | cu-central-api/main-api/src/resolvers/hr/hrAddress.js | Vol 3 · cu-central-api |
| CORR-BO-02 | vtrc-backoffice | High | Login flow hardcode isRemember = 1 เสมอ — token ทุกตัวเก็บใน localStorage ไม่มีวันหมด | vtrc-backoffice/src/pages/Login/index.js:45-78, LoginForm/index.js:1-21 | Vol 4 · vtrc-backoffice |
| CORR-BONEW-01 | vtrc-backoffice-new | High | Login flow hardcode isRemember = 1 เสมอ (สืบทอด bug จาก vtrc-backoffice) | src/pages/Login/index.js:79 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| CORR-PMS-01 | pms-api | High | Cron sync ทุก 1 นาทีไม่มีการป้องกัน overlapping execution | usagePermission.service.ts:1928-1936 (branch: uat) | Vol 6 · pms-api |
| CORR-AIRECRUIT-01 | ai-recruitment-api | High | Sync mechanism ระหว่าง recruitment.jobReqPosition กับ recruitment_ai.jobReqPosition ไม่ปรากฏในโค้ดทั้งสอง repo | ดู 03-persistence (branch: prod) | Vol 6 · ai-recruitment-api |
| CORR-WORKFLOW-01 | workflow-api | High | TypeORM ต่อตรงไปฐานข้อมูลของ service อื่น (vtrc, dbHRMI_Center, dbHRMI_Center_NBC, benefit) — distributed-monolith | database.module.ts:51-199 (branch: uat) | Vol 6 · workflow-api |
| CORR-SSO-01 | sso-api | High | signIn() ไม่ออก JWT ของตัวเอง (sign ถูก comment), JwtService ไม่ได้ inject | app.service.ts:27,143-191,220-223 | Vol 6 · sso-api |
| CORR-CHAT-01 | chat-center-api | High | นัดหมายแจ้งเตือนเป็น in-memory CronJob ต่อรายการ หายเมื่อ process restart | appointment.service.ts:33-67 (branch: prod) | Vol 6 · chat-center-api |
| CORR-CHAT-02 | chat-center-api | High | connection main (MSSQL 2way) ตั้ง synchronize: true — auto-migrate ทุก boot | config/configuration.ts:7-21 | Vol 6 · chat-center-api |
| CORR-RECRUIT-01 | recruitment-api | High | Race condition ตอนลด remainingManpower (read-then-write ไม่ atomic) | contract.service.ts:740-763 (branch: prod) | Vol 6 · recruitment-api |
| CORR-BENEFIT-01 | benefit-api | High | ข้อมูล WdHospitals ซ้ำกัน 2 schema (benefit/vtrc) ไม่มี sync mechanism ที่ตรวจสอบได้ | wdHospitals.entity.ts, payments.service.ts:493-573 (branch: prod) | Vol 6 · benefit-api |
| CORR-2WAYVTRC-01 | 2way-vtrc-api | High | Insert หลายตารางต่อเนื่อง (createIncident) ไม่มี Sequelize transaction | routes/TwoWayAPI/incident/createIncident.ts:38-151 (branch: prod) | Vol 5 · 2way-vtrc-api |
| CORR-2WAYVTRC-02 | 2way-vtrc-api | High | MongoDB connection comment ปิดใน entrypoint แต่ chat feature ยังพึ่งพา Mongoose schema | app.ts:10 (branch: prod) | Vol 5 · 2way-vtrc-api |
| CORR-MOBILE-01 | vtrc-mobile | High | Config.MEETING_API hardcode ชี้ host UAT เสมอ ไม่มี branch สำหรับ prod | src/config/index.js:12 | Vol 8 · vtrc-mobile |
| CORR-MTVTRC-01 | meeting-vtrc-api | High | refreshtoken.ts route ไม่ถูก mount ใน app.ts (dead endpoint) + createToken() ไม่ persist ลง DB | routes/auth/refreshtoken.ts:5-19 | Vol 7 · meeting-vtrc-api |
| CORR-MTBO-01 | meeting-backoffice | High | BASE_PATH env ตั้งใน compose แต่ next.config.js hardcode basePath: '/meetingbo' — env ไม่มีผล | docker-compose.yml:8, next.config.js:11-22 | Vol 7 · meeting-backoffice |
| CORR-MTBONEW-01 | meeting-backoffice-new | High | ทุกหน้าอ่าน env var REACT_APP_MEETING_API/REACT_APP_2WAY_API แต่ไม่มีไฟล์ .env/.env.example — fetch ไป undefined แบบเงียบ | src/pages/index.tsx:19 | Vol 7 · meeting-backoffice-new |
| CORR-VTRC-API-04 | vtrc-api | Medium | getCurrentProfileSession fallback ข้าม user — cross-user session leak ในกรณี edge case | vtrc-api/api/src/session/session.js:214-228 | Vol 3 · vtrc-api |
| CORR-BO-01 | vtrc-backoffice | Medium | axios-workforce.js มี unreachable code — return ผิดคืน endpoint localhost เสมอ | vtrc-backoffice/src/config/axios-workforce.js:5-8 | Vol 4 · vtrc-backoffice |
| CORR-SSO-02 | sso-api | Medium | catch block เข้าถึง error.response.data โดยไม่เช็ค error.response ก่อน | app.service.ts:184-189 | Vol 6 · sso-api |
| CORR-RCWEB-01 | recruitment-web | Medium | Dockerfile ประกาศ ENV REACT_APP_* ที่ stage 2 (nginx) ซึ่งไม่มีผลจริง เพราะ CRA inline ตอน stage 1 | Dockerfile:1-21 | Vol 9 · recruitment-web |
| CORR-MTVTRC-02 | meeting-vtrc-api | Medium | addNewMeeting insert 4 ตาราง (bulkCreate แยกกัน) ไม่มี sequelize.transaction() | routes/secure/meeting/meeting.ts:187-243 | Vol 7 · meeting-vtrc-api |
| CORR-MTVTRC-03 | meeting-vtrc-api | Medium | sendMailToDelegate() มีอยู่แต่จุดเรียกใช้ถูก comment ออก — ตัวแทนไม่ได้รับแจ้งเตือน | routes/secure/meeting/acceptancemeeting.ts:125,342-370 | Vol 7 · meeting-vtrc-api |
| CORR-MTVTRC-04 | meeting-vtrc-api | Medium | cron แจ้งเตือน (checkScheduleJob) ดึงเฉพาะงานของ "วันนี้" — พลาด backlog จากวันก่อนหน้า | util/helper/corn.email.helper.ts:19-47 | Vol 7 · meeting-vtrc-api |
| CORR-MTBO-02 | meeting-backoffice | Medium | หน้า index.tsx/listapprover ใช้ getStaticProps (SSG) ไม่มี revalidate — ข้อมูลค้าง | pages/index.tsx:29-49, pages/listapprover/index.tsx:29-49 | Vol 7 · meeting-backoffice |
| CORR-WORKFLOW-02 | workflow-api | Low | enum ค่าคงที่ผสมเข้า raw SQL ด้วย string interpolation ปนกับ parameterized value | ipd-batch.service.ts:1942-1948 (branch: uat) | Vol 6 · workflow-api |
LEG — Legacy / EOL / dependency (22 รายการ: Critical 1, High 8, Medium 12, Low 1)
| ID | Repo | Severity | คำอธิบาย | file:line | Source |
|---|---|---|---|---|---|
| LEG-CU-01 | cu-central-api | Critical | axois typosquat ของ axios ใน package.json — npm reserve 0.0.1-security สำหรับ typosquat นี้ | cu-central-api/main-api/package.json | Vol 3 · cu-central-api |
| LEG-CU-02 | cu-central-api | High | error-ex pin ไปที่ git URL แทน npm version — mutable ref ไม่มี hash protection | package.json | Vol 3 · cu-central-api |
| LEG-CU-03 | cu-central-api | High | ldapjs ^2.2.0 — archived project ตั้งแต่ 2023 | package.json | Vol 3 · cu-central-api |
| LEG-CU-04 | cu-central-api | High | jsonwebtoken@8.5.1 — EOL, CVE-2022-23529 family มี patch ใน v9+ | package.json | Vol 3 · cu-central-api |
| LEG-CU-05 | cu-central-api | High | Node 12.18.3 + esm shim — Node 12 EOL เม.ย. 2022 | Dockerfile:1, package.json | Vol 3 · cu-central-api |
| LEG-CU-06 | cu-central-api | High | xlsx ^0.16.9 — SheetJS community มี prototype pollution CVE history | package.json | Vol 3 · cu-central-api |
| LEG-MOBILE-01 | vtrc-mobile | High | React Native 0.63.2 + React 16.13.1 — เก่ากว่า 5 ปี ไม่ได้รับ security patch แล้ว | package.json:63-64 | Vol 8 · vtrc-mobile |
| LEG-MOBILE-02 | vtrc-mobile | High | ไม่มี runtime endpoint resolver — endpoint ประกาศซ้ำ 3 ไฟล์ที่ค่าไม่ตรงกันจริง | src/config/index.js:1-15, src/constants/HostApi.js:1-36, src/utils/hostUrl.js:1-6 | Vol 8 · vtrc-mobile |
| LEG-FRONT-01 | vtrc-application-front | High | ไฟล์ติดตั้ง iOS ที่ compile แล้ว (VTRC.ipa, binary) commit ตรงเข้า git โดยไม่มี build pipeline | repo root (git ls-files) | Vol 8 · vtrc-application-front |
| LEG-VTRC-API-01 | vtrc-api | Medium | Playground + introspection เปิดใน production | vtrc-api/api/src/index.js:68-69 | Vol 3 · vtrc-api |
| LEG-BO-01 | vtrc-backoffice | Medium | Dockerfile ไม่ build จาก source (FROM nginx:1.18 เท่านั้น) — พึ่งพา build/ ที่ commit ไว้ล่วงหน้า | vtrc-backoffice/Dockerfile:1-2, docker-compose.yml:9-19 | Vol 4 · vtrc-backoffice |
| LEG-BO-02 | vtrc-backoffice | Medium | react-scripts (CRA) คงที่ 3.4.3 — เก่ามาก (ปี 2020) | vtrc-backoffice/package.json:40 | Vol 4 · vtrc-backoffice |
| LEG-BO-03 | vtrc-backoffice | Medium | AntD คงที่ v4.15.4 — อยู่ใน EOL branch ของ Ant Design | vtrc-backoffice/package.json:11 | Vol 4 · vtrc-backoffice |
| LEG-BONEW-01 | vtrc-backoffice-new | Medium | react-scripts (CRA) คงที่ 3.4.3 เหมือน vtrc-backoffice | package.json:40 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| LEG-BONEW-02 | vtrc-backoffice-new | Medium | AntD คงที่ v4.15.4 — EOL branch | package.json:11 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| LEG-OCRAPI-01 | vtrc-ocr-api | Medium | ไม่มี test suite ใด ๆ — npm test เป็น placeholder ที่ exit 1 | package.json:9 | Vol 9 · vtrc-ocr-api |
| LEG-RCWEB-01 | recruitment-web | Medium | ไฟล์แนบแปลงเป็น base64 ฝัง JSON แทน multipart upload แยก ตรวจ type/ขนาดเฉพาะ client | uploadForm.js:22-30, content.js:654-668,677-696 | Vol 9 · recruitment-web |
| LEG-BENEFIT-01 | benefit-api | Medium | sftp-upload + ssh2-sftp-client สอง package ทำงานเดียวกัน (sftp-upload อาจไม่ได้ใช้แล้ว) | package.json:57-58 (branch: prod) | Vol 6 · benefit-api |
| LEG-2WAYVTRC-01 | 2way-vtrc-api | Medium | รันด้วย ts-node app.ts ตรงใน production — ไม่มี build/compile step | package.json:7 | Vol 5 · 2way-vtrc-api |
| LEG-2WAYMTBO-01 | 2way-meeting-backoffice | Medium | Next.js 12 (EOL), React 17 (EOL security patch ตามรอบ Next.js) | package.json:44,47,49 | Vol 5 · 2way-meeting-backoffice |
| LEG-2WAYBATCH-01 | 2way-batch | Medium | Dockerfile build ด้วย node:16-alpine ทั้งสองสเตจ — Node 16 EOL กันยายน 2023 | Dockerfile:1,15 | Vol 5 · 2way-batch |
| LEG-AIRECRUIT-01 | ai-recruitment-api | Low | Node.js 18 (EOL กำลังใกล้) ต่างจาก Node 20 ที่ repo อื่นในกลุ่มใช้ | Dockerfile:1 (branch: prod) | Vol 6 · ai-recruitment-api |
QUAL — Code quality (99 รายการ: High 8, Medium 84, Low 7)
| ID | Repo | Severity | คำอธิบาย | file:line | Source |
|---|---|---|---|---|---|
| QUAL-CU-01 | cu-central-api | High | requires directive arg ถูก comment ออก — ไม่มี RBAC จริง | directives/auth.js | Vol 3 · cu-central-api |
| QUAL-PMS-01 | pms-api | High | เอกสารระบบแจ้งเตือน (PMS-Period-Notification-System.md) ไม่ตรงกับโค้ดจริง | docs/PMS-Period-Notification-System.md (branch: uat) | Vol 6 · pms-api |
| QUAL-AIRECRUIT-01 | ai-recruitment-api | High | Dead code หลายไฟล์ที่ไม่ถูก mount เป็น route | controllers/module2_1_get_background_v2.js และอื่น ๆ (branch: prod) | Vol 6 · ai-recruitment-api |
| QUAL-OCRAPI-01 | vtrc-ocr-api | High | Endpoint หลัก (POST /api/ocr/process) ไม่มี OCR engine จริง คืน mock คงที่เสมอ | services/ocr.service.js:26-34 | Vol 9 · vtrc-ocr-api |
| QUAL-OCRAPI-02 | vtrc-ocr-api | High | ผลลัพธ์เก็บใน in-memory Map เท่านั้น — หายเมื่อ restart | models/ocr.model.js:5, config/database.js:5-25 | Vol 9 · vtrc-ocr-api |
| QUAL-RECRUIT-01 | recruitment-api | High | TypeORM connection 2 ชุด (vtrc, workforce) ประกาศไว้แต่ไม่มีการใช้งานจริง | app.module.ts:42-53 (branch: prod) | Vol 6 · recruitment-api |
| QUAL-BENEFIT-01 | benefit-api | High | Logic SQL builder ซ้ำกันหลายร้อยบรรทัดใน payments.service.ts (copy-paste 3 รอบ) | payments.service.ts:488-573,640-720,1341-1427 (branch: prod) | Vol 6 · benefit-api |
| QUAL-NEW-01 | new-vtrc-mobile | High | refreshToken() ยิงไปที่ URL ตัวอย่างจาก boilerplate ที่ยังไม่ถูกแทนที่ | src/utils/Auth.ts:8-17 | Vol 8 · new-vtrc-mobile |
| QUAL-VTRC-API-01 | vtrc-api | Medium | Op.like บน JSON/TEXT column หลายจุด — substring collision risk | session/session.js:31, centralize/controllers/graphql.js:31 | Vol 3 · vtrc-api |
| QUAL-VTRC-API-02 | vtrc-api | Medium | Dynamic model/table access (Models[table]) — injection risk ทางทฤษฎี | excel/excel.js, lib/model.js | Vol 3 · vtrc-api |
| QUAL-VTRC-API-03 | vtrc-api | Medium | Fire-and-forget cron jobs — ไม่มี error handling, ไม่มี await | crons.js:20-22, fund/fund.js:926-928 | Vol 3 · vtrc-api |
| QUAL-VTRC-API-04 | vtrc-api | Medium | await arr.map(async ...) แบบไม่ Promise.all — parallel write ที่ไม่ถูก await | document/documentDivision.js, career/careerDivision.js | Vol 3 · vtrc-api |
| QUAL-VTRC-API-05 | vtrc-api | Medium | Debug artifact ค้างในโค้ด — hardcoded path เครื่อง developer, artificial delay | file/zip.js:4, slip/slip.js | Vol 3 · vtrc-api |
| QUAL-CU-02 | cu-central-api | Medium | clockTolerance misuse — ใส่เป็น payload claim ไม่มีผล | jwtToken.js | Vol 3 · cu-central-api |
| QUAL-CU-03 | cu-central-api | Medium | signInDomains hardcoded 26-row org list — เพิ่ม org ต้อง deploy code ใหม่ | resolvers/authentication.js | Vol 3 · cu-central-api |
| QUAL-BO-01 | vtrc-backoffice | Medium | routes.js มีบล็อก route ซ้ำที่ comment ปิดทั้งกลุ่มจำนวนมาก (10+ module) | vtrc-backoffice/src/config/routes.js:1118-1546 | Vol 4 · vtrc-backoffice |
| QUAL-BO-02 | vtrc-backoffice | Medium | มี checkLinkURL() สองตัวคนละไฟล์ชื่อเดียวกันแต่คืนค่าคนละรูปแบบ | vtrc-backoffice/src/utils/auth.js:50-64 | Vol 4 · vtrc-backoffice |
| QUAL-BO-03 | vtrc-backoffice | Medium | ไฟล์ backup/legacy (*_bk*.js, *-prd.js) กระจายอยู่อย่างน้อย 41 ไฟล์ | src/pages/HospitalPaid/Payments/index_bk.js และอื่น ๆ | Vol 4 · vtrc-backoffice |
| QUAL-BONEW-01 | vtrc-backoffice-new | Medium | Dockerfile มี multi-stage build จริงแต่ docker-compose.yml ไม่ได้อ้างถึงเลย | Dockerfile:1-11, docker-compose.yml:1-19 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| QUAL-BONEW-02 | vtrc-backoffice-new | Medium | ชื่อ network ใน compose ไม่มีคำ uat สลับกับที่คาดตามชื่อ repo | docker-compose.yml:19 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| QUAL-BONEW-03 | vtrc-backoffice-new | Medium | ไฟล์ src/config/appllo_bk.js มีอยู่ใน git แต่เนื้อหาเปล่า (0 บรรทัด) | src/config/appllo_bk.js (branch: uat) | Vol 4 · vtrc-backoffice-new |
| QUAL-PMS-02 | pms-api | Medium | Dockerfile build โดยไม่ล็อค lockfile (yarn install ไม่มี --frozen-lockfile) | Dockerfile:19 (branch: uat) | Vol 6 · pms-api |
| QUAL-PMS-03 | pms-api | Medium | 5 module ปรับเงินเดือนชื่อคล้ายกันมาก ไม่มีเอกสารอธิบายความสัมพันธ์ | salaryRange, salaryPercentage, salaryAdjust, salaryAdjustment, salaryAdjustToHRMI (branch: uat) | Vol 6 · pms-api |
| QUAL-PMS-04 | pms-api | Medium | Third-party AI service บน domain ภายนอก (vtrcsupport.com) รับข้อมูลผลประเมิน | createForm.service.ts:408 (branch: uat) | Vol 6 · pms-api |
| QUAL-AIRECRUIT-02 | ai-recruitment-api | Medium | Hardcode สมมติฐานประชากร (ethnicity/age) ใน AI prompt โดยไม่มี config | module2_2_controller.js:31-44 (branch: prod) | Vol 6 · ai-recruitment-api |
| QUAL-WORKFLOW-01 | workflow-api | Medium | AuditLogService มี fallback query หลายชุดจาก schema drift ระหว่าง environment | audit-log.service.ts:120-160,232-266 (branch: uat) | Vol 6 · workflow-api |
| QUAL-WORKFLOW-02 | workflow-api | Medium | ชื่อ repo (workflow-api) กับชื่อ package จริง (ai-pms-nest) ไม่ตรงกัน ครอบ 3 domain ที่ไม่เกี่ยวกัน | package.json:2,4 (branch: uat) | Vol 6 · workflow-api |
| QUAL-WORKFLOW-03 | workflow-api | Medium | database/schema.sql ไม่ตรงกับ entity จริงที่ประกาศใน src/modules/embedding/entities/ | database/schema.sql:1-50 (branch: uat) | Vol 6 · workflow-api |
| QUAL-WORKFLOW-04 | workflow-api | Medium | ไฟล์ service ขนาดใหญ่เกินจัดการ (2,753 / 2,527 / 1,398 บรรทัด) | ipd-batch.service.ts, embedding.service.ts, health-program-config.service.ts (branch: uat) | Vol 6 · workflow-api |
| QUAL-COMMON-01 | vtrc-common | Medium | /testTumbol, /testTumbol2 ชื่อบอกว่าทดลองแต่เป็น production path จริง | address.controller.ts:32-41 | Vol 6 · vtrc-common |
| QUAL-COMMON-02 | vtrc-common | Medium | libs/jwt, libs/log เหมือนกันไบต์ต่อไบต์กับ chat-center-api/job-scheduler-api (copy-paste ข้าม repo) | เทียบ libs/jwt/jwt-auth.guard.ts | Vol 6 · vtrc-common |
| QUAL-SSO-01 | sso-api | Medium | verifySession() เป็น stub คืนค่า { body } ตรง ไม่มี logic ตรวจสอบจริง | app.service.ts:220-223 | Vol 6 · sso-api |
| QUAL-SSO-02 | sso-api | Medium | ssoEndpoint/ssoUsername/ssoPassword/ssoAppId อ่านจาก process.env ตรง ไม่สม่ำเสมอกับ ConfigService | app.service.ts:22-25 | Vol 6 · sso-api |
| QUAL-JOBSCHED-01 | job-scheduler-api | Medium | TypeOrmModule import แต่ไม่เคยถูกเรียกใช้ใน @Module({imports}) | app.module.ts:6,11-19 | Vol 6 · job-scheduler-api |
| QUAL-JOBSCHED-02 | job-scheduler-api | Medium | .env ตั้ง BASE_PATH=benefit-api/, DB_NAME=benefit — copy จาก benefit-api ไม่ได้แก้ | .env:3,11 | Vol 6 · job-scheduler-api |
| QUAL-JOBSCHED-03 | job-scheduler-api | Medium | ไฟล์ log จริงจาก dev environment commit เข้า git | logs/30-01-2023.log | Vol 6 · job-scheduler-api |
| QUAL-CHAT-01 | chat-center-api | Medium | libs/jwt, libs/log, libs/exception เหมือนกันไบต์ต่อไบต์กับ vtrc-common, job-scheduler-api | เทียบ libs/jwt/jwt-auth.guard.ts | Vol 6 · chat-center-api |
| QUAL-CHAT-02 | chat-center-api | Medium | console.log debug + บล็อกโค้ด comment ทิ้งไว้จำนวนมากในระดับ service | chat.gateway.ts:59,73-74, chat.service.ts:38,54,100 | Vol 6 · chat-center-api |
| QUAL-OCRAPI-03 | vtrc-ocr-api | Medium | middleware/error.middleware.js export ครบแต่ app.js ไม่ import ใช้ — เขียน error handler ซ้ำ inline | middleware/error.middleware.js:2-29, app.js:57-64 | Vol 9 · vtrc-ocr-api |
| QUAL-OCRAPI-04 | vtrc-ocr-api | Medium | utils/response.js helper มีให้ใช้แต่ controller ทุกตัวเขียน response เองตรง | utils/response.js:1-27 | Vol 9 · vtrc-ocr-api |
| QUAL-OCRAPI-05 | vtrc-ocr-api | Medium | ไม่มี .env.example ใน repo — ไม่มีหลักฐานยืนยันชื่อ/ค่า env variable ทั้งหมด | — | Vol 9 · vtrc-ocr-api |
| QUAL-RCWEB-01 | recruitment-web | Medium | Dead code src/api/login.js, src/api/index.js — ไม่มี component ใด import ใช้ | src/api/login.js:1-53, src/api/index.js:1-6 | Vol 9 · recruitment-web |
| QUAL-RCWEB-02 | recruitment-web | Medium | utils/axios.js interceptor ตั้งชื่อพารามิเตอร์ผิด + CORS header ที่ไม่มีผล (dead code) | src/utils/axios.js:8-15 | Vol 9 · recruitment-web |
| QUAL-RCWEB-03 | recruitment-web | Medium | typo env var REACT_APP_RECAPTCHA_SITE_KET (ควรเป็น KEY) สอดคล้องกันทั้ง 3 จุด | .env:13, .env.uat:8, content.js:1355 | Vol 9 · recruitment-web |
| QUAL-RCWEB-04 | recruitment-web | Medium | Logic decrypt PII ~25 field เขียนซ้ำแทบคำต่อคำใน 2 ที่ | header/index.js:104-148, content.js:492-537 | Vol 9 · recruitment-web |
| QUAL-REPORTLOG-01 | report-log | Medium | users.json array UUID 9,485 รายการไม่มี header/context อธิบาย | users.json:1-9485, app.js:111,124 | Vol 9 · report-log |
| QUAL-REPORTLOG-02 | report-log | Medium | app.js เป็นสคริปต์เฉพาะกิจ hardcode ช่วงวันที่/path output, export code comment ปิด | app.js:4,211,221-229 | Vol 9 · report-log |
| QUAL-RECRUIT-02 | recruitment-api | Medium | WORKFORCE_COMMON_SERVER/VTRC_COMMON_SERVER ชี้ dev URL ใน production .env | .env:41 (branch: prod) | Vol 6 · recruitment-api |
| QUAL-RECRUIT-03 | recruitment-api | Medium | Business rule ผูกกับ client string โดยไม่มี TypeScript enum บังคับ | candidate.service.ts:456,491-504 (branch: prod) | Vol 6 · recruitment-api |
| QUAL-BENEFIT-02 | benefit-api | Medium | validateData() เป็น stub คืนค่า true เสมอ ไม่ตรวจสอบอะไรจริง | disaster.service.ts:361-366 (branch: prod) | Vol 6 · benefit-api |
| QUAL-BENEFIT-03 | benefit-api | Medium | docType เป็น magic number (1-5) ไม่มี enum กลาง กระจายทั่ว 3 service | payments.service.ts, approvedisaster.service.ts, disbursement.service.ts (branch: prod) | Vol 6 · benefit-api |
| QUAL-2WAYVTRC-01 | 2way-vtrc-api | Medium | โค้ดตัวอย่าง/mock สไตล์ tutorial ยัง mount อยู่ที่ path production จริง | app.ts:110-113, routes/TwoWayAPI/index.ts:196-259 (branch: prod) | Vol 5 · 2way-vtrc-api |
| QUAL-2WAYVTRC-02 | 2way-vtrc-api | Medium | ชื่อ package คือ "express" v1.0.0 ไม่เคยถูกแก้ไขให้ตรงกับ repo | package.json:2-3 (branch: prod) | Vol 5 · 2way-vtrc-api |
| QUAL-2WAYMTBO-01 | 2way-meeting-backoffice | Medium | ชื่อ repo ("meeting-backoffice") ทำให้เข้าใจผิดว่าเกี่ยวกับระบบประชุม — จริงคือ backoffice ของ 2way | ยืนยันจาก src/features/2way/* | Vol 5 · 2way-meeting-backoffice |
| QUAL-2WAYMTBO-02 | 2way-meeting-backoffice | Medium | ฟังก์ชันเรียก API ทุกไฟล์ catch error แล้ว console.log เฉย ๆ ไม่ throw ต่อ | services/surveys.tsx:8-10,17-19,44-45, utils/fetchApiWithAxios.tsx:35-40 | Vol 5 · 2way-meeting-backoffice |
| QUAL-2WAYMTBO-03 | 2way-meeting-backoffice | Medium | getChatDetail() hardcode roomEmpCode เป็นค่าคงที่ ไม่รับพารามิเตอร์จริง | services/chat-center.tsx:6 | Vol 5 · 2way-meeting-backoffice |
| QUAL-2WAYMTBO-04 | 2way-meeting-backoffice | Medium | Material-UI v4 และ MUI v5 ใช้ปนกันในโปรเจกต์เดียว | package.json:23,25 | Vol 5 · 2way-meeting-backoffice |
| QUAL-2WAYLINE-01 | 2way-line-service | Medium | dependency + entity/DTO ของ TypeORM/MSSQL ครบชุดแต่ AppModule ไม่ได้ตั้ง TypeOrmModule เลย | app.module.ts:9-16 | Vol 5 · 2way-line-service |
| QUAL-2WAYLINE-02 | 2way-line-service | Medium | env CENTRALIZE_SERVER ประกาศแต่ไม่มีการเรียกใช้ในซอร์สโค้ดเลย | .env.example:16 | Vol 5 · 2way-line-service |
| QUAL-2WAYLINE-03 | 2way-line-service | Medium | ไฟล์ scratch/note (endpoint.txt, lineText.text) commit ไว้ใน root repo | endpoint.txt, lineText.text | Vol 5 · 2way-line-service |
| QUAL-2WAYBATCH-01 | 2way-batch | Medium | โฟลเดอร์ module มีไฟล์ controller/service ครบชุดแต่ไม่ได้ import เข้า AppModule | app.module.ts:37-42 | Vol 5 · 2way-batch |
| QUAL-2WAYBATCH-02 | 2way-batch | Medium | ไม่มีไฟล์ .env.example ใน repo (ผิดกับ repo อื่นในกลุ่มเดียวกัน) | — | Vol 5 · 2way-batch |
| QUAL-2WAYAPI-01 | 2way-api | Medium | มีโมดูลซ้ำที่สร้างไว้แต่ไม่ได้ต่อสายเข้า AppModule (โค้ดค้างจาก refactor) | app.module.ts:1-19 (branch: prod) | Vol 5 · 2way-api |
| QUAL-2WAYAPI-02 | 2way-api | Medium | AppModule (root) import ตัวเองเข้าไปใน imports array ของตัวเอง | app.module.ts:46 (branch: prod) | Vol 5 · 2way-api |
| QUAL-2WAYAPI-03 | 2way-api | Medium | console.log ปนกับ I3GatewayLogger กระจายทั่ว service layer รวม log ที่อาจมี PII | announces.service.ts:56,94,112,289 (branch: prod) | Vol 5 · 2way-api |
| QUAL-2WAYAPI-04 | 2way-api | Medium | Node engine ที่ประกาศ (>=18.0.0) ไม่ตรงกับ Dockerfile.prod ที่ใช้ node:16-alpine | package.json:27, Dockerfile.prod:1 | Vol 5 · 2way-api |
| QUAL-2WAYAPI-05 | 2way-api | Medium | Package manager ไม่สอดคล้อง — มีทั้ง yarn.lock และ package-lock-prod.json | yarn.lock, package-lock-prod.json | Vol 5 · 2way-api |
| QUAL-2WAYAPI-06 | 2way-api | Medium | LineService เรียก IP-address ตรงแทนอ่านจาก config/env | line.service.ts:76,86 (branch: prod) | Vol 5 · 2way-api |
| QUAL-MOBILE-01 | vtrc-mobile | Medium | ชื่อไฟล์ typo Merdical/witchdraw ฝังลงชื่อไฟล์/route/function 20+ จุด | src/containers/MerdicalExpensesApprove.js, src/components/witchdraw/ | Vol 8 · vtrc-mobile |
| QUAL-MOBILE-02 | vtrc-mobile | Medium | Automated test มีเพียงไฟล์ default smoke test จาก RN CLI template | __tests__/App-test.js:1-14 | Vol 8 · vtrc-mobile |
| QUAL-MOBILE-03 | vtrc-mobile | Medium | Navigation library (react-native-router-flux) ไม่มี release ใหม่มาหลายปี | package.json:99, App.js:227-1062 | Vol 8 · vtrc-mobile |
| QUAL-MOBILE-04 | vtrc-mobile | Medium | ชื่อ internal package (rn_redcross) เป็นชื่อตอน scaffold ที่ไม่เคยถูกเปลี่ยน | package.json:2, app.json:1-4 | Vol 8 · vtrc-mobile |
| QUAL-MOBILE-05 | vtrc-mobile | Medium | มี async-action สอง pattern คู่ขนาน (features/*Slice.js จริง กับ actions/*Slice.js ที่ไม่ใช่ slice จริง) | authSlice.js:79-252, actions/ssoSlice.js:1-30 | Vol 8 · vtrc-mobile |
| QUAL-NEW-02 | new-vtrc-mobile | Medium | ค่า host default เป็น UAT ไม่ใช่ prod พร้อม prod ที่ comment ทิ้งไว้ | src/constants/HostAPI.ts:1-18 | Vol 8 · new-vtrc-mobile |
| QUAL-NEW-03 | new-vtrc-mobile | Medium | รหัสผ่านผู้ใช้ (เข้ารหัส RSA) ถูกเก็บไว้ใน redux state ที่ persist โดยไม่จำเป็นชัดเจน | src/features/auth/authSlice.ts:11-22,28-35 | Vol 8 · new-vtrc-mobile |
| QUAL-NEW-04 | new-vtrc-mobile | Medium | ชื่อ internal package/app (MyNewProject) เป็นชื่อ scaffold เริ่มต้นที่ไม่เคยถูกเปลี่ยน | app.json:1-4, package.json:2 | Vol 8 · new-vtrc-mobile |
| QUAL-NEW-05 | new-vtrc-mobile | Medium | CheckEmpCode screen มีไฟล์ครบแต่ import ถูก comment ปิดใน AuthNavigator | src/navigation/AuthNavigator.tsx:5,12 | Vol 8 · new-vtrc-mobile |
| QUAL-FRONT-01 | vtrc-application-front | Medium | เลขเวอร์ชันที่แสดงในหน้าเว็บเป็นข้อความ hardcode ต้องแก้มือทุกครั้งที่ปล่อยเวอร์ชันใหม่ | index.html:47 | Vol 8 · vtrc-application-front |
| QUAL-FRONT-02 | vtrc-application-front | Medium | QR code image 3 ไฟล์ยังอยู่ใน repo แต่ tag ที่อ้างถึงถูก comment ปิด | index.html:66-69 | Vol 8 · vtrc-application-front |
| QUAL-MTVTRC-01 | meeting-vtrc-api | Medium | mongoose dependency ประกาศ+require แต่ไฟล์เชื่อมต่อถูก comment — ขัดสมมติฐานเดิมว่าเป็น "Express + Mongoose" | app.ts:8, util/mongo.config.ts:1-14, util/db.config.ts:1-6 | Vol 7 · meeting-vtrc-api |
| QUAL-MTVTRC-02 | meeting-vtrc-api | Medium | model/login.ts นิยามตาราง user/user_group สไตล์เกม ไม่พบ route อ้างถึงตรง | model/login.ts:1-122 | Vol 7 · meeting-vtrc-api |
| QUAL-MTVTRC-03 | meeting-vtrc-api | Medium | สองไฟล์ emailsender.ts/Emailsender.func.ts ต่างกันแค่ตัวพิมพ์ใหญ่-เล็ก เสี่ยง case-sensitive filesystem | util/helper/emailsender.ts:4 | Vol 7 · meeting-vtrc-api |
| QUAL-MTVTRC-04 | meeting-vtrc-api | Medium | ทั้ง repo สะกด "cron" เป็น "corn" ทุกที่ — เป็น public API path แล้ว ห้ามแก้ครั้งเดียว | corn-job/, routes/secure/meeting/corn-email.ts | Vol 7 · meeting-vtrc-api |
| QUAL-MTVTRC-05 | meeting-vtrc-api | Medium | ไม่มีไฟล์ Dockerfile แต่ docker-compose.yml สั่ง build: context: . | docker-compose.yml:6-11 | Vol 7 · meeting-vtrc-api |
| QUAL-MTBO-01 | meeting-backoffice | Medium | package.json name/version เป็น "reportmonitor"/"5.0.0" ไม่สัมพันธ์กับแอปจริง | package.json:2-3 | Vol 7 · meeting-backoffice |
| QUAL-MTBO-02 | meeting-backoffice | Medium | typescript.ignoreBuildErrors: true — production build ผ่านแม้มี type error จริง | next.config.js:11-19 | Vol 7 · meeting-backoffice |
| QUAL-MTBO-03 | meeting-backoffice | Medium | Dockerfile:20 รัน CMD ["yarn","dev"] — คอนเทนเนอร์ production รัน Next.js dev server | Dockerfile:1-20 | Vol 7 · meeting-backoffice |
| QUAL-MTBO-04 | meeting-backoffice | Medium | Sidebar มีเมนูแค่ 2 รายการ แต่มีหน้าอื่นที่ใช้งานได้จริงเข้าถึงได้แค่ผ่าน URL ตรง | src/layouts/Sidebar.tsx:41-63 | Vol 7 · meeting-backoffice |
| QUAL-MTBO-05 | meeting-backoffice | Medium | public/locales/de/ มีไฟล์แปลภาษาเยอรมันเต็มชุด — ซากจาก starter template | public/locales/de/*.json | Vol 7 · meeting-backoffice |
| QUAL-MTBONEW-01 | meeting-backoffice-new | Medium | โฟลเดอร์ build/ (webpack bundle + sourcemap) commit ตรงเข้า git แทนให้ CI generate | build/static/js/main.633a23c6.js | Vol 7 · meeting-backoffice-new |
| QUAL-MTBONEW-02 | meeting-backoffice-new | Medium | ไม่มี @sentry/* หรือเครื่องมือ error-tracking ใด ๆ | package.json:6-27 | Vol 7 · meeting-backoffice-new |
| QUAL-MTBONEW-03 | meeting-backoffice-new | Medium | docker-compose.yml ไม่ตรงกับวิธี deploy จริง (static build ถูกฝังใน vtrc-backoffice ด้วยมือ) | docker-compose.yml:1-9 | Vol 7 · meeting-backoffice-new |
| QUAL-BONEW-04 | vtrc-backoffice-new | Low | 2 เมนู (WorkForce Org, Attendance abstainTime) ถูก comment ปิดโดยไม่มีคำอธิบาย | src/config/routes.js:272-295,718-743 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| QUAL-PMS-05 | pms-api | Low | TODO ค้างอยู่ 1 จุด — business logic ที่ยังไม่ยืนยันสมบูรณ์ | salaryAdjust.service.ts:127 (branch: uat) | Vol 6 · pms-api |
| QUAL-PMS-06 | pms-api | Low | Typo ในชื่อ entity (periodExtesnd ควรเป็น periodExtend) กลายเป็นชื่อตารางถาวรแล้ว | entities/periodExtesnd.entity.ts (branch: uat) | Vol 6 · pms-api |
| QUAL-AIRECRUIT-03 | ai-recruitment-api | Low | ไฟล์ภาพ 300+ ไฟล์ commit อยู่ใน repo แทนเก็บที่ object storage | storage-uploads/ (branch: prod) | Vol 6 · ai-recruitment-api |
| QUAL-RECRUIT-04 | recruitment-api | Low | ejs template สำรอง/เก่าหลายไฟล์ (.bak.ejs, _old.ejs) commit ปนกับไฟล์ที่ใช้จริง | libs/pdfTemplate/announcement/qualified-exam_old.ejs และอื่น ๆ (branch: prod) | Vol 6 · recruitment-api |
| QUAL-BENEFIT-04 | benefit-api | Low | ไฟล์ผู้ใช้จริง (ภาพประกอบการเบิกภัยพิบัติ) commit อยู่ใน uploads/ ตั้งแต่ปี 2023 | uploads/disaster/2023-02-27/*.png (branch: prod) | Vol 6 · benefit-api |
| QUAL-BENEFIT-05 | benefit-api | Low | Base entity สองตัว (base.ts, baseBenefit.entity.ts) ทำหน้าที่ซ้ำกันเกือบหมด | entities/base.ts, baseBenefit.entity.ts (branch: prod) | Vol 6 · benefit-api |
OBS — Observability (24 รายการ: High 2, Medium 21, Low 1)
| ID | Repo | Severity | คำอธิบาย | file:line | Source |
|---|---|---|---|---|---|
| OBS-VTRC-API-01 | vtrc-api | High | PII logging — userRole, device token, request/response ถูก log เต็มรูปแบบ | session/session.js:147, firebase/firebasePushNotification.js | Vol 3 · vtrc-api |
| OBS-PMS-01 | pms-api | High | Cron error handling แบบ silent — ไม่มี alert ต่อเมื่อ job ล้มเหลว | configNotification.controller.ts:33-40 (branch: uat) | Vol 6 · pms-api |
| OBS-VTRC-API-02 | vtrc-api | Medium | Redis caching layer ตายทั้งระบบ — bug (tr undefined) ที่ทุก caller ถูก comment ไว้ | redis.controller.js:16 | Vol 3 · vtrc-api |
| OBS-VTRC-API-03 | vtrc-api | Medium | ไม่มี structured logging, tracing ID, health check, graceful shutdown | wlog.js, logging.js, index.js | Vol 3 · vtrc-api |
| OBS-CU-01 | cu-central-api | Medium | dbHRMI_test dead connection — เปิด pool 100 session ทุก boot โดยไม่มี model ผูก | connector.js | Vol 3 · cu-central-api |
| OBS-BO-01 | vtrc-backoffice | Medium | console.log/warn/error ถูก override เป็น no-op ทุกครั้งที่ App mount | containers/App/index.js:14 | Vol 4 · vtrc-backoffice |
| OBS-BONEW-01 | vtrc-backoffice-new | Medium | console.log = console.warn = console.error = () => {} override เหมือน vtrc-backoffice ทุกประการ | src/containers/App/index.js:14 (branch: uat) | Vol 4 · vtrc-backoffice-new |
| OBS-PMS-02 | pms-api | Medium | console.log มากที่สุดในกลุ่ม (111 จุด) แม้จะถูก no-op ใน prod | main.ts:16-18 (branch: uat) | Vol 6 · pms-api |
| OBS-AIRECRUIT-01 | ai-recruitment-api | Medium | ไม่มี test suite เลยทั้ง repo (ไม่พบไฟล์ .test.js/.spec.js แม้แต่ไฟล์เดียว) | — (branch: prod) | Vol 6 · ai-recruitment-api |
| OBS-AIRECRUIT-02 | ai-recruitment-api | Medium | console.log ใช้เป็น logger หลักในหลายจุดแทน logger.js ที่มีอยู่แล้ว | routes/index.js:26,41-48 (branch: prod) | Vol 6 · ai-recruitment-api |
| OBS-COMMON-01 | vtrc-common | Medium | เอกสาร workspace-level อธิบาย vtrc-common ผิดว่าเป็น "shared library" ทั้งที่เป็น standalone microservice | ดู 02-core-pipeline | Vol 6 · vtrc-common |
| OBS-SSO-01 | sso-api | Medium | ไม่มี Dockerfile, docker-compose.yml, .env/.env.example, หรือไฟล์ CI ใดเลย | — (branch: master) | Vol 6 · sso-api |
| OBS-JOBSCHED-01 | job-scheduler-api | Medium | Dockerfile ประกาศ EXPOSE 3000 แต่พอร์ตจริงตาม .env/compose คือ 9900 | Dockerfile:24 | Vol 6 · job-scheduler-api |
| OBS-CHAT-01 | chat-center-api | Medium | ไม่มี docker-compose.yml หรือไฟล์ manifest การ deploy ใน repo | — (branch: prod) | Vol 6 · chat-center-api |
| OBS-OCRAPI-01 | vtrc-ocr-api | Medium | Health check ตรวจแค่ process.uptime()/memoryUsage() ไม่ตรวจ dependency จริง | services/health.service.js:1-24 | Vol 9 · vtrc-ocr-api |
| OBS-REPORTLOG-01 | report-log | Medium | ไม่มี error handling ใด ๆ ใน IIFE หลักหรือ readData/setData | app.js:85-88,208-219 | Vol 9 · report-log |
| OBS-RECRUIT-01 | recruitment-api | Medium | console.log ปนกับ structured logger (71 จุดทั่ว repo) | — (branch: prod) | Vol 6 · recruitment-api |
| OBS-BENEFIT-01 | benefit-api | Medium | console.log ปนกับ I3GatewayLogger — log payload เต็มรวม PII ออกไปที่ production stdout | payments.service.ts:82,85,90,145,265... (branch: prod) | Vol 6 · benefit-api |
| OBS-BENEFIT-02 | benefit-api | Medium | ไม่มี health check endpoint เฉพาะ แม้ import TerminusModule ไว้แล้ว | app.module.ts:34 (branch: prod) | Vol 6 · benefit-api |
| OBS-2WAYMTBO-01 | 2way-meeting-backoffice | Medium | ชื่อ env variable ไม่สื่อความหมายตรงปลายทางจริง (appConnectChatAPI ไม่ได้เชื่อม chat-center) | next.config.js env block | Vol 5 · 2way-meeting-backoffice |
| OBS-MOBILE-01 | vtrc-mobile | Medium | ไม่มี crash reporting/error tracking SDK ใด ๆ — auth flow สำคัญ catch error แล้วไม่รายงาน | authSlice.js:423-425,613-624,662-673 | Vol 8 · vtrc-mobile |
| OBS-MTVTRC-01 | meeting-vtrc-api | Medium | Sentry DSN hardcode ตรงในซอร์สไม่ผ่าน env — ผูกทุก environment เข้า project เดียวกัน | app.ts:80 | Vol 7 · meeting-vtrc-api |
| OBS-MTBONEW-01 | meeting-backoffice-new | Medium | ทั้ง repo มีแค่ 6 commit ทั้งหมดในวันเดียว ข้อความ commit กว้าง ๆ ไม่มี ticket reference | git log --oneline | Vol 7 · meeting-backoffice-new |
| OBS-RECRUIT-02 | recruitment-api | Low | Test coverage กระจุกอยู่เฉพาะบางโมดูล (24 ไฟล์ .spec.ts) — ไม่ยืนยันความลึกของ assertion | — (branch: prod) | Vol 6 · recruitment-api |