3.2.9 · Scorecard + comparison
บทสุดท้ายของ Volume 3.2 สรุป health ของ cu-central-api ตาม dimension เทียบกับ vtrc-api และ outline modernization target
Health scorecard
| มิติ | Current State | After Wave 0 | After Wave 2 (target) |
|---|---|---|---|
| Authentication | 🔴 JWT_SECRET empty default, /auth/signinbypass, hardcoded apiKeys | 🟡 rotated secrets + hard-fail | 🟢 go-ldap + golang-jwt + OIDC |
| Authorization | 🔴 requires commented out, ignoreAuth bypass | 🟡 remove bypass + implement RBAC | 🟢 Casbin + policy test matrix |
| Data layer | 🟡 6 connections, SourceDB sharding works + dead dbHRMI_test + HrTimeAttendance miss scope | 🟡 fix dead dbHRMI_test + missing scope | 🟢 shard-per-connection + sqlc |
| Schema | 🟡 32 SDL files, dead payrollSlip_removed.js, typos in public schema | 🟡 purge dead files | 🟢 gqlgen + co-located ops |
| Integrations | 🟡 SSO + Conicle + HIS + HRMI + SMS + SMTP — httpRequest.js broken | 🟡 add timeout/retry + fix axios dep | 🟢 outbound port adapters |
| Security | 🔴 6 Critical + 7 High | 🟡 Wave 0 ปิดทั้งหมด | 🟢 strict types + secret manager |
| Runtime | 🔴 Node 12 + esm shim + Apollo v2 | 🟡 Node 20 LTS + native ESM | 🟢 Go runtime |
| HA / scaling | 🔴 in-process cron, no rate limit | 🟡 BullMQ + rate limit | 🟢 Asynq + autoscaling |
Legend
- 🔴 Critical = active risk
- 🟡 High = impact จริงแต่มีเงื่อนไข
- 🟢 Medium/Good = hygiene ที่ทำได้
เปรียบเทียบ cu-central-api vs vtrc-api
| Aspect | vtrc-api | cu-central-api |
|---|---|---|
| Stack | Node 12 + Apollo v2 + Sequelize + MariaDB | Node 12 + Apollo v2 + Sequelize + MSSQL |
| DB connections | 2 (db + db2) | 6 (db + dbHr + dbHrTemp + dbMasDb + dbHRMI_test + dbHRMI_Center_HIS) |
| Auth source | local DB + forward ไป cu-central-api | LDAP/AD direct bind |
| apiKey | config.js (7 prod keys) | hardcoded 2 keys ใน controller |
| JWT default | 'secret' | '' (empty) |
| Schema size | ใหญ่กว่ามาก (queries.js ไฟล์เดียว 4,500 LOC) | 2,629 LOC SDL + 1,826 LOC resolvers |
| Multi-tenancy | single DB | SourceDB sharding ทุก association |
| Cron | node-schedule in-process | node-schedule + APP_NO gating |
| Introspection | 🔴 true เสมอ | 🟢 gate ด้วย IS_PRODUCTION |
| CORS | 🔴 typo + default * | 🟢 ไม่ set CORS (delegated ไป nginx) |
| REST routes | 77 KB routes.js | 64 LOC routes.js (5 endpoints) |
| execSync injection | 🔴 5 endpoints | 🟢 ไม่มี |
| SQL injection | 🔴 statLog.js | 🟢 ไม่พบ |
| File upload | 🔴 multer no filter | 🟢 ไม่มี |
| Rate limit | 🔴 ไม่มี | 🔴 ไม่มี |
| Passwordless signin | 🟢 ไม่มี | 🔴 /auth/signinbypass |
| Modernization target | decompose เป็นหลาย Go services | decompose เป็น identity + hr-data services |
cu-central-api ดีกว่า vtrc-api ตรงไหน
- ไม่มี
execSyncinjection — ไม่มี PDF/qpdf stack จึงไม่มี vector นี้ - ไม่มี SQL injection — ทุก raw query ใช้ parameterized bindings ถูกต้อง
- Gate introspection/playground ด้วย
IS_PRODUCTION(index.js:77-79) — ไม่ leak schema ใน prod - ไม่มี CORS bug — ไม่ set CORS เลย (delegated ไป nginx)
- Session lookup ดีกว่า — Redis key pattern ตรง ไม่ใช่
LIKE '%jwtid%'JSON scan (session.js:18-20) - ไม่มี file upload — ไม่มี multer/path-traversal surface
- Error handling ละเอียดกว่า — directive แยก
TokenExpiredErrorvsJsonWebTokenError(directives/auth.js:61-67)
cu-central-api แย่กว่าตรงไหน
JWT_SECRETdefault empty — แย่กว่า'secret'ของvtrc-apiเพราะ""ดูเหมือน "ยังไม่ set" ทำให้มีโอกาสลืม set env/auth/signinbypasspasswordless — endpoint ที่vtrc-apiไม่มี (routes.js:31-37)ignoreAuthbypass — pattern ที่vtrc-apiไม่มี (apiKey อย่างเดียวพอ)- LDAP TLS ปิด —
rejectUnauthorized: falseใน LDAP connection (activeDirectory.connector.js:21) - 6 DB connections — ซับซ้อนกว่า 2 ของ
vtrc-api(และมี dead connection) SourceDBsharding complexity — pattern ที่ไม่มีในvtrc-apiและมี boilerplate มหาศาล + pattern miss (HrTimeAttendanceไม่มี scope)- apiKeys hardcoded —
vtrc-apiเก็บใน config (แยกไฟล์) แต่cu-central-apihardcode ใน controller เลย HrTimeAttendanceไม่มี scope constraint — silent bug ที่อาจทำให้ time attendance ข้าม shard- OTP inconsistency —
hrAddressปิด OTP,hrPhoneNumberยังเปิด
Modernization target
ตาม audit/05-tech-debt-register.md §5.3 ลำดับ Wave 2
| Order | Bounded Context | Target |
|---|---|---|
| 1 | document-renderer (จาก vtrc-api) | — |
| 2 | identity (รวม cu-central-api auth) | Go + Casbin + Postgres |
| 3 | payroll | — |
| 4 | time-attendance | — |
| 5 | leave | — |
| 6 | welfare | — |
| 7 | hr-data (cu-central-api HR queries) | Go + per-shard connection |
cu-central-api จะถูก decompose เป็น 2 contexts หลัก
identity-service
รับผิดชอบ
- LDAP/AD bind (ผ่าน
go-ldap/ldap/v3) - JWT issuance (ผ่าน
golang-jwt/jwt/v5) - Session store (ผ่าน
go-redis) - RBAC policy (ผ่าน Casbin)
cmd/
└── identity-service/
internal/identity/
├── domain/ (User, Session, Role, Grant)
├── port/ (Authenticator, SessionStore)
├── adapter/
│ ├── ldap/ (go-ldap adapter)
│ ├── redis/ (session store)
│ └── jwt/ (token signer)
└── usecase/ (login, refresh, logout, authorize)hr-data-service
รับผิดชอบ
- HR data read/write (MSSQL per-shard)
SourceDBsharding เป็นรายละเอียดภายใน service (ผู้เรียกไม่ต้องรู้)- HRMI HTTP API integration
- HIS heal-card integration
cmd/
└── hr-data-service/
internal/hrdata/
├── domain/ (Employee, Organization, Payroll, ...)
├── port/ (EmployeeRepo, OrgRepo)
├── adapter/
│ ├── mssql/ (per-shard connection pool)
│ ├── hrmi/ (HTTP API client)
│ └── his/ (heal-card API client)
└── usecase/ (getEmployee, updateAddress, ...)Cross-reference ไป volume อื่น
| Volume | Topic | Relevance |
|---|---|---|
| Volume 2 | Architecture & Topology | cu-central-api ใน topology |
| Volume 3.1 | vtrc-api Deep Dive | comparison + centralize bridge |
| Volume 3.3 | centralize-api | คนละ service (NestJS) |
| Volume 8 | Data Model & Persistence | MSSQL schemas |
| Volume 12 | Security | .env.develop-test + secrets |
| Volume 19 | Roadmap | Go target |
สรุป Volume 3.2
cu-central-api เป็น satellite service ที่โครงสร้างคล้าย vtrc-api ในหลายด้าน แต่มีจุดเด่นเฉพาะตัว
- LDAP/AD auth — เป็นเจ้าของ credential verification จริง (
vtrc-apiforward มา) ผ่าน 2-stage bind (service account → user bind) SourceDBsharding — pattern ที่ไม่มีในvtrc-apiและเป็นแก่นของ repo (ทุก HR association ต้อง scope)- 6 MSSQL connections — กระจาย 5 schemas + 1 dead (
dbHRMI_test) - External integrations — SSO + Conicle + HIS + HRMI + SMS + SMTP (เป็น service เดียวที่เรียก)
- Severity — 🔴 6 Critical + 🟡 7 High + 🟢 5 Medium (น้อยกว่า
vtrc-apiแต่ก็ยังมีจำนวนมาก)
Security posture โดยรวม ดีกว่า vtrc-api ในหลายด้าน (ไม่มี execSync, ไม่มี SQLi, gate introspection ถูก) แต่มี risk เฉพาะตัว (sign-in bypass, LDAP TLS ปิด, JWT empty default, ignoreAuth bypass)
Modernization path ชัดเจน — decompose เป็น identity-service + hr-data-service ใน Go (Volume 19 Roadmap)
Debt ID index ของ Volume นี้
| ID | Severity | Topic | บทที่ detail |
|---|---|---|---|
| SEC-CU-01 | 🔴 | JWT_SECRET default empty | 3.2.8 |
| SEC-CU-02 | 🔴 | apiKeys hardcoded | 3.2.4, 3.2.8 |
| SEC-CU-03 | 🔴 | .env.develop-test committed | 3.2.8, Volume 12 |
| SEC-CU-04 | 🔴 | /auth/signinbypass passwordless | 3.2.3, 3.2.8 |
| SEC-CU-05 | 🔴 | ignoreAuth bypass | 3.2.4, 3.2.8 |
| SEC-CU-06 | 🔴 | LDAP rejectUnauthorized: false | 3.2.3, 3.2.8 |
| LEG-CU-01 | 🔴 | axois typosquat | 3.2.8 |
| LEG-CU-02 | 🟡 | error-ex git URL | 3.2.8 |
| LEG-CU-03 | 🟡 | ldapjs unmaintained | 3.2.8 |
| LEG-CU-04 | 🟡 | jsonwebtoken@8 CVE | 3.2.8 |
| LEG-CU-05 | 🟡 | Node 12 + esm shim | 3.2.8 |
| LEG-CU-06 | 🟡 | xlsx CVE history | 3.2.8 |
| CORR-CU-01 | 🔴 | httpRequest.js broken import | 3.2.7, 3.2.8 |
| CORR-CU-02 | 🟡 | OTP inconsistency | 3.2.6 |
| CORR-CU-03 | 🟢 | syncModelToTable ใน prod | 3.2.2 |
| QUAL-CU-01 | 🟡 | requires commented out | 3.2.4 |
| QUAL-CU-02 | 🟢 | clockTolerance misuse | 3.2.3, 3.2.8 |
| QUAL-CU-03 | 🟢 | signInDomains hardcoded | 3.2.6 |
| OBS-CU-01 | 🟢 | dbHRMI_test dead connection | 3.2.2 |
| PERF-CU-01 | 🟢 | ไม่มี timeout/retry/circuit breaker | 3.2.7 |
| PERF-CU-02 | 🟢 | decode token 2 ครั้ง | 3.2.4 |
| CORR-CU-04 | 🔴 | HrTimeAttendance ไม่มี scope | 3.2.5 |
กลับไป ภาพรวม Volume 3.2 · ไป Volume ถัดไป 3.3 centralize-api →