Skip to content

3.3.9 · Scorecard, ownership, what's next

บทสุดท้ายสรุปสถานะของ centralize-api ในรูปแบบ scorecard, ownership mapping, เปรียบเทียบกับ services อื่นใน platform, และแนะนำขั้นตอนต่อ


Scorecard

มิติScoreหลักฐาน
Functional correctness6/10endpoints ทำงานได้ แต่ขาด test (บท 3.3.1 — dead spec/e2e)
Security2/104 Critical + 7 High (บท 3.3.8)
Code quality4/10CTE copy-paste (3.3.4), profanity (3.3.4), dead code (3.3.1)
Maintainability4/10TypeScript strict ปิด (3.3.1), dependency outdated (3.3.1)
Documentation5/10Swagger setup มี แต่ response type ไม่ annotated (3.3.7)
Observability3/10logger ไม่ rotate (3.3.7), ไม่มี metric/trace
Production-readiness3/10ไม่มี helmet, compression, health endpoint (3.3.7)
Test coverage1/10spec/e2e fail/dead (3.3.1)
Total3.5/10

อ่านเพิ่มเติม — scorecard นี้ base บท evidence ในบท 3.3.1–3.3.8 score ต่ำเพราะ auth bypass + credential leak ที่ยังไม่แก้


Ownership — ใครรับผิดชอบอะไร

centralize-api ไม่มี CODEOWNERS file ใน repo → สรุปจาก package.json author + รูปแบบ code

ส่วนรับผิดชอบ (推测)หลักฐาน
API surface (17 endpoints)ทีม VTRC APIDTO naming convention เหมือน vtrc-api
HRMI integration (raw SQL)ทีม VTRC API + ทีม HRMI (CU/RC)raw SQL อ้าง HRMI tables, CASE WHEN mapping SourceDB → code
Auth (JWT, guard)ทีม VTRC APIcopy pattern จาก starter template
Deployment (Docker, CI/CD)DevOpsDockerfile + npm scripts
HRMI schema (tables, views)ทีม CU/RC (ไม่ใช่ทีม VTRC)HRMI = HR Management Information ของจุฬา/สภากาชาด

การสื่อสารข้ามทีม

สถานการณ์ทีมที่ต้องประสาน
เพิ่ม endpoint ใหม่ทีม VTRC API (caller: vtrc-api)
เปลี่ยน HRMI table structureทีม CU/RC (HRMI owner)
เพิ่ม index บน HRMI tableทีม CU/RC
เปลี่ยน MSSQL serverDevOps + ทีม VTRC API
แก้ security debt (บท 3.3.8)ทีม VTRC API + DevOps

เปรียบเทียบกับ services อื่นใน platform

Aspectcentralize-apicu-central-apivtrc-api2way-api
StackNestJS + TypeORM + MSSQLNode + Sequelize + MSSQL/LDAPNode + Apollo GraphQL + Sequelize + MariaDB/MSSQLNestJS + Mongoose + MongoDB
Lines of code~2,500~5,000+~30,000+~10,000+
Endpoints17 REST~50 RESTGraphQL (hundreds of resolvers)~80 REST
AuthJWT guard bypass (@Public)apiKey header@auth(accessRole) directive + apiKeyNestJS JWT guard (works)
Test coverage1/101/101/103/10
Security debt22 issuesTBD~30+ issues (Vol 3.1)~10 issues (Vol 5)
Documentation depth (v2)บท 3.3.1–3.3.9 (this)บท 3.2 (planned)บท 3.1 (planned)บท 5 (planned)

จุดสำคัญ

  • centralize-api มีขนาดเล็กที่สุดในกลุ่ม legacy core → ใช้เวลา remediate น้อยที่สุด
  • security posture แย่ที่สุดในกลุ่ม เพราะ auth bypass ทั้งระบบ
  • แต่ risk ต่ำกว่า vtrc-api เพราะเป็น backend-to-backend เท่านั้น (ไม่ internet-facing โดยตรง)

Migration / modernization path

ระยะสั้น (1–3 เดือน)

ขั้นActionImpact
1Fix Phase 1 (บท 3.3.8 §"Phase 1 — minimal fix")ลด critical risk
2ลบ dead code (UserEntity, EmployeeResponseDto, spec/e2e ที่พัง)ลด confusion
3เปิด TypeScript strict + แก้ type errorลด runtime bug
4เพิ่ม health endpoint + helmet + compressionproduction-ready

ระยะกลาง (3–6 เดือน)

ขั้นActionImpact
5Implement real JWT validation (lookup user in DB, check revoked)close auth bypass
6เปลี่ยน logging: ['query']logging: ['error'] + redact PIIprevent PII leak
7อัปเกรด NestJS 8 → 10, moment → date-fnssecurity patch + ลด bundle size
8เพิ่ม unit test สำหรับ service layer (target 50% coverage)confidence ในการแก้ bug

ระยะยาว (6–12 เดือน)

ขั้นActionImpact
9Refactor CTE copy-paste → helper function หรือ HRMI viewDRY + ลด bug surface
10สร้าง entity สำหรับทุก table ที่ใช้บ่อยtype safety + ลด raw SQL
11เพิ่ม OpenTelemetry tracingobservability
12พิจารณา merge เข้า vtrc-api ถ้า caller มีอันเดียวลด service count

Open questions — สิ่งที่ยังไม่ชัดเจน

คำถามเหตุผลที่ยังไม่กระจ่าง
Caller จริงของ centralize-api คือใคร?ไม่มี doc ระบุชัด vtrc-api มี env END_POINT_CENTRALIZE แต่ไม่มี evidence ใน code ว่าใช้จริง
auth_user table อยู่ที่ไหน?UserEntity อ้างถึง แต่ table ไม่มีใน HRMI — dead code?
centralize/ folder ใน vtrc-api เกี่ยวข้องกับ centralize-api ไหม?ชื่อคล้ายกัน แต่ข้อมงใน vtrc-api ชี้ไปยัง cu-central-api ไม่ใช่ NestJS centralize-api
ทำไม source code มี fuckQuery?อาจเป็น frustration ตอน debug → ควรถาม original author
ทำไม secret key คือ 127.0.0.1?placeholder ที่ไม่ได้ replace?
HRMI tables มี index บน SourceDB ไหม?ไม่มี doc — ต้อง inspect HRMI database โดยตรง
TypeORM ทำไมถึง register entity ทั้ง center + NBC เข้า center connection?glob pattern *.entity match ทั้งคู่ (บท 3.3.2, 3.3.6)

V1 corrections — แก้ไขจาก V1 documentation

บทนี้รวม drift ที่พบระหว่าง V1 documentation (docs-v1-archive/volume-05-centralize-api/) กับ source code ปัจจุบัน (centralize-api/)

V1 claimActual (current code)Chapter
V1: addServer() ×4, setDescription(''), addTag() ×4จริง: addServer() ×2 (env-driven PORT), setDescription('Centralize API'), ไม่มี addTag3.3.7
V1: Dockerfile 3-stage mixed yarn/npmจริง: 2-stage exclusively yarn, COPY .env ./ explicit3.3.2
V1: hrTimeTemp.dto.tsShiftTimeType/ResponseGetShiftTimeWithWork class, timeIn/timeOut Dateจริง: เป็น interface, timeIn/timeOut string3.3.3
V1: SourceDB non-nullable on EmployeeLevel/TechnicalPositionจริง: nullable ทุก entity3.3.6
V1: HttpExceptionFilter ~46 LOC verbose, logs path/method/timestampจริง: 26 LOC คืน { statusCode, message }, log เฉพาะ message3.3.7
V1: hrpayslip service [...body.empCode] spread operatorจริง: spread operator ยังอยู่ แต่ line number เปลี่ยน3.3.4
V1: ไม่ได้พูดถึง RootObject interface ใน app.controller.tsจริง: มี RootObject interface unused3.3.3

สรุปประเด็นสำคัญของบททั้งหมด (3.3.1–3.3.9)

ขนาดของระบบ

  • ~2,500 LOC TypeScript
  • 17 REST endpoints (1 ปัจจุบันใช้ + 16 employee/HR)
  • 6 live entity + 1 dead (UserEntity)
  • 2 MSSQL databases (center + NBC) → cross-database query ผ่าน raw SQL
  • 1 caller confirmed (vtrc-api ผ่าน END_POINT_CENTRALIZE env) — caller อื่นยังไม่ยืนยัน

Architecture

  • NestJS module pattern → 1 module per business domain
  • Service layer ใช้ raw SQL เป็นหลัก (TypeORM active record เป็นรอง)
  • Multi-tenant sharding ผ่าน SourceDB column
  • No GraphQL, no message queue → simple REST API

Security posture

  • Critical: .env commit, Dockerfile copy .env, JWT secret = 127.0.0.1, @Public() บนทุก route
  • High: CORS wildcard, JWT validation ผิด, PII log, hardcoded IP, profanity, TLS verify off
  • Medium: ไม่มี rate limit, helmet, health endpoint, entity coverage ไม่ครบ, TypeScript strict ปิด, deps outdated
  • Low: dead code, CTE copy-paste, console.log

Trust model

centralize-api ออกแบบเป็น internal-only → trust network layer → ปัญหา security ทั้งหมด "less critical" ในสภาพแวดล้อมที่ trust แต่จะ "catastrophic" ถ้า expose ออก internet โดยไม่แก้

Action items ที่จำเป็น

  1. Phase 1 — ลบ .env, ลบ COPY .env, ลบ @Public() บน PII endpoint (ภายใน 1 สัปดาห์)
  2. Phase 2 — close HIGH issues (ภายใน 1 เดือน)
  3. Phase 3 — modernize (TypeScript strict, deps upgrade, tests) (backlog)

Dependency graph — inbound + outbound

เพื่อให้เห็นภาพ risk ของการเปลี่ยนแปลง centralize-api นี่คือ dependency ที่เกี่ยวข้อง

Inbound (อะไรเรียก centralize-api)

CallerProtocolEndpointEvidence
vtrc-apiHTTP RESTEND_POINT_CENTRALIZE envvtrc-api/api/.env.example:36-37 (Vol 3.1)
อื่น ๆไม่ยืนยันไม่มี doc ระบุ

หมายเหตุ — ชื่อ env END_POINT_CENTRALIZE ใน vtrc-api อาจชี้ไปยัง cu-central-api (NestJS ตัวเดิม) หรือ centralize-api (ตัวใหม่) ไม่ชัดเจน — ต้อง verify ใน Vol 3.1

Outbound (centralize-api เรียกอะไร)

CalleeProtocolPurposeEvidence
MSSQL dbHRMI_CenterTDS (port 1433)HR data ของ RC Centralcentralize-api/src/app.module.ts:25-40
MSSQL dbHRMI_Center_NBCTDS (port 1433)HR data ของ RC NBCcentralize-api/src/app.module.ts:44-58
(ไม่มี HTTP outbound)ไม่มี HTTP client ใน codebase

→ centralize-api เป็น "leaf service" — ไม่เรียก service อื่น จึงไม่มี risk จาก downstream failure (นอกจาก MSSQL เอง)

Failure modes ที่คาดการณ์ได้

FailureSymptomSeverity
MSSQL dbHRMI_Center downทุก endpoint ที่ query center → 500High
MSSQL dbHRMI_Center_NBC downendpoint ที่ query NBC → 500, แต่บาง endpoint cross-join → 500 ด้วยHigh
Network latency center ↔ NBCendpoint ที่ cross-database join ช้าMedium
Disk full จาก log fileทุก endpoint ค่อย ๆ ช้า → eventually failMedium
JWT secret mismatch กับ callerแต่เพราะ @Public() bypass → ไม่กระทบNone (ปัจจุบัน)

Cost estimate — remediation effort

ประมาณการ effort สำหรับแต่ละ phase (สมมุติ 1 dev + รู้จัก NestJS + MSSQL)

PhaseItemsEffort (dev-days)Risk if skip
Phase 1 — minimal fixCRIT-01, 02, 03, 043–5credential leak, auth bypass ongoing
Phase 2 — high priorityHIGH-01 → 077–10PII leak, MITM, etc.
Phase 3 — mediumMED-01 → 0610–15regressions, slow incident response
Phase 4 — low + cleanupLOW-01 → 053–5maintainability drift
Total23–35 dev-days(~1.5–2 months for 1 dev)

หมายเหตุ — ตัวเลขนี้ไม่รวม test writing ซึ่งเป็น prerequisite ของบาง fix (เช่น การลบ @Public() ต้องมี integration test ก่อนเพื่อยืนยันว่า JWT flow จริง ๆ ทำงาน)


Recommendation — ควร decommission ไหม?

ตัวเลือกข้อดีข้อเสีย
Fix in place (Phase 1–3)เก็บ separation of concerns, ใช้ stack ที่ทีมรู้จักใช้เวลา 1.5–2 เดือน
Merge เข้า vtrc-apiลด service count, ใช้ auth + logger ของ vtrc-apivtrc-api ใหญ่แล้ว, migration risk
Merge เข้า cu-central-apistack คล้ายกัน (Node + MSSQL)cu-central-api มี debt ของตัวเอง (Vol 3.2)
Decommission + ไม่แทนที่ถ้า caller จริง ๆ มี vtrc-api ตัวเดียว → vtrc-api อาจไป query HRMI ตรง ๆ ได้ต้อง verify caller ก่อน

→ แนะนำ — ทำ Phase 1 + 2 ก่อน (fix security debt) แล้วค่อยตัดสินใจเรื่อง merge/decommission หลังมี test coverage + ownership ชัดเจน


Definition of done — เกณฑ์ว่า centralize-api "แก้แล้ว"

เกณฑ์ที่จะใช้ตัดสินใจว่าบท 3.3 นี้ outdated แล้ว (คือ dev แก้ code จน score ดีขึ้น)

เกณฑ์Targetปัจจุบัน
Critical issues04
High issues07
Test coverage≥50%~0%
TypeScript strictเปิดปิด
Health endpointมีไม่มี
.env in gitไม่มีมี
Auth bypassปิดเปิด

→ เมื่อทุกเกณฑ์ผ่าน → รีวิวใหม่ + ปรับ scorecard


อ้างอิง

  • V1 documentation: docs-v1-archive/volume-05-centralize-api/ (read fully before writing — 10 files, ~2,744 lines)
  • Source code: centralize-api/ (read + verified against V1)
  • Style guide: docs/_style/style-guide.md
  • Workspace structure: .cursor/rules/workspace-structure.mdc
  • Related volumes — Vol 3.1 (vtrc-api), Vol 3.2 (cu-central-api), Vol 3.4 (legacy core data flow)

จบบทที่ 3.3

บทต่อไป — 3.4 cu-central-api (Vol 3.4) และ 3.5 vtrc-api (Vol 3.5) — ใช้รูปแบบ depth เดียวกับบท 3.3 นี้