3 · Persistence & integrations — workflow-api
อ้างอิง branch: uat
Six TypeORM connections
ประกาศทั้งหมดใน DatabasePgModule (workflow-api/src/core/database/database.module.ts (branch: uat):7-207)
1) postgres — PMS AI ของตัวเอง
| รายการ | ค่า / พฤติกรรม | หลักฐาน |
|---|---|---|
| Engine | PostgreSQL (type: 'postgres') | database.module.ts:14 |
| Env prefix | DB_PMS_* | :15-23 |
| Default database | pms_ai (ชื่อ DB จาก env; schema จาก DB_PMS_SCHEMA) | :19-20 |
| synchronize | DB_PMS_SYNCHRONIZE === 'true' | :21-22 |
| Pool | extra.max/min/idleTimeoutMillis/connectionTimeoutMillis | :26-37 |
| Entities | autoLoadEntities: true + Course forFeature | :24,200 |
.env.example ตั้ง DB_PMS_SYNCHRONIZE=true (.env.example:32) — อันตรายใน shared/UAT DB ถ้าใช้ค่านี้จริง (คล้าย CORR ของ synchronize บน MSSQL ในบริการอื่น)
Host ในตัวอย่าง: DB_PMS_HOST ชี้ IP ภายนอก (.env.example:26) — เป็น DB ของ PMS AI ไม่ใช่ MSSQL ของ Red Cross campus
2) vtrc — legacy core schema
| รายการ | ค่า | หลักฐาน |
|---|---|---|
| Engine | MSSQL (DB_SCHEMA default mssql) | :56 |
| Database | DB_VTRC_NAME default vtrc | :61 |
| Credentials | DB_USERNAME / DB_PASSWORD / DB_HOST ร่วมกับ connection อื่น | :57-60 |
| synchronize | false | :62 |
ตาราง IPD เช่น ipdBillingBatch, ipdBillingFile, ipdBillingItem, ipdLogs, ipdLogDetails ถูกเข้าถึงด้วย raw SQL จาก IpdBatchService ผ่าน DataSource ที่ inject มา — อยู่ใน schema ที่ vtrc-api เป็นเจ้าของตามชื่อ connection (cross-service DB coupling)
3) hrmi — dbHRMI_Center
| รายการ | ค่า | หลักฐาน |
|---|---|---|
| Database | DB_HRMI_NAME default dbHRMI_Center | :83 |
| ใช้ทำ | จับคู่พนักงาน/สิทธิ์ใน IPD match | module ipd-hrmi-match |
4) hrmi_nbc — dbHRMI_Center_NBC
| รายการ | ค่า | หลักฐาน |
|---|---|---|
| Database | DB_HRMI_NBC_NAME default dbHRMI_Center_NBC | :105-108 |
| ใช้ทำ | HRMI สาย NBC (org อีกชุด) |
5) benefit — read
| รายการ | ค่า | หลักฐาน |
|---|---|---|
| Database | DB_BENEFIT_NAME default benefit | :127 |
| Host | DB_BENEFIT_READ_HOST หรือ fallback DB_HOST | :128-130 |
| ใช้ทำ | อ่าน config / ข้อมูลสิทธิประโยชน์ |
6) benefit_write — write
| รายการ | ค่า | หลักฐาน |
|---|---|---|
| Database | ชื่อเดียวกับ benefit | :164 |
| Host | DB_BENEFIT_WRITE_HOST หรือ fallback read host | :168-169 |
| ใช้ทำ | AuditLogService เขียน healthCheckLogs; health-checkup mutations | audit-log.service.ts |
.env.example ตั้ง write host เป็น 10.188.128.58 (.env.example:55-56) — อาจเป็นโฮสต์เดียวกับ read ในบาง env (UNVERIFIED ว่าแยกจริงในทุก environment)
Architectural meaning — distributed monolith
workflow-api
│
├── postgres/pms_ai ← ของตัวเอง
├── MSSQL/vtrc ← ของ vtrc-api (legacy)
├── MSSQL/dbHRMI_Center ← ของ HRMI
├── MSSQL/dbHRMI_Center_NBC ← ของ HRMI NBC
└── MSSQL/benefit ← ของ benefit-api (read + write)ไม่ เรียก REST/GraphQL ของ vtrc-api หรือ benefit-api เพื่อข้อมูลเหล่านี้ — ต่อ DB ตรง (CORR-WORKFLOW-01)
ผลกระทบ: schema change ในทีมเจ้าของ DB ทำให้ workflow-api พังตอน runtime โดยไม่มี contract version ที่ชัดเจน
IPD tables (จาก SQL ใน service — ไม่มี TypeORM entity ใน repo)
จาก query ใน ipd-batch.service.ts ที่อ่านได้:
| Table | บทบาท |
|---|---|
ipdBillingBatch | header ของชุดวางบิล (status, dates, hospitalCode, memo*, totals) |
ipdBillingFile | ไฟล์ Excel ต่อ batch (validationStatus, isActive) |
ipdBillingItem | แถวบิล (claimAmount, claimLct, eligibility flags, …) |
ipdLogs | audit ของ batch actions |
ipdLogDetails | field-level change ของ log |
Connection ที่ใช้: DataSource ของ IPD module (ชื่อ connection ใน inject — ผูกกับ vtrc ตาม topology ของ database.module)
PostgreSQL embedding entities
อยู่ที่ src/modules/embedding/entities/ (branch: uat):
| Entity | หน้าที่ |
|---|---|
MasterCourse / MasterCourseEmbedded | หลักสูตรก่อน/หลัง embed |
EmbeddingJob / EmbeddingJobItem | lifecycle + รายการงาน |
CourseGroup | กลุ่มจาก similarity clustering |
CourseAssignment | มอบหมายให้พนักงาน |
database/schema.sql อธิบายตาราง employees / performance_records / courses ที่ ไม่ตรง ชุด entity นี้ — อย่าใช้เป็น schema จริง (QUAL-WORKFLOW-03)
Audit log (healthCheckLogs)
AuditLogService (workflow-api/src/core/audit-log/audit-log.service.ts (branch: uat)):
- Table คงที่:
healthCheckLogs - Connection:
benefit_write - Action union กว้าง:
CREATE,EDIT,APPROVE,REJECT,SIMULATE,BULK_DECISION, …
มี fallback query เมื่อเจอ error แบบ "Invalid column name 'parentId'" แล้วลอง query ชุดที่ไม่มีคอลัมน์นั้น — บ่งชี้ schema drift ข้าม environment (QUAL-WORKFLOW-01, ดูช่วงบรรทัด ~120-160 และ ~232-266 ตาม docs เดิมที่ verify แล้ว)
External integrations
AI Router (ManageAI)
| Operation | URL | Auth | หลักฐาน |
|---|---|---|---|
| Chat completion | {AI_ROUTER_BASE_URL}/chat/completions | Bearer AI_ROUTER_API_KEY | llm.service.ts:41-79 |
| Embeddings | {AI_ROUTER_BASE_URL}/embeddings | Bearer เดียวกัน | llm.service.ts:82-113 |
Default base URL ในโค้ด: https://ai-router.manageai.co.th/v1 (llm.service.ts:31-34)
โมเดล embedding ใน .env.example: Qwen/Qwen3-Embedding-8B, dimensions 4096 (.env.example:12,18)
ถ้าไม่มี API key — console.error ตอน construct (llm.service.ts:36-38) แต่ service ยัง boot ได้
Email
nodemailer อยู่ใน dependencies (package.json:38) และมี ipd-notification.service.ts — รายละเอียด SMTP env ไม่ได้ ไล่ครบในรอบนี้ (UNVERIFIED ว่าใช้จริงในทุก flow)
Static uploads
main.ts:21-23 serve ./uploads ที่ prefix /workflow-api/ — ใช้กับไฟล์ IPD ที่อัปโหลด
Env surface (ชื่อตัวแปร — ไม่ใส่ค่า secret)
จาก .env.example (branch: uat):
| กลุ่ม | ตัวแปร |
|---|---|
| App | PORT, NODE_ENV, SWAGGER_PATH, BASE_PATH, PUBLIC_API_URL, SWAGGER_PUBLIC_URL |
| AI | AI_ROUTER_API_KEY, AI_ROUTER_BASE_URL, AI_ROUTER_EMBEDDING_MODEL, EMBEDDING_* |
| Postgres | DB_PMS_HOST, DB_PMS_PORT, DB_PMS_NAME, DB_PMS_SCHEMA, DB_PMS_USERNAME, DB_PMS_PASSWORD, DB_PMS_SYNCHRONIZE, pool vars |
| MSSQL shared | DB_SCHEMA, DB_USERNAME, DB_PASSWORD, DB_HOST, DB_PORT |
| MSSQL DBs | DB_VTRC_NAME, DB_HRMI_NAME, DB_HRMI_NBC_NAME, DB_BENEFIT_NAME |
| Benefit hosts | DB_BENEFIT_WRITE_HOST, DB_BENEFIT_WRITE_PORT (+ read host optional) |
SEC-WORKFLOW-02 — ไฟล์ที่ชื่อว่า .env.example มีค่า password/API key จริง ไม่ใช่ placeholder; ต้อง rotate และแทนด้วย dummy ในตัวอย่าง
Cron / queue
- ไม่มี
@nestjs/scheduleในpackage.json - ไม่มี Bull/Redis queue ใน dependencies ที่อ่านได้
- Embedding job และ IPD batch ถูก trigger จาก HTTP ของผู้ใช้
Local disk artifacts
| Path | ผู้เขียน | หมายเหตุ |
|---|---|---|
./uploads/ | IPD file upload | serve ที่ /workflow-api/ |
embedding .npy files | embedding utils | เก็บเวกเตอร์ numpy |
logs/ | Winston + Dockerfile mkdir -p logs | application/error rotate |
Persistence ของ uploads/npy ข้าม deploy ขึ้นกับ volume mount ซึ่งไม่ปรากฏใน Dockerfile (OBS)