Skip to content

Type Deep Dive — Affiliate Approval And Status

1. Registration Paths

1.1 Staff path

ListCreate gọi mutation affiliateUserRegistration(data) khi không có id. Ở backend, nếu caller role là user hoặc admin:

  • validate tag_id,
  • tìm hoặc tạo customer account theo phone_number,
  • insert affiliate_user với is_active = true,
  • set approved_at = now,
  • update account.affiliate_tag_id.

Kết luận: staff create không phải "tạo hồ sơ chờ duyệt", mà gần như là approve ngay.

1.2 Customer / anonymous path

Cùng action affiliateUserRegistration, nhưng nếu caller role là customer hoặc anonymous:

  • insert affiliate_user pending,
  • không set is_active,
  • không bắt buộc tag,
  • giữ record trong approval queue để staff duyệt sau.

2. Approval Queue Surface

ApprovalList chỉ query affiliate_user với is_active = false. Đây là queue gộp cho:

  • hồ sơ khách tự đăng ký đang chờ duyệt,
  • hồ sơ đã từng active nhưng bị revoke.

Do đó queue này không phải chỉ chứa "new applications".

3. User Status Engine

Popup ListActivePopup gọi ChangeAffiliateUserStatus(input) với:

  • type = user,
  • new_status = approve hoặc revoke,
  • tag_id bắt buộc khi approve.

3.1 Approve user

handleApproveAffiliate sẽ:

  1. tìm customer account theo phone,
  2. nếu chưa có thì CreateCustomer,
  3. validate tag tồn tại,
  4. update affiliate_user sang active,
  5. ghi affiliate_action_log với action grant permission.

3.2 Revoke user

handleRevokeAffiliate chỉ:

  • set is_active = false,
  • clear approved_at,
  • giữ lại account linkage và dữ liệu lịch sử khác.

Điểm quan trọng: revoke không xóa CTV và không rollback order/payment lịch sử.

4. Route / Navigation Semantics

module.ts cho thấy:

  • root /affiliate redirect vào approval ở admin flow,
  • POS special flow có thể redirect vào list,
  • cùng component ListCreate được mount ở cả approval edit, list create, list edit.

Điều này cho thấy UI đang xem approval shell và active list như hai góc nhìn khác nhau của cùng entity affiliate_user, không phải hai entity khác nhau.

5. Referral Surface

ListReferral và các aggregate queries dùng affiliate_summary_view, không dùng action mutation đặc biệt. Referral detail vì vậy là read-model/reporting shell của affiliate user, không phải trạng thái lõi.

6. Audit / Logs

Action affiliateUserChangeStatus luôn append affiliate_action_log sau khi mutation thành công, map theo:

  • user.approve -> grant permission,
  • user.revoke -> revoke permission.

Ngoài action log, affiliate user còn có:

  • affiliate_user_log để lưu quan hệ affiliate/referral,
  • reference_file cho KYC front/back.

7. Findings kỹ thuật

IDMứcFinding
A-01P0Approval queue không chỉ là "new pending registrations"; record bị revoke cũng quay lại cùng queue vì filter chỉ nhìn is_active = false.
A-02P0Staff create path bypass approval queue hoàn toàn, nên nếu PO/QA giả định mọi CTV đều qua approval list thì sẽ sai.
A-03P1affiliateUserRegistrationaffiliateUserChangeStatus(type=user, approve) có phần side effect chồng nhau: cả hai đều có thể create/bind account và activate affiliate, nhưng qua hai entry points khác nhau.
A-04P2CreateCustomer bootstrap account với default cứng từ backend, nên affiliate approval hiện còn gánh trách nhiệm account provisioning thay vì chỉ change status.