Skip to content

recruitment-web

recruitment-web (default branch: master, canonical branch: prod, 200 tracked files บน prod) เป็นเว็บสมัครงานสาธารณะของสภากาชาดไทย — ผู้สมัครภายนอก (ไม่ใช่พนักงาน) กรอกใบสมัครงาน (application profile), แนบไฟล์เอกสาร, และสมัครตำแหน่งงานที่เปิดรับผ่านหน้านี้ เชื่อมกับ backend ชื่อ recruitment-api (อยู่ใน Domain Microservices group — นอก scope ลึกของเล่มนี้ ยกเว้น endpoint ที่ frontend เรียก)

ชื่อ package คือ recruitment-web (recruitment-web/package.json:2) — ตรงกับชื่อ repo


Stack และเวอร์ชัน

Dependencyเวอร์ชันหลักฐาน
react / react-dom^18.2.0recruitment-web/package.json:21-22
react-scripts (CRA)5.0.1recruitment-web/package.json:31
antd5.18.0recruitment-web/package.json:13
react-router-dom^6.8.1recruitment-web/package.json:30
recoil^0.7.6recruitment-web/package.json:33
axios^1.4.0recruitment-web/package.json:14
crypto-js^4.1.1recruitment-web/package.json:15
react-google-recaptcha^3.1.0recruitment-web/package.json:26
react-pdf^9.1.0recruitment-web/package.json:29
react-ga4^2.1.0recruitment-web/package.json:25
moment^2.29.4recruitment-web/package.json:19
sass^1.58.3recruitment-web/package.json:34
tailwindcss (dev)^3.2.7recruitment-web/package.json:67

Stack เป็น Create React App (CRA) มาตรฐาน — ไม่ใช่ Next.js ควรอ้างอิงจาก react-scripts ใน package.json เป็นหลัก

Package manager ที่ Dockerfile ใช้คือ yarn (recruitment-web/Dockerfile:7-9) แม้ repo จะมีทั้ง package-lock.json และอาจมี yarn.lock ตาม context build — ตรวจ lockfile จริงก่อนรัน CI


Entrypoint และพอร์ต

src/index.js คือ entrypoint ของ CRA — wrap ด้วย RecoilRoot แล้ว BrowserRouter แล้ว render <App /> (recruitment-web/src/index.js:13-19)

Dev server รันที่พอร์ต 3006 ตาม script "start": "PORT=3006 react-scripts start" (recruitment-web/package.json:40)

App.js ทำหน้าที่:

  1. ปิด console.log/warn/error นอก hostname ที่เป็น uat-jobs หรือ localhost (recruitment-web/src/App.js:29-32)
  2. initialize Google Analytics ด้วย REACT_APP_GA_ID (recruitment-web/src/App.js:34)
  3. ตั้ง CSS variables ของ theme จาก Recoil + localStorage (recruitment-web/src/App.js:36-47)
  4. route gate — ถ้าไม่มี checkLogin.isOtp ที่ decrypt ได้ จะ redirect ออกจาก /myJob และ /applicantProfile กลับ / (recruitment-web/src/App.js:49-62)
  5. ส่ง GA pageview ตาม pathname (recruitment-web/src/App.js:64-74)

Deploy artifact

Dockerfile แบบ multi-stage:

StageBase imageทำอะไรCitation
stage-1node:20-alpineyarn แล้ว yarn buildrecruitment-web/Dockerfile:1-9
stage-2nginx:1.30.2copy build/ ไป /usr/share/nginx/html/build/ + default.confrecruitment-web/Dockerfile:11-25

nginx SPA fallback: try_files $uri $uri/ /index.html (recruitment-web/default.conf:7-11) listen port 80

ข้อสังเกตสำคัญDockerfile ประกาศ ENV REACT_APP_SECRET_KEY=... และ endpoint อื่น ๆ ไว้ที่ stage 2 (nginx) (Dockerfile:15-21) แต่ CRA inline ค่า REACT_APP_* ทั้งหมดเข้า JS bundle ตอน yarn build ที่ stage 1 เท่านั้น — ค่า ENV ที่ประกาศใน stage 2 จึงไม่มีผลต่อ bundle ที่ deploy จริง ค่าที่ถูก bake เข้า bundle มาจากไฟล์ .env / .env.uat / .env.dev ที่อยู่ใน build context ตอนรัน yarn build (ดู 04-scorecard CORR-RCWEB-01)


Backend ที่เชื่อมต่อ (พิสูจน์จากโค้ด)

ปลายทางผ่าน env varใช้ทำอะไรหลักฐาน
recruitment-apiREACT_APP_END_POINT_RECRUITMENT_APICRUD ใบสมัคร, login/OTP, สมัครตำแหน่งrecruitment-web/src/config.js:11, axios-rc.js:11
recruitment-api (path แนบไฟล์)REACT_APP_END_POINT_RECRUITMENT_API_ATTACHFILEpreview ไฟล์แนบที่ upload แล้วconfig.js:12, axios-rc.js:5-7
"common API" (คาด vtrc-common)REACT_APP_END_POINT_COMMON_APIประกาศใน axios-common.jsไม่พบ caller ใน componentaxios-common.js:6, grep ไม่พบ import
"workflow / workforce API"REACT_APP_END_POINT_WF_API_ATTACHFILEประกาศใน config — ไม่พบจุดใช้งานconfig.js:13UNVERIFIED

Endpoint hosts ตาม env file (branch: prod)

ไฟล์REACT_APP_NODE_ENVRecruitment API host
.env'prod'https://vtrcapi.redcross.or.th/recruitment-api/api/v1
.env.uat'uat'https://uat-vtrcapi.redcross.or.th/recruitment-api/api/v1
.env.dev'dev'http://localhost:9330/recruitment-api/api/v1

(อ่านจากไฟล์ env ที่ track ใน git บน branch prod — ไม่ paste ค่า secret)


ธีมหลักของเล่มนี้

  1. OTP login ทางอีเมลsent_otpvalidate_otp ผ่าน GET query string (email + OTP รั่วใน access log / browser history)
  2. AES ฝั่ง clientcrypto-js AES ด้วย REACT_APP_SECRET_KEY / REACT_APP_PRIVATE_KEY ที่ bake ใน bundle
  3. PII ใน localStorage — เก็บหลัง decrypt ใต้ key user-login โดยไม่มี expiry จริง
  4. ไฟล์แนบเป็น base64 ใน JSON payload ไม่ใช่ multipart
  5. ทุกหน้าและทุก HTTP call ที่ frontend ยิง — ดู 03-pages-and-endpoints

สารบัญ

บทหัวข้อ
01Repository map — โฟลเดอร์, env, axios clients, Recoil
02Core pipeline — OTP, AES/localStorage, submit profile, apply job
03Every page + HTTP endpoint catalog
04Scorecard

ดูภาพรวมกลุ่ม OCR & Auxiliary ที่ Volume 9 index.