Appearance
Module Overview — Gamification Lucky Shaking
1. Scope
Flow này không nằm gọn trong một page hay một bảng. Nó cắt qua:
- frontend
lucky-shakingroutes cho list, create/update popup, detail tabs, - backend
ecommerce-apiactions cho status change, update, duplicate, gift-to-friend, receive-gift, share success, - scheduler
end_expired_gamification, - Hasura metadata của domain
ecommerce, - read-models qua
gamification_statisticsview và các RPC functions cho summary/chart.
Mental model nên giữ từ đầu:
gamificationlà campaign shell,missions,gift_configs,files,notification_configslà nested parts của campaign,gamification_claim_logslà runtime ledger-ish table cho spin/gift events,- statistics và notification là sidecar projections/dispatch layers.
2. Bức tranh kiến trúc
text
Admin create/update campaign
-> gamification + missions + gift_configs + files + notification_configs
-> status action: publish / stop / continue / end / cancel
-> scheduler end_expired_gamification auto-end campaign khi quá hạn
Customer runtime
-> shakingLuckyEvent / mission log / claim_logs
-> own gift claim hoặc gift-to-friend pending
-> receive gift => transfer voucher hoặc create voucher mới
-> notification dispatch / logs
-> statistics functions + history tabs đọc lại claim_logs và views3. Frontend Surface
3.1 Route families
| Family | Route group | Boundary |
|---|---|---|
| Campaign list shell | /lucky-shaking/campaign | List, filter, action menu |
| Create / edit | /lucky-shaking/campaign/create, /lucky-shaking/campaign/:id/edit | Stepper form chung cho create/update |
| Detail shell | /lucky-shaking/campaign/:id | Redirect vào statistics |
| Detail tabs | statistics, gift-history, shake-history | Three read surfaces từ cùng runtime data |
3.2 Runtime map thực tế
| Boundary | Ghi chú |
|---|---|
| Navigation | Mounted trên ADMIN, CRM, POS, nhưng permission thực tế chỉ ITLeader và ITStaff |
| Create flow | Có thể insert thẳng campaign với status gf_status_published, không bắt buộc publish riêng |
| Action menu | edit/copy/activate/pause/resume/end/cancel đều gắn trực tiếp theo status string |
| Detail tabs | ShakeHistory và GiftHistory đều đọc gamification_claim_logs, chỉ khác filter semantics |
4. Backend Boundary Map
| Lớp | File chính | Vai trò |
|---|---|---|
| Action | change_gamification_status.go | State machine publish/pause/resume/end/cancel |
| Action | update_gamification.go | Update main campaign và nested missions/gifts/noti/files |
| Action | duplicate_gamification.go | Clone campaign sang draft mới với nested data |
| Action | gamification_gift_to_friend.go | Tạo pending gift log cho flow tặng bạn bè |
| Action | receive_gamification_gift.go | Chấp nhận quà, transfer voucher hoặc create voucher mới |
| Action | gamification_log_share_success.go | Log mission share thành công, cộng lượt lắc nếu đủ điều kiện |
| Scheduler | end_expired_gamification.go | Auto-end campaign hết hạn nhưng còn published |
| Helper | gamification_notification.go | Parse config, schedule/send noti, log runtime |
5. Data Layer Map
| Layer | Object chính | Vai trò |
|---|---|---|
| Campaign core | gamification | Tên, thời gian, sharing content, sample sentence, status |
| Mission engine | gamification_mission, gamification_mission_logs | Điều kiện tích lũy lượt lắc |
| Gift engine | gamification_gift_config | Own gift vs giveaway gift, rate, quantity, gifting limits |
| Runtime logs | gamification_claim_logs | Spin outcome, gifting pending/received, voucher linkage |
| Read model | gamification_statistics | Summary list cards |
| Analytics RPC | get_gamification_campaign_summary, get_gamification_spins_by_time, get_gamification_gift_distribution | Detail statistics |
| Notification | gamification_notification_config, gamification_notification_logs | Trigger config và dispatch history |
6. Semantic Rules Cần Nhớ
- Campaign create không đồng nghĩa draft-only; FE có thể insert trực tiếp với
gf_status_published(CampaignCreateUpdate.tsx:1058-1061). - Update published/paused campaign vẫn được phép, nhưng backend freeze trường
fromvà áp dụng rule update nested khác với draft (update_gamification.go:116-150,update_gamification.go:189-205). - Own gift và giveaway gift chỉ là hai
typecủa cùng bảnggamification_gift_config, nhưng runtime nhận quà và gift history xử lý rất khác nhau. gamification_claim_logskhông chỉ là “shake logs”; bảng này còn mang trạng tháigift_pending/gift_received.- Statistics view đang loại trừ blessing/greeting khỏi một số tỷ lệ quà, nên chart/summary không đại diện toàn bộ mọi outcome của game.
7. Rủi ro / Findings
| ID | Mức | Finding |
|---|---|---|
| F-01 | P1 | FE constants trong constants/master-data.ts lệch thật với master data DB: status, config type, mission condition, notification condition, stop condition, file type đều không khớp. |
| F-02 | P1 | changeGamificationStatus có comment TODO/unclear logic ở nhánh cancel, cho thấy state machine chưa được khóa chặt hoàn toàn (change_gamification_status.go:96-110). |
| F-03 | P1 | FE create flow có thể tạo campaign ở trạng thái published ngay từ insert path, nên audit nếu chỉ nhìn action publish sẽ thiếu một nhánh phát hành. |
| F-04 | P1 | gamification_claim_logs bị overload làm cả shake history lẫn friend-gifting runtime, nên QA nếu test một tab riêng sẽ dễ bỏ sót side effects lên tab còn lại. |
| F-05 | P2 | Navigation platform rộng hơn permission thực, nên UX “thấy module nhưng không vào được” có thể xảy ra nếu menu không đồng bộ guard. |