StackTrading Docs

QnA Init Docs — UC_8.3.1 (Flow 8 - Pay Raise, L7+)

UC liên quan: UC_8.3.1 — Flow 8: Pay Raise Engine (Dual-Rail) Trigger: Promotion Level 7+ (W-2 or Senior Contractor) — xem thêm mục [CROSS_UC_DEPENDENCY] bên dưới Agent tạo: Agent 2 (Challenger), theo system_init_workflow.md — Init Flow Ngày tạo: 2026-10-10 Nguồn: References/QnA from clients/07_STAGE6_CAREER_PATH/level promotion/QnA_Level_Promotion.md → Section 5 (business logic gốc + Round 1-4)


⚠️ [CROSS_UC_DEPENDENCY] — Liên kết với UC_8.1.1 (Phase 2.2, MANDATORY)

IDCâu hỏiGiả định (BA/QC đề xuất)BA chốt (ưu tiên cao nhất)Trạng thái
B-01UC_8.1.1 (Flow 4A) đã chốt tại mục A-19 (QnA_init_docs.md của UC_8.1.1, nguồn STAGE6-008): "Path C, với New_Level > 6 (vd Level 7,8,9) → MUST trigger Flow 8 (Pay Raise Engine) để recalculate compensation". Vậy lệnh gọi Flow 8 từ Flow 4A là đồng bộ (middleware chờ Flow 8 xử lý xong trước khi coi promotion hoàn tất) hay bất đồng bộ (fire-and-forget, promotion vẫn hoàn tất ngay dù Flow 8 chạy nền)?Đề xuất: bất đồng bộ — Flow 8 chỉ ảnh hưởng compensation/payroll, không ảnh hưởng trading account/ledger (đã xử lý xong ở Stage 1-4 của Flow 4A). Promotion UI (certificate, celebration modal) không cần chờ Flow 8. Nếu Flow 8 fail, không rollback promotion.Không — Flow 8 phải done thì Flow 4A mới được coi là done promotion flow (đồng bộ, không phải fire-and-forget).✅ Đã chốt
B-02Flow 8 trigger ởmọi level >6 (7, 8, 9, ...24) mỗi lần promote, hay chỉ trigger khi bước qua mốc W-2/Senior Contractor (vd chỉ Level 7 lần đầu, các level sau 7 không đổi track)? Business logic gốc ghi "Trigger: Promotion Level 7+" — có thể hiểu là >= 7 (mọi lần) hoặc đúng lúc chạm 7 (một lần).Đề xuất: >= 7, mọi lần promote (khớp với Data Lookup "Retrieve ... for the New Level" — ngụ ý chạy lại mỗi lần vì mỗi level cóBase_Income khác nhau trong Table A/B). Round 2 Q1/A1 (skip-if-identical) cũng ngụ ý flow CHẠY mỗi lần, chỉ bypass action nếu lương không đổi — nếu chỉ trigger 1 lần duy nhất thì rule skip-if-identical sẽ vô nghĩa.If the Base_Income (or Base_Income_Flex) and the Title for the new level are mathematically identical to the trader's current level, you must completely bypass this flow. Skip-rule vẫn áp dụng. Xác nhận trigger ở mọi level >= 7 mỗi lần promote.✅ Đã chốt

UC_8.3.1 — Rate Selection & Data Lookup

IDCâu hỏiGiả định (BA/QC đề xuất)BA chốt (ưu tiên cao nhất)Trạng thái
B-03Comp_Track là field backend-only, chỉ HR/Ops sửa tay trong Rippling (đã chốt QnA Round 1 Q3/A3). Nhưng giá trị khởi tạo ban đầu (lúc trader mới hire ở Level 6, trước khi chạm Level 7 lần đầu) được set bởi ai/khi nào — có thuộc scope Flow 6 (Level 6 Transition) không?Đề xuất: thuộc scope Flow 6 (UC_8.1 — "Flow 6 - L6 Transition", hiện "[Not yet authored]") — Typeform Offer Configurator (Path A/B riêng biệt theo QnA Flow 6 Round 2) là nơi setcomp_track lần đầu. UC_8.3.1 chỉ đọc field này, không set.đồng ý assumption✅ Đã chốt
B-04Round 1 A4 yêu cầu backend tínhOld_Adjusted_Retainer để làm input công thức delta (New_Adjusted_Retainer - Old_Adjusted_Retainer) * Proration_Factor, nhưng chưa có nguồn nào xác nhận: Old_Adjusted_Retainer được tính lại từ Table A/B tại thời điểm promote (dùng current_level cũ + Rate cũ) hay đọc từ 1 field đã lưu sẵn trong DB (vd cột mới users.current_adjusted_retainer được cập nhật mỗi lần raise)?Đề xuất: tính lại real-time tại thời điểm promote — query Table A/B bằngcurrent_level (level TRƯỚC khi promote, lấy từ Users.current_level trước khi field này được update sang New_Level) + compensation_track hiện tại, áp cùng công thức Adjusted_Retainer (Hourly/Annual) để ra Old_Adjusted_Retainer. Không cần thêm cột mới nếu order of operations đảm bảo đọc current_level TRƯỚC khi Flow 4A ghi đè.Không — lấy theo con số đã lưu lúc Flow 4A chạy (snapshot tại thời điểm lên level), KHÔNG tính lại real-time theo trạng thái hiện tại. Đây phải là bộ param "inject" tại đúng thời điểm lên level đó, không phải truy vấn lại hiện tại. Comp_Track cũng lấy theo field đã lưu trong DB (không tính lại).✅ Đã chốt — 🔴 HIGH (ảnh hưởng trực tiếp công thức breaking-change đã chốt ở Round 1)
B-05[EN] For the very first time a trader hits Level 7 (i.e. they are moving from Level 6 → Level 7, right after Flow 6 "Level 6 Transition" has run) — at Level 6, the trader's pay is tracked using Flow 6's own fields (Base_Income / Base_Income_Type), not the "Adjusted_Retainer" concept, which only exists inside Flow 8's logic. Now, following B-04's answer (Old value = the number already saved at the time Flow 4A ran, NOT recalculated live), Flow 8 Path B still needs an Old_Adjusted_Retainer number to subtract in the delta formula (New_Adjusted_Retainer - Old_Adjusted_Retainer) * Proration_Factor. But for this very first Level 6→7 transition, there is no prior "Adjusted_Retainer" value ever saved for this trader — Flow 8 has never run for them before. Question: should the system take the trader's Level 6 pay data (Base_Income + Base_Income_Type from Flow 6) and run it through the SAME Adjusted_Retainer formula (Hourly → annualize via Standard_Hours, or Annual → divide by 12) to produce a synthetic Old_Adjusted_Retainer for this one-time case? Or is the Level 6→7 transition a special exception — for example, no subtraction at all, and the trader is paid the FULL New_Adjusted_Retainer * Proration_Factor for the remaining days (since Level 6 was never paid under the Dots-retainer mechanism in the first place)?Đề xuất: áp dụng cùng công thức Adjusted_Retainer cho dữ liệu Level 6 (Base_Income_Type Hourly/Annual theo Flow 6) để raOld_Adjusted_Retainer — không coi là ngoại lệ, vì Flow 6 Round 2 đã xác nhận trader International nhận lương qua Dots monthly retainer kể cả ở Level 6.No synthetic calculation. Level 6 is already paid under the Dots-retainer mechanism for International contractors — Flow 6 (Path B) already calculates and saves the initial monthly retainer to users.dots_monthly_retainer at the Level 6 transition. For the Level 6→7 promotion, the Middleware simply queries the existing Users.dots_monthly_retainer field to serve as Old_Adjusted_Retainer — exactly the same mechanism used for Level 8, Level 9, and every subsequent promotion. No special-case branch required.✅ Đã chốt

UC_8.3.1 — Path A (US W-2) Degradation Flow

IDCâu hỏiGiả định (BA/QC đề xuất)BA chốt (ưu tiên cao nhất)Trạng thái
B-06Round 2 Q2/A2 xác nhận Path A đổi sang Freshdesk ticket + Slack alert khi Rippling không có API. Nếuwebhook Zapier tạo Freshdesk ticket thất bại (Zapier timeout, Freshdesk API lỗi) — có retry/alert riêng không, hay chỉ dựa vào Slack alert làm backup thông báo?Đề xuất: theo pattern Discord bot failure handling đã dùng ở UC_8.1.1 (A-14) — 5xx/429 retry qua cron 30 phút, 404/4xx drop + Slack alert#ops-general với message rõ Trader [ID] + lý do fail, để Ops không bị mất thông tin backdate.đồng ý✅ Đã chốt — 🔴 HIGH
B-07Skip-rule (Round 2 Q1/A1) áp dụng khiBase_Income/Base_Income_Flex và Title giống nhau. Nếu chỉ Title đổi (vd đổi chức danh ở level mới) nhưng lương giữ nguyên — Flow 8 có cần chạy để chỉ update Title (qua Freshdesk ticket Path A, hoặc gọi /calculate-prorated-raise Path B chỉ để đổi field hiển thị, không có Prorated_Adjustment) không?Đề xuất: vẫn chạy flow nhưng chỉ phần Title update (ticket payload chỉ cóNew_Job_Title, bỏ New_Compensation_Rate hoặc để = giá trị cũ); Path B không cần gọi /calculate-prorated-raise nếu Base_Income_Flex/Base_Income không đổi — chỉ cần 1 lệnh update Title riêng (có thể qua endpoint khác hoặc field Title trong Users table, chưa rõ cơ chế update Title cho Path B).đồng ý assumption✅ Đã chốt

UC_8.3.1 — Path B (International/Dots) Cron Mechanics

IDCâu hỏiGiả định (BA/QC đề xuất)BA chốt (ưu tiên cao nhất)Trạng thái
B-08Round 3 Q4/A4 chốt thêm cộtusers.dots_monthly_retainer + cron ngày 1 hàng tháng gọi POST /v2/transfers cho user có dots_monthly_retainer > 0. Nếu POST /v2/transfers fail cho 1 user cụ thể (vd Dots API lỗi tạm thời) — cron có tiếp tục xử lý user tiếp theo (fail-isolated per-user) hay dừng toàn bộ batch?Đề xuất: fail-isolated per-user — mỗi user là 1 transfer riêng, lỗi 1 user không block user khác; user lỗi được log + alert Slack#ops-general, retry ở lần cron kế tiếp (ngày 1 tháng sau) KHÔNG tự động retry trong tháng (tránh double-pay nếu request đầu thực ra đã thành công nhưng response timeout).đồng ý✅ Đã chốt
B-09Khi Prorated_Adjustment one-off payout (dispatch ngay lúc promote theo Round 4 Q2/A2)và cron tháng sau cùng update dots_monthly_retainer = Adjusted_Retainer — có khả năng race condition nếu promotion xảy ra đúng ngày 1 lúc cron đang chạy (vd promote lúc 00:05 ngày 1, cron chạy lúc 00:00 ngày 1 dùng giá trị dots_monthly_retainer CŨ)?Đề xuất: không coi là race condition nghiêm trọng — Prorated_Adjustment chỉ tính cho "remaining days trong tháng hiện tại", nếu promote đúng ngày 1 thì remaining days = toàn bộ tháng, về bản chất giống hệt việc cron đã dùng rate mới luôn (không có ngày nào bị trả rate cũ). Không cần xử lý đặc biệt.Không cần cover case này — chốt theo đề xuất BA/QC, bỏ qua race condition này.✅ Đã chốt

[PATTERN] Rule candidates cho common_rules.md

IDNội dung
B-P-01Pattern "graceful degradation khi vendor thiếu API" (Rippling không có API update compensation → Freshdesk ticket + Slack alert cho Ops) đã xuất hiện ở Flow 8 Path A. Nếu pattern này lặp lại ở flow khác (vd vendor khác cũng thiếu API) → đề xuất tách thành CR riêng mô tả chuẩn payload Freshdesk ticket (Trader Name/User ID/vendor ID/thay đổi cần làm). Chưa đủ dữ liệu để confirm lặp lại — chỉ ghi nhận candidate.

Tổng kết trạng thái

  • Đã chốt (từ QnA có sẵn, không cần hỏi lại BA): toàn bộ business logic gốc + Round 1-4 của Flow 8 (effective date, comp_track field, track không editable, skip-if-identical, Path A Freshdesk degradation, Path B cron mechanics, Dots timing, phân biệt Flow 5 vs Flow 8) — xem QnA_Level_Promotion.md Section 5.
  • Đã chốt bởi BA (lần này): B-01 (Flow 8 phải đồng bộ với Flow 4A — Flow 4A chỉ done khi Flow 8 done), B-02 (trigger ở mọi level >= 7 mỗi lần promote), B-03 (comp_track khởi tạo lần đầu thuộc scope Flow 6), B-04 (Old_Adjusted_Retainer/Comp_Track lấy theo giá trị đã snapshot/lưu lúc Flow 4A chạy tại thời điểm lên level, KHÔNG tính lại real-time — 🔴 breaking impact tới công thức Round 1), B-05 (Level 6→7 lần đầu KHÔNG cần synthetic calculation — đọc trực tiếp Users.dots_monthly_retainer đã được Flow 6 ghi sẵn, dùng chung mechanism với mọi promotion N→N+1 khác), B-06 (Freshdesk ticket failure theo pattern Discord bot: 5xx/429 retry cron 30 phút, 404/4xx drop + Slack alert), B-07 (Title-only change vẫn chạy flow, chỉ update Title), B-08 (cron Dots fail-isolated per-user, retry ở cron tháng sau), B-09 (bỏ qua race condition ngày 1).
  • Pattern candidate: B-P-01.
  • ✅ ĐỦ ĐIỀU KIỆN qua Step 3 (Architect) theo PAUSE Gate của system_init_workflow.md — toàn bộ B-01→B-09 đã chốt, không còn case nào bị loại trừ.

On this page