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 ทั้งหมด