Skip to content

Documentation Integrity Report

FieldValue
Protocol/docs-verify
Date (local)2026-07-11
ModeCORPUS
Scope pathsdocs/**/*.md (excluding node_modules, .vitepress build)
Repos consultedvtrc-api, cu-central-api, centralize-api, vtrc-web, vtrc-rc-backoffice
Files in scope202
Files fully claim-extractedTrap-driven + high-risk volumes (see §7); not every pedagogical sentence in all 202 files
Overall verdictFAIL
Evidence standardStatic code + config in workspace (no e2e / no production runtime)
Prior audits as leads onlyYes — docs/DOC-CODE-DISCREPANCY-AUDIT.md, docs/volume-17-appendices/08-changelog-errata.md

1. Executive Verdict

English: The corpus FAILS national-grade integrity. Multiple P0 claims still instruct readers to use NestJS centralize-api as the live HR/auth path, store OTP in vtrc Redis, treat KBANK as Bangkok Bank, and follow an invented statusKcash map. Primary code shows END_POINT_CENTRALIZE → cu-central-api GraphQL/LDAP, OTP in MariaDB (Models.Otp), Kasikorn wording, and statusKcash ids 6–10 with SUCCESS = '9'.

ไทย: คู่มือทั้งชุด ไม่ผ่าน เกณฑ์ — ยังมีข้อผิด P0 ที่ชี้อ่านไป NestJS เป็นสะพาน HR/auth, OTP ใน Redis ของ vtrc, KBANK = กรุงเทพ, และตาราง statusKcash ที่ไม่ตรงโค้ด ทั้งที่หลักฐานยืนยันว่า live path คือ cu-central-api, OTP อยู่ใน MariaDB, ธนาคารคือกสิกรไทย, และ SUCCESS = รหัส '9'


2. Canonical Truths (verified this run)

FactValueEvidence
Live HR/GraphQL bridge from vtrc-apiGraphQLClient(END_POINT_CENTRALIZE)vtrc-api/api/src/centralize/controllers/graphql.js:3,21,84
Auth forward from vtrc-api${END_POINT_CENTRALIZE_AUTH}/signin (and related)vtrc-api/api/src/centralize/controllers/auth.js:28,52,75,98
Client target in vtrc-api examplehttp://localhost:8082/api/graphql and /authvtrc-api/api/.env.example:36-37 · class CLIENT_TARGET / ENV_EXAMPLE
cu-central listen defaultAPP_PORT = 8080cu-central-api/main-api/src/config.js:20; .env.example:4 · class CODE_DEFAULT
cu-central Dockerfile metadataEXPOSE 9000cu-central-api/main-api/Dockerfile:18 · class DOCKER_EXPOSE only
cu-central compose host ports8000:8000, 8002:8000, 8003:8000cu-central-api/docker-compose.yml:53,72,89 · class COMPOSE_HOST
NestJS hrPaySlip method@Post() under @Controller('hrPaySlip')centralize-api/src/modules/hrPaySlip/hrpayslip.controller.ts:13,18
NestJS employee GET count14employee.controller.ts @Get( count = 14
NestJS HTTP route total17 (App 1 + Employee 14 + PaySlip 1 + TimeTemp 1)Controllers under centralize-api/src
NBC MSSQL name in NestJS SQLdbHRMI_Center_NBC (not dbHRMI_NBC)Grep unique dbHRMI_* under centralize-api/src
vtrc-api Sequelize exportsdb, db2 onlyvtrc-api/api/src/connector.js:8,29,50
KBANK institutional label in config copyกสิกรไทยvtrc-api/api/src/config.js:389
statusKcash SUCCESSid '9', status: 'SUCCESS', label PAID / โอนสำเร็จvtrc-api/api/src/config.js:508-511
statusKcash FAILED ids'6','7','8','10' (no id '0')config.js:488-518
Active vtrc-api cronsFund rate if APP_NO===1; updateDelegatesExpire + statLog ungatedvtrc-api/api/src/crons.js:14-27
OTP persistenceModels.Otp.create in cu-central; expire minutes default 3sendOtp.model.js:12-14; sendOtp.js:113; config.js:74
vtrc-api Redis cache on common pathsCall sites largely commentede.g. routes.js:411-442; resolvers/post.js:39-41
OTP request from vtrc-apiProxied via requestOtpCD → GraphQL mutationverification.js repository + centralize/controllers/verification.js:42-47
Device key fieldvalue.key === apiKeyvtrc-api/api/src/index.js:34; config.js:45 (key:)
Session Redis key pattern (cu-central)sess:{userUid}_{sessionId}cu-central-api/main-api/src/lib/session/session.js:18-19
syncModels active entries79Measured from vtrc-api/api/src/lib/model.js
Gate #4 session errorsCANNOT_ACCESS / TOKEN_INVALIDsession.js:24,39,44
Backoffice Apollo transportcreateUploadLink; apiKeyNews(); refresh via Queries.refreshTokenBOvtrc-rc-backoffice/src/config/apollo.js:39,48-65,71-76
Backoffice isLoggedInBoolean (token ∧ refreshToken)utils/auth.js
Backoffice Dockerfile runtimeStage-2 nginx:1.24.0vtrc-rc-backoffice/Dockerfile:13
Web checkLinkURL originsvtrc / uat-vtrc / localhost → endpoints as codedvtrc-web/src/config/apollo.js (verified this run)
Compose network_mode: hostOn nginx service only (vtrc-api compose)vtrc-api/docker-compose.yml:34
NestJS caller from vtrc-apiNot found in workspace HTTP clientsGrep of bridge uses GraphQL/auth URLs only; E-08 stands

3. Findings

IDDocClassClaim (short)VerdictSevCode evidenceCorrection
F-001volume-00/.../02-system-map.mdC1/C2Payslip steps 3–4 → NestJS REST + TypeORMWRONGP0slip.jsGraphqlCDWithToken; graphql.js:21Route to cu-central GraphQL
F-002volume-00/.../02-system-map.mdC2cu-central Port 9000WRONGP0APP_PORT=8080; EXPOSE 9000 metadata onlyUse port classification rubric
F-003volume-00/.../02-system-map.mdC2GET /api/hrPaySlipWRONGP0@Post() hrPaySlipDocument POST
F-004volume-00/.../02-system-map.mdC4DB name dbHRMI_NBCWRONGP0dbHRMI_Center_NBC in NestJS SQLRename
F-005volume-00/.../02-system-map.mdC6Redis cache payslip:{emp}:{date} on pathWRONGP0No active write on slip path; cache helpers commentedRemove or mark vestigial
F-006volume-00/.../02-system-map.mdC8/C2URL table attributed solely to vtrc-web apollo includes backoffice originsPARTIALP1Web apollo.js lacks backoffice hosts; BO has own fileSplit tables per frontend
F-007volume-00/.../02-system-map.mdC1Absolute “never write MSSQL”PARTIALP1Same doc admits cu-central two-way syncSoften absolute rule
F-008volume-00/.../03-employee-day.mdC1Slip miss → NestJSWRONGP0Same as F-001Align with cu-central
F-009volume-00/.../04-admin-day.mdC10KBANK = ธนาคารกรุงเทพWRONGP0config.js:389 กสิกรไทยReplace bank name
F-010volume-00/.../04-admin-day.mdC6Check K-Cash cronWRONGP0crons.js has no K-Cash jobManual import only
F-011volume-00/.../04-admin-day.mdC2POST /api/downloadExcelWRONGP1routes.js GET /download/excel/:tableFix method/path
F-012volume-00/.../05-key-features.mdC1/C6Time attendance → NestJS + Redis; cron pulls K-Cash/กรุงเทพWRONGP0timeAttendance.js GraphQL; no K-Cash cronRewrite
F-013volume-00/.../05-key-features.mdC8Paths like vtrc-api/typeDefs/...WRONGP1Real root vtrc-api/api/src/Fix prefixes
F-014volume-00/.../06-quick-glossary.mdC10/C4KBANK Bangkok; dbHr in vtrc connector.js; dbHRMI_NBCWRONGP0connector exports db/db2; bank text; NBC nameFix glossary rows
F-015volume-01/.../04-payroll-slip.mdC1NestJS + Redis on slipWRONGP0GraphQL bridgeFix flow
F-016volume-01/.../10-time-attendance.mdC1Diagram NestJS (conflicts later prose)WRONG + CONFLICTP0GraphQL; doc self-conflictUnify on cu-central
F-017volume-01/.../11-payments-kbank.mdC10ธนาคารกรุงเทพ (KBANK)WRONGP0กสิกรไทยRename
F-018volume-01/.../07-welfare-hospital.mdC10กรุงเทพ / K-CashWRONGP0SameRename
F-019volume-04/.../index.mdC1Topology edge vtrc-api → NestJSWRONGP0No NestJS clientRemove or mark unconfirmed
F-020volume-04/.../09-scorecard-comparison.mdC1Auth forward → centralize-apiWRONGP0END_POINT_CENTRALIZE_AUTHSay cu-central
F-021volume-03/.../index.mdC2“port 8082 … ตรงกับ cu-central-api” as absolutePARTIALP0CODE_DEFAULT 8080; CLIENT_TARGET 8082Qualify by class
F-022volume-05/.../index.md + 01 + 03 + 09C712 / 14 / 16 endpoints (inconsistent)WRONGP1Measured 17 total; employee 14 GETHarmonize to 14/17
F-023volume-07/.../03-apollo-checklinkurl.mdC5/C8createHttpLink, getApikey, JWT-from-isLoggedInWRONGP0createUploadLink, apiKeyNews, boolean isLoggedInRewrite from apollo.js
F-024volume-07/.../02-bootstrap-build.mdC7Docker serve / alpine narrativeWRONGP0nginx:1.24.0 stage-2Rewrite Dockerfile section
F-025volume-07/.../04-routing-auth-gate.mdC5PrivateRoute / getApikey menuWRONGP0No PrivateRoute; workforce axiosAlign with App/Sider
F-026volume-08/.../01-persistence-topology.md + 09 + 11C4dbHRMI_NBC; NestJS as primary live reader framingWRONG / PARTIALP0dbHRMI_Center_NBC; live reader via cu-central for vtrc-apiFix names + ownership
F-027volume-09/.../02-authentication-flow.mdC1/C5Login → NestJS; MSSQL password checkWRONGP0Auth REST to cu-central; LDAP at cu-centralFull rewrite of live path
F-028volume-09/.../05-credential-secrets.md + 10-supply-chain-runtime.mdC1Remaining gate = NestJS passwordWRONGP0cu-central authFix naming
F-029volume-10/.../02-auth-headers.mdC5/C8Filter key.apiKey; Redis sess:<sid>WRONGP1value.key; sess:{uid}_{sid}Fix snippets
F-030volume-10/.../01-api-topology.mdC2Implies cu-central default 8082 in placesPARTIALP1CODE_DEFAULT 8080Qualify
F-031volume-11/.../03-welfare-hospital.mdC6statusKcash id '0' SUCCESS; labels บัญชีปิด…WRONGP0Literal config.js:488-518Replace table with code dump
F-032volume-12/.../11-cron-scorecard.md + relatedC6Every job gated APP_NO===1WRONGP0Only fund-rate gatedCorrect SPOF narrative
F-033volume-12/.../04-docker-compose.mdC2Stack-wide network_mode: hostWRONGP1Only nginxFix table
F-034volume-12/.../01-hosting-topology.mdC1NestJS on same prod traffic path without caveatPARTIALP0Caller unconfirmed (E-08)Add unconfirmed label
F-035volume-12/.../07-database-redis.mdC5/C6vtrc Redis OTP TTL 5m / cron locksWRONGP0OTP in Models.Otp; crons no RedisRewrite vtrc Redis section
F-036volume-13/.../06-redis-operations.mdC6otp:* on vtrc-redis TTL 300sWRONGP0DB OTP; TTL 3 minReplace runbook
F-037volume-13/.../08-debug-playbooks.mdC6Debug OTP via Redis KEYSWRONGP0SamePoint to cu-central DB
F-038volume-13/.../07-user-session-management.mdC6OTP stored in RedisWRONGP0SameFix step
F-039volume-14/.../02-high-security.md vs volume-16/.../04-debt-id-index.mdC9SEC-6/7/8 ID meaningsCONFLICTP0Vol14: SEC-6 trustCert, SEC-7 axois, SEC-8 PII; A.4 swappedMake A.4 match Vol 14
F-040volume-16/.../06-environment-variables.mdC3DB_USER for vtrc-api; cu PORT=8082 patternsWRONGP1vtrc .env.example uses DB_USERNAME; cu APP_PORT=8080Regenerate from examples
F-041volume-16/.../05-volume-cross-ref.mdC2“cu-central … port 8082” unqualifiedPARTIALP1Same as F-021Qualify
F-042volume-15/.../08-infrastructure-evolution.mdC1Current-state → NestJS centralizeWRONGP0Live bridge cu-centralFix current-state only
F-043docs/audit/*C1/C2NestJS live path; cu-central port 9000WRONGP1Same evidenceMark audit superseded or fix
F-044Vol 3 persistence / mapC4/C7syncModels 88; core User model pathWRONGP179 active; no models/core/userRecount / retarget
F-045Vol 3 02-graphql-pipeline.mdC5Gate emits SESSION_INVALID/EXPIREDWRONGP1CANNOT_ACCESS / TOKEN_INVALIDFix codes
F-046Vol 6 inventory (queries 95; user components 56)C7CountsWRONGP1~137 gql; 36 user folders (measure when fixing)Recount before publish
F-047Vol 0 axios “16” instancesC716 axiosSTALEP215 axios*.js filesUpdate count
F-048Various file:line (execSync, nginx compose line)C8Exact linesSTALEP2Drift vs current filesRefresh on edit

4. Cross-Document Conflicts

IDDoc ADoc BTopicResolution (code wins)
X-001Vol 2.1–2.5 (cu-central live)Vol 0/1/9 NestJS liveLive HR/auth bridgecu-central-api via END_POINT_CENTRALIZE(_AUTH)
X-002Vol 10 NestJS “17 endpoints”Vol 5 “12/16 endpoints”NestJS route inventory17 total; employee 14 GET
X-003Vol 14 SEC-6/7/8/10 titlesA.4 debt-id indexDebt ID mappingVol 14 chapters are authoritative for IDs
X-004Vol 2 Redis vestigialVol 12/13 OTP in RedisOTP storecu-central MariaDB otp
X-005Vol 0.3 summary (cu-central) vs steps (NestJS)Same fileInternal contradictionPrefer code path GraphQL
X-006A.1 glossary vs A.2 “Volunteer Thai Red Cross”Acronym/glossaryVTRC expansionAlign to one definition (verify with org naming — UNVERIFIED if no charter in repo)

5. UNVERIFIED Register

IDClaimBlockerHow to unlock
U-001NestJS centralize-api has a production callerNo client in this workspace (E-08); team-mentioned NEW_CENTRAIL_API / benefit-api absentObtain caller repo/config
U-002Host nginx TLS cipher suite / prod cert chainHost-mounted nginx not fully auditable as production (E-02)Ops sslscan + host conf
U-003Exact production listen port of cu-central behind nginxCompose shows 8000; client example 8082; code default 8080Confirm deployed env + nginx upstream
U-004Official English expansion of “VTRC”Conflict between glossary and acronyms; no charter file in workspaceOrg naming authority
U-005Every non-trap factual sentence in all 202 filesTime-boxed CORPUS; full line-by-line claim extraction incomplete for low-risk narrative chaptersFILE/VOLUME passes per volume
U-006npm/yarn audit CVE inventory as stated in Vol 14Network audit not re-run this session (E-01)Run audits with network

6. Correction Checklist

P0

  • [ ] Theme A — Live bridge: Fix NestJS-as-live-path in Vol 0, 1, 4, 8, 9, 12, 15 (and diagrams). Match Vol 2/3 wording.
  • [ ] Theme B — Ports: Rewrite all absolute “cu-central = 8082/9000” using CODE_DEFAULT / CLIENT_TARGET / COMPOSE / EXPOSE classes.
  • [ ] Theme C — KBANK: Replace ธนาคารกรุงเทพ with กสิกรไทย in Vol 0/1.
  • [ ] Theme D — OTP/Redis: Rewrite Vol 12.7 and Vol 13.6/7/8; remove otp:* vtrc-redis runbooks for registration OTP.
  • [ ] Theme E — statusKcash + cron gating: Replace Vol 11.3 table from config.js:488-518; fix Vol 12 cron APP_NO narrative; remove K-Cash cron claims.
  • [ ] Theme F — Volume 7 Apollo/Docker/auth: Rewrite 7.2–7.4 from current source files.
  • [ ] Theme H1 — Debt IDs: Make A.4 match Vol 14 SEC/LEG IDs exactly.

P1

  • [ ] NestJS endpoint counts → 14 employee GET / 17 total across Vol 5.
  • [ ] dbHRMI_Center_NBC rename across Vol 0/8/glossary.
  • [ ] Vol 10 auth header + session key snippets.
  • [ ] Env appendix regenerate from .env.example files.
  • [ ] Vol 3 model counts, User path, session error codes.
  • [ ] Vol 6/7 inventory recounts (queries, folders, axios).
  • [ ] Mark or repair docs/audit/* as superseded where wrong.

P2

  • [ ] Refresh stale file:line citations when editing those chapters.
  • [ ] Axios instance count 15; minor LOC drifts.

7. Coverage & Limitations

  • Full trap verification (T1–T14): completed this run against primary sources.
  • Mandatory cross-doc sweeps: completed (bridge, ports, bank, OTP/Redis, debt IDs).
  • Volumes with dense claim re-check: 0, 1 (payments/slip/attendance), 3 (index/bridge claims), 4 (topology/scorecard), 5 (counts), 7 (Apollo/Docker), 8 (DB names), 9 (auth flow), 10 (auth headers/topology), 11.3, 12 (cron/redis/compose), 13 (redis/OTP runbooks), 14↔16 debt/env, 15.8 current-state, docs/audit spot.
  • Deferred (U-005): exhaustive sentence-level extraction for remaining business narrative chapters (parts of Vol 1, 6 page deep-dives, 8 ERD field-by-field, 11 non-hospital workflows, 15 aspirational roadmap text except current-state). Deferred reason: CORPUS trap completion first; residual risk is lower-severity inventory/pedagogy unless traps reappear.
  • Runtime verification: none.
  • Prior audits: used as lead lists only; every P0 above re-validated in this run.

Add to docs/volume-17-appendices/08-changelog-errata.md if not already present:

  • E-09 NestJS still described as live bridge in multiple volumes
  • E-10 cu-central port confusion (8080 / 8082 / 9000)
  • E-11 KBANK documented as Bangkok Bank
  • E-12 OTP/Redis mis-attributed to vtrc-api
  • E-13 statusKcash table in Vol 11 diverges from config.js
  • E-14 Volume 7 Apollo/Docker docs diverge from source
  • E-15 A.4 debt-id index conflicts with Vol 14

9. Sign-off

CheckStatus
No CORRECT without evidence☑ (canonical truths all cited)
All P0 have dual evidence when trap-class
Cross-doc sweeps done for scope
UNVERIFIED not hidden☑ (U-001–U-006)
Overall verdict consistent with findingsFAIL (P0 open)
Full 202-file sentence extraction☐ deferred (U-005) — prevents PASS even after P0 fixes until VOLUME sweeps complete

Action checklist (earlier lead document): docs/DOC-CODE-DISCREPANCY-AUDIT.md
This file is the /docs-verify CORPUS report of record for 2026-07-11.