Appearance
Module Overview — Timekeeping Request Working Schedule
1. Scope
Flow này không nằm gọn trong 1 page WorkingSchedule. Nó cắt qua:
- frontend
timekeepingroutes choWorkingSchedulevàWorkingTimeSheet, - backend actions
createRequestWorkingSchedule,updateDataRequestWorkingSchedule,changeStatusRequestWorkingSchedule, - event triggers
request_working_schedule_insert,request_log_insert,request_working_schedule_update, - direct CRUD của
time_slot_userqua Hasura mutationupsertTimeSlotUser, - timesheet read model
time_slot_time_keeping, - salary/timekeeping side effects ở
request_working_schedule_update.
Mental model nên giữ từ đầu:
request_working_schedulelà approval/request engine generic,time_slot_userlà schedule source cho lịch làm việc tuần,time_slot_time_keepinglà actual attendance log/projection,WorkingTimeSheetlà UI merge layer của attendance + approved requests.
2. Bức tranh kiến trúc
text
Request engine path
-> createRequestWorkingSchedule / updateDataRequestWorkingSchedule
-> request_working_schedule + request_log + approver chain
-> changeStatusRequestWorkingSchedule
-> request_working_schedule_update event
-> mutate salary / timekeeping / other domains + notification
Direct schedule path
-> WorkingSchedule / import Excel
-> delete_time_slot_user in range
-> insert_time_slot_user
-> no approval step
Timesheet read path
-> ListTimeKeeping(time_slot_time_keeping)
-> ListRequestWorkingSchedule(approved only)
-> store merge by employee
-> WorkingTimeSheetItem render request overlays and clocking flags3. Frontend Surface
3.1 Route families
| Family | Route group | Boundary |
|---|---|---|
| Working schedule | /timekeeping/working-schedule | Tuần làm việc, create/edit/import/export |
| Working timesheet | /timekeeping/working-sheet | Bảng công tháng, merged projection |
3.2 Permission/runtime map
| Boundary | Ghi chú |
|---|---|
Route config working_schedule | Cho ITLeader, ITStaff, BranchPOS và call-center tree |
Route config working_sheet | Cho cả BranchPOS |
Navigation submenu working_sheet | Chỉ cho ITLeader, ITStaff |
| Write path | WorkingScheduleCreate và import Excel đều dùng upsertTimeSlotUser, không gọi request actions |
4. Backend Boundary Map
| Lớp | File chính | Vai trò |
|---|---|---|
| Action | create_request_working_schedule.go | Tạo request, validate quota/annual leave, insert request |
| Action | update_data_request_working_schedule.go | Chỉnh sửa request pending, reinsert files/items/clock_in_out_items |
| Action | change_status_request_working_schedule.go | Approve/reject/cancel/recall, validate approver chain, ghi request log |
| Event | request_working_schedule_insert.go | Tính capture leave balance, gửi notification pending |
| Event | request_log_insert.go | Gửi notification approved/rejected/canceled/next-step pending |
| Event | request_working_schedule_update.go | Apply side effects vào timekeeping, salary, negative payment, task status |
5. Data Layer Map
| Layer | Object chính | Vai trò |
|---|---|---|
| Request core | request_working_schedule | Generic request record cho leave, remote, overtime, clock in/out, device, negative payment, doctor commission |
| Request audit | request_log, request_approver | Approval chain và action history |
| Request nested data | request_clock_in_out_item, request_working_schedule_item, hrm_reference_file | Chi tiết item/file theo loại request |
| Schedule source | time_slot_user, time_slot_template, time_slot_group_user | Lịch làm việc tuần và shift template |
| Attendance projection | time_slot_time_keeping | Log chấm công, late/early/off, auto update reason |
6. Semantic Rules Cần Nhớ
request_working_schedulekhông phải table riêng cho "lịch làm việc"; nó là request bus cho nhiều request families trong HRM và ecommerce side effects.- Page
WorkingScheduleđang không dùng request bus; nó mutatetime_slot_usertrực tiếp bằng delete + insert trong khoảng tuần. - Page
WorkingTimeSheetchỉ loadrequest_working_schedulecóstatus_id = approved, nên rejected/pending requests không đi vào projection. - Approve request có thể đi qua nhiều bước: nếu chưa tới bước cuối, action ghi
approved_step_onethay vìapprovedhoàn toàn. request_working_schedule_updateevent mới là nơi apply timekeeping/salary side effects khi status đổi.
7. Rủi ro / Findings
| ID | Mức | Finding |
|---|---|---|
| F-01 | P0 | Write model đang tách đôi: schedule page/import ghi thẳng time_slot_user, còn approval engine nằm ở request_working_schedule; hai nhánh này không bị buộc đi cùng nhau. |
| F-02 | P0 | request_working_schedule là engine generic, nhưng tên module/timekeeping dễ làm người đọc hiểu sai là chỉ phục vụ lịch làm việc. |
| F-03 | P1 | WorkingTimeSheet là merged projection từ time_slot_time_keeping + approved requests trong store, nên nếu chỉ test query attendance sẽ bỏ sót request overlay logic. |
| F-04 | P1 | Permission drift có thật: route working_sheet cho BranchPOS, nhưng navigation submenu lại không hiện cho role này. |
| F-05 | P1 | Import lịch làm việc xóa toàn bộ time_slot_user trong range tuần cho tập user trước khi insert lại, nên đây là overwrite batch chứ không phải merge an toàn. |
| F-06 | P1 | Event update request có side effects vượt xa timekeeping, gồm salary, negative payment, project task; QA nếu chỉ nhìn module timekeeping sẽ thiếu phạm vi thật. |