0.3 · วันหนึ่งของพนักงาน
บทนี้เล่าว่าพนักงานสภากาชาดกระทบส่วนไหนของระบบบ้าง ตลอดวันทำงานหนึ่งวัน
จุดประสงค์ไม่ใช่สอนวิธีใช้ (พนักงานคงไม่อ่านคู่มือเล่มนี้) แต่เพื่อให้คนที่ดูแลระบบเข้าใจว่า แต่ละ feature ที่เห็นในโค้ด มาจากความต้องการจริงของใคร ในเวลาไหนของวัน
08:30 — เข้างานและเช็คอิน
พนักงานสแกนนิ้วหรือบัตรที่เครื่องสแกนก่อนเข้าอาคาร ข้อมูลเวลาเข้าไปเก็บในระบบ HRMI (MSSQL) โดยตรง — VTRC ไม่ได้มีส่วนเกี่ยวข้องตรงนี้
หลายชั่วโมงต่อมา พนักงานเปิดแอปและกดดู "เวลาทำงาน" ของวันนี้ VTRC ทำหน้าที่แค่ read-only consumer — ดึงข้อมูลจาก HRMI ผ่าน vtrc-api → centralize/controllers/timeAttendance.js → GraphQL END_POINT_CENTRALIZE (cu-central-api) มาแสดง
ถ้าเวลาที่แสดงในแอปไม่ตรง เช่นสแกนแล้วไม่ขึ้น — ปัญหาไม่ได้อยู่ที่ VTRC แต่อยู่ที่เครื่องสแกนหรือระบบ HRMI เอง
09:00 — ดูสลิปเงินเดือน
พนักงานเปิดหน้าสลิป แล้วกดเดือนที่ต้องการดู
สิ่งที่เกิดขึ้นในระบบตามลำดับ
- browser ส่ง GraphQL query
fetchSlip(month, year, identityCard, ...)ไปที่vtrc-api vtrc-apiตรวจ apiKey และ JWT ก่อน- เรียก
centralize/controllers/slip.js→GraphqlCDWithTokenไปที่ GraphQL ของcu-central-api(END_POINT_CENTRALIZE) — ไม่ใช่ NestJScentralize-api cu-central-apiคิวรี่ MSSQL (PaySlip) แล้วส่ง JSON กลับvtrc-apiส่งข้อมูลกลับ browser — ไม่มี การเขียน Redis key แบบpayslip:{emp}:{date}บน path นี้- browser render รายได้/รายจ่ายในรูปแบบตาราง
ถ้าพนักงานกดดาวน์โหลด PDF เป็น flow อื่นที่ใช้ REST endpoint ไม่ใช่ GraphQL — vtrc-api จะ
- render EJS template เป็น HTML
- ใช้
html-pdf(PhantomJS-based) แปลงเป็น PDF - เรียก
qpdf --encrypt <password> ...ผ่านexecSyncเพื่อเข้ารหัส PDF - ส่ง URL ที่มี hash ให้ browser (valid 1 ชั่วโมง)
- browser เปิด URL →
vtrc-apiส่ง PDF กลับ → ลบไฟล์หลัง 5 วินาที
password ของ PDF คือ เลขบัตรประชาชน ของพนักงาน
ส่วน execSync เป็น command injection vector — ถ้า identityCard มี shell metacharacter จะรัน command อะไรก็ได้ใน container รายละเอียดใน Volume 15 SEC-1
10:00 — ขอลาป่วย
พนักงานเปิดหน้า "ขอลา" เลือกประเภทการลา (ลาป่วย ลากิจ ลาพักผ่อน ลาคลอด ฯลฯ 12 ประเภท) กรอกวันที่เริ่ม-สิ้นสุด เหตุผล และผู้รับมอบหมาย (delegate)
ระบบตรวจก่อนบันทึก
- จำนวนวันลาเกินกว่ากำหนดสูงสุดต่อครั้งของประเภทนั้น? → reject พร้อมข้อความไทย เช่น
"<type> ไม่เกิน N วัน ต่อครั้ง" - จำนวนวันน้อยกว่าขั้นต่ำ? → reject
- จองล่วงหน้าเกินกว่าที่กำหนด? → reject
- จองย้อนหลังเกินกว่าที่กำหนด? → reject
ตรรกะทั้งหมดอยู่ใน vtrc-api/api/src/lib/controllers/hrmi/hrmi.js:1295-1319
มีบายพาส — args.adminCanPass === true ข้ามการตรวจทั้งหมด และ HR HQ (orgUnitCode.substring(0,4) === '0734') ก็ได้รับการปฏิบัติพิเศษ
หลังบันทึก status ของ LeaveDocument จะเป็น PENDING แล้ววิ่งเข้า chain การอนุมัติ (ดู บท 0.4)
คำเตือน — ENUM status มี typo ที่ติดมาตั้งแต่ต้น คือ PEDDING_CANCLE (ควรเป็น PENDING_CANCEL) อยู่ในโค้ด production ตั้งแต่ models/core/leave/leave.js:59 ทุก consumer ต้องสะกดผิดเหมือนกันตลอดไป
13:00 — เบิกค่ารักษาพยาบาลบุตร
พนักงานเปิดหน้า "เบิกสวัสดิการ" เลือกความสัมพันธ์ (ตัวเอง คู่สมรส บิดา มารดา บุตร) เลือกโรงพยาบาล เลือกโรค กรอกยอดเบิก แนบใบเสร็จ ส่งคำขอ
ระบบเขียน row ใหม่ลง WDHospital table ใน MariaDB status เริ่มต้นเป็น DRAFT หรือ PENDING แล้วแต่ flow
ความสัมพันธ์ถูกจำกัดโดย code ใน config.js:392-429 (relationHrmi)
| Code | ความสัมพันธ์ |
|---|---|
00 | พนักงาน (ตัวเอง) |
10 | บิดา |
20 | มารดา |
70 | คู่สมรส |
81–85 | บุตรคนที่ 1–5 |
เบิกให้บุตรได้สูงสุด 5 คน เป็น policy ที่ hardcode ไว้
หลังส่งแล้ว status วิ่งเข้า state machine 13-state — ดูรายละเอียดใน Volume 12 · Business Logic
15:00 — อ่านข่าวและดูเอกสารนโยบาย
พนักงานเปิดหน้าข่าว (Post) หรือหน้านโยบาย (Policy) — เป็น read-only จากตาราง Post และ Policy ใน MariaDB
ถ้าดาวน์โหลดเอกสารแนบ จะผ่าน REST endpoint ที่ลงท้ายด้วย hash คล้ายๆ PDF สลิป (valid 1 ชั่วโมง)
16:00 — แจ้ง HR
พนักงานใช้ฟีเจอร์ "Contact Us" ส่งคำถามไป HR — เขียนผ่าน mutation contactUs ลงตาราง contactUs ใน MariaDB HR เห็นใน backoffice และตอบกลับได้
17:00 — ล็อกเอาต์
พนักงานกด logout → vtrc-api ทำลาย Session row → browser ล้าง localStorage → redirect กลับหน้า login
สรุปแบบกระชับ
| เวลา | สิ่งที่ทำ | ระบบที่เกี่ยวข้อง |
|---|---|---|
| 08:30 | สแกนนิ้ว | HRMI (ไม่ใช่ VTRC) |
| 09:00 | ดูสลิป + ดาวน์โหลด PDF | vtrc-web → vtrc-api → cu-central-api → MSSQL |
| 10:00 | ขอลาป่วย | vtrc-web → vtrc-api (write MariaDB) |
| 13:00 | เบิกค่ารักษาบุตร | vtrc-web → vtrc-api (write MariaDB) |
| 15:00 | อ่านข่าว + ดูเอกสาร | vtrc-web → vtrc-api (read MariaDB) |
| 16:00 | แจ้ง HR | vtrc-web → vtrc-api (write MariaDB) |
| 17:00 | ล็อกเอาต์ | vtrc-web → vtrc-api (delete Session) |