recruitment-api Deep Dive
recruitment-api (branch: prod, package name rest-structure, recruitment-api/package.json (branch: prod):2) เป็น NestJS 9 service ที่รองรับกระบวนการสรรหาบุคลากร (recruitment) ทั้งวงจร — ตั้งคำขอเปิดรับ (Job Request), ประกาศรับสมัคร (Job List/Advertisement), ผู้สมัครยื่นใบสมัคร (Candidate/AppProfile), ประกาศผลสอบ/สัมภาษณ์ (Announcement), ขึ้นบัญชีดำ (Blacklist), และจบด้วยการออกสัญญาจ้าง (Contract) ที่ export ข้อมูลไปเข้าระบบ HRMI
Stack
| ส่วน | ค่า | หลักฐาน |
|---|---|---|
| Framework | NestJS 9 (@nestjs/core ^9.0.0) | recruitment-api/package.json (branch: prod):29 |
| ORM | TypeORM ^0.3.10 | recruitment-api/package.json (branch: prod):61 |
| Database | MSSQL (mssql ^9.1.1) — 4 connection ประกาศไว้ แต่ใช้จริงแค่ 2 | recruitment-api/package.json (branch: prod):47, recruitment-api/src/app.module.ts (branch: prod):30-53 |
| Auth | Passport JWT (passport-jwt ^4.0.0) global guard + self-managed JWT ผ่าน jsonwebtoken โดยตรงใน AuthDataService | recruitment-api/libs/jwt/jwt-auth.guard.ts (branch: prod), recruitment-api/src/modules/auth/auth.service.ts (branch: prod):8 |
puppeteer ^19.7.5 + ejs (สัญญาจ้าง, ใบเปรียบเทียบผู้สมัคร, ประกาศผลสอบ) | recruitment-api/package.json (branch: prod):55,42 | |
| Excel | exceljs ^4.4.0 | recruitment-api/package.json (branch: prod):43 |
nodemailer ^6.9.1 (SMTP ผ่าน Outlook) | recruitment-api/package.json (branch: prod):49, recruitment-api/.env (branch: prod):50-52 | |
| Rich text | draft-js + draftjs-to-html + draftjs-md-converter (เนื้อหาประกาศรับสมัคร) | recruitment-api/package.json (branch: prod):39-41 |
| Language | TypeScript ^4.7.4 | recruitment-api/package.json (branch: prod):86 |
| Package manager | yarn (yarn.lock, Dockerfile รัน yarn) | recruitment-api/Dockerfile (branch: prod):19 |
Entry point และพอร์ต
- Entry point:
recruitment-api/src/main.ts (branch: prod):15— global prefix${BASE_PATH}api/v1, เปิด static asset 2 เส้นทาง (/uploadsและ/uploads-migrate) ที่ prefix/recruitment-api/— บ่งชี้ว่าเคย migrate ข้อมูลไฟล์จากระบบเดิมมาเก็บคนละโฟลเดอร์ - พอร์ตจาก
.env:PORT=9330(recruitment-api/.env (branch: prod):5) ตรงกับ DockerfileEXPOSE 9330(recruitment-api/Dockerfile (branch: prod):25) - CORS เปิดกว้างสุด (
origin: '*', allowedHeaders: '*',recruitment-api/src/main.ts (branch: prod):41-45) - Swagger เปิดที่
${BASE_PATH}docsโดยไม่มี env flag ปิดใน production (recruitment-api/src/main.ts (branch: prod):47-48)
Deploy artifact
Dockerfile (branch: prod) — node:20-alpine + ติดตั้ง chromium, nmap, harfbuzz, freetype, nss (ชุดเดียวกับ benefit-api สำหรับ puppeteer, ไม่ทราบว่าทำไมต้องมี nmap ด้วย — UNVERIFIED) build ด้วย yarn build, run ด้วย yarn start:prod
Database topology
recruitment-api ประกาศ TypeORM connection ไว้ 4 ชุด แต่จากการตรวจ @InjectEntityManager() ทั่ว repo พบว่าใช้จริงแค่ 2 ชุด:
| Connection name | env prefix | database | สถานะการใช้งาน |
|---|---|---|---|
main | DB_* | recruitment | ใช้งานจริงหนักสุด — ทุก entity ของ recruitment ผูกกับ connection นี้ |
ai | DB_AI_* | recruitment_ai | ใช้งานจริง — raw query/query builder จาก jobList, candidate, appProfile repository เพื่ออ่าน/เขียนผลการวิเคราะห์ผู้สมัครด้วย AI |
vtrc | VTRC_DB_* | vtrc (user hrmiworkforce) | ประกาศไว้ใน app.module.ts แต่ ไม่พบการ inject ใช้งานที่ใดในโค้ด ระหว่างการสำรวจรอบนี้ |
workforce | WORKFORCE_DB_* | dbWorkforce (user hrmiworkforce) | ประกาศไว้แต่ ไม่พบการ inject ใช้งานที่ใดในโค้ด — การเชื่อมต่อ workforce ที่ใช้จริงทั้งหมดเป็น HTTP ผ่าน workforceServer env var ไม่ใช่ query database ตรง |
หลักฐาน — recruitment-api/src/app.module.ts (branch: prod):30-53, recruitment-api/config/configuration.ts (branch: prod):11-74 ดูรายละเอียดที่ 06 Scorecard (OBS-RECRUIT-01)
ข้อสังเกตสำคัญ — recruitment-api ใช้ database ที่ชื่อ recruitment_ai ร่วมกับ (สันนิษฐานว่า) ai-recruitment-api — เป็น cross-service database coupling ที่ต้องตรวจสอบยืนยันอีกฝั่งเมื่อสำรวจ ai-recruitment-api (ดู 04 Auth + integrations)
สิ่งที่ควรรู้ก่อนอ่านบทถัดไป
- ไฟล์
.envที่ commit อยู่ใน repo มี production MSSQL credential, JWT secret, refresh-token secret, SMTP password, และ Google reCAPTCHA secret เป็น plaintext (ดู 06 ScorecardSEC-RECRUIT-01) - ไฟล์
vtrc-gcp-sa-key.json(GCP service account key) ถูก commit ไว้ที่ root ของ repo เช่นเดียวกับที่พบในvtrc-api— ไม่ได้เปิดอ่านเนื้อหาไฟล์ตามนโยบายความปลอดภัย แต่ยืนยันการมีอยู่จริงของไฟล์ (recruitment-api/vtrc-gcp-sa-key.json (branch: prod)) JWT_SECRET(SECRET_KEY) ใน.envของrecruitment-apiมีค่าเดียวกันกับSECRET_KEYของbenefit-api— ยืนยันว่าแพลตฟอร์มนี้ใช้ shared JWT secret ข้าม microservice เพื่อให้ token ที่ vtrc-api หรือ service หนึ่งออกให้ ใช้ยืนยันตัวตนกับอีก service ได้ (ดู 04 Auth + integrations)
สารบัญ
| บท | หัวข้อ |
|---|---|
| 01 | Repository map |
| 02 | Core pipeline — job request → candidate application → contract → export HRMI |
| 03 | Persistence — entities, ตาราง, ความสัมพันธ์ |
| 04 | Auth model + external integrations |
| 05 | Cron jobs |
| 06 | Scorecard + debt register |