7.5 · GraphQL queries + mutations catalog
บทนี้ทำดัชนี GraphQL operations ทั้งหมดที่ vtrc-web ใช้ — 138 queries + 41 mutations รวม 179 operations (นับจาก export default keys ใน queries.js / mutations.js; แท็ก gql มี 137 และ 42 ตามลำดับ)
เป้าหมายคือให้ค้นหา "ฟีเจอร์นี้ใช้ query ชื่ออะไร" แล้วไปดูในไฟล์ queries.js / mutations.js ได้โดยตรง
โครงสร้างไฟล์
src/graphql/
├── queries.js 4,493 บรรทัด — 138 query definitions (export keys)
├── mutations.js 1,447 บรรทัด — 41 mutation definitions (export keys)
└── index.js 2 บรรทัด — re-exportsrc/graphql/index.js ทั้งหมด:
export { default as Queries } from './queries'
export { default as Mutations } from './mutations'ทุกหน้า import ผ่าน import { Queries, Mutations } from '../graphql' — ไม่ import ตรงจากไฟล์
รูปแบบการประกาศ
query และ mutation แต่ละตัวประกาศเป็น const ที่ระดับ module แล้วรวมใน export default {} ท้ายไฟล์:
// queries.js (ตัวอย่าง pattern)
import gql from "graphql-tag";
const fetchSlip = gql`
query (
$month: String!
$year: String!
$identityCard: String!
$profileKey: String!
) {
fetchSlip(
month: $month
year: $year
identityCard: $identityCard
profileKey: $profileKey
) {
paymentDate
income { lists { name value } total totalPerMonth totalPerYear }
expense { total withholdingTax lists { name value } }
baseTax406
}
}
`;
// ... 138 queries ...
export default {
fetchListPost,
fetchListPostType,
fetchProfile,
fetchSlip,
// ...
};ข้อควรระวังเกี่ยวกับ helper
utils/string.js export toGqlTypes, toGqlArgs, toGqlFields:
export const capitalizeFirstLetter = word =>
word && word.charAt(0).toUpperCase() + word.substring(1)
export const toGqlTypes = args => {
let gqlTypes = ''
args.forEach((arg, index) => {
if (index !== 0) {
gqlTypes = gqlTypes + ' '
}
gqlTypes = gqlTypes + `$${arg.name}: ${arg.type}`
})
return gqlTypes
}
export const toGqlArgs = args => {
let gqlArgs = ''
args.forEach((arg, index) => {
if (index !== 0) {
gqlArgs = gqlArgs + ' '
}
gqlArgs = gqlArgs + `${arg.name}: $${arg.name}`
})
return gqlArgs
}
export const toGqlFields = fields => {
let gqlFields = ''
for (let n in fields) {
gqlFields = gqlFields + fields[n]
if (n !== fields.length - 1) {
gqlFields = gqlFields + '\n'
}
}
return gqlFields
}helpers ทั้ง 3 ถูก import ใน queries.js:2 แต่ ไม่ได้ใช้จริง — ทุก query เขียนเป็น template literal ด้วยมือ เป็น helper ที่ค้างจากการวางแผน refactor ในอดีต
ถ้าจะ refactor ในอนาคต อย่าเอา helpers พวกนี้ไปใช้โดยไม่ทดสอบ — มีบั๊กในตัวเอง (เช่น toGqlFields เทียบ n !== fields.length - 1 ผิดเพราะ for...in วน key ไม่ใช่ index)
Queries — 138 ตัว จัดเป็น 12 cluster
Cluster 1 — Auth & onboarding (12 queries)
| Query | หน้าที่ |
|---|---|
refreshToken | refresh JWT (ใช้ใน errorLink บ่อยที่สุด) |
verifyUser | ตรวจ username ก่อนใส่ password (login ขั้นที่ 1) |
verifyEmpCodeLogin | verify employee code |
generateCaptcha | ขอ captcha ก่อน login |
checkRequestCaptcha | ตรวจ captcha |
requestSendingOTP | ขอ OTP |
sendVerifyCode | ส่ง verify code |
setupPassword | ตั้ง password ครั้งแรก |
forgetPassword | ลืม password |
checkSMSforgetPassword | ตรวจ SMS สำหรับ forget password |
resetPassword | reset password |
requestProfileCheck | ตรวจ profile ก่อน verify |
Cluster 2 — Profile (10 queries)
| Query | หน้าที่ |
|---|---|
fetchProfile | profile หลัก (ใช้ใน SiderLayout) |
fetchProfileForLeave | profile สำหรับ leave (subset) |
fetchProfileDetail | detail ของ profile |
fetchEmployeeProfile | employee profile ขยาย |
fetchEmployeeDetail | employee detail |
fetchEmployeeProfileHistory | ประวัติการเปลี่ยนแปลง profile |
checkIsEmployeeProfileHistoryActive | ตรวจว่า profile history ยัง active |
detchProfileListDetail | profile list detail (สะกดผิด detch แต่ใช้จริง) |
fetchDetailProfileListCC | profile list CC |
accordingProfile | profile ตามเงื่อนไข |
Cluster 3 — Slip & tax (11 queries)
| Query | หน้าที่ |
|---|---|
fetchSlip | สลิปเงินเดือน (main) |
fetchSlipPayDate | วันที่จ่ายของ slip |
fetchUrlSlip | URL ดาวน์โหลด slip (PDF) |
dropDownSlipPayment | dropdown ปี/เดือนของ slip |
dropDownMasterSlipPayment | dropdown slip master data |
fetchUrlTax | URL ดาวน์โหลดภาษี |
fetchUrlTax6Month | URL ภาษี 6 เดือน |
fetchUrlTaxYears | URL ภาษีรายปี |
fetchTaxDraft | tax draft |
fetchDetailTaxAll | detail tax ทั้งหมด |
templateFormTax | template ของ form tax |
Cluster 4 — News, policy, document (10 queries)
| Query | หน้าที่ |
|---|---|
fetchListPost | รายการโพสต์ (ข่าว) |
fetchListPostType | รายการโพสต์ตาม type |
fetchListNotification | รายการแจ้งเตือน |
fetchCountAllNotification | จำนวนแจ้งเตือนทั้งหมด (badge) |
fetchNotification | detail แจ้งเตือน |
fetchPolicyLastVersion | policy เวอร์ชันล่าสุด |
fetchListDocumen | รายการ document (สะกดผิด Documen แต่ใช้จริง) |
fetchListDocumenList | document list (subset) |
fetchListDocumentGroup | document group |
fetchListDocumentCategoryMasterData | document category master data |
Cluster 5 — Hospital / medical claim (10 queries)
| Query | หน้าที่ |
|---|---|
fetchListWDHospital | รายการเบิกค่ารักษา |
fetchListSearchWDHospital | ค้นหารายการเบิก |
fetchMedicalExpensesLicensee | ผู้มีสิทธิเบิก |
dropdownMedicalExpensesLicensee | dropdown ผู้มีสิทธิ |
fetchApproverMedical | approver ทางการแพทย์ |
fetchOptionApprover | ตัวเลือก approver |
fetchListWDHospitalApprover | รายการที่ต้อง approve |
fetchListSearchWDHospitalApprover | ค้นหารายการ approve |
fetchWDHospitalHistory | ประวัติการเบิก |
fetchHospital | detail โรงพยาบาล |
Cluster 6 — Leave (15 queries)
| Query | หน้าที่ |
|---|---|
fetchLeaveDocumentList | รายการใบลา |
fetchLeaveDocumentDetail | detail ใบลา |
fetchLeaveDocumentDetailStatus | status ใบลา |
fetchLeaveDocumentDetailDraf | draft ใบลา (สะกดผิด Draf แต่ใช้จริง) |
fetchLeaveDocumentHistory | ประวัติใบลา |
fetchListLeaveDocumentApprover | รายการที่ต้อง approve |
fetchApproverLeave | approver ใบลา |
fetchOptionApproverLeave | ตัวเลือก approver |
fetchLeaveDay | จำนวนวันลา |
fetchLeaveDayAll | วันลาทั้งหมด |
fetchLeaveHour | จำนวนชั่วโมงลา |
fetchLeaveShiftTime | shift time ของ leave |
fetchWorkingDay | วันทำการ |
fetchTotalDayOff | วันหยุดรวม |
detailLeaveDocumentAsFlow | detail leave document flow |
Cluster 7 — Leave studies (4 queries)
| Query | หน้าที่ |
|---|---|
fetchListStudyLeaveRequest | รายการขอลาศึกษา |
fetchStudyLeaveRequestById | detail ขอลาศึกษา |
dropDownstudyLeaveYear | dropdown ปีการศึกษา |
fetchMasterConfigTypeLeave | master config type leave |
Cluster 8 — Welfare / fund (10 queries)
| Query | หน้าที่ |
|---|---|
fetchAllProvidentFundDetail | รายละเอียดกองทุนสงเคราะห์ |
fetchConfigChangeProvPercentage | config % เปลี่ยนกองทุน |
fetchFundChangeHistory | ประวัติการเปลี่ยนแปลงกองทุน |
fetchFundChangeBenefitPersonDetail | detail ผู้รับผลประโยชน์ |
fetchListChildTuitions | รายการค่าเล่าเรียนบุตร |
fetchListChildDetailInTuition | detail บุตรในค่าเล่าเรียน |
fetchEachChildTuitionDetail | detail รายบุตร |
fetchEmpwithCoA | employee with CoA |
fetchEmployeeFamily | ครอบครัว employee |
fetchEmployeeRights | สิทธิของ employee |
Cluster 9 — Master data / dropdown (12 queries)
| Query | หน้าที่ |
|---|---|
fetchListDropDownMasterData | master data ทั่วไป |
fetchDropDownMasterData | master data (duplicate) |
fetchListDropDownDivisionCDMasterData | division master data |
fetchListDocumentTypeMasterData | document type |
fetchListDocumentCategoryMasterData | document category |
dropdownListRelation | ความสัมพันธ์ |
dropdownRelationShipLabel | label ความสัมพันธ์ |
dropdownListTitleMale | คำนำหน้าชาย |
dropdownListTitleFemale | คำนำหน้าหญิง |
dropdownListProvince | จังหวัด |
dropdownListAmphur | อำเภอ |
dropdownListDistrict | ตำบล |
Cluster 10 — Organization / contact (5 queries)
| Query | หน้าที่ |
|---|---|
fetchListOrganization | รายการหน่วยงาน |
fetchListOrganizationGroup | กลุ่มหน่วยงาน |
fetchListContactUs | ติดต่อเรา |
fetchListContactUsCategory | หมวดหมู่ติดต่อ |
fetchListSystem | ระบบ |
Cluster 11 — Salary certificate (5 queries)
| Query | หน้าที่ |
|---|---|
fetchSalaryCert | หนังสือรับรองเงินเดือน |
fetchUrlSalaryCert | URL ดาวน์โหลด |
fetchUrlSalaryCertForBank | URL สำหรับธนาคาร |
fetchConditionSalaryCertText | เงื่อนไข text |
fetchConditionSalaryCertForBankText | เงื่อนไขสำหรับธนาคาร |
Cluster 12 — อื่น ๆ (8 queries)
| Query | หน้าที่ |
|---|---|
fetchTimeAttendanceByDate | เวลาเข้า-ออกงาน |
fetchEmployeeBankAccount | บัญชีธนาคาร |
fetchEmployeeTax | ภาษี employee |
fetchEmployeeCompensation | compensation |
fetchEmployeeProvidentFund | กองทุน employee |
fetchCourse, fetchCourseList | หลักสูตร |
fetchApplicationSetting | ตั้งค่าแอป |
howToOpenPayrollSlip | วิธีเปิด slip |
Cluster 13 — Conicle + KCMH document (5 queries)
| Query | หน้าที่ |
|---|---|
fetchUrlConicleAllPolicy | Conicle policy ทั้งหมด |
fetchUrlConicleRequestPolicy | Conicle request |
fetchUrlConicleMyPolicy | Conicle ของฉัน |
fetchUrlConicleRedirectPath | Conicle redirect |
fetchListKCMHDocument, fetchListKCMHDocumentList, fetchListKCMHQualityDocument, fetchListKCMHQualityDocumentList | KCMH document |
Cluster 14 — PMS (3 queries)
| Query | หน้าที่ |
|---|---|
fetchMasterConfigTypePMS | config type PMS |
fetchCountListAllApproving | จำนวนรายการ approving |
listCancelWaitingForApproval | รายการ cancel waiting |
Cluster 15 — Delegate / approver proxy (3 queries)
| Query | หน้าที่ |
|---|---|
fetchListDelegateApprover | รายการมอบหมาย |
fetchListDelegator | ผู้มอบหมาย |
employeeDetailProfileForLeave | รายละเอียด employee สำหรับมอบหมาย |
Mutations — 41 ตัว จัดเป็น 7 cluster
Cluster M1 — Auth (6 mutations)
| Mutation | หน้าที่ |
|---|---|
login | login หลัก |
logout | logout |
setupPassword | ตั้ง password ครั้งแรก |
changePassword | เปลี่ยน password |
requestVerifyOTPandSetupPassword | ขอ OTP ก่อน setup |
resetPassword | reset password |
Cluster M2 — Profile (6 mutations)
| Mutation | หน้าที่ |
|---|---|
changeCurrentProfile | เปลี่ยน profile ปัจจุบัน |
createConsent | บันทึก consent |
changePhoneNumber | เปลี่ยนเบอร์โทร |
createAddress | เพิ่มที่อยู่ |
updateAddress | แก้ไขที่อยู่ |
createPostRead | ทำเครื่องหมายอ่านแล้ว |
Cluster M3 — Tax (2 mutations)
| Mutation | หน้าที่ |
|---|---|
createTaxDraft | สร้าง tax draft |
updateTaxDraft | แก้ไข tax draft |
Cluster M4 — Hospital (6 mutations)
| Mutation | หน้าที่ |
|---|---|
createWDHospital | สร้างคำขอเบิก |
updateWDHospital | แก้ไขคำขอเบิก |
destroyWDHospital | ลบคำขอเบิก |
destroyWDSlip | ลบ slip |
destroyWDHospitalDocument | ลบเอกสาร |
cancelExportWDHospital | ยกเลิก export |
Cluster M5 — Leave (9 mutations)
| Mutation | หน้าที่ |
|---|---|
createLeaveDocument | สร้างใบลา |
updateLeaveDocument | แก้ไขใบลา |
multipleUpdateLeaveDocument | แก้ไขหลายใบพร้อมกัน |
removeLeaveDocumentDraf | ลบ draft |
checkRemoveLeaveDocumentAsFlow | ตรวจการลบตาม flow |
mutipleApproveCancelLeaveDocumentAsFlow | approve cancel หลายรายการ |
approveCancelLeaveDocumentAsFlow | approve cancel รายการเดียว |
updateStudyLeaveRequest | อัปเดตคำขอลาศึกษา |
deleteAttachmentFile | ลบไฟล์แนบ |
Cluster M6 — Delegate (2 mutations)
| Mutation | หน้าที่ |
|---|---|
createDelegateApprover | มอบหมาย approver |
revokeDelegateApprover | ยกเลิกการมอบหมาย |
Cluster M7 — Fund (5 mutations)
| Mutation | หน้าที่ |
|---|---|
createFundRateChange | สร้างคำขอเปลี่ยนอัตรา |
updateFundRateChange | แก้ไขคำขอ |
createFundApplication | สมัครกองทุน |
createFundBenefitPerson | เพิ่มผู้รับผลประโยชน์ |
updateFundBenefitPerson | แก้ไขผู้รับผลประโยชน์ |
createFundBenefitPersonFormPDF | สร้าง PDF ผู้รับผลประโยชน์ |
Cluster M8 — อื่น ๆ (3 mutations)
| Mutation | หน้าที่ |
|---|---|
createUserReadNotification | ทำเครื่องหมายอ่าน notification |
createUserResultNotification | ทำเครื่องหมายผลลัพธ์ notification |
updateClickCount | อัปเดต click count (analytics) |
สัดส่วน queries : mutations
queries 138 (77%)
mutations 41 (23%)
total 179
ratio 3.37 : 1ฐานนับ: จำนวน key ใน export default (138 queries / 41 mutations ≈ 3.37 : 1) — ไม่ใช่จำนวนแท็ก gql (137 / 42)
อัตราส่วน queries : mutations ที่ ≈ 3.37 : 1 บ่งชี้ว่าแอปเป็น read-heavy — อ่านข้อมูลมากกว่าเขียน ซึ่งสอดคล้องกับเอกลักษณ์ของ employee portal
Typos ที่ติดอยู่ใน GraphQL schema (คำเตือน)
GraphQL schema ฝั่ง vtrc-api ถูก author ด้วยมือและเผยแพร่สู่สาธารณะแล้ว เปลี่ยนชื่อไม่ได้โดยไม่ทำ breaking change typos เหล่านี้จึงคงอยู่ใน query/mutation names ตลอดไป:
| Typo | ที่ควรเป็น | ที่พบ |
|---|---|---|
fetchListDocumen | fetchListDocument | queries.js + ใช้ใน page |
fetchLeaveDocumentDetailDraf | fetchLeaveDocumentDetailDraft | queries.js |
detchProfileListDetail | fetchProfileListDetail | queries.js |
dropDownstudyLeaveYear | dropDownStudyLeaveYear | queries.js (s ตัวเล็ก) |
กฎเหล็ก — ถ้าเจอ query/mutation ที่ดูสะกดผิด ให้ใช้ตามที่เป็น ห้ามแก้ชื่อโดยไม่ได้รับมอบหมาย เพราะจะทำให้ request fail
เคล็ดลับตอนทำงานจริง
ตอนค้นหา query สำหรับฟีเจอร์
- ค้นใน
queries.jsด้วยคำที่เกี่ยวข้อง (เช่นSlip,Leave,Hospital) - ดูชื่อ field ที่ query คืน — ถ้าตรงกับที่ต้องการ ใช้ตัวนั้น
- cross-check ในฝั่ง page ที่ใช้ — grep
Queries.<name>ในpages/เพื่อดูตัวอย่างการใช้
ตอนเพิ่ม query ใหม่
- เพิ่ม
const newQuery = gql\...`ในตำแหน่งที่เหมาะสมในqueries.js` - เพิ่ม
newQuery,ในexport default {}ท้ายไฟล์ - cross-check ฝั่ง vtrc-api ว่า query นั้นมีอยู่จริงใน schema
- อย่าลืมเพิ่มใน
queries_bk.jsด้วยถ้าทีมต้องการ (แต่ปกติไม่ต้อง)
ตอน debug "query ตอบ null"
- ตรวจ variables ที่ส่งไป — ครบตามที่ query กำหนดไหม
- ตรวจ
extensions.codeใน response — อาจเป็นFORBIDDEN(ไม่มีสิทธิ์) หรือBAD_USER_INPUT - ถ้าทุกอย่างถูกแต่ได้ null — อาจเป็นที่ฝั่ง resolver return null เพราะไม่พบข้อมูล
ตอนใช้ query ใน page
Pattern มาตรฐาน:
this.props.client.query({
query: Queries.fetchSlip,
variables: {
month: '01',
year: '2568',
identityCard: '...',
profileKey: '...'
},
fetchPolicy: 'no-cache' // optional, default อยู่แล้ว
})
.then(({ data, errors }) => {
if (errors) {
// errorLink จัดการให้แล้ว
return
}
this.setState({ slip: data.fetchSlip })
})หรือแบบ async/await:
const { data, errors } = await this.props.client.query({
query: Queries.fetchSlip,
variables: { ... }
})ตอนใช้ mutation
this.props.client.mutate({
mutation: Mutations.createLeaveDocument,
variables: {
leaveType: '...',
startDate: '...',
endDate: '...',
// ...
}
})
.then(({ data, errors }) => {
if (errors) return
alertMessage('success', 'บันทึกสำเร็จ')
this.props.history.push('/leave/search')
})