recruitment-web — Pages & Endpoints Catalog
บทนี้ (branch: prod) ไล่ทุกหน้าใน mainRoutes.js และทุก HTTP call ที่พบใน src/ ผ่าน axiosRc — เพื่อให้ผู้อ่าน map UI → API ได้โดยตรงโดยไม่ต้องเดา
Page: Home (/ และ /:org)
| ส่วน | ไฟล์ | บทบาท |
|---|---|---|
| Shell | pages/home/index.js | ครอบ Header/Footer + provider |
| Context | pages/home/context/homeContext.js | โหลด dropdown + รายการงาน |
| Scope1 | content/scope1/* | banner, search form, carousel |
| Scope2–4 | `content/scope2 | 3 |
| AI | content/aiRecommend/* | แนะนำงานจาก AI (ถ้า login) |
HTTP
| Method | Path (relative to recruitment-api base) | Caller | Citation |
|---|---|---|---|
| GET | /jobList/get_default_data | homeContext.getDefaultData | homeContext.js:82 |
| GET | /jobList/get_by_org_unit_id/?orgUnitId=...&searchKeyword=... | homeContext.getDataByOrgUnitId | homeContext.js:153-164 |
| GET | /jobList/get_job_recommend_ai/{userId} | formSearch.js | formSearch.js:111 |
พฤติกรรมพิเศษ: ถ้าไม่มี :org ใน URL และมี search_history ใน storage จะ history(/{orgUnitName}) (homeContext.js:96-102) มิฉะนั้นใช้ cards[0]
Theme/logo จาก response ถูกเขียนลง Recoil + home-image / rc-theme storage (homeContext.js:167-176)
Page: JobDetail (/JobDetail/:org/:jobId)
| ส่วน | ไฟล์ |
|---|---|
| Shell | pages/jobDetail/index.js |
| Content | content/index.js, content-left.js, content-right.js, content-title.js |
| Related | content/carousel/* |
| Banner | banner.js |
HTTP
| Method | Path | Caller | Citation |
|---|---|---|---|
| GET | /jobList/get_job_detail_by_id/{jobId} | jobDetail/index.js | index.js:19 |
| PUT | /jobRequest/update_visit body { id: jobId } | หลังโหลดสำเร็จ | index.js:27-30 |
| GET | candidate/check_duplicate_jobRequestNo?email=&jobReqDocumentNo= | ก่อนสมัคร | content/index.js:58 |
| POST | candidate/create | สมัครจากหน้ารายละเอียด | content/index.js:330 |
content-right.js ใช้ urlAttachFileRc() สำหรับแสดงไฟล์จาก path ที่ server คืน (content-right.js:6-13)
Page: JobHistory / MyJob (/MyJob)
| ส่วน | ไฟล์ |
|---|---|
| Shell | pages/jobHistory/index.js |
| Table | myJobTable.js |
| Banner/Content | banner.js, content.js |
ต้องผ่าน OTP gate ใน App.js (ดู 02-core-pipeline)
HTTP
| Method | Path | Caller | Citation |
|---|---|---|---|
| GET | /candidate/get_list_my_job/?email=&appProfileId= | fetchData | myJobTable.js:25-26 |
| GET | candidate/exportpdf_candidate?id= (blob) | พิมพ์ใบสมัคร | myJobTable.js:64-66 |
| PUT | /candidate/cancel_apply body { id } | ยกเลิกสมัคร | myJobTable.js:88-91 |
email และ appProfileId มาจาก JSON.parse(user.data) ใน localStorage (myJobTable.js:22-25) — PII ที่ decrypt แล้วถูกใช้สร้าง query string อีกชั้น
Page: ApplicantProfile (/ApplicantProfile)
| ส่วน | ไฟล์ |
|---|---|
| Shell | pages/applicantProfile/index.js + DropdownDataProvider |
| Orchestrator | content.js (~1400 บรรทัด) |
| Steps UI | steps.js + constant.js progressSteps |
| Sections | personal/, contact/, edu/, exp/, capability/, reference/, attachment/, criminal/, information/, consent/ |
| Upload | uploadForm.js |
HTTP
| Method | Path | Caller | Citation |
|---|---|---|---|
| GET | /appProfile/get_dropdown_data | dropdown context | dropdownDataContext.js:47 |
| POST | appProfile/check_emp_redcross | ก่อน save | content.js:889 |
| POST | appProfile/create_app_profile | สร้างใหม่ | content.js:407 |
| PUT | appProfile/update_app_profile | อัปเดต | content.js:418 |
| GET | /appProfile/get_by_email/{email} | refresh หลัง save | content.js:490 |
| GET | candidate/check_duplicate_jobRequestNo?... | ก่อน apply | content.js:1250 |
| POST | candidate/create | apply หลัง save | content.js:1022 |
Preview ไฟล์ที่มี filePath แล้ว: urlAttachFile + filePath (uploadForm.js:84)
Consent step ใช้ react-pdf ผ่าน consent/PDFViewer.js และข้อความใน consent/constant.js / consentDetail.js
Page: Login modal (ไม่ใช่ route แยก)
เปิดจาก components/header/index.js เป็น Modal — ไม่มี path ของตัวเอง
| Component | บทบาท | Citation |
|---|---|---|
pages/login/index.js | เลือกแสดง SignIn / OTP / SignOut | — |
form-signIn.js | กรอกอีเมล | — |
form-otp.js | OTP 6 ช่อง + validate | form-otp.js:48-62 |
form-signOut.js | โปรไฟล์ย่อ + ลบบัญชี | form-signOut.js:53-175 |
otp-remaining.js | cooldown ส่งซ้ำ | — |
otp-remaining-expire.js | นับถอยหลังหมดอายุ OTP | — |
HTTP (login / account)
| Method | Path | Caller | Citation |
|---|---|---|---|
| GET | /jobList/sent_otp/{email} | handleLogin | header/index.js:232 |
| GET | /jobList/validate_otp/?email=&otp= | handleConfirmOtp | form-otp.js:51-52 |
| GET | /appProfile/get_by_email/{email} | onFinish หลัง OTP | header/index.js:74 |
| PUT | /jobList/logout?email= | onOkLogOut | header/index.js:266 |
| GET | dropdown/get_dropdown_by_type?dropdownType=delAccReason | form-signOut | form-signOut.js:54-55 |
| POST | deleteHistory/create_delete_history | ขอลบบัญชี | form-signOut.js:175 |
| PUT | deleteHistory/check_update_del_acc | ยกเลิกลบ | header/index.js:182 |
| POST | {base}/auth/refresh_token | axios interceptor | axios-rc.js:34 |
Page: RefreshData (/RefreshData)
| พฤติกรรม | Citation |
|---|---|
localStorage.clear() แล้ว history('/') | pages/clear/index.js:6-8 |
แสดงข้อความ Loading . . . ชั่วคราว | pages/clear/index.js:11 |
ไม่มี HTTP call — ใช้ล้าง session ฝั่ง browser แบบ hard reset
Page: NotFound (/NotFound)
pages/notFound/index.js — หน้า 404 ภายในแอป; route * redirect ไป / ไม่ได้ชี้มาที่นี่โดยอัตโนมัติ (mainRoutes.js:39-41) ดังนั้น /NotFound ต้องถูก navigate มาเองถ้ามีจุดเรียก (ค้นหา caller ตาม task — UNVERIFIED ว่ามีลิงก์ภายในชี้มาบ่อยแค่ไหน)
Shared components ที่ยิง API
| Component | Method / Path | Citation |
|---|---|---|
components/sharedModal.js | POST Share/share_link | sharedModal.js:47 |
components/footer/index.js | GET jobList/export_other_doc | footer/index.js:83 |
ตารางรวม HTTP ทั้งหมดที่พบใน src/ (axiosRc)
เรียงตาม domain:
jobList / jobRequest
| Method | Path pattern | Files |
|---|---|---|
| GET | /jobList/get_default_data | homeContext.js:82 |
| GET | /jobList/get_by_org_unit_id/{query} | homeContext.js:164 |
| GET | /jobList/get_job_detail_by_id/{jobId} | jobDetail/index.js:19 |
| GET | /jobList/get_job_recommend_ai/{userId} | formSearch.js:111 |
| GET | /jobList/sent_otp/{email} | header/index.js:232 |
| GET | /jobList/validate_otp/?email=&otp= | form-otp.js:52 |
| PUT | /jobList/logout?email= | header/index.js:266 |
| GET | jobList/export_other_doc | footer/index.js:83 |
| PUT | /jobRequest/update_visit | jobDetail/index.js:30 |
appProfile
| Method | Path pattern | Files |
|---|---|---|
| GET | /appProfile/get_dropdown_data | dropdownDataContext.js:47 |
| GET | /appProfile/get_by_email/{email} | header/index.js:74, content.js:490 |
| POST | appProfile/create_app_profile | content.js:407 |
| PUT | appProfile/update_app_profile | content.js:418 |
| POST | appProfile/check_emp_redcross | content.js:889 |
candidate
| Method | Path pattern | Files |
|---|---|---|
| GET | /candidate/get_list_my_job/{query} | myJobTable.js:26 |
| GET | candidate/check_duplicate_jobRequestNo{query} | jobDetail/content/index.js:58, content.js:1250 |
| POST | candidate/create | jobDetail/content/index.js:330, content.js:1022 |
| PUT | /candidate/cancel_apply | myJobTable.js:91 |
| GET | candidate/exportpdf_candidate?id= | myJobTable.js:65 |
dropdown / deleteHistory / Share / auth
| Method | Path pattern | Files |
|---|---|---|
| GET | dropdown/get_dropdown_by_type?dropdownType= | form-signOut.js:55 |
| POST | deleteHistory/create_delete_history | form-signOut.js:175 |
| PUT | deleteHistory/check_update_del_acc | header/index.js:182 |
| POST | Share/share_link | sharedModal.js:47 |
| POST | /auth/refresh_token | axios-rc.js:34 |
Dead API surface (ไม่ถูกเรียกจาก UI)
| Method | Path | File | Note |
|---|---|---|---|
| POST | login | api/login.js:5 | dead |
| POST | login/check | api/login.js:17 | dead |
| POST | login/forgotpassword | api/login.js:28 | dead |
| POST | login/resetPassword | api/login.js:39 | dead |
UI composition ต่อหน้า (สรุป)
Container
├── HeaderHome ← login modal, logout, nav
├── [page body]
│ ├── Home ← HomeContextProvider + scopes
│ ├── JobDetail ← Banner + Content + related carousel
│ ├── JobHistory ← Banner + MyJobTable
│ └── ApplicantProfile← Steps sidebar + 10 section forms
└── FooterHome ← export_other_doc, linksTheme สี: DefaultTheme (แดง) vs blueTheme ตาม org (App.js:39-45, assets/styles/theme/index.js)
Font หลักใน config: 'Kanit', sans-serif (config.js:8)
สิ่งที่เล่มนี้ไม่ยืนยัน (UNVERIFIED)
- Response schema เต็มของแต่ละ endpoint ฝั่ง
recruitment-api(ต้องอ่าน reporecruitment-apiแยก) - ว่า server ตรวจไฟล์/MIME/ขนาดซ้ำหรือไม่
- ว่า
REACT_APP_COOKIESถูกอ่านที่จุดใดในโค้ด (ชื่อมีใน.env*— ต้อง grep เพิ่มก่อนสรุปว่าใช้จริง) - Deploy host จริงของ frontend (jobs.redcross.or.th vs อื่น) นอกเหนือจากค่าใน Dockerfile stage-2 /
.envที่ bake