1 · Repository map — workflow-api
โครงสร้างอ้างอิง branch uat (~153 ไฟล์ tracked ไม่รวม node_modules, .git, dist)
ทีมกำหนด convention "NestJS Clean Architecture" ใน .cursor/rules/backend-clean-architecture.mdc — core/ = infra, common/ = utility เบา, integrations/ = external client, modules/ = business domain
Tree
workflow-api/
├── .cursor/rules/backend-clean-architecture.mdc
├── artifacts/screenshots/generate-api-slides.mjs เครื่องมือ dev ไม่ใช่ runtime
├── database/
│ ├── schema.sql schema ตัวอย่างเก่า — ไม่ตรง entity จริง (QUAL-WORKFLOW-03)
│ └── seed-data.sql
├── docs/
│ ├── pms-ai-api-spec.md
│ └── pms-ai-test-cases.md
├── src/
│ ├── main.ts
│ ├── app.module.ts
│ ├── common/
│ │ ├── auth/jwt-actor.util.ts decode JWT ไม่ verify — ใช้ทั่ว repo
│ │ ├── errors/ error-codes, error-formatter
│ │ ├── filters/http-error.filter.ts
│ │ └── validation/validate-request.ts
│ ├── core/
│ │ ├── audit-log/ เขียน healthCheckLogs บน benefit_write
│ │ ├── database/
│ │ │ ├── database.module.ts 6 TypeORM connections (export DatabasePgModule)
│ │ │ ├── entities/course.entity.ts
│ │ │ └── services/course-pg.service.ts
│ │ ├── logger/logger.module.ts
│ │ └── middleware/request-context.middleware.ts
│ ├── integrations/
│ │ └── llm/llm.service.ts AI router (chat + embeddings)
│ ├── modules/
│ │ ├── db-connection-check/ GET health ของหลาย DB
│ │ ├── embedding/ ~35 ไฟล์ — jobs, groups, assignments, reports
│ │ ├── health-checkup/
│ │ │ ├── extra-benefit-persons/
│ │ │ └── health-program-config/ controller ~672 บรรทัด, service ~1398
│ │ └── ipd/ ~25 ไฟล์ — batch + documents + HRMI match
│ └── types/nestjs-missing-modules.d.ts
├── Dockerfile multi-stage node:22-alpine + pnpm
├── .env.example มี secret จริง (SEC-WORKFLOW-02)
├── .env.uat
├── package.json name: ai-pms-nest
└── jest.config.js มี unit/e2e specs กระจายใน modulesRoot module wiring
AppModule นำเข้า (workflow-api/src/app.module.ts (branch: uat):11-23):
| Import | หน้าที่ |
|---|---|
ConfigModule.forRoot({ envFilePath: '.env' }) | โหลด env ทั้งแอป |
LoggerModule | Winston daily rotate |
AuditLogModule | audit ข้าม domain |
DbConnectionCheckModule | health check DB |
EmbeddingModule | PMS AI |
HealthCheckupModule | โปรแกรมตรวจสุขภาพ |
IpdModule | IPD billing |
RequestContextMiddleware ผูกทุก route (app.module.ts:26-28)
หมายเหตุ — DatabasePgModule ไม่ได้ import โดยตรงใน AppModule; ถูกดึงเข้าผ่าน feature modules ที่ import TypeORM connections (embedding / ipd / health / db-check)
Module breakdown
| Module | Controllers | Path prefix (หลัง global prefix) | หลักฐาน |
|---|---|---|---|
DbConnectionCheckModule | 1 | pms-ai/db-connections | db-connection-check.controller.ts:6 |
EmbeddingModule | 4 | pms-ai/embedding/jobs, pms-ai/course-groups, pms-ai/assignments, pms-ai/reports | controllers ใน modules/embedding/ |
HealthCheckupModule | health-program-config (+ extra-benefit-persons) | health-checkups/health-programs/configurations | health-program-config.controller.ts:34 |
IpdModule | 4 | ipd, approval-center, accounting-center, chartOfAccount | ipd.controller.ts:49, sibling controllers |
HTTP endpoint inventory (สรุป)
Global prefix จริง: /workflow-api/api/v1 (จาก .env.example BASE_PATH + api/v1)
IPD (IpdController → ipd/...)
| Method | Path | หมายเหตุสั้น | หลักฐาน |
|---|---|---|---|
| GET | /ipd/batches | list กรองตาม role | ipd.controller.ts:61 |
| POST | /ipd/batches | สร้าง — CHULA only | ipd.controller.ts:75 |
| PATCH | /ipd/batches/:batchId | save draft | ipd.controller.ts:91 |
| GET | /ipd/batches/:batchId | detail | ipd.controller.ts:108 |
| GET | /ipd/batches/:batchId/items | รายการบิล | ipd.controller.ts:121 |
| PATCH | /ipd/batches/:batchId/items/:itemId | ตัดสินรายแถว | ipd.controller.ts:142 |
| PATCH | /ipd/batches/:batchId/items | bulk decision | ipd.controller.ts:163 |
| POST | /ipd/batches/:batchId/reject | ปฏิเสธ | ipd.controller.ts:183 |
| POST | /ipd/batches/:batchId/files | upload Excel | ipd.controller.ts:210 |
| DELETE | /ipd/batches/:batchId | soft delete | ipd.controller.ts:231 |
| DELETE | /ipd/batches/:batchId/files/:fileId | ลบไฟล์ | ipd.controller.ts:246 |
| GET | /ipd/batches/:batchId/files/:fileId/download | ดาวน์โหลด | ipd.controller.ts:264 |
| POST | /ipd/batches/:batchId/submit | ส่งตรวจ (→ PENDING_REVIEW) | ipd.controller.ts:291 |
| POST | /ipd/batches/:batchId/submit-approval | ส่งอนุมัติ | ipd.controller.ts:307 |
| POST | /ipd/batches/:batchId/approval-decision | อนุมัติ/คืน/ปฏิเสธ | ipd.controller.ts:323 |
| GET | /ipd/batches/:batchId/logs | audit logs | ipd.controller.ts:340 |
| GET | /ipd/batches/:batchId/export/* | cover-memo / summary-by-org / person / coa | ipd.controller.ts:353-442 |
| GET/PATCH | /ipd/document-config | config เอกสาร | ipd.controller.ts:369-389 |
ทุก handler เรียก resolveIpdUser(req) ก่อนเข้า service (ipd.controller.ts:63 เป็นต้นแบบ)
Approval / Accounting / Chart of account
| Controller | Path | Endpoints หลัก |
|---|---|---|
ApprovalCenterController | approval-center | GET pending |
AccountingCenterController | accounting-center | GET pending |
ChartOfAccountController | chartOfAccount | POST createChartOfAccount |
หลักฐาน — approval-center.controller.ts:10,17, accounting-center.controller.ts:10,16, chart-of-account.controller.ts:10,24
Embedding (PMS AI)
| Method | Path | สถานะ | หลักฐาน |
|---|---|---|---|
| POST | /pms-ai/embedding/jobs/initial | เปิดใช้ | embedding.controller.ts:26 |
| GET | /pms-ai/embedding/jobs/:id | เปิดใช้ | embedding.controller.ts:40 |
| GET | /pms-ai/embedding/jobs | comment ปิด — "Temporarily disabled per product direction" | embedding.controller.ts:59 |
| POST | /jobs/:id/cancel, /retry | comment ปิด | embedding.controller.ts:71,90 |
| GET | /pms-ai/course-groups | list กลุ่มหลักสูตร | course-groups.controller.ts:8-12 |
| POST | /pms-ai/assignments | มอบหมาย | assignments.controller.ts:20-24 |
| POST | /pms-ai/assignments/sync, /cancel | sync / cancel | assignments.controller.ts:45,61 |
| GET | /pms-ai/reports/course-groups | รายงาน | reports.controller.ts:8-12 |
| GET | /pms-ai/db-connections/health | ตรวจ DB | db-connection-check.controller.ts:6,12 |
Health program config
| Method | Path | หลักฐาน |
|---|---|---|
| GET | /health-checkups/health-programs/configurations | health-program-config.controller.ts:110 |
| GET | .../dropdowns | :187 |
| GET | .../:id | :271 |
| POST | .../ (create) | :396 |
| PATCH | .../:id | :502 |
| PATCH | .../:id/toggle-status | :563 |
| DELETE | .../:id | :595 |
| POST | .../eligibility-simulator | :663 |
Mutation ใช้ resolveHealthProgramActor(req, ...) สำหรับชื่อใน audit log — ไม่ใช่ cryptographic auth
Embedding entities (PostgreSQL pms_ai)
อยู่ที่ src/modules/embedding/entities/:
| Entity file | หน้าที่โดยย่อ |
|---|---|
master-course.entity.ts | master หลักสูตร |
master-course-embedded.entity.ts | หลักสูตรที่ embed แล้ว |
embedding-job.entity.ts | job lifecycle |
embedding-job-item.entity.ts | รายการใน job |
course-group.entity.ts | กลุ่มที่จัดจาก similarity |
course-assignment.entity.ts | มอบหมายให้พนักงาน |
Course ใน core/database/entities/course.entity.ts เป็น entity ที่ DatabasePgModule ลงทะเบียนด้วย TypeOrmModule.forFeature([Course], 'postgres') (database.module.ts:200)
IPD supporting services
| ไฟล์ | บรรทัดโดยประมาณ | หน้าที่ |
|---|---|---|
ipd-batch.service.ts | ~2753 | CRUD batch, status transitions, SQL หลัก |
ipd-document.service.ts | — | parse Excel + generate docx/xlsx/pdf buffers |
ipd-hrmi-match.service.ts | — | จับคู่รายการบิลกับพนักงาน HRMI |
ipd-notification.service.ts | — | แจ้งเตือน (nodemailer ใน dependencies) |
ipd.constants.ts | ~214 | BATCH_STATUS, Excel column map, affiliation maps |
ipd-user.util.ts | ~72 | resolveIpdUser / requireRole / inferHospitalUserRole |
ไฟล์ที่ควรรู้จักก่อนแก้โค้ด
| ไฟล์ | ทำไมสำคัญ |
|---|---|
src/core/database/database.module.ts:9-199 | 6 connections — รู้ว่า module ไหนแตะ DB ของ service อื่น |
src/common/auth/jwt-actor.util.ts:1-4,33-47 | จุดเริ่ม SEC-WORKFLOW-01 — comment ในไฟล์ยืนยันเอง |
src/modules/ipd/ipd-user.util.ts:20-65 | role จาก sourceDB ไม่ใช่ role claim ที่ verify แล้ว |
src/modules/ipd/ipd.constants.ts:3-15,24-30 | status machine + mapping hospital จาก sourceDB |
src/integrations/llm/llm.service.ts:41-113 | เรียก AI router ภายนอก |
database/schema.sql | อย่าเชื่อ เป็น source of truth — เก่ากว่า entity จริง |
Tests
Repo มี Jest specs จำนวนมากใต้ modules/ (เช่น ipd-batch.service.spec.ts, embedding.e2e.spec.ts, ipd-user.util.spec.ts) — ต่างจาก chat-center-api ที่มีแค่ e2e scaffold ว่าง ระดับความครอบคลุมต่อ flow ไม่ได้ วัดในรอบเอกสารนี้ (UNVERIFIED coverage %)