8.1 · Repository map + legacy/backup files
บทนี้เจาะโครงสร้างของ vtrc-rc-backoffice/src/ เพื่อให้ค้นหาและแก้ไขโค้ดได้ง่ายขึ้น พร้อมทั้งระบุไฟล์ legacy/backup กว่า 75 ไฟล์ และ typos ที่ติดอยู่ในชื่อไฟล์/โฟลเดอร์จริง (เปลี่ยนไม่ได้)
โครงสร้าง src/ ระดับบน
src/
├── index.js 33 บรรทัด — entry point + ApolloProvider + RecoilRoot
├── serviceWorker.js 135 บรรทัด — CRA default (เรียก unregister)
├── assets/
│ ├── css/ — main.css 4,644 + work-force.css 794 + theme/*.css
│ ├── sass/ — main.scss, work-force.scss (source ที่ compile ด้วย Prepros)
│ ├── fonts/ — Kanit, Kanit-Medium, Kanit-Regular, THSarabun
│ ├── images/, pdf/ — assets รวม PDF template (couse_pdf, jobReq_pdf)
├── components/ 104 ไฟล์ — domain components (41 โฟลเดอร์)
├── config/ 35 ไฟล์ — apollo, axios* 15 ไฟล์, routes, datasets, CSS
│ ├── apollo.js 187 บรรทัด — Apollo Client หลัก (createUploadLink + setContext + errorLink)
│ ├── apollo-workforce.js 154 บรรทัด — Apollo Client สำหรับ workforce-api
│ ├── axios-bo.js — factory AxiosBO + interceptor
│ ├── axios-workforce.js / axios-workforce-upload.js
│ ├── axios-recruitment.js / axios-recruitment-upload.js
│ ├── axios-benefit.js / axios-benefit-i3.js
│ ├── axios-pms.js / axios-ai.js / axios-payments.js
│ ├── axios-meeting.js / axios-common.js / axios-vtrc.js / axios-i3.js
│ ├── axiosAll.js
│ ├── routes.js 2,550 บรรทัด — route table 276 paths
│ ├── custom-antd.css 21,189 บรรทัด — AntD v4 override (compiled)
│ ├── datasets*.js ~1,610 บรรทัด — dropdown master data
│ └── refreshToken.js 34 บรรทัด — refresh ผ่าน Queries.refreshTokenBO (Apollo)
├── containers/
│ └── App/index.js 32 บรรทัด — root router + isLoggedIn() gate (ไม่มี PrivateRoute)
├── graphql/
│ ├── queries.js 4,108 บรรทัด — 120 query definitions
│ ├── mutations.js 2,208 บรรทัด — 94 mutation definitions
│ ├── WorkForce/ — queries/mutations ของ workforce service
│ ├── graphql-pingpong/ — legacy (เก็บไว้)
│ └── index.js 5 บรรทัด — re-export Queries, Mutations, Queries_wf, Mutations_wf
├── pages/ 66 โฟลเดอร์ — 871 page files
├── recoil/states/ 57 โฟลเดอร์ — atom definitions (~1,251 บรรทัด)
└── utils/ 33 ไฟล์ — helpers (~1,849 บรรทัด)ไฟล์สำคัญและหน้าที่
| ไฟล์ | LOC | หน้าที่ |
|---|---|---|
src/index.js:1-33 | 33 | React root + ApolloProvider + RecoilRoot |
src/containers/App/index.js:1-36 | 36 | BrowserRouter + Switch + isLoggedIn() gate + console override |
src/config/apollo.js:1-185 | 185 | Apollo Client หลัก + errorLink + authLink |
src/config/apollo-workforce.js:1-154 | 154 | Apollo Client สำหรับ /workforce-api/api/graphql |
src/config/routes.js:1-2550 | 2,550 | route table + render helpers + permission check |
src/utils/auth.js:1-137 | 137 | token storage + URL resolver + isLoggedIn |
src/utils/formatdate.js:1-160 | 160 | date format พ.ศ. (manual +543) |
src/utils/checkError.js:1-21 | 21 | error code → ข้อความไทย |
src/graphql/queries.js:1-4108 | 4,108 | 120 queries |
src/graphql/mutations.js:1-2208 | 2,208 | 94 mutations |
src/components/SiderLayout/index.js:1-1168 | 1,168 | shell layout + dynamic menu + role fetch |
src/pages/Login/index.js:1-418 | 418 | login (RSA + loginBackoffice mutation) |
src/pages/ManageUser/index.js:1-762 | 762 | จัดการผู้ใช้ + role |
src/pages/OtherWelfare/Form/index.js:1-2075 | 2,075 | ฟอร์มสวัสดิการอื่น (ใหญ่ที่สุดเป็นอันดับ 2) |
src/pages/LeaveStudiesPayments/form/index.js:1-1824 | 1,824 | ฟอร์มเบิกค่าเล่าเรียน (multi-tab) |
pages 66 โฟลเดอร์ — จัดเป็น cluster
| Cluster | โฟลเดอร์ตัวอย่าง |
|---|---|
| Auth / onboarding | Login/, PathLogin/, SetPasswordsFirstTime/, ChangePassword/, ConfirmUserA1/, ConfirmUserA2/, ForgetPassword/ |
| Dashboard / home | Dashboard/, News/, DetailNews/, Notification/ |
| Document / policy | DocumentGroup/, Document/, DocumentHR/, Policy/, PolicyOfficerDocuments/ |
| Contact | ContactUS/, ContactUSCategory/ |
| Organization / career / course | Organization/, OrganizationGroup/, Career/, Course/, System/ |
| User / role management | ManageUser/, ManageRole/ |
| Hospital / medical claim | HospitalHr/, HospitalPaid/, HospitalFailed/, SicknessName/, BankBranches/ |
| Leave | Leave/, LeaveHR/, LeaveStudies/, LeaveStudiesAdmin/, LeaveStudiesPayments/, LeaveStudiesScholar/, LeaveStudiesScholarAdmin/, Delegate/ |
| Welfare / fund | OtherWelfare/, Fund/ |
| WorkForce module | WorkForce/Employee/, WorkForce/PositionManage/, WorkForce/PositionTechnical/, WorkForce/PerfessionalLicense/, WorkForce/PerfessionalDepartment/, WorkForce/ManpowerManage/, WorkForce/Candidate/, WorkForce/JobRequest/, WorkForce/Learning/, WorkForce/Report/, WorkForce/Dashboard/ |
| Recruitment | Recruitment/Announcement/, Recruitment/Candidate/, Recruitment/PreviewEmail/ |
| PMS | PMS/Evaluations/, PMS/PerformanceRecord/, PMS/ReportResults/, PMS/Shared/ |
| Attendance | Attendance/AbstainTimeGroup/ |
| Bank / payment | Payment/ExportPayment/, Payment/Payroll/, Payment/SalaryCert/ |
| Misc | AboutUS/, TheamCss/ (typo — ใช้จริง), NotFound/ |
ไฟล์ legacy/backup — ห้ามแตะ ห้ามใช้เป็นต้นแบบ
vtrc-rc-backoffice มีไฟล์ legacy/backup มากกว่า 75 ไฟล์ รวมถึง โฟลเดอร์ page _bk ทั้งโฟลเดอร์ 4 ชุด
กฎเหล็ก
- อย่าแก้ไข — ไฟล์ที่ลงท้ายด้วย
_bk,_prd,_copy,_tempFilter,_bk-*หรือไฟล์ที่อยู่ในโฟลเดอร์_bkทั้งโฟลเดอร์ - อย่าใช้เป็นต้นแบบ — ถ้า copy โค้ดจากไฟล์เหล่านี้ มีโอกาสได้ query ที่ deprecated แล้ว
- อย่าลบทิ้งเอง — บางไฟล์เก็บไว้สำหรับ rollback ดู git history ก่อน และถามทีมก่อนลบ
โฟลเดอร์ page _bk ทั้งโฟลเดอร์
| โฟลเดอร์ | จำนวนไฟล์ | ที่มา |
|---|---|---|
src/pages/Leave_bk/ | 12 ไฟล์ | snapshot ระบบลาเก่า |
src/pages/LeaveHR_bk/ | 13 ไฟล์ | snapshot ฝั่ง HR |
src/pages/LeaveStudies_bk/ | 15 ไฟล์ (รวม Form/Tab0..10/) | snapshot การลาศึกษาเก่า |
src/pages/OtherWelfare/Form_bk/ | 3 ไฟล์ | snapshot ฟอร์มสวัสดิการอื่น |
ไฟล์ legacy ที่พบบ่อย
| รูปแบบชื่อ | ตัวอย่าง | ที่มา |
|---|---|---|
_bk.js | pages/Login/index_bk.js, components/SiderLayout/index_bk.js, components/LoginForm/index_bk.js | snapshot ก่อน refactor |
_bak.js, _bk-prd.js, _bk_uat_*.js, _bk_up_prd_*.js | config/routes_bak.js, config/routes_bk-prd.js, config/routes_bk_uat_100423.js, config/routes_bk_up_prd_100423.js | snapshot ของ route table แยกตาม env |
_bk-061265.js, _bk-061254.js | graphql/queries_bk-061265.js, graphql/mutations_bk-061254.js | snapshot queries/mutations ลงวันที่ |
_bk copy.js (มี space ในชื่อ!) | pages/LeaveStudies/Form/Tab7/index_bk copy.js | snapshot ที่ตั้งชื่อผิด |
_bk-bk.js, _bk-send.js, _prd.js | pages/HospitalPaid/Payments/generatorFileDetail_bk-bk.js, detailDarf_bk-send.js, generatorFileDetail-prd.js | snapshot ซ้อน snapshot |
index-axios.js, index-axio.js | pages/LeaveStudiesPayments/form/index-axios.js, pages/OtherWelfare/Form/index-axio.js | ทดลอง impl ด้วย axios แทน apollo |
routes_gql_payments.js, routes_payments_axios.js | config/ | ทดลอง impl ระบบ payment 2 แบบ |
ตัวอย่างที่ต้องระวังมากเป็นพิเศษ
src/config/
├── routes.js ← ตัวจริง (2,550 บรรทัด)
├── routes_bak.js ← snapshot
├── routes_bk-prd.js ← snapshot prod
├── routes_bk_uat_100423.js ← snapshot UAT ลงวันที่ 10/04/2023
├── routes_bk_up_prd_100423.js ← snapshot update-prod ลงวันที่ 10/04/2023
├── routes_bk-mapgroup.js ← snapshot สำหรับ map group
├── routes_payments_axios.js ← ทดลอง payment ด้วย axios
└── routes_gql_payments.js ← ทดลอง payment ด้วย GraphQL
src/graphql/
├── queries.js ← ตัวจริง (4,108 บรรทัด, 120 queries)
├── queries_bk.js ← snapshot
├── queries_bk-061265.js ← snapshot 06/12/2565
├── mutations.js ← ตัวจริง (2,208 บรรทัด, 94 mutations)
├── mutations_bk.js ← snapshot
└── mutations_bk-061254.js ← snapshot 06/12/2565
src/components/SiderLayout/
├── index.js ← ตัวจริง (1,168 บรรทัด)
├── index_bk.js ← snapshot
└── index_menu.js ← snapshot เฉพาะส่วน menuวิธีตรวจสอบว่าไฟล์ที่จะแก้เป็นของจริง
- ชื่อไฟล์ไม่มี
_bk,_bak,_prd,_copy,_tempFilter,_bk-*,index-axios,index-axio - ไม่ได้อยู่ในโฟลเดอร์ที่ลงท้ายด้วย
_bk(เช่นLeave_bk/,LeaveHR_bk/) - ถ้าเป็น query/mutation — ต้องเป็น
queries.jsหรือmutations.jsตัวเดียวเท่านั้น ไม่ใช่ variant
Typos ที่ติดอยู่ในชื่อไฟล์/โฟลเดอร์จริง (เปลี่ยนไม่ได้)
เพราะเป็นชื่อที่ใช้ใน import path ทั้งระบบ + route entry + recoil atom name — การแก้ชื่อทำให้ไฟล์พังทั้งระบบ
| Typo | ควรเป็น | ที่พบ |
|---|---|---|
PerfessionalLicense | ProfessionalLicense | pages/WorkForce/PerfessionalLicense/, recoil/states/PerfessionalLicense/, config/routes.js:114,696-700 |
PerfessionalDepartment | ProfessionalDepartment | pages/WorkForce/PerfessionalDepartment/, recoil/states/PerfessionalDepartment/ |
TheamCss | ThemeCss | pages/TheamCss/, config/routes.js:8, containers/App/index.js:8 (route /TheamCss) |
AboutUS | AboutUs | components/AboutUS/, pages/AboutUS/ |
announment | announcement | pages/Recruitment/Announcement/announment/ |
managgeAssign | manageAssign | pages/WorkForce/ManpowerManage/info/managgeAssign.js |
HospitalHr | HospitalHR | pages/HospitalHr/ (Hr ตัวเล็ก) |
couse_pdf | course_pdf | assets/couse_pdf/ (PDF template ของ course) |
AlldataShow | AllDataShow | components/AlldataShow/ |
ModalshowAllImage | ModalShowAllImage | components/ModalshowAllImage/ |
ImageFileNewtab | ImageFileNewTab | components/ImageFileNewtab/ |
FormContactUS | FormContactUs | components/FormContactUS/ |
time_attendace.css | time_attendance.css | assets/css/theme/time_attendace.css (d หาย) |
themeplate.css, themplate.css | template.css | assets/css/theme/ — มี 3 ไฟล์ใกล้เคียงกัน (template.css, themeplate.css, themplate.css) |
refundScholaship | refundScholarship | graphql/queries.js:3799 — query name (เป็น schema ฝั่ง server ด้วย เปลี่ยนไม่ได้) |
กฎเหล็กเมื่อเจอ typo
- อย่าแก้ชื่อโฟลเดอร์/ไฟล์/query — เพราะจะทำให้ไฟล์อื่นที่ import พัง
- ถ้าสร้างไฟล์ใหม่ในโฟลเดอร์ที่มี typo ให้ใช้ชื่อโฟลเดอร์เดิม
- ถ้าทนไม่ได้ ให้ plan refactor เป็น batch (เปลี่ยนทุก import + route entry + recoil atom พร้อมกัน)
utils/ — 33 ไฟล์ helper
| ไฟล์ | หน้าที่ |
|---|---|
auth.js:1-137 | token storage + URL resolver + isLoggedIn + appVersion |
apiKey.js:1-25 | คืน apiKey UUID ตาม origin (hardcode) |
formatdate.js:1-160 | date format พ.ศ. (manual +543) |
checkError.js:1-21 | แมป error → ข้อความไทย |
message.js:1-30 | alertMessage(type, msg) wrapper |
eventLog.js:5-45 | ส่ง log event ผ่าน axios |
cryptoJs.js:1-32 | AES encrypt/decrypt (ใช้ REACT_APP_PRIVATE_KEY) |
fetchApiAxios.js:1-85 | helper axios ที่ใส่ Authorization อัตโนมัติ |
work-force.service.js:1-194 | WorkForce localStorage helpers (currentId, viewOnly, searchList) |
storage.js:1-29 | setWithExpiry / getWithExpiry |
string.js:1-35 | capitalizeFirstLetter + toGqlTypes/Args/Fields (หลังไม่ได้ใช้) |
markDown.js:1-14 | markdown → HTML |
pdfDownloader.js:1-28 | downloadPdf(base64, filename) |
downloadLink.js:1-19 | trigger browser download |
base64.js:1-11 | getBase64(file) ผ่าน FileReader |
menuBar.js:1-93 | SVG → Icon component factory |
modal.js:1-68 | AntD modal helpers |
settingInput.js:1-44 | form input rules |
dropDownList.js:1-106 | สร้าง dropdown option array |
fetchImage.js:1-56 | ดึง binary image → base64 |
leave.js:1-168 | leave calculation helpers |
hospital.js:1-150 | hospital/sickness dropdown helpers |
fund.js:1-55 | fund dropdown/formatting |
delegate.js:1-16 | delegate approver helpers |
payments.js:1-18 | payment status mapping |
changestring.js:1-33 | convertstatus, converttypenews |
number.js:1-15 | parseFloatStringToNumber |
checkType.js:1-21 | type validators |
checkOrganization.js:1-83 | org-code parsing |
LeaveStudies.js:1-42 | study-leave status helper |
youtube.js:1-7 | YouTube URL parser |
variables.js:1-4 | 1 constant |
service.js:1-7 | placeholder |
ข้อควรระวังเกี่ยวกับ utils
toGqlTypes,toGqlArgs,toGqlFieldsในutils/string.jsถูก import ใน queries.js แต่ไม่ได้ใช้จริง — เป็น helper ที่ค้างจากการวางแผน refactor ในอดีตcryptoJs.jsใช้REACT_APP_PRIVATE_KEYจาก.env— เป็น AES key ที่ expose ใน bundle (ดู บท 7.9)
เคล็ดลับตอนทำงานจริง
ตอนค้นหา "ฟีเจอร์นี้อยู่ที่ไฟล์ไหน"
- เริ่มที่
src/config/routes.js— ค้นหาชื่อเมนูหรือ path - ดู
componentfield ใน route entry — เป็นชื่อ component ที่ import จากpages/ - ถ้าไม่เจอใน
routes.jsอาจเป็นเพราะเมนู dynamic — ค้นหาใน backendfetchsidemenuresponse - จากนั้นเปิดไฟล์ใน
pages/<Feature>/index.js
ตอนเจอชื่อโฟลเดอร์แปลก ๆ
pages/TheamCss/— typo จากThemeCssแต่เป็น route จริง (/TheamCss) ห้ามแก้pages/WorkForce/PerfessionalLicense/— typo จากProfessionalแต่เป็นโฟลเดอร์จริง ห้ามแก้pages/Leave_bk/— snapshot ทั้งโฟลเดอร์ ห้ามใช้
ตอน grep ไม่เจอ symbol ที่คาดไว้
- ถ้า grep
<Query,<Mutation,useQuery,useMutationใน module เก่า — ไม่เจอเพราะใช้withApollo+this.props.client.query/mutate - ถ้า grep ใน module ใหม่ (WorkForce, PMS) — อาจเจอ
useRecoilStateแทนthis.state
ตอนเจอ route entry ที่ import โฟลเดอร์ _bk
บาง route entry อาจ import จากโฟลเดอร์ _bk โดยไม่ได้ตั้งใจ (เช่น LeaveStudies_bk/Form/Tab0/) — ให้ตรวจก่อนว่า route นั้นเปิดใช้งานจริงหรือเป็น fallback