vtrc-common Deep Dive
vtrc-common (branch: prod, 58 tracked files) เป็น NestJS 9 standalone HTTP microservice ที่ให้บริการ master data และไฟล์กลาง 3 domain — ที่อยู่ไทย (จังหวัด/อำเภอ/ตำบล/รหัสไปรษณีย์), รายชื่อธนาคาร+สาขา, และอัปโหลด/ลบ/ดาวน์โหลดไฟล์แบบ base64 — ให้ frontend และ NestJS service อื่นเรียกผ่าน REST แทนที่จะ implement ซ้ำในแต่ละ repo
ข้อสันนิษฐานเดิมคลาดเคลื่อน — เอกสาร workspace รุ่นก่อนอธิบายว่า vtrc-common เป็น "shared NestJS library ที่ service อื่น npm install แล้ว import โค้ด" แต่หลักฐานจากโค้ดชี้ตรงกันข้าม: มี Dockerfile + .env + MSSQL DB ของตัวเอง + consumer เรียกผ่าน HTTP URL เท่านั้น ไม่มี repo ใดใน monorepo ประกาศ vtrc-common / vtrc-common-v1 เป็น npm dependency — ดูรายละเอียดใน 02 · Core pipeline
ชื่อใน package.json คือ vtrc-common-v1 (vtrc-common/package.json (branch: prod):2) — ไม่ตรงกับชื่อโฟลเดอร์ vtrc-common (pattern เดียวกับ repo อื่นในกลุ่ม Domain ที่ชื่อ package ≠ ชื่อ deploy)
Stack
| ส่วน | ค่า | หลักฐาน |
|---|---|---|
| Framework | NestJS 9 (@nestjs/core ^9.0.0) | vtrc-common/package.json (branch: prod):27-29 |
| ภาษา | TypeScript ^4.7.4 | vtrc-common/package.json (branch: prod):71 |
| ORM | TypeORM ^0.3.11 บน MSSQL — named connection main | vtrc-common/package.json (branch: prod):47, vtrc-common/src/app.module.ts (branch: prod):18-37 |
| DB driver | mssql ^9.1.1 | vtrc-common/package.json (branch: prod):40 |
| Auth | Passport JWT (passport-jwt ^4.0.0) + global JwtAuthGuard — แต่เกือบทุก route ถูก mark @Public() | vtrc-common/libs/jwt/jwt-auth.guard.ts (branch: prod):5-41, vtrc-common/src/main.ts (branch: prod):27 |
| Validation | class-validator ^0.14.0 + global ValidationPipe (whitelist + forbidNonWhitelisted) | vtrc-common/package.json (branch: prod):38, vtrc-common/src/main.ts (branch: prod):28 |
| Swagger | @nestjs/swagger ^6.1.3 ที่ {BASE_PATH}docs | vtrc-common/package.json (branch: prod):32, vtrc-common/src/main.ts (branch: prod):35-36 |
| File helpers | mime-types, uuid, moment, fs/fs-extra (ผ่าน runtime) | vtrc-common/src/modules/file/file.service.ts (branch: prod):9-18 |
| Package manager | yarn (Dockerfile รัน yarn) | vtrc-common/Dockerfile (branch: prod):11 |
| Package name | vtrc-common-v1 (private, UNLICENSED) | vtrc-common/package.json (branch: prod):2-7 |
Entry point และพอร์ต
- Entry point:
vtrc-common/src/main.ts (branch: prod):12-41—bootstrap()สร้าง Nest app พร้อมI3GatewayLogger, ตั้ง global prefix เป็น`${BASE_PATH}api/v1`, เปิด body parser limit50mb(รองรับ base64 ไฟล์ใหญ่), ผูกHttpExceptionFilter+JwtAuthGuard+ValidationPipe, เปิด CORSorigin: '*', และ mount Swagger - พอร์ต runtime อ่านจาก
ConfigService.get('port')fallback3000(vtrc-common/src/main.ts (branch: prod):19) — ค่าจริงจาก.envคือPORT=9310(vtrc-common/.env (branch: prod):5) BASE_PATH=vtrc-common/(vtrc-common/.env (branch: prod):3) → HTTP path จริงคือ/vtrc-common/api/v1/*SERVER_URL=https://vtrcapi.redcross.or.th/(vtrc-common/.env (branch: prod):4)- Swagger UI เปิดที่
`${BASE_PATH}docs`(vtrc-common/src/main.ts (branch: prod):36) — ไม่มีการปิดด้วย env flag
รวมกันแล้ว service นี้ถูกเข้าถึงจากภายนอกผ่าน https://vtrcapi.redcross.or.th/vtrc-common/api/v1/* (pattern nginx path-based routing ของแพลตฟอร์ม) — ตรงกับ URL ที่ hardcode ใน frontend (vtrc-web/src/utils/auth.js:214-220, vtrc-rc-backoffice/src/config/axios-common.js:6-8)
Database topology
vtrc-common ใช้ 1 MSSQL database + local disk:
| Store | env | ค่า | ใช้ทำอะไร |
|---|---|---|---|
TypeORM main | DB_* | database vtrc_common ที่ 10.188.128.61:1433 | master ที่อยู่ (m_province / m_aumphur / m_tumbol / m_zipcode), bank, file |
| Local disk | MULTER_DEST | ./uploads (path จริงในโค้ดคือ process.cwd()/uploads/...) | binary ของไฟล์ที่อัปโหลดผ่าน /file/save |
หลักฐาน — vtrc-common/src/app.module.ts (branch: prod):18-37, vtrc-common/config/configuration.ts (branch: prod):1-11, vtrc-common/.env (branch: prod):7-14, vtrc-common/src/modules/file/file.service.ts (branch: prod):53-58
Connection main ตั้ง synchronize: false (vtrc-common/src/app.module.ts (branch: prod):28) — schema เปลี่ยนด้วย SQL script ในโฟลเดอร์ sql/ เท่านั้น (ดู 03 · Persistence)
Deploy artifact
Dockerfilemulti-stage บนnode:18-alpine(develop→production):yarn→yarn build→ copy.env+dist+package.json→CMD yarn start:prod(vtrc-common/Dockerfile (branch: prod):1-25)- สำคัญ — stage
productioncopy.envเข้า image โดยตรง (vtrc-common/Dockerfile (branch: prod):19) → credential ที่ commit ใน git ถูก bake เข้า container docker-compose.ymlมี servicedev/prod(port9310:9310) + MariaDB local (legacy — runtime จริงใช้ MSSQL ตาม.env) บน network ภายนอกvtrc-api_default(vtrc-common/docker-compose.yml (branch: prod):1-46)bitbucket-pipelines.yml— CI บน branchprod/uat/develop/master: build → docker image → push GCR (vtrc-common/bitbucket-pipelines.yml (branch: prod):126-131) —yarn testถูก comment ปิด (:17)
สิ่งที่ควรรู้ก่อนอ่านบทถัดไป
- ไม่ใช่ npm library — ไม่มี
exportsfield สำหรับ publish, ไม่มี consumer ที่importclass จาก package นี้; consumer ทั้งหมดเป็น HTTP client - Auth เกือบไร้ผล — address/bank ทุก route เป็น
@Public(); filesave/deleteก็@Public();getFile/getFileArrayไม่มี@Public()แต่SECRET_KEYcommit ใน.envทำให้ forge JWT ได้ — ดู SEC-COMMON-01 - SQL injection ใน address — 2 เมธอด raw SQL interpolate
provCode/amphCodeจาก query string — ดู SEC-COMMON-02 และ 02 - Consumer จริง 4 ราย —
benefit-api(เฉพาะ/file/*),vtrc-mobile,vtrc-web,vtrc-rc-backoffice;job-scheduler-api/recruitment-apiมี env อย่างเดียว (vestigial) - Schema เคยอยู่ MariaDB (SQL script เดือน ก.พ.–มี.ค. 2023) แล้วย้ายมา MSSQL — ดู
sql/common_20230313_Convert_MariaDB_To_MsSql.sql
สารบัญ
| บท | หัวข้อ |
|---|---|
| 01 | Repository map — โครงสร้างไฟล์, module, endpoint surface |
| 02 | Core pipeline — bootstrap, auth, API ทุก module, SQL injection, consumer map |
| 03 | Persistence & integrations — entities, SQL migrate, disk layout, inbound callers |
| 04 | Scorecard + debt register |