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
ข้อตกลงเบื้องต้นที่ต้องรู้
อ่านมาถึงตรงนี้แล้วควรเคยผ่าน
- Vol 0 ภาพรวม VTRC
- Vol 1 ภาพธุรกิจ
- Vol 2 สถาปัตยกรรม — โดยเฉพาะ 2.1 และ 2.3
ถ้าข้ามมาเล่มนี้ก่อนจะงงเรื่อง 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
ตัวเลขที่ควรจำ
| ตัวเลข | ค่า | ที่มา |
|---|---|---|
| typeDefs | 43 ไฟล์ | api/src/typeDefs/*.js |
| resolvers | 43 ไฟล์ mirror typeDefs | api/src/resolvers/*.js |
| controllers | 30 โฟลเดอร์, ~25,800 LOC | api/src/lib/controllers/ |
| repositories | 32 โฟลเดอร์ | api/src/lib/repositories/ |
| Models (sync list) | 79 ตาราง (active ใน syncModels) | api/src/lib/model.js:17-99 |
| REST routes | 1,302 LOC, ~40 endpoints | api/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.1 | Repository map + boot sequence | process เริ่มที่ไหน โหลดอะไร syncModels 79 ตัวอยู่อย่างไร |
| 3.2 | GraphQL request pipeline | request หนึ่งตัวผ่านกี่ gate แต่ละ gate ทำอะไร |
| 3.3 | Authentication & session internals | JWT, session, RBAC, refresh token ทำงานอย่างไร มี bug อะไร |
| 3.4 | The centralize bridge | เรียก cu-central-api อย่างไร ทำไมไม่มี fallback |
| 3.5 | Persistence layer | Sequelize sync คืออะไร transaction bug ระบบ-wide คืออะไร |
| 3.6 | Controller layer survey | 30 โฟลเดอร์ controllers จัดเป็น 7 cluster |
| 3.7 | REST surface (routes.js) | ทำไมต้องมี REST คู่ GraphQL qpdf ทำงานอย่างไร |
| 3.8 | Cron + background jobs | node-schedule ทำงานอย่างไร APP_NO คืออะไร |
| 3.9 | Cross-cutting concerns | logging, error format, file storage, redis ที่พัง |
| 3.10 | vtrc-api scorecard + known bugs | สรุปสุขภาพ repo bug catalog ลำดับความคุ้ม |
วิธีอ่านเล่มนี้
แต่ละบทมีโครงสร้างคล้าย Volume 2
- ภาพรวม — อธิบายสั้น ๆ ก่อน
- รายละเอียดพร้อม file:line reference — ให้เปิดโค้ดจริงดูได้
- "เคล็ดลับตอนทำงานจริง" — opinion ของเรา จุดที่ต้องระวัง จุดที่มักเข้าใจผิด
อ่านจบแต่ละบทแล้วแนะนำให้เปิดไฟล์จริงใน repo ดู 1-2 ไฟล์ — คู่มือนี้เป็นแผนที่ ไม่ใช่ตัวแทนของโค้ด