Phase 1 — Tech Stack & Dependency Matrix
⚠️ SUPERSEDED / ถูกแทนที่แล้ว — This audit snapshot is not authoritative.
อย่าใช้ตัดสินใจ operational โดยไม่ verify โค้ด / Do not use for operational decisions without verifying code.Authoritative docs: VitePress volumes (
docs/volume-00…docs/volume-16) ·docs/audits/docs-verify-2026-07-11-delta.md·docs/volume-17-appendices/08-changelog-errata.mdKnown stale claims ในไฟล์นี้: NestJS เป็น live
END_POINT_CENTRALIZEtarget · cu-central port 9000 เป็น listen (จริงคือEXPOSEเท่านั้น) ·dbHRMI_NBCแทนdbHRMI_Center_NBC· KBANK bank name errors อาจปรากฏ
i3 Gateway Knowledge Base · VTRC Platform · Generated by deep-scan of all five sub-repos. Evidence basis: every
package.json,package-lock.json,yarn.lock,Dockerfile, anddocker-compose*.ymlin the workspace. Cross-checked against actualimport/requireusage in*/src. Modernization target framing: Go (Hexagonal / DDD) for backends · Nuxt 3 (Feature-Sliced Design) for frontends.
1.1 Platform Topology at a Glance
The VTRC platform is a multi-repo monorepo (no root package.json, no root lockfile). Each top-level directory is an independent git repository with its own toolchain.
| Repo | Path | Stack | Runtime | Package Mgr | Has Lockfile | Entry | Default Port |
|---|---|---|---|---|---|---|---|
| vtrc-api | vtrc-api/api/ | Node.js (ESM via esm) + Apollo GraphQL 2 + Sequelize 6 + MariaDB + Redis | Node 12 (Dockerfile) | npm | ✅ package-lock.json | index.js | 8081 (/api/graphql) |
| vtrc-web | vtrc-web/ | React 16 + Webpack 4 + Apollo Client v2 + AntD v3 + styled-components | Browser | yarn | ✅ yarn.lock + package-lock.json ⚠️ both present | src/index.js | 3000 |
| vtrc-rc-backoffice | vtrc-rc-backoffice/ | React 16 + CRA (react-scripts 3.4.3) + Apollo v2 + AntD v4 + MUI v5 + Recoil | Browser | npm | ✅ package-lock.json | src/index.js | 3000 |
| centralize-api | centralize-api/ | NestJS 9 + TypeScript 4.7 + TypeORM 0.3 + MSSQL (mssql/tedious) + Swagger | Node 16 (Dockerfile) | yarn (in Dockerfile) | ❌ NO lockfile committed | src/main.ts | 3000 (/api, /docs) |
| cu-central-api | cu-central-api/main-api/ | Node.js (ESM) + Apollo GraphQL 2 + Sequelize 6 + LDAP (ldapjs) + Redis + MSSQL (tedious) | Node 12.18.3 (Dockerfile) | npm | ✅ package-lock.json | index.js | 9000 (Dockerfile EXPOSE only — not listen; CODE_DEFAULT often 8080 / CLIENT_TARGET often 8082) |
Cross-Cutting Runtime Risks (apply to every row above)
| # | Finding | Evidence | Risk |
|---|---|---|---|
| R1 | No engines field in any package.json | rg '"engines"' across all 5 manifests → 0 matches | Any Node version can install/run; CI drift; irreproducible builds. |
| R2 | Two Node.js LTS generations in production | vtrc-api → node:12; cu-central-api → node:12.18.3; centralize-api → node:16 | Node 12 reached EOL April 2022 (≈4 years past EOL). Node 16 reached EOL Sept 2023. No security backports. |
| R3 | vtrc-web commits both yarn.lock and package-lock.json | Both files present in vtrc-web/ | Dual-resolver state; resolver-dependent hoisting; classic source of "works on my machine" bugs. |
| R4 | centralize-api ships with NO lockfile | ls centralize-api/yarn.lock package-lock.json → not found, yet Dockerfile runs yarn install | Build is non-reproducible; supply-chain drift on every yarn install. |
| R5 | centralize-api ignores engine constraints | Dockerfile: RUN yarn install --ignore-engines | Masks resolver/peer-dep incompatibilities; silent breakage on upgrade. |
1.2 Master Dependency Matrix
Legend for Risk Status:
- 🟢 = current, actively maintained, low-risk
- 🟡 = old/EOL runtime or library, deprecated but functional, upgrade advised
- 🔴 = unmaintained / abandoned / typosquat / known-CVE / supply-chain hazard — action required
1.2.1 vtrc-api — Core GraphQL API (vtrc-api/api/package.json)
| Library | Version | Usage Domain | Risk |
|---|---|---|---|
apollo-server | ^2.16.1 | GraphQL server | 🔴 v2 line EOL; Apollo moved to @apollo/server v4. No security patches. |
graphql | ^15.3.0 | GraphQL runtime | 🟡 v15 superseded by v16 (current v17). |
graphql-upload | ^9.0.0 | Multipart file uploads over GraphQL | 🔴 v9 deprecated; project moved to graphql-upload v16 (different fork lineage). |
graphql-resolvers | ^0.4.2 | Resolver composition / shield-like auth | 🔴 Last published 2018; effectively abandoned. Replaced in modern stacks by graphql-shield. |
graphql-request | ^3.1.0 | Minimal GraphQL client (for inter-service calls) | 🟡 v3 superseded by v6+. |
graphql-type-decimal | ^1.0.0 | Custom GraphQL Decimal scalar | 🟡 Niche, low maintenance. |
sequelize | ^6.3.4 | ORM for MariaDB | 🟡 v6 supported; v7 in beta. Patch-level very old (6.3 → 6.x current). |
mariadb | ^2.4.2 | MariaDB driver | 🔴 v2 EOL; current is v3.x. v2 has known issues with newer MariaDB servers. |
mysql2 | ^2.1.0 | MySQL driver (likely fallback/dual) | 🟡 v2 legacy; v3 current. Both mariadb and mysql2 declared → ambiguous driver strategy. |
redis | ^3.1.2 | Cache / session / OTP store | 🔴 v3 callback-style; v4 is fully Promise-based. v3 has CVE history. |
jsonwebtoken | ^8.5.1 | JWT issue/verify | 🔴 v8 has CVE-2022-23529 family. Current is v9. |
bcryptjs | ^2.4.3 | Password hashing (pure JS) | 🟡 Slower than native bcrypt; acceptable but slower = weaker cost-factor ceiling. |
crypto-js | ^4.1.1 | General crypto (AES, etc.) | 🟡 v4.2 current; 4.1.x has advisory CVE-2023-46233 (PBKDF2 1-round default). |
firebase-admin | ^9.2.0 | FCM push notifications | 🔴 v9 EOL; current v12. Locked to old Google APIs. |
googleapis | ^59.0.0 | Google Drive / Workspace | 🔴 v59 (2020); current v140+. Massive API drift. |
nodemailer | ^6.8.0 | SMTP email | 🟢 v6 maintained. |
exceljs | ^4.3.0 | Excel read/write | 🟢 v4 maintained. |
pdfreader | ^1.0.7 | PDF text extraction | 🟡 v1 legacy; v2 current. |
html-pdf | ^2.2.0 | HTML→PDF (PhantomJS-based) | 🔴 Depends on PhantomJS (abandoned 2018). Dockerfile comments reveal it was once installed. |
node-qpdf | ^1.0.3 | PDF encrypt/decrypt (native qpdf binary) | 🔴 Last published 2017; requires system qpdf (installed in Dockerfile). Brittle native dep. |
svg-captcha | ^1.4.0 | SVG CAPTCHA generation | 🟡 Low maintenance; accessibility concerns. |
multer | ^1.4.3 | Multipart upload middleware | 🟡 v1 has CVE-2024-47764; v2 current. |
node-schedule | ^2.1.0 | Cron-like in-process scheduler | 🟢 Maintained. ⚠️ In-process = no HA failover (see Phase 5). |
set-cookie-parser | ^2.4.8 | Cookie parsing for inter-service calls | 🟢 Stable. |
archiver | ^5.3.0 | ZIP streaming | 🟢 Maintained. |
ejs | ^3.1.5 | HTML templating for PDF generation | 🟡 v3 has had multiple prototype-pollution CVEs (CVE-2022-29078, CVE-2024-33733); v3.1.10+ patched. |
iconv-lite | ^0.6.3 | Thai-encoding conversion | 🟢 Stable. |
image-size | ^1.0.0 | Image dimension probe | 🟢 Stable. |
resize-img | ^2.0.0 | Image resizing | 🟡 Pure-JS, slow; sharp is the modern standard. |
axios | ^0.20.0 | HTTP client (→ centralize-api) | 🔴 v0.20 (2020) predates many CVEs (CVE-2021-3749, CVE-2023-45857, CVE-2024-39338). Current v1.x. |
fs-capacitor | ^5.0.0 | Streaming buffer for graphql-upload | 🟡 Tied to graphql-upload v9 EOL. |
findit | ^2.0.0 | Directory walking | 🔴 Last published 2014; replaced by Node fs.promises.readdir recursive. |
thai-baht-text | ^1.0.8 | Number→Thai-Baht words (cheque/PDF) | 🟢 Niche but functional. |
mime-types | ^2.1.35 | MIME lookup | 🟢 Stable. |
uuid | ^8.3.0 | UUID v4 | 🟡 v8 legacy; v9/v10 current (ESM). |
dotenv | ^8.2.0 | Env loader | 🟡 v8 legacy; v16+ current (supports multiline, expansion). |
esm | ^3.2.25 | ESM shim for Node 12 | 🔴 The entire reason Node 12 is locked. esm is unmaintained (last release 2019). Native ESM in Node ≥14 makes it obsolete. |
s | ^1.0.0 | ❓ UNKNOWN | 🔴 NEVER imported anywhere in api/src (verified). Likely typo/accidental npm i s. Supply-chain hazard. |
stream | ^0.0.2 | ❓ UNKNOWN | 🔴 npm package shadowing Node core. Dead weight + supply-chain hazard. (stream is a Node built-in; the npm package is a 2014 stub.) |
css | ^3.0.0 | ❓ UNKNOWN | 🟡 Declared; verify usage. Likely stray. |
standard (dev) | ^14.3.4 | ESLint shareable config | 🟡 v14 legacy; current v17. |
1.2.2 vtrc-web — End-User Web App (vtrc-web/package.json)
| Library | Version | Usage Domain | Risk |
|---|---|---|---|
react / react-dom | ^16.14.0 | UI runtime | 🔴 React 16 EOL; no hooks lint updates, no concurrent features, no useTransition. Current v18/v19. |
react-router-dom | ^5.3.3 | Routing | 🟡 v5 legacy; v6/v7 current (different API). |
react-apollo | ^3.1.5 | Apollo React integration | 🔴 Package renamed to @apollo/client in 2020. react-apollo is frozen/dead. |
apollo-client | ^2.6.3 | Apollo Core | 🔴 v2 line EOL; replaced by @apollo/client v3. |
apollo-cache-inmemory | ^1.6.2 | Apollo cache | 🔴 v1 EOL (folded into @apollo/client). |
apollo-link / apollo-link-http / apollo-link-context / apollo-link-error | ^1.x | Apollo link chain | 🔴 Entire apollo-link-* family deprecated in favor of @apollo/client core. |
apollo-upload-client | ^11.0.0 | File upload link | 🟡 Maintained but tied to legacy Apollo. |
apollo-fetch | ^0.7.0 | Legacy GraphQL fetcher | 🔴 Abandoned (2017). Almost certainly dead weight. |
graphql | ^15.8.0 | GraphQL runtime | 🟡 v15 legacy; v16 current. |
graphql-tag | ^2.12.6 | gql tag | 🟢 Stable. |
antd | ^3.26.20 | Component library | 🔴 AntD v3 EOL since 2020. No security patches. v5/v6 current. Backoffice uses v4 — split versions across frontends. |
@ant-design/icons | ^4.7.0 | Icon set | 🟡 Mismatched with AntD v3 (icons v3 pairs with AntD v3). |
styled-components | ^5.3.5 | CSS-in-JS | 🟡 v5 stable; v6 current. Pairs with React 16. |
moment | ^2.29.4 | Date library | 🟡 moment is in legacy maintenance (project recommends dayjs/luxon). Bundle bloat (~67 KB). |
axios | ^0.21.4 | HTTP | 🔴 v0.21 has multiple CVEs (see vtrc-api row). |
webpack | 4.42.0 | Bundler | 🔴 Webpack 4 EOL; no security support. Webpack 5 current (since 2020). |
webpack-dev-server | 3.11.0 | Dev server | 🔴 v3 EOL; v5 current. |
html-webpack-plugin | 4.0.0-beta.11 | HTML emit | 🔴 BETA version pinned in production. |
workbox-webpack-plugin | 4.3.1 | PWA service worker | 🔴 Workbox v4 EOL; v7 current. |
jest | 24.9.0 | Test runner | 🔴 v24 (2019); v29 current. |
babel-eslint | 10.1.0 | ESLint parser | 🔴 Renamed to @babel/eslint-parser. v10 dead. |
eslint | ^6.6.0 | Linter | 🔴 v6 EOL; v9 current. |
eslint-plugin-react-hooks | ^1.6.1 | Hooks lint rules | 🔴 v1 ancient; v4+ current. Hooks bugs will not be caught. |
react-pdf / pdfjs-dist | ^5.7.2 / ^2.16.105 | PDF viewer | 🟡 Older line; pdfjs-dist v4 current. |
@react-pdf-viewer/* (3 pkgs) | ^2.11.0 | PDF viewer kit | 🟡 v2; v5 current. |
@react-pdf/renderer | ^2.3.0 | React→PDF | 🟡 v3 current. |
react-markdown | ^8.0.3 | MD rendering | 🟢 Recent. |
react-dnd / react-dnd-html5-backend | ^11.1.3 | Drag-and-drop | 🟡 v15 current. |
react-input-mask | ^2.0.4 | Input masking | 🟡 Maintained-ish. |
react-otp-input | ^3.1.1 | OTP input | 🟢 Maintained. |
react-electron-web-view / react-electron-webview | ^2.0.x | Electron webview | 🔴 BOTH declared AND NEVER imported. Electron is not part of this stack. Dead supply-chain weight. |
react-electron-web-view | ^2.0.1 | (dup) | 🔴 Same as above (two near-duplicate packages). |
pdf-viewer-reactjs | ^2.2.3 | Another PDF viewer | 🟡 Third PDF viewer library in same app — strategy chaos. |
react-pdf-to-image | ^1.0.2 | PDF→image | 🟢 Niche. |
draftjs-* (3 pkgs) | various | Rich-text conversion | 🟡 Tied to legacy Draft.js. |
react-draft-wysiwyg | ^1.15.0 | WYSIWYG editor | 🔴 Last release 2019; unmaintained. |
lodash | ^4.17.21 | Utils | 🟢 Patched; v4 still canonical. |
uuid | ^8.3.2 | UUID | 🟡 Legacy line. |
dotenv | 8.2.0 | Env | 🟡 Legacy. |
thaidatepicker-react | ^0.2.2 | Thai Buddhist-era date picker | 🟡 Niche, low maintenance. |
clean-webpack-plugin | ^4.0.0 | Build clean | 🟡 Webpack-4 era. |
terser-webpack-plugin | 2.3.8 | Minify | 🟡 WC-4 era. |
worker-loader / url-loader / file-loader / sass-loader / css-loader / style-loader / postcss-* / resolve-url-loader / pnp-webpack-plugin / ts-pnp / case-sensitive-paths-webpack-plugin / mini-css-extract-plugin / optimize-css-assets-webpack-plugin / webpack-manifest-plugin | various | Webpack 4 pipeline | 🟡 All WC-4 era; several loaders removed/renamed in WC-5. |
save | ^2.9.0 | ❓ UNKNOWN | 🔴 NEVER imported in src (verified). Stray package. |
react-icons | ^5.6.0 | Icons | 🟢 Recent. |
react-lines-ellipsis / react-truncate | various | Text truncation | 🟡 Two truncation libs — duplication. |
1.2.3 vtrc-rc-backoffice — Admin/Backoffice (vtrc-rc-backoffice/package.json)
| Library | Version | Usage Domain | Risk |
|---|---|---|---|
react / react-dom | ^16.13.1 | UI runtime | 🔴 React 16 EOL. |
react-scripts | 3.4.3 | CRA toolchain | 🔴 CRA itself is deprecated (2023). react-scripts 3.4 ships Webpack 4 + ESLint 6 + Workbox 4 + Babel 7.9 — all EOL. |
antd | 4.15.4 | Component library | 🟡 AntD v4 in maintenance; v5/v6 current. (Note: differs from web app's v3.) |
@mui/material / @mui/icons-material | ^5.11.x | MUI components | 🟢 v5 current. ⚠️ Two design systems coexist (AntD + MUI). |
@emotion/react / @emotion/styled | ^11.10.5 | MUI styling engine | 🟢 Current. |
@ant-design/icons | ^4.2.2 | AntD icons | 🟡 AntD v4 era. |
styled-components | ^5.1.1 | CSS-in-JS (third styling lib) | 🟡 Third styling approach (AntD less-in-JS + Emotion + styled-components). |
react-apollo / apollo-client / apollo-cache-inmemory / apollo-link* / apollo-fetch | v2 / v1 | Apollo stack | 🔴 Same legacy-Apollo cluster as vtrc-web. |
apollo-upload-client | ^11.0.0 | Uploads | 🟡 Legacy-tied. |
graphql | ^15.3.0 | Runtime | 🟡 v15 legacy. |
graphql-tag | ^2.10.1 | gql tag | 🟢 Stable. |
react-router-dom | ^5.2.0 | Routing | 🟡 v5 legacy. |
recoil | ^0.7.5 | State management | 🟡 Recoil is experimental, low activity since Meta layoffs. Jotai is the active successor. |
react-query | ^3.39.2 | Server-state (TanStack Query) | 🟡 v3 legacy; renamed to @tanstack/react-query v5. |
axios | ^1.2.0 | HTTP | 🟢 v1 line — the one healthy axios in the workspace. |
crypto-js | ^4.2.0 | Crypto | 🟡 v4.2 (newer than vtrc-api's 4.1). |
moment | ^2.27.0 | Dates | 🟡 Legacy; app also has dayjs — duplicate date strategy. |
dayjs | ^1.11.7 | Dates | 🟢 Modern — but coexists with moment. |
draft-js + draft-js-import-html + draft-js-import-markdown + draftjs-* (×3) + react-draft-wysiwyg | various | Rich text | 🔴 Draft.js is unmaintained (deprecated by Meta 2022). react-draft-wysiwyg last release 2019. |
exceljs | ^4.3.0 | Excel | 🟢 Stable. |
file-saver | ^2.0.5 | Download | 🟢 Stable. |
react-csv | ^2.2.2 | CSV export | 🟢 Stable. |
html2canvas | ^1.4.1 | DOM→image | 🟢 Stable. |
react-to-print | ^2.14.8 | 🟢 Stable. | |
primereact | ^5.0.2 | PrimeReact components | 🔴 v5 (2021); v10 current. Fourth component library (AntD + MUI + styled + PrimeReact). |
stimulsoft-reports-js / stimulsoft-dashboards-js | ^2023.3.4 | Reporting engine (proprietary) | 🟡 Vendor-locked; large bundle. Date-stamped 2023.3 — verify license. |
react-pdf | ^5.3.0 | PDF viewer | 🟡 v5; v9 current. |
react-sortable-hoc | ^1.11.0 | DnD (old) | 🔴 Deprecated — README says "use dnd-kit." @dnd-kit/* is also in this package.json. Duplicate DnD stack. |
array-move | ^3.0.1 | Helper for react-sortable-hoc | 🔴 Tied to deprecated lib. |
@dnd-kit/core / @dnd-kit/modifiers / @dnd-kit/sortable | ^6.x/^9.x/^10.x | Modern DnD | 🟢 Current — but coexists with the legacy DnD above. |
react-input-mask | ^2.0.4 | Input mask | 🟡 Maintained-ish. |
uuid | ^8.3.1 | UUID | 🟡 Legacy. |
sass | ^1.56.0 | SASS | 🟢 Current. |
concurrently | ^7.4.0 | Run multi-scripts | 🟡 v7 legacy; v9 current. |
atob | ^2.1.2 | Base64 decode | 🔴 Node atob is built-in (≥16). Polyfill not needed. |
@fortawesome/* (4 pkgs) | ^6.2.1 | Icons | 🟢 Current — but third icon set (AntD icons + MUI icons + FontAwesome). |
i | ^0.3.7 | ❓ UNKNOWN | 🔴 NEVER imported (verified). Stray. |
npm | ^9.2.0 | ❓ UNKNOWN | 🔴 Shipping npm inside the app bundle — almost certainly accidental. ~60 MB of dead weight. |
undefined-service-web | ^1.0.16 | ❓ UNKNOWN | 🔴 NEVER imported (verified). Name suggests typosquat/placeholder. Remove & audit. |
save | ^2.4.0 | ❓ UNKNOWN | 🔴 NEVER imported (verified). |
@ckeditor/ckeditor5-alignment (dev) | ^23.1.0 | CKEditor plugin | 🔴 Stray devDep; no CKEditor core declared. |
1.2.4 centralize-api — NestJS HR Data Service (centralize-api/package.json)
| Library | Version | Usage Domain | Risk |
|---|---|---|---|
@nestjs/common / @nestjs/core | ^9.0.0 | NestJS framework | 🟡 v9 (2022); v10/v11 current. Nest 9 still patched on demand. |
@nestjs/platform-express | ^9.0.0 | Express adapter | 🟡 Same. |
@nestjs/swagger | ^6.1.3 | OpenAPI generation | 🟡 v6 pairs with Nest 9; v8 current. |
@nestjs/typeorm | ^9.0.1 | TypeORM integration | 🟡 v9 pairs; v10 current. |
@nestjs/config | ^2.2.0 | ConfigService | 🟡 v2 pairs; v3 current. |
@nestjs/passport | ^9.0.0 | Auth adapter | 🟡 Pairs with Nest 9. |
passport | ^0.6.0 | Auth middleware | 🟡 v0.6 legacy; v0.7 current. |
passport-jwt | ^4.0.0 | JWT strategy | 🟢 Stable. |
passport-local | ^1.0.0 | Local strategy | 🟢 Stable. |
typeorm | ^0.3.10 | ORM | 🟡 0.3 line; current 0.3.20+. Patch old. |
mssql | ^9.1.1 | MSSQL driver (tedious wrapper) | 🟢 v9 current. |
class-transformer | ^0.5.1 | DTO transform | 🟢 Stable. |
class-validator | ^0.13.2 | DTO validation | 🟡 v0.14 current. |
rxjs | ^7.2.0 | Reactive primitives (NestJS core dep) | 🟢 v7 supported. |
reflect-metadata | ^0.1.13 | Decorator metadata | 🟡 v0.2 current. |
moment | ^2.29.4 | Dates | 🟡 Legacy. |
rimraf | ^3.0.2 | Build clean | 🟢 Stable. |
typescript (dev) | ^4.7.4 | Compiler | 🔴 v4.7 EOL; v5.x current. No lockfile → tsc behavior may drift. |
ts-jest / jest | 28.x | Test | 🟡 v28 legacy; v29 current. |
@nestjs/cli | ^9.0.0 | CLI | 🟡 Pairs with Nest 9. |
eslint | ^8.0.1 | Linter | 🟡 v8 maintenance; v9 current. |
prettier | ^2.3.2 | Formatter | 🟡 v2 legacy; v3 current. |
ts-loader | ^9.2.3 | TS loader | 🟢 Stable (only used by nest build webpack). |
ts-node | ^10.0.0 | TS runner | 🟢 Stable. |
supertest | ^6.1.3 | HTTP test | 🟢 Stable. |
⚠️ Critical config risks (
tsconfig.json):strictNullChecks: false,noImplicitAny: false,forceConsistentCasingInFileNames: false,strictBindCallApply: false. TypeScript's safety net is effectively disabled. See Phase 5.
1.2.5 cu-central-api — Legacy CU Auth/Data Service (cu-central-api/main-api/package.json)
| Library | Version | Usage Domain | Risk |
|---|---|---|---|
apollo-server | ^2.16.1 | GraphQL server | 🔴 v2 EOL. |
graphql | ^15.3.0 | Runtime | 🟡 Legacy. |
graphql-tag | ^2.11.0 | gql tag | 🟢 Stable. |
sequelize | ^6.3.5 | ORM | 🟡 Patch-old. |
tedious | ^9.2.1 | MSSQL driver | 🔴 v9 (2020); v18 current. Massive drift. |
redis | ^3.0.2 | Cache | 🔴 v3 callback-style; CVE history. |
node-redis-scan | ^1.3.0 | Redis SCAN wrapper | 🟡 Tied to redis v3. |
ldapjs | ^2.2.0 | LDAP auth (CU directory) | 🔴 ldapjs is unmaintained; fork ldapts is the active successor. CVE-2023-27045 family. |
sha512crypt-node | ^0.1.0 | SHA512-crypt (Linux /etc/shadow) | 🔴 Niche, low downloads, unmaintained. |
password-validator | ^5.1.0 | Password policy rules | 🟢 Stable. |
jsonwebtoken | ^8.5.1 | JWT | 🔴 CVE family (see vtrc-api). |
node-crc | ^1.3.0 | CRC (native binding) | 🟡 Native binding; brittle across Node versions. |
node-schedule | ^2.0.0 | Scheduler | 🟢 Stable. |
nodemailer | ^6.4.11 | SMTP | 🟢 Stable. |
email-templates | ^7.1.1 | Templated email | 🟡 v7 legacy; v12 current (renamed email-templates → maintain). |
xlsx | ^0.16.9 | Excel (SheetJS community) | 🔴 ⚠️ SheetJS community edition xlsx on npm has known prototype-pollution CVEs; official maintained version moved to https://cdn.sheetjs.com. |
ssh2-sftp-client | ^6.0.1 | SFTP file transfer | 🟡 v9 current; v6 (2021) old. |
date-diff | ^0.2.2 | Date diff | 🔴 Last release 2017; trivially replaceable. |
parse-duration | ^1.0.0 | Duration parsing | 🟢 Stable. |
sprintf-js | ^1.1.2 | sprintf | 🟢 Stable. |
validator | ^13.1.1 | String validation | 🟡 Patch-old; v13 current. |
body-parser | ^1.19.0 | Express body parser | 🟢 Stable (now in Express core). |
dotenv | ^8.2.0 | Env | 🟡 Legacy. |
uuid | ^8.3.1 | UUID | 🟡 Legacy. |
esm | ^3.2.25 | ESM shim | 🔴 Same Node-12 lock-in as vtrc-api. |
axois | 0.0.1-security | ❓ TYPOSQUAT of axios | 🔴 httpRequest.js does import axois from 'axios' — but axios is NOT in package.json. Verified axios is absent from node_modules. This file cannot run as written. |
error-ex | git+https://github.com/Qix-/node-error-ex.git | Error formatting | 🔴 Git URL dependency — non-reproducible, supply-chain hazard, no version pin. |
standard (dev) | ^14.3.4 | ESLint config | 🟡 Legacy. |
chai / mocha (dev) | ^4.2.0 / ^8.1.3 | Test | 🟡 Legacy lines. |
1.3 Critical Dependency Risk Register (Top Threats)
Ranked by systemic blast radius, not just CVE count.
| Rank | Risk | Repos Affected | Evidence | i3 Gateway Modernization Strategy |
|---|---|---|---|---|
| 🥇 1 | Node 12 / 16 EOL runtimes | vtrc-api, cu-central-api (12); centralize-api (16) | Dockerfiles pin node:12 / node:12.18.3 / node:16 | Migrate API layer to Go 1.22+ services (Hexagonal). Eliminates the Node-version tax entirely. Interim: bump to Node 20 LTS. |
| 🥈 2 | esm shim lock-in | vtrc-api, cu-central-api | package.json start script: node -r esm . | The esm package (unmaintained since 2019) is the real reason these services cannot upgrade Node. Go rewrite sidesteps this. Interim: convert to native ESM ("type":"module") and drop esm. |
| 🥉 3 | jsonwebtoken v8 (CVE-2022-23529 et al.) | vtrc-api, cu-central-api | Both pin ^8.5.1 | Critical auth-library CVE cluster. Upgrade to v9+ immediately; in Go target use golang-jwt/jwt/v5. |
| 4 | Legacy Apollo v2 stack (apollo-server v2, apollo-client v2, apollo-link-*, react-apollo) | All 5 repos | Per-repo tables above | Frontend: Nuxt 3 + @nuxtjs/apollo or nuxt-graphql-client. Backend: gqlgen (Go) or Apollo Server v4 if interim TS. |
| 5 | React 16 EOL across both frontends | vtrc-web, vtrc-rc-backoffice | react ^16.x | Nuxt 3 (Vue 3 + Composition API) under Feature-Sliced Design. Interim: React 18 + Vite. |
| 6 | react-scripts 3.4.3 (CRA) — deprecated toolchain | vtrc-rc-backoffice | react-scripts: 3.4.3 | CRA officially deprecated 2023. Migrate to Vite (interim) or Nuxt 3 (target). |
| 7 | Webpack 4 EOL | vtrc-web (and backoffice via CRA) | webpack: 4.42.0, html-webpack-plugin: 4.0.0-beta.11 | Webpack 5 (interim) → Vite/Rspack → Nuxt 3 (target). |
| 8 | redis v3 | vtrc-api, cu-central-api | redis ^3.x (callback API, CVE history) | Upgrade to redis v4 (Node) → in Go use redis/go-redis/v9. |
| 9 | mariadb v2 + mysql2 v2 dual drivers | vtrc-api | Both declared | Single-source driver (v3) → Go go-sql-driver/mysql. |
| 10 | PhantomJS-era PDF stack (html-pdf, node-qpdf, pdfreader) | vtrc-api | Dockerfile comments + deps | PhantomJS abandoned 2018. Use Playwright/Chromium (interim) → Go-side use chromedp, go-pdf, or outsource to a renderer microservice. |
| 11 | firebase-admin v9 + googleapis v59 | vtrc-api | Version pins | Massive API drift; upgrade to current → in Go use firebase.google.com/go/v4 and google.golang.org/api. |
| 12 | Draft.js + react-draft-wysiwyg unmaintained | vtrc-web, vtrc-rc-backoffice | Rich-text deps | Migrate to Tiptap (ProseMirror) or Lexical. |
| 13 | Draft dual date libs (moment + dayjs) | vtrc-rc-backoffice | Both present | Standardize on dayjs. In Nuxt 3 target use native Intl + @vueuse/core date utils. |
| 14 | Four UI component libraries in one app | vtrc-rc-backoffice | AntD v4 + MUI v5 + PrimeReact + styled-components | Consolidate to one design system (recommend AntD v5 or full MUI v5). Nuxt 3 target: Nuxt UI or PrimeVue. |
| 15 | Three styling approaches in one app | vtrc-rc-backoffice | AntD CSS-in-JS + Emotion + styled-components | Pick one (recommend styled-components or @emotion/css). |
| 16 | Three icon sets in one app | vtrc-rc-backoffice | @ant-design/icons + @mui/icons-material + @fortawesome/* | Standardize on one (recommend lucide-react / in Nuxt: lucide-vue-next). |
| 17 | Duplicate DnD libs | vtrc-rc-backoffice | react-sortable-hoc (deprecated) + array-move + @dnd-kit/* | Drop react-sortable-hoc; use @dnd-kit exclusively. |
| 18 | Three PDF viewers in one app | vtrc-web | react-pdf + @react-pdf-viewer/* + pdf-viewer-reactjs | Pick one (@react-pdf-viewer/core). |
| 19 | Typosquat / placeholder packages | cu-central-api (axois), vtrc-rc-backoffice (undefined-service-web, i, npm, save), vtrc-web (save, react-electron-webview ×2), vtrc-api (s, stream, css) | Per-repo tables | Purge and run npm audit + lockfile regeneration. Supply-chain audit recommended. |
| 20 | tsconfig safety disabled | centralize-api | strictNullChecks: false, noImplicitAny: false | Re-enable strict mode incrementally. Go target is strict by default. |
| 21 | axios v0.x CVE cluster | vtrc-api (^0.20), vtrc-web (^0.21.4) | Pinned below v1 | Upgrade to axios v1.x. Go target: stdlib net/http or resty. |
| 22 | No engines field anywhere | All 5 repos | rg '"engines"' → 0 | Add engines.node constraints; enforce via CI. |
| 23 | Dual lockfile in vtrc-web | vtrc-web | yarn.lock + package-lock.json both present | Pick one (yarn classic given existing yarn.lock). |
| 24 | No lockfile in centralize-api | centralize-api | ls centralize-api/yarn.lock → not found | Commit yarn.lock. CI must fail on lockfile drift. |
| 25 | Git-URL dependency (error-ex) | cu-central-api | "error-ex": "git+https://github.com/...node-error-ex.git" | Replace with a versioned npm package. |
| 26 | xlsx (SheetJS) on npm with CVE history | cu-central-api | xlsx ^0.16.9 | Move to SheetJS CDN build or exceljs. |
| 27 | ldapjs unmaintained | cu-central-api | ldapjs ^2.2.0 | Migrate to ldapts (active fork). Go target: go-ldap/ldap/v3. |
| 28 | multer v1 (CVE-2024-47764) | vtrc-api | multer ^1.4.3 | Upgrade to v2. |
| 29 | node-schedule in-process scheduler (no HA) | vtrc-api, cu-central-api | Both use it for cron jobs | Replace with a real job queue (BullMQ + Redis) → Go target: robfig/cron + distributed lock, or Asynq. |
| 30 | standard v14 + babel-eslint | vtrc-api, cu-central-api, vtrc-web | ESLint 6-era configs | Move to ESLint 9 + @babel/eslint-parser or Biome. |
1.4 Modernization Scorecard
| Dimension | vtrc-api | vtrc-web | vtrc-rc-backoffice | centralize-api | cu-central-api |
|---|---|---|---|---|---|
| Runtime modernity | 🔴 Node 12 | 🟢 Browser | 🟢 Browser | 🟡 Node 16 | 🔴 Node 12 |
| Framework support | 🔴 Apollo 2 EOL | 🔴 React 16 EOL | 🔴 React 16 + CRA EOL | 🟡 Nest 9 (1 gen old) | 🔴 Apollo 2 EOL |
| Dependency hygiene | 🔴 (3 stray pkgs) | 🔴 (2 stray pkgs, 3 PDF libs) | 🔴 (4 stray pkgs, 4 UI libs) | 🟡 (no lockfile, strict off) | 🔴 (typosquat axois, git URL) |
| Security posture | 🔴 (jwt v8, axios 0.20, multer 1) | 🔴 (axios 0.21, WC4) | 🔴 (xlsx-style, CRA) | 🟡 (mssql v9 ok; strict off) | 🔴 (ldapjs, xlsx, jwt v8) |
| Reproducibility | 🟡 (lockfile ok, no engines) | 🔴 (dual lockfile) | 🟡 (lockfile ok, no engines) | 🔴 (no lockfile) | 🟡 (lockfile ok, no engines) |
| Overall | 🔴 | 🔴 | 🔴 | 🟡 | 🔴 |
Bottom line: The platform is a frozen-in-time 2020-era Node/React/Apollo stack. Every sub-repo except centralize-api is critically end-of-life. The strategic path — Go (Hex/DDD) backends + Nuxt 3 (FSD) frontends — is not just an upgrade but a clean-slate de-risking of the entire dependency surface catalogued above.
Phase 1 complete. Proceed to 02-architecture-map.md.