Skip to content

Volume 3 · vtrc-api Deep Dive

เล่มนี้เจาะลึกที่ตัว vtrc-api ตัวเดียว — service แกนกลางที่ทุก request ทั้งฝั่งพนักงานและฝั่ง HR ต้องผ่าน ถ้า Volume 2 เล่า "มีกี่ส่วนและวิ่งเข้าหากันอย่างไร" Volume 3 ตอบ "ในแต่ละส่วนเกิดอะไรขึ้นบ้างเป็นบรรทัดๆ"

เป้าหมายคืออ่านจบแล้วเปิดไฟล์ไหนก็รู้ว่ามันอยู่ตรงไหนของ pipeline และจะไป track bug ต่อที่ไหน


ใครควรอ่าน

  • Engineer ที่จะแก้ backend — อ่านตามลำดับ 3.1 → 3.10
  • Engineer ที่ debug ปัญหา auth/session — ข้ามไป 3.2 กับ 3.3 ก่อน แล้วย้อนมา 3.5
  • Engineer ที่ debug ปัญหา PDF/Excel/file download — เริ่มที่ 3.7
  • Engineer ที่จะเขียน cron หรือ background job ใหม่ — เริ่มที่ 3.8
  • Engineer ที่เจอ "transaction ไม่ roll back" — อ่าน 3.5 ก่อน (มี bug ระบบ-wide)
  • Architect ที่วางแผน modernize — อ่าน 3.4 กับ 3.10 จะเห็นจุดที่ควรเริ่มก่อน

สิ่งที่ Volume 3 ไม่ทำ

  • ไม่เล่า business rule ของแต่ละ domain (leave, welfare, fund) ลึก — นั่นอยู่ใน Volume 12 Business Logic
  • ไม่ list schema ทุกตาราง — นั่นอยู่ใน Volume 9 Data Model
  • ไม่ลง security hole แบบเจาะลึกพร้อม exploit — นั่นอยู่ใน Volume 10 Security
  • ไม่ให้ API reference แบบ operation-by-operation — นั่นอยู่ใน Volume 11 API Reference

เล่มนี้ focus ที่ structure และ execution path ของ vtrc-api ไม่ใช่ semantic ของแต่ละ field


ข้อตกลงเบื้องต้นที่ต้องรู้

อ่านมาถึงตรงนี้แล้วควรเคยผ่าน

ถ้าข้ามมาเล่มนี้ก่อนจะงงเรื่อง device key, apiKey header, JWT, APP_TYPE, และทำไม frontends ถึงไม่ยิง cu-central-api โดยตรง


ภาพรวม vtrc-api ใน 1 รอบ

Browser ─► Nginx ─► ApolloServer (Express)

                    ├─ context()         ← gate #1: apiKey ต้องตรง API_DEVICE_KEY
                    │                    ← gate #2: ถอด JWT ดู uid

                    ├─ @auth directive   ← gate #3: verifyToken
                    │                    ← gate #4: checkSession (role + jti)
                    │                    ← gate #5: checkMenuAuth (menu ABAC)

                    ├─ resolver          ← typeDefs/*.js → resolvers/*.js

                    ├─ controller        ← lib/controllers/* (orchestration)

                    ├─ repository        ← lib/repositories/* (data access)

                    ├─ Models            ← models/* (Sequelize; syncModels active = 79)
                    │                    ├─ db  → MariaDB vtrc
                    │                    └─ db2 → MariaDB vtrc-centralize

                    └─ centralize/       ← bridge ไป cu-central-api
                              │              ├─ GraphQL (graphql.js)
                              │              └─ REST auth (auth.js)

                          cu-central-api ─► MSSQL (HRMI)
                                          ─► LDAP/AD

มี 5 gates ระหว่าง request เข้ามาถึง business logic — gate ไหน fail ก็ reject ที่นั่น ความซับซ้อนส่วนใหญ่อยู่ที่ gate #3-5 และที่ centralize bridge

ตัวเลขที่ควรจำ

ตัวเลขค่าที่มา
typeDefs43 ไฟล์api/src/typeDefs/*.js
resolvers43 ไฟล์ mirror typeDefsapi/src/resolvers/*.js
controllers30 โฟลเดอร์, ~25,800 LOCapi/src/lib/controllers/
repositories32 โฟลเดอร์api/src/lib/repositories/
Models (sync list)79 ตาราง (active ใน syncModels)api/src/lib/model.js:17-99
REST routes1,302 LOC, ~40 endpointsapi/src/routes.js
Schemas ที่เขียน2 (db, db2 บน MariaDB เดียวกัน)api/src/connector.js:8-48

ชื่อในโค้ด ≠ ชื่อ service จริง

โฟลเดอร์ชื่อ centralize/ และ env ชื่อ END_POINT_CENTRALIZE แต่ปลายทางจริงคือ cu-central-api (GraphQL + REST auth) ไม่ใช่ NestJS centralize-api (port 3000 REST)

หลักฐานจาก vtrc-api/api/.env.example:36-37 (CLIENT_TARGET ตัวอย่างใช้ port 8082):

END_POINT_CENTRALIZE="http://localhost:8082/api/graphql"
END_POINT_CENTRALIZE_AUTH="http://localhost:8082/auth"

พอร์ต cu-central-api ต้องแยกชั้น: CODE_DEFAULT APP_PORT=8080 (main-api/src/config.js / .env.example), CLIENT_TARGET ใน vtrc .env.example อาจชี้ 8082, Docker EXPOSE 9000 ≠ listen port, compose มัก map 8000 — path /api/graphql ชี้ cu-central ไม่ใช่ NestJS — ไม่พบ call จาก vtrc-api ไป NestJS centralize-api ใน workspace นี้

จะอธิบายเต็มใน บท 3.4 The centralize bridge — พร้อม evidence


สารบัญ

บทหัวข้อคำถามที่ตอบ
3.1Repository map + boot sequenceprocess เริ่มที่ไหน โหลดอะไร syncModels 79 ตัวอยู่อย่างไร
3.2GraphQL request pipelinerequest หนึ่งตัวผ่านกี่ gate แต่ละ gate ทำอะไร
3.3Authentication & session internalsJWT, session, RBAC, refresh token ทำงานอย่างไร มี bug อะไร
3.4The centralize bridgeเรียก cu-central-api อย่างไร ทำไมไม่มี fallback
3.5Persistence layerSequelize sync คืออะไร transaction bug ระบบ-wide คืออะไร
3.6Controller layer survey30 โฟลเดอร์ controllers จัดเป็น 7 cluster
3.7REST surface (routes.js)ทำไมต้องมี REST คู่ GraphQL qpdf ทำงานอย่างไร
3.8Cron + background jobsnode-schedule ทำงานอย่างไร APP_NO คืออะไร
3.9Cross-cutting concernslogging, error format, file storage, redis ที่พัง
3.10vtrc-api scorecard + known bugsสรุปสุขภาพ repo bug catalog ลำดับความคุ้ม

วิธีอ่านเล่มนี้

แต่ละบทมีโครงสร้างคล้าย Volume 2

  1. ภาพรวม — อธิบายสั้น ๆ ก่อน
  2. รายละเอียดพร้อม file:line reference — ให้เปิดโค้ดจริงดูได้
  3. "เคล็ดลับตอนทำงานจริง" — opinion ของเรา จุดที่ต้องระวัง จุดที่มักเข้าใจผิด

อ่านจบแต่ละบทแล้วแนะนำให้เปิดไฟล์จริงใน repo ดู 1-2 ไฟล์ — คู่มือนี้เป็นแผนที่ ไม่ใช่ตัวแทนของโค้ด


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

ไป บท 3.1 Repository map + boot sequence