Skip to content

2.4 · การเชื่อมต่อกับระบบภายนอก

บทนี้แมประบบภายนอกทั้งหมดที่ VTRC พูดด้วย — แต่ละตัวเชื่อมอย่างไร ผ่านบริการไหน auth อะไร

ถ้าระบบใดระบบหนึ่งล่ม — บทนี้บอกว่า VTRC จะเจอ error แบบไหน และต้องแก้ที่ไหน


ภาพรวม — ระบบภายนอก 7 ตัว

                                  vtrc-api

       ┌──────────┬──────────┬───────┼────────┬──────────┬──────────┐
       │          │          │       │        │          │          │
       ▼          ▼          ▼       ▼        ▼          ▼          ▼
   HRMI/MSSQL  LDAP/AD     KBANK   SMS     Conicle     GCP        SMTP
   (HR data)  (identity)  (K-Cash) (OTP)  (training) (Drive+FCM) (email)
       │          │
       │          │  bind
       │          ▼
       │      cu-central-api ─── SFTP (file transfer)
       │           ▲
       │           │  GraphQL (END_POINT_CENTRALIZE)
       │           │
       └───────────┘

              │  (NestJS centralize-api ก็อ่าน HRMI ได้เช่นกัน
              │   แต่ caller จาก vtrc-api ยังไม่ยืนยัน — ดูบท 5.9)

         NestJS centralize-api (port 3000 REST)

สำคัญ — path ที่ vtrc-api ใช้จริงเมื่อต้องการ HR data คือ END_POINT_CENTRALIZE → cu-central-api GraphQL (CLIENT_TARGET ตัวอย่างอาจใช้พอร์ต 8082; CODE_DEFAULT ของ cu-central คือ APP_PORT=8080) ไม่ใช่ NestJS centralize-api


1. HRMI / MSSQL — source of truth ทาง HR

HRMI = HR Management Information ของสภากาชาด เป็น source of truth ของข้อมูลพนักงานทุกอย่าง (profile, ตำแหน่ง, เงินเดือน, สาขา, ผู้บังคับบัญชา)

เชื่อมผ่าน 2 ทาง (ทั้งคู่ไป MSSQL HRMI แต่ caller ไม่เหมือนกัน)

ทางบริการที่เชื่อมDatabaseConnectionCaller จาก vtrc-api
Production pathcu-central-apiDB_HR_NAME, DB_MASTER_DATA_NAME, DB_HRMI_CENTER_HIScu-central-api/main-api/src/connector.js:8-170 (Sequelize × 6)ใช่ — ผ่าน END_POINT_CENTRALIZE
NestJS facadecentralize-apidbHRMI_Center + dbHRMI_Center_NBCcentralize-api/src/app.module.ts:23-60 (TypeORM mssql × 2)ยังไม่ยืนยัน — ดู บท 5.9

รายละเอียด connection

  • cu-central-api เปิด pool 6 ตัว (db, dbHr, dbHrTemp, dbMasDb, dbHRMI_test, dbHRMI_Center_HIS) — cu-central-api/main-api/src/connector.js:8-170
  • ทุก pool ตั้ง max: 100 (ยกเว้น dbHrTemp ที่ 50) ดังนั้น cu-central-api เปิด connection ได้สูงสุด ~550 จาก process เดียว
  • NestJS centralize-api เปิด connection pool 2 ตัว (center + nbc) ไปที่ host เดียวกัน แต่ database ต่างกัน — centralize-api/src/app.module.ts:25,44

ระวัง — ถ้า MSSQL ล่ม → VTRC ไม่สามารถ

  • ยืนยันตัวตนพนักงานใหม่ (verifyEmpCodeLogin)
  • ดึงรายชื่อผู้อนุมัติการลา (chain อยู่ใน HRMI)
  • แสดงสลิปเงินเดือน, ภาษี, เวลาทำงาน

login ที่เคย login แล้วยังใช้ได้ (JWT ยังไม่หมดอายุ) แต่ action ใหม่ที่ต้อง query HRMI จะ fail


2. LDAP / Active Directory — identity ของจุฬา

LDAP ใช้สำหรับ verify password ของพนักงานที่ affiliated กับจุฬาลงกรณ์มหาวิทยาลัย (โรงพยาบาลจุฬาฯ)

เชื่อมผ่าน cu-central-apildapjscu-central-api/main-api/src/lib/auth/activeDirectory.connector.js:26-36

flow การ auth

1. cu-central-api bind service account (AD_USERNAME + AD_PASSWORD)
2. cu-central-api bind ด้วย DN + password ของ user
3. ถ้าผ่าน → mint JWT (ใน cu-central-api)
4. ส่ง JWT กลับ vtrc-api ผ่าน centralize bridge

ระวัง

  • TLS verification ปิดอยู่ (rejectUnauthorized: false ที่ activeDirectory.connector.js:21) — LDAP ไม่ได้ตรวจ cert
  • AD username ที่ใช้ bind มาจาก CRC64 ของ identityCard (auth.controller.js:226-230) — CRC64 ไม่ใช่ cryptographic hash เลย collision ได้
  • ถ้า AD_IS_ENABLED=0 (default ใน config.js:50) → bindAdWithUserAndPassword return null ทันที → ใครก็ login ผ่าน AD ไม่ได้

3. KBANK K-Cash — ระบบจ่ายเงินสวัสดิการ

KBANK รับไฟล์ batch (KBank_welfare.txt) ประมวลผล T+1 ถึง T+3 วันทำการ แล้วส่งไฟล์ผลกลับมา

เชื่อมผ่าน ไม่มี API — เป็น manual file exchange

1. HR เลือกรายการใน backoffice → vtrc-api generate ไฟล์ .txt + .xlsx
2. HR download zip จากระบบ (ผ่าน fetchUrlExportWdHospital)
3. HR เอาไฟล์ไป upload ที่หน้าเว็บ K-Cash ของธนาคาร ด้วยมือ
4. KBANK ประมวลผล (T+1 ถึง T+3 วันทำการ)
5. HR download ไฟล์ผลจาก K-Cash
6. HR upload ไฟล์ผลเข้า vtrc-api → importUpdateStatus(file)
7. vtrc-api parse ไฟล์ + map status → update WDHospital + ส่ง notification ให้พนักงาน

จุดที่เชื่อมในโค้ด

  • Export — vtrc-api/api/src/routes.js:772-901 (REST /wdHospital/export)
  • Import — vtrc-api/api/src/routes.js (ค้นหา importUpdateStatus)
  • Status mapping — vtrc-api/api/src/config.js:488-519 (statusKcash — code 6/7/8/9/10)

ระวัง — ไม่มี cron อัตโนมัติ ถ้า HR ลืม upload ไฟล์ผล → สถานะพนักงานจะค้างที่ "exported" ตลอดไป


4. SMS — OTP และ notification

SMS gateway อยู่ที่ SMS_GATEWAY_URL + SMS_GATEWAY_KEY (cu-central-api/main-api/src/lib/sms.js:29-61)

เชื่อมผ่าน cu-central-api ส่ง HTTP POST ไปยัง gateway

เคสที่ใช้ SMS

  • OTP ตอน register / reset password (cu-central-api/main-api/src/lib/otp/sendOtp.js:74-106)
  • OTP TTL 15 นาที (SMS_OTP_EXPIRE_MINUTES default 3 นาที จาก config.js:74)
  • ส่งได้ใหม่ทุก 30 วินาที (SMS_RESENT_SECONDS)

ระวัง

  • ถ้า env SMS_SANDBOX_PHONE_NUMBER ตั้งไว้ → ทุก SMS จะถูกส่งไปเบอร์นั้นแทน (sms.js:14-16) — เอาไว้ทดสอบ staging แต่ถ้าลืมปิดใน prod พนักงานจะไม่ได้รับ OTP จริง
  • vtrc-api เองก็มี stub /ais-smsgw (vtrc-api/api/src/routes.js:990-993) แต่แค่ echo OK ไม่ได้ทำอะไรจริง

5. Conicle — ระบบ training ภายนอก

Conicle เป็น LMS (Learning Management System) ภายนอก ที่ต้อง sync รายชื่อพนักงานไปทุกวัน

เชื่อมผ่าน SFTP — cu-central-api/main-api/src/lib/transferFile/transferFile.class.js:1-60

flow

1. cron 03:40 ทุกวัน → transferFileToConicle('long')
   (cu-central-api/main-api/src/cron.js:21-23)
2. query รายชื่อพนักงานทั้งหมดจาก HRMI (limit 999,999)
3. generate ไฟล์ .xlsx (พนักงาน + org unit)
4. SFTP upload ไปที่ Conicle server
5. log ผลใน Models.ConicleFileLog

ระวัง

  • /api/conicle/longterm endpoint (cu-central-api/main-api/src/routes.js:11-19) ไม่มี auth — ใครก็ยิง POST แล้ว trigger SFTP push ได้
  • ไฟล์ที่ push มี identityCard + birthDate ของพนักงานทั้งหมด — ถ้า SFTP creds รั่ว เท่ากับ PII leak

6. GCP — file storage + push notification

GCP ให้บริการ 2 อย่าง

  • Google Drive — เก็บไฟล์แนบ (เอกสารลา, ใบเสร็จ)
  • Firebase Cloud Messaging (FCM) — push notification ไปมือถือ

เชื่อมผ่าน vtrc-apigoogleapis / firebase-admin

ไฟล์เชื่อมต่อ

  • vtrc-api/vtrc-gcp-sa-key.json — service account key (committed to repo — ห้าม log ห้าม exfiltrate)
  • vtrc-api/api/src/lib/firebase/ — module สำหรับส่ง FCM

ระวัง — service account key committed อยู่ใน git ถ้าทำ security audit ต้อง rotate key + ย้ายเก็บที่ secret manager


7. SMTP — ส่ง email

ใช้ nodemailer — เชื่อมจากทั้ง vtrc-api และ cu-central-api

เคสที่ใช้ email

  • แจ้งเตือน HR เมื่อมี action สำคัญ
  • ส่งใบเสร็จ / เอกสารทางการเงิน

ไฟล์

  • cu-central-api/main-api/src/lib/mailer/email.js:1-107
  • ใช้ email-templates library — templates อยู่ใน cu-central-api/main-api/email-templates/

ระวัง

  • ถ้า env EMAIL_TLS_REJECT_UNAUTHORIZED=false ตั้งไว้ → TLS verification จะปิด
  • EMAIL_BCC_RECEIVE_BACKUP ถ้าตั้ง → ทุก email จะ BCC ไปที่เบอร์นี้ด้วย

ตารารางสรุป contract

ระบบProtocolAuthServiceEndpoint
HRMI MSSQLTCP 1433 (SQL)DB credentialscentralize-api, cu-central-apicentralize-api/.env:7-10
LDAP/ADTCP 389/636 (LDAP)service bind + user bindcu-central-apicu-central-api/main-api/src/lib/auth/activeDirectory.connector.js:26-36
KBANK K-CashFile exchange (manual)vtrc-api (generate + parse)vtrc-api/api/src/routes.js:772-901
SMSHTTPS POSTapiKey bodycu-central-apicu-central-api/main-api/src/lib/sms.js:29-61
ConicleSFTPusername/passwordcu-central-apicu-central-api/main-api/src/lib/transferFile/transferFile.class.js:5-19
GCP DriveHTTPSservice account JSONvtrc-apivtrc-api/api/src/lib/firebase/
GCP FCMHTTPSservice account JSONvtrc-api(เดียวกับ Drive)
SMTPSMTPS / SMTPuser/passcu-central-api, vtrc-apicu-central-api/main-api/src/lib/mailer/email.js:1-107
SSO จุฬาHTTPS + basic authSSO_USERNAME / SSO_PASSWORDcu-central-apicu-central-api/main-api/src/lib/sso/sso.js:103-126

เคล็ดลับตอนทำงานจริง

ลำดับการล่มที่เจอบ่อย

จากประสบการณ์ — ลำดับความถี่ที่ระบบภายนอกล่ม

  1. LDAP/AD — เพราะ TLS verification ปิดอยู่ และมักมีปัญหาเรื่อง cert หมดอายุ
  2. SMS gateway — เคยมีเรื่อง quota เต็ม หรือ gateway ไม่ตอบ
  3. MSSQL — connection pool เต็ม (เพราะมีหลาย pool เปิดพร้อมกัน)
  4. KBANK — ไม่ใช่ "ล่ม" แต่ "ช้า" (T+1 ถึง T+3)
  5. GCP / SMTP — แทบไม่เคยล่ม

ตอน debug "OTP ไม่ถึง"

อย่าเริ่มที่โค้ด ให้เริ่มที่

  1. เบอร์โทรใน HRMI ถูกไหม — VTRC อ่านจาก HRMI ไม่ใช่จากตัวเอง
  2. SMS_SANDBOX_PHONE_NUMBER ตั้งไว้ไหม — ถ้าตั้ง OTP จะถูกเบี่ยงไปเบอร์นั้น
  3. OTP หมดอายุไปแล้วไหม (default 3 นาที) — ถ้า user รอนานเกินไป OTP จะ invalid

อย่าทำ assumed trusted ระหว่าง internal services

แม้ vtrc-apicu-central-api จะอยู่ใน internal network แต่ auth ยังใช้ API_CENTRALIZE_KEY ที่ static — ถ้าเครื่องหนึ่งโดน compromise มันสามารถเรียกอีกเครื่องได้ทันที

ถ้าทำ modernization — ควรเปลี่ยนเป็น mTLS หรือ short-lived token แทน


ขั้นตอนถัดไป

ไป บท 2.5 Data flow + caching