Skip to content

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:

  1. inject created_by từ session user,
  2. validate quota request tháng trước cho late/early và forget clock,
  3. validate annual leave balance nếu là annual leave,
  4. 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_profile và 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

  1. chặn cùng một user approve 2 lần,
  2. check current user có nằm trong reviewer chain hoặc là owner,
  3. owner chỉ được làm một số actions như cancel,
  4. 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

IDMứcFinding
R-01P0request_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-02P0approved_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-03P1Update 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-04P1Notification pending/rejected/approved bị phân tán giữa request_working_schedule_insertrequest_log_insert, nên tracing một request phải nhìn cả insert event lẫn log event.