Skip to content

5.9 · Scorecard + ownership + comparison

บทสุดท้ายของ Volume 5 สรุป centralize-api ในรูปแบบ scorecard เทียบกับมาตรฐาน NestJS production, ทบทวน ownership และ caller ที่ยังไม่ยืนยัน, และเปรียบเทียบกับ vtrc-api และ cu-central-api เพื่อให้เห็นตำแหน่งของ service ตัวนี้ในระบบ VTRC


Scorecard — ภาพรวมตามตัวชี้วัด

มิติคะแนนหมายเหตุ
Type safety2/5strictNullChecks: false, noImplicitAny: false, any ใช้แพร่หลาย
Test coverage0/5ไม่มี unit test จริง — empty spec + broken e2e
Documentation2/5Swagger doc พอใช้ แต่ response type ไม่ annotated + README เป็น starter default
Error handling1/5BadRequestException สำหรับทุก error, filter จับแค่ HttpException
Security1/54 Critical + 7 High (บท 5.8)
Production hardening1/5ไม่มี helmet, compression, health check, graceful shutdown
Dependency hygiene2/5outdated 2-3 major, moment deprecated, passport-local unused
Code organization3/5NestJS module pattern ชัดเจน แต่มี dead code + copy-paste CTE 4 ครั้ง
SQL safety4/5parameterized queries ทุกที่ ไม่พบ injection (ดีที่สุดในระบบ)
Schema migration5/5synchronize: false — TypeORM ไม่ alter HRMI ไม่มีความเสี่ยง
รวม21/50ต่ำ — service ทำงานได้แต่มี debt สะสมสูง

รายละเอียดตามมิติ

Type safety — 2/5

TypeScript ปิด strict checks ส่วนใหญ่ทำให้เสียประโยชน์หลักของภาษา ในระบบมี any กระจายอยู่ใน JwtStrategy, repositories ทั้ง 3, และ controller return types

→ NestJS + TypeScript โดยปกติให้ type safety สูง แต่ centralize-api ตั้งค่าทำให้กลายเป็น JavaScript ที่มี decorator

Test coverage — 0/5

ไม่มี unit test หรือ integration test จริง — ไฟล์ *.spec.ts และ *.e2e-spec.ts ที่มีเป็นโค้ดค้างจาก starter template ที่ไม่ได้เขียน logic อะไร

→ ทุก refactor เสี่ยงเพราะไม่มี safety net

Documentation — 2/5

Swagger UI (/docs) serve ได้แต่

  • response type ไม่ annotated → client ไม่ทราบ shape
  • description ของ service ว่าง (setDescription(''))
  • IP internal รั่วใน addServer
  • BearerAuth หลอก เพราะ guard bypass

README เป็น NestJS starter default — ไม่มีข้อมูล architecture, env vars, deploy

Security — 1/5

บท 5.8 ระบุช่องโหว่ 4 Critical + 7 High — ส่วนใหญ่ยังไม่ได้รับการแก้ไขใน production

ถ้า service ถูก expose ออก internet โดยตรง → data breach ทันที ปัจจุบันอาจรอดเพราะอยู่ใน private network แต่ก็เป็นอันตรายที่ซ่อนรอ

SQL safety — 4/5 (จุดเด่น)

parameterized queries ทุกที่ — ไม่มี string interpolation ของ user input ใน SQL ใด ๆ ทำให้ centralize-api เป็น service ที่ปลอดภัยจาก SQL injection ที่สุดในระบบ VTRC

ลด 1 คะแนนเพราะ WITH (NOLOCK) ทุกที่ทำให้ dirty read เป็นไปได้ (acceptable สำหรับ HR facade แต่ต้องเขียน doc)


Ownership + caller ที่ยังไม่ยืนยัน

ข้อเท็จจริงที่ตรวจสอบได้จาก code

  1. centralize-api รันบน port 3000 ด้วย REST API ที่ prefix /api
  2. vtrc-api มี config END_POINT_CENTRALIZE ใน .env.example:36 ชี้ไป http://localhost:8082/api/graphql (CLIENT_TARGET ตัวอย่าง)
  3. path /api/graphql ตรงกับ cu-central-api (Node 12 Apollo GraphQL) — CODE_DEFAULT APP_PORT=8080; ไม่ใช่ NestJS centralize-api (port 3000)
  4. ไม่พบ code ใน vtrc-api ที่เรียก /api/employee, /api/hrPaySlip, /api/hrTimeTemp ของ NestJS centralize-api โดยตรง

สาเหตุที่เป็นไปได้

#สมมุติฐานหลักฐานสนับสนุนหลักฐานคัดค้าน
Acentralize-api ตัวนี้เป็น service ที่ยังไม่เสียบใช้จริง (orphan)มี .env committed, มี Swagger doc → ดูเหมือนจะใช้แต่ไม่พบ caller — ทำไม commit แล้ว?
Bมี caller อื่นที่ไม่ใช่ vtrc-api (เช่น cu-central-api proxy ต่อ)cu-central-api เป็น Node 12 ที่อาจเรียก REST ของ centralize-api ผ่าน axios หรือ node-fetchไม่ได้ตรวจสอบ cu-central-api ในระดับนี้
Cenv ใน .env.example ไม่ตรงกับสภาพแวดล้อมจริงใน production.env.example เป็นตัวอย่าง dev — production อาจชี้ END_POINT_CENTRALIZE ไป port 3000 จริงแต่ถ้าเช่นนั้นควรมี .env.production ที่บอก
Dcentralize-api ตัวนี้เป็นเวอร์ชั่น rewrite ของ cu-central-api ที่จะมาแทนที่ทั้งสองอ่าน HRMI schema เดียวกัน, มี SourceDB pattern เดียวกันแต่ cu-central-api ใช้ GraphQL + LDAP auth ส่วน NestJS ใช้ REST + JWT — ไม่ใช่การแทนที่โดยตรง

คำแนะนำในการ verify

ก่อน refactor centralize-api ตัวนี้ ควรตรวจสอบให้แน่ใจว่า caller คือใครก่อน

  1. Log access — เปิด access log ของ centralize-api แล้วดูว่าในช่วง 7 วันมี request เข้ามาจาก IP ใดบ้าง
  2. ค้นหาในทุก repo — grep :3000/api/ หรือ centralize-api ในทุก source code ขององค์กร (รวม backoffice, internal tools)
  3. สอบถามทีม CU/RC — เพราะ HRMI schema เป็นของทีม CU/RC อาจทราบว่ามี caller ที่ไม่ได้เก็บใน VTRC repo
  4. ทดสอบด้วยการปิด service — ถ้าปิด centralize-api แล้ว feature ใดพัง → feature นั้นคือ caller

ถ้าไม่พบ caller ใด ๆ → อาจ safe to deprecate หรือ archive

ผลกระทบต่อการวางแผน refactor

สถานการณ์คำแนะนำ
ไม่พบ caller จริงอย่า refactor ทันที — อาจเป็นการเสียเวลา ให้ deprecate หรือ archive ก่อน
พบ caller 1-2 ตัวใน VTRCวางแผน coordinated refactor พร้อม caller
พบ caller ภายนอก VTRCต้องประสานงานข้ามทีมก่อน refactor ใด ๆ

เปรียบเทียบกับ vtrc-api และ cu-central-api

ตารางเปรียบเทียบโครงสร้าง

มิติvtrc-apicu-central-apicentralize-api
StackNode.js + Express + Apollo GraphQLNode.js + Apollo GraphQL + SequelizeNestJS + TypeORM + TypeScript
DatabaseMariaDB (Sequelize)MSSQL HRMI (Sequelize)MSSQL HRMI (TypeORM)
Port8081 /api/graphqlCODE_DEFAULT APP_PORT=8080 (CLIENT_TARGET ตัวอย่าง 8082; compose มัก 8000; EXPOSE 9000 ≠ listen)3000 /api/...
รูปแบบ APIGraphQL (hand-written schema)GraphQLREST + Swagger
AuthJWT + apiKey (custom)LDAP/AD + JWTJWT (แต่ bypass)
SourceDB shardingไม่มีมีมี
Cron jobsมี (node-schedule)มีไม่มี
Health endpointมี (ผ่าน /api)ไม่ชัดเจนไม่มี
Test coverageไม่มีจริงไม่มีไม่มี

บทบาทในระบบ VTRC

                       ┌─────────────────────────────┐
                       │      vtrc-web (front-end)   │
                       └─────────────────────────────┘


                  ┌─────────────────────────────────────────┐
                  │              vtrc-api (core)            │
                  │  - บริการหลักของทั้งสอง frontend         │
                  │  - เก็บข้อมูล welfare/leave/slip ใน MariaDB │
                  └─────────────────────────────────────────┘
                       │                       │
            (graphql)  │                       │ (REST/Swagger?)
                       ▼                       ▼ (caller ไม่ยืนยัน)
       ┌────────────────────────┐   ┌──────────────────────────┐
       │   cu-central-api       │   │   centralize-api (NestJS) │
       │  - ตัวกลาง auth LDAP   │   │  - HR facade read-only    │
       │  - HR data integration │   │  - 17 endpoints           │
       │  - multi-tenant sharding│   │  - auth bypass            │
       └────────────────────────┘   └──────────────────────────┘
                       │                       │
                       └───────────┬───────────┘

                       ┌────────────────────────┐
                       │   HRMI MSSQL           │
                       │  - dbHRMI_Center       │
                       │  - dbHRMI_Center_NBC   │
                       └────────────────────────┘

จุดสังเกต — vtrc-api เป็น caller ของ cu-central-api ที่ยืนยันแล้ว (ผ่าน END_POINT_CENTRALIZE) แต่ caller ของ centralize-api (NestJS) ยังไม่ยืนยัน

จุดเด่นที่ centralize-api มีเป็น unique

  1. TypeScript + NestJS — service ตัวเดียวในระบบที่ใช้ TypeScript จริงจัง (cu-central-api ก็เป็น Node 12 JavaScript)
  2. REST + Swagger — service ตัวเดียวที่มี interactive API documentation (vtrc-api และ cu-central-api ใช้ GraphQL ที่ต้องใช้ GraphQL Playground)
  3. DTO validation — class-validator + class-transformer ที่ตรวจ input ทุก request (vtrc-api ตรวจใน resolver เอง)
  4. SQL injection-safe — parameterized queries 100% (ดีที่สุดในระบบ)

จุดด้อยเมื่อเทียบกับ vtrc-api

มิติvtrc-apicentralize-api
AuthJWT + apiKey ทำงานจริงJWT bypass
Mutationมี mutation endpointไม่มี (read-only)
Business logicมี welfare/leave/slip logic มากมีเฉพาะ time attendance merge
Schema migrationมี syncModelToTablesynchronize: false
Cronมี 5+ jobsไม่มี

→ centralize-api มีขอบเขตแคบกว่า vtrc-api มาก ทำหน้าที่เป็น facade ฝั่งอ่านเท่านั้น


สรุป — บทบาทของ centralize-api ในระบบ VTRC

จากการวิเคราะห์ทั้ง Volume สรุปได้ว่า centralize-api มีลักษณะดังนี้

  1. เป็น HR master data facade — อ่าน HRMI MSSQL ผ่าน raw SQL parameterized queries อย่างปลอดภัย
  2. ขนาดเล็กและจำกัดขอบเขต — 17 endpoints ทั้งหมด read-only, ไม่มี cron, ไม่มี mutation
  3. ออกแบบด้วย NestJS + TypeScript — pattern ที่ทันสมัย แต่ configuration ปิด type safety ไว้มาก
  4. มี Swagger documentation — จุดเด่นที่ service อื่นไม่มี แต่ doc ไม่สมบูรณ์
  5. มี technical debt สูง — 4 Critical + 7 High severity security issues ที่ active
  6. Caller ยังไม่ยืนยัน — ใน source code ที่ตรวจสอบ vtrc-api ไม่ได้เรียกตรง ๆ อาจมี caller อื่นที่ไม่ได้เก็บใน repo

คำแนะนำสำหรับทีม

  • เร็วที่สุด — verify caller ก่อน (§"Ownership") แล้วค่อยวางแผน Phase 1 security fix
  • Phase 1 — แก้ 4 Critical (เปลี่ยน password, สุ่ม JWT secret, เปิด auth, ปิด query logging)
  • Phase 2 — แก้ 7 High + error handling refactor
  • Phase 3 — ปรับปรุงระบบสมัยใหม่ (upgrade dep, เปิด strict mode, เขียน test)
  • Phase 4 — เลือกว่าจะ keep service นี้, deprecate, หรือ merge เข้า cu-central-api

จบ Volume 5

Volume นี้เจาะ centralize-api ตั้งแต่ระดับไฟล์ไปจนถึง business logic และ security posture โดยมี file:line reference ครอบคลุมทุกประเด็นที่สำคัญ หากต้องการเจาะลึกเพิ่มเติมแนะนำ

  • Volume 3.4 — The centralize bridge ใน vtrc-api ที่เรียก cu-central-api (ชื่อโฟลเดอร์ centralize/ แต่ปลายทางคือ cu-central)
  • Volume 4 — cu-central-api ที่เป็น downstream จริงของ END_POINT_CENTRALIZE
  • Volume 8.1 + 8.9 — Persistence topology + Identity across databases ที่อธิบาย HRMI schema เต็มรูปแบบ