Appearance
Type Deep Dive — Request Lifecycle And Approval
1. Request engine rộng hơn timekeeping UI
Schema CreateWorkingScheduleInput cho thấy request có thể mang:
type,behavior,from,to,workday,clock_in_out_items,files,items,capture,fee,branch_id,leave_type,original_slot_id.
Thực tế backend dùng cùng engine này cho:
- leave,
- remote,
- overtime,
- late arrival / leave early,
- forget/clock in out,
- device broken / handover,
- negative payment,
- doctor commission.
2. Create request path
createRequestWorkingSchedule:
- inject
created_bytừ session user, - validate quota request tháng trước cho late/early và forget clock,
- validate annual leave balance nếu là annual leave,
- insert request vào
request_working_schedule.
Ngay sau insert, event request_working_schedule_insert:
- load reviewers bước kế tiếp,
- với annual leave thì cập nhật
capture.remaining_leave_days, - có thể update tạm
employee_profilevà annual leave logs, - gửi notification pending cho reviewers.
3. Update request path
updateDataRequestWorkingSchedule chỉ cho request pending.
Handler tách nhiều nhánh:
- leave -> cập nhật leave balance sớm + reinsert clock_in_out_items + files,
- clock_in_out -> reinsert clock items + files,
- device -> reinsert request items/files,
- other -> update core request fields.
Điểm chính là update không patch nhẹ; nhiều nested arrays bị delete rồi insert lại.
4. Change status path
changeStatusRequestWorkingSchedule là action status engine chính.
Validation chính
- chặn cùng một user approve 2 lần,
- check current user có nằm trong reviewer chain hoặc là owner,
- owner chỉ được làm một số actions như cancel,
- nếu approve nhưng chưa qua hết step thì đổi sang
approved_step_one.
Side effects trực tiếp trong action
- insert
request_log, - update
request_working_schedule.status_id, - tăng
num_approved, - một số request types có side effects ngay trong action, như device handover.
5. Notification engine
request_log_insert gửi notification theo từng action:
canceled-> báo cho reviewers hiện tại,rejected-> báo cho requester,approved-> báo cho requester,- nếu approved mà request còn pending next-step -> gửi tiếp notification pending cho reviewers bước sau.
Điều này cho thấy request log không chỉ là audit trail; nó là trigger source cho notification chain.
6. Update event side effects
request_working_schedule_update mới là nơi apply status change xuống runtime business data:
- doctor commission -> update
project_task.status_id, - negative payment -> update
invoice.paid_at,payment_verified_at, - approved leave/clock in out/remote -> backfill
time_slot_time_keeping, salary data, leave workday, - canceled/rejected -> chạy nhánh rollback tương ứng.
Đây là boundary quan trọng nhất của whole flow.
7. Findings kỹ thuật
| ID | Mức | Finding |
|---|---|---|
| R-01 | P0 | request_working_schedule là approval engine generic có blast radius sang salary, projects, ecommerce, nên mọi thay đổi ở đây là cross-domain by default. |
| R-02 | P0 | approved_step_one cho thấy approval là multi-step thật; nếu QA chỉ test pending -> approved một bước sẽ thiếu logic giữa chừng. |
| R-03 | P1 | Update request pending thường dùng pattern delete-and-reinsert cho nested data, nên risk mất file/item cũ khi payload mới không đầy đủ là có thật. |
| R-04 | P1 | Notification pending/rejected/approved bị phân tán giữa request_working_schedule_insert và request_log_insert, nên tracing một request phải nhìn cả insert event lẫn log event. |