Core Function Dependency — Flow 1-9

ภาพนี้แสดงว่าแต่ละ Flow เรียก core function อะไรบ้าง และ function ไหนถูกใช้ร่วมกัน
ใช้ประเมิน impact ก่อนแก้ไข logic


ภาพรวม: ทุก Flow ลงมาที่ Core เดียวกัน

แสดงให้เห็นว่าทั้ง 9 Flow แม้จะมี trigger ต่างกัน แต่ทุกอันลงมาใช้ core function ชุดเดียวกัน
อ่าน diagram นี้เพื่อเข้าใจ “ถ้าแก้ที่จุดนี้ จะกระทบ flow ไหนบ้าง” ก่อนลงมือแก้โค้ด
⚠️ = path แยก ไม่ผ่าน updateMemberTier() ต้องระวังเป็นพิเศษ

flowchart LR subgraph FLOWS ["Flows (Entry Points)"] direction TB F1["Flow1 · Sales Txn"] F2["Flow2 · Refund/Void"] F3A["Flow3A · Batch Accum"] F3B["Flow3B · Batch Recalc ⚠️"] F4["Flow4 · Maintain Tier"] F5["Flow5 · Reconcile"] F6p["Flow6 · Admin ADD"] F6m["Flow6 · Admin DEDUCT"] F7["Flow7 · Co-Brand"] F8["Flow8 · Staff Exit"] F9e["Flow9 · Import existing"] F9n["Flow9 · Import new ⚠️"] end subgraph DECIDE ["Tier Decision — ตัดสินใจว่า Tier ใหม่คืออะไร"] CTU["calculateTierToUpgrade()"] CTA["calculateTierAdjustment()"] CNT["calculateNewTier()"] CNTM["calculateNewTierFromMaintainSpending()"] CNM["calculateNewMinimumTier()"] end subgraph MUTATE ["Core Mutation — เขียนผล: เปลี่ยน Tier, บันทึกประวัติ, ยิง Event"] UMT["🔴 updateMemberTier()"] PST["processSpendingAndTierUpdate()<br/>F3B only"] CR["create()<br/>F9 new only"] end subgraph CALC ["Core Calculation — คำนวณยอดสะสมที่ใช้ตัดสิน Tier"] CAS["calculateAccumulateSpending()"] CAMS["calculateAccumulateMaintainSpending()"] CA["🔴 calculateAccumulate()<br/>root of everything"] end %% Upgrade path (green) F1 --> CTU --> UMT F6p --> CTU %% Downgrade path (red) F2 --> CTA --> UMT F5 --> CTA F6m --> CTA %% Co-Brand / Staff path (purple) F7 --> CNM F7 --> CNT --> UMT F8 --> CNT %% Maintain path (blue) F4 --> CNM F4 --> CNTM --> UMT %% Other paths F9e --> UMT F3A --> CAS %% Isolated paths (orange) F3B --> PST F9n --> CR %% Calculation links CTU --> CAS CTA --> CAS CNT --> CAS UMT --> CAMS CAS --> CA CAMS --> CA %% Node styles — Flows (light blue) style F1 fill:#1e3a5f,color:#fff style F2 fill:#1e3a5f,color:#fff style F3A fill:#1e3a5f,color:#fff style F3B fill:#1e3a5f,color:#fff style F4 fill:#1e3a5f,color:#fff style F5 fill:#1e3a5f,color:#fff style F6p fill:#1e3a5f,color:#fff style F6m fill:#1e3a5f,color:#fff style F7 fill:#1e3a5f,color:#fff style F8 fill:#1e3a5f,color:#fff style F9e fill:#1e3a5f,color:#fff style F9n fill:#1e3a5f,color:#fff %% Node styles — Decision (yellow/amber) style CTU fill:#5c4a00,color:#fff style CTA fill:#5c4a00,color:#fff style CNT fill:#5c4a00,color:#fff style CNTM fill:#5c4a00,color:#fff style CNM fill:#5c4a00,color:#fff %% Node styles — Mutation (red) style UMT fill:#7a0000,color:#fff style PST fill:#7a4400,color:#fff style CR fill:#7a4400,color:#fff %% Node styles — Calculation (green) style CAS fill:#004d00,color:#fff style CAMS fill:#004d00,color:#fff style CA fill:#004d00,color:#fff %% Link styles — Upgrade (green): F1→CTU, CTU→UMT, F6p→CTU linkStyle 0 stroke:#00cc00,stroke-width:2px linkStyle 1 stroke:#00cc00,stroke-width:2px linkStyle 2 stroke:#00cc00,stroke-width:2px %% Link styles — Downgrade (red): F2→CTA, CTA→UMT, F5→CTA, F6m→CTA linkStyle 3 stroke:#ff4444,stroke-width:2px linkStyle 4 stroke:#ff4444,stroke-width:2px linkStyle 5 stroke:#ff4444,stroke-width:2px linkStyle 6 stroke:#ff4444,stroke-width:2px %% Link styles — Co-Brand/Staff (purple): F7→CNM, F7→CNT, CNT→UMT, F8→CNT linkStyle 7 stroke:#cc66ff,stroke-width:2px linkStyle 8 stroke:#cc66ff,stroke-width:2px linkStyle 9 stroke:#cc66ff,stroke-width:2px linkStyle 10 stroke:#cc66ff,stroke-width:2px %% Link styles — Maintain (blue): F4→CNM, F4→CNTM, CNTM→UMT linkStyle 11 stroke:#4488ff,stroke-width:2px linkStyle 12 stroke:#4488ff,stroke-width:2px linkStyle 13 stroke:#4488ff,stroke-width:2px %% Link styles — Other (gray): F9e→UMT, F3A→CAS linkStyle 14 stroke:#888,stroke-width:1px linkStyle 15 stroke:#888,stroke-width:1px %% Link styles — Isolated (orange): F3B→PST, F9n→CR linkStyle 16 stroke:#ff8800,stroke-width:2px linkStyle 17 stroke:#ff8800,stroke-width:2px %% Link styles — Calculation (gray dashed): CTU→CAS, CTA→CAS, CNT→CAS, UMT→CAMS, CAS→CA, CAMS→CA linkStyle 18 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 19 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 20 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 21 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 22 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 23 stroke:#aaa,stroke-width:2px,stroke-dasharray:5

สี node: 🔵 Flows · 🟡 Decision · 🔴 Mutation · 🟢 Calculation
สีเส้น: 🟢 upgrade · 🔴 downgrade · 🔵 maintain · 🟣 co-brand/staff · 🟠 isolated · ⚫ calculation (เส้นประ)
เส้นประ = การเรียก function ภายใน ไม่ใช่ flow หลัก

ภาพรวม: Flow → Core Function

แต่ละ Flow เข้าระบบผ่าน entry point function ของตัวเอง ก่อนส่งต่อไปยัง tier decision และ core mutation
diagram นี้แสดงเฉพาะ “ใครเรียกใคร” ในระดับ orchestration — ยังไม่ลงลึกถึง logic ภายใน

flowchart LR F1([Flow1<br/>Sales Txn]) F2([Flow2<br/>Refund/Void]) F3A([Flow3A<br/>Batch Accum]) F3B([Flow3B<br/>Batch Recalc]) F4([Flow4<br/>Maintain Tier]) F5([Flow5<br/>Reconcile]) F6A([Flow6<br/>Admin ADD]) F6D([Flow6<br/>Admin DEDUCT]) F7([Flow7<br/>Co-Brand]) F8([Flow8<br/>Staff Exit]) F9E([Flow9<br/>Import<br/>Existing]) F9N([Flow9<br/>Import<br/>New]) ANS["addNewSalesTransaction()"] ANR["addNewRefundSalesTransaction()"] UAS["updateAccumulateSpending()"] PST["processSpendingAndTierUpdate()<br/>⚠️ bypasses updateMemberTier()"] MT["maintainTier()"] AT["adjustTier()"] CBU["coBrandCardUpdated()<br/>updateMemberLinkCoBrand()"] PSE["processStaffExit()"] IU["importUpdate()"] CR["create()"] F1 --> ANS F2 --> ANR F3A --> UAS F3B --> PST F4 --> MT F5 --> AT F6A --> ANS F6D --> ANR F7 --> CBU F8 --> PSE F9E --> IU F9N --> CR

Level 1 → Level 2: Tier Decision → Core Mutation

entry point → tier decision → core mutation → core calculation

ลงลึกกว่า diagram แรก — แสดง chain การเรียกจากต้นทางไปถึงปลายทาง

  • entry point — จุดที่แต่ละ flow เริ่มต้น เช่น รับ Kafka event หรือ Admin กด submit
  • tier decision — ตัดสินใจว่า tier ใหม่ควรเป็นอะไร (ขึ้น / ลง / คงเดิม)
  • core mutation — เขียนผลลัพธ์ลง member: เปลี่ยน tier, บันทึกประวัติ, ยิง event
  • core calculation — คำนวณยอดสะสมที่ใช้ตัดสิน tier — ทุก path ลงมาบรรจบที่นี่

สังเกตว่า calculateAccumulate() คือ root ที่ทุก path ลงมาบรรจบกัน

flowchart LR subgraph EP ["Entry Point"] ANS["addNewSalesTransaction()"] ANR["addNewRefundSalesTransaction()"] MT["maintainTier()"] AT["adjustTier()"] CBU["coBrandCardUpdated()<br/>updateMemberLinkCoBrand()"] PSE["processStaffExit()"] IU["importUpdate()"] UAS["updateAccumulateSpending()"] PST["processSpendingAndTierUpdate()<br/>⚠️ isolated path"] CR["create()<br/>⚠️ isolated path"] end subgraph TD ["Tier Decision"] CTU["calculateTierToUpgrade()"] CTA["calculateTierAdjustment()"] CNT["calculateNewTier()"] CNTM["calculateNewTierFromAccumulateMaintainSpending()"] CNM["calculateNewMinimumTier()"] end subgraph CM ["Core Mutation"] UMT["🔴 updateMemberTier()"] PSTU["processSpendingAndTierUpdate()<br/>(mutation — Flow3B only)"] end subgraph CC ["Core Calculation"] CAS["calculateAccumulateSpending()"] CAMS["calculateAccumulateMaintainSpending()"] CA["🔴 calculateAccumulate()"] end ANS --> CTU --> UMT ANR --> CTA --> UMT AT --> CTA AT --> UMT MT --> CNM --> UMT MT --> CNTM --> UMT CBU --> CNM CBU --> CNT --> UMT PSE --> CNT IU --> UMT PST --> PSTU CTU --> CAS CTA --> CAS CNT --> CAS UAS --> CAS UMT --> CAMS CAS --> CA CAMS --> CA %% Link styles — Upgrade (green): ANS→CTU, CTU→UMT linkStyle 0 stroke:#00cc00,stroke-width:2px linkStyle 1 stroke:#00cc00,stroke-width:2px %% Link styles — Downgrade (red): ANR→CTA, CTA→UMT, AT→CTA, AT→UMT linkStyle 2 stroke:#ff4444,stroke-width:2px linkStyle 3 stroke:#ff4444,stroke-width:2px linkStyle 4 stroke:#ff4444,stroke-width:2px linkStyle 5 stroke:#ff4444,stroke-width:2px %% Link styles — Maintain (blue): MT→CNM, CNM→UMT, MT→CNTM, CNTM→UMT linkStyle 6 stroke:#4488ff,stroke-width:2px linkStyle 7 stroke:#4488ff,stroke-width:2px linkStyle 8 stroke:#4488ff,stroke-width:2px linkStyle 9 stroke:#4488ff,stroke-width:2px %% Link styles — Co-Brand/Staff (purple): CBU→CNM, CBU→CNT, CNT→UMT, PSE→CNT linkStyle 10 stroke:#cc66ff,stroke-width:2px linkStyle 11 stroke:#cc66ff,stroke-width:2px linkStyle 12 stroke:#cc66ff,stroke-width:2px linkStyle 13 stroke:#cc66ff,stroke-width:2px %% Link styles — Other (gray): IU→UMT linkStyle 14 stroke:#888,stroke-width:1px %% Link styles — Isolated (orange): PST→PSTU linkStyle 15 stroke:#ff8800,stroke-width:2px %% Link styles — Calculation (gray dashed): CTU→CAS, CTA→CAS, CNT→CAS, UAS→CAS, UMT→CAMS, CAS→CA, CAMS→CA linkStyle 16 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 17 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 18 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 19 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 20 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 21 stroke:#aaa,stroke-width:2px,stroke-dasharray:5 linkStyle 22 stroke:#aaa,stroke-width:2px,stroke-dasharray:5

สีเส้น: 🟢 upgrade · 🔴 downgrade · 🔵 maintain · 🟣 co-brand/staff · 🟠 isolated · ⚫ calculation (เส้นประ)


Impact Matrix: แก้ Function นี้ → กระทบ Flow ไหน

flowchart LR subgraph CRITICAL ["🔴 CRITICAL — กระทบหลาย Flow"] CA["calculateAccumulate()"] CAS["calculateAccumulateSpending()"] UMT["updateMemberTier()"] PST["processSpendingAndTierUpdate()"] end subgraph HIGH ["🟠 HIGH — กระทบ Flow เฉพาะกลุ่ม"] CAMS["calculateAccumulateMaintainSpending()"] CTU["calculateTierToUpgrade()"] CTA["calculateTierAdjustment()"] CNT["calculateNewTier()"] CNTM["calculateNewTierFromAccumulateMaintainSpending()"] CNM["calculateNewMinimumTier()"] CNTE["calculateNewTierEndedAt()"] end subgraph ISOLATED ["🟡 ISOLATED — Flow เดียว"] UAS["updateAccumulateSpending()"] CNTSP["calculateNewTierStartDateFromSalesTransactionPeriod()"] CR["create()"] end CA -->|"กระทบ"| F1_8["Flow1,2,3A,5,6,7,8"] CAS -->|"กระทบ"| F1_8 UMT -->|"กระทบ"| F_most["Flow1,2,4,5,6,7,8,9(existing)"] PST -->|"กระทบ"| F3B["Flow3B เท่านั้น<br/>(path แยก)"] CAMS -->|"กระทบ"| F1_2["Flow1,2 (direct)<br/>+ ทุก flow ผ่าน updateMemberTier"] CTU -->|"กระทบ"| F1_6A["Flow1, 6(ADD)"] CTA -->|"กระทบ"| F2_5_6D["Flow2, 5, 6(DEDUCT)"] CNT -->|"กระทบ"| F7_8["Flow7, 8"] CNTM -->|"กระทบ"| F4["Flow4"] CNM -->|"กระทบ"| F4_7_9["Flow4, 7, 9(existing)"] CNTE -->|"กระทบ"| F_cnte["Flow1,2,3B,5,6,7,8,9"] UAS -->|"กระทบ"| F3A["Flow3A เท่านั้น"] CNTSP -->|"กระทบ"| F5_only["Flow5 เท่านั้น"] CR -->|"กระทบ"| F9N["Flow9(new member) เท่านั้น"]

สรุปตาราง: Function ↔ Flow

Function Flow1 Flow2 Flow3A Flow3B Flow4 Flow5 Flow6+ Flow6- Flow7 Flow8 Flow9e Flow9n Impact
calculateAccumulate() 🔴 CRITICAL
calculateAccumulateSpending() 🔴 CRITICAL
updateMemberTier() 🔴 CRITICAL
processSpendingAndTierUpdate() 🔴 (isolated path)
calculateAccumulateMaintainSpending() ✅* ✅* ✅* ✅* ✅* 🟠 HIGH
calculateTierToUpgrade() 🟠 HIGH
calculateTierAdjustment() 🟠 HIGH
calculateNewTier() 🟠 HIGH
calculateNewTierFromAccumulateMaintainSpending() 🟠 HIGH
calculateNewMinimumTier() 🟠 HIGH
calculateNewTierEndedAt() 🟠 HIGH
updateAccumulateSpending() 🟡 ISOLATED
calculateNewTierStartDateFromSalesTransactionPeriod() 🟡 ISOLATED
create() 🟡 ISOLATED

✅* = ถูกเรียกผ่าน updateMemberTier() ไม่ใช่ direct call
Flow6+ = Admin ADD, Flow6- = Admin DEDUCT, Flow9e = Import existing member, Flow9n = Import new member


จุดที่ต้องระวังเป็นพิเศษ

Flow 3B แยก path จากทุก Flow อื่น

  • processSpendingAndTierUpdate() ไม่เรียก updateMemberTier()
  • สร้าง MemberTierHistory โดยตรง
  • ถ้าแก้ updateMemberTier() → Flow 3B ไม่ได้รับผลกระทบ และในทางกลับกัน

Flow 9 new member แยก path จาก existing member

  • create() ตั้งค่า initial tier โดยตรง ไม่ผ่าน updateMemberTier()
  • ถ้าแก้ updateMemberTier() → Flow 9 new member ไม่ได้รับผลกระทบ

calculateAccumulate() คือ root ของทุกอย่าง

  • ทั้ง calculateAccumulateSpending() และ calculateAccumulateMaintainSpending() เรียกผ่าน calculateAccumulate()
  • แก้ที่นี่จุดเดียว กระทบ Flow 1, 2, 3A, 5, 6, 7, 8 ทั้งหมด