Skip to content

Gamification - Technical Map

Scope kỹ thuật

Tài liệu này chỉ bám vào phần đang mount thật: lucky-shaking. Các phần backend mở rộng như giveaway/gift friend và notification chỉ được nêu ở mức liên quan trực tiếp.

Frontend map

FileVai trò
diva-admin/src/modules/gamification/lucky-shaking/module.tsRoute tree, permission, navigation
.../pages/campaign/list/List.tsxList + filter + mở create/edit/detail
.../pages/campaign/create-update/CampaignCreate.tsxWrapper create/edit
.../components/campaign/form/CampaignCreateUpdate.tsxForm wizard chính
.../pages/campaign/detail/Statistics.tsxSummary + charts
.../pages/campaign/detail/GiftHistory.tsxGift history
.../pages/campaign/detail/ShakeHistory.tsxShake history
.../graphql/lucky-shaking.graphqlQueries/mutations

Route tree

RouteComponent
/lucky-shakingLayout -> Container -> Tab
/lucky-shaking/campaignList
/lucky-shaking/campaign/createCampaignCreate
/lucky-shaking/campaign/:id/editCampaignCreate
/lucky-shaking/campaign/:idListDetail -> redirect Statistics
/lucky-shaking/campaign/:id/statisticsStatistics
/lucky-shaking/campaign/:id/gift-historyGiftHistory
/lucky-shaking/campaign/:id/shake-historyShakeHistory

Nguồn: diva-admin/src/modules/gamification/lucky-shaking/module.ts:26-123.

GraphQL operations chính

OperationLoạiDùng cho
InsertGamificationmutationTạo campaign
UpdateGamificationmutationSửa campaign
ChangeGamificationStatusmutationĐổi trạng thái
DuplicateGamificationmutationNhân bản campaign
GetGamificationAggregatequeryĐếm list
GetGamificationqueryList campaign
GetGamificationByIdqueryLoad edit form
GetGamificationClaimLogsqueryShake history
GetGamificationMasterDataqueryMaster data select box
GetGamificationCampaignSummaryquerySummary cards
GetGamificationSpinsByTimequeryLine chart
GetGamificationGiftDistributionqueryDonut chart
GetGamificationGiftHistoryqueryGift history

Nguồn: diva-admin/src/modules/gamification/lucky-shaking/graphql/lucky-shaking.graphql:5-420.

DB / Hasura map

Core tables

TableVai trò
gamificationcampaign header
gamification_missionnhiệm vụ
gamification_gift_configquà
gamification_claim_logslog quay/tặng/nhận
gamification_notification_confignotification config
gamification_notification_logsnotification logs

Read model / result tables

Table / viewVai trò
gamification_statisticsaggregate theo campaign
gamification_campaign_summary_resultsummary cards
gamification_spins_by_time_resultline chart
gamification_gift_distribution_resultdonut chart
gamification_giveaway_gifts_resultread model cho giveaway/gift friend
my_gamification_giftsvoucher view cho user

Permission snapshot

TableScope
gamificationanonymous, customer, user select; user insert/update/delete
gamification_missionanonymous, customer, user select; user write
gamification_gift_configanonymous, customer, user select; user write
gamification_claim_logscustomer, user select; customer, user insert; user delete
gamification_notification_configuser CRUD
gamification_notification_logsuser select, filter self by customer_id

Nguồn: diva-backend/services/controller/metadata/databases/ecommerce/tables/public_gamification.yaml:84-159, public_gamification_mission.yaml:25-102, public_gamification_gift_config.yaml:36-144, public_gamification_claim_logs.yaml:59-139, public_gamification_notification_config.yaml:45-102, public_gamification_notification_logs.yaml:32-48, public_gamification_statistics.yaml:15-45, public_gamification_campaign_summary_result.yaml:4-18, public_gamification_spins_by_time_result.yaml:4-11, public_gamification_gift_distribution_result.yaml:4-11, public_gamification_giveaway_gifts_result.yaml:15-75, public_my_gamification_gifts.yaml:78-122.

Backend actions / scheduler

HandlerVai trò
changeGamificationStatusState machine cho publish/pause/resume/end/cancel
updateGamificationUpdate campaign header + missions + gifts + notification + files
duplicateGamificationCopy campaign sang draft mới
shakingLuckyEventRandom gift selection + write claim log + tạo voucher
gamificationGiftToFriendTạo pending gift cho người nhận
gamificationReceiveGiftNhận quà và tạo/transfer voucher
gamificationLogShareSuccessGhi log nhiệm vụ share success
endExpiredGamificationCron tự đóng campaign quá hạn

Nguồn: diva-backend/services/ecommerce-api/action/*.go, diva-backend/services/ecommerce-api/scheduler/end_expired_gamification.go:23-88.

Rule / formula đáng chú ý

FORMULA-001: Claim rate

  • claim_rate = vouchers_claimed / total_vouchers × 100
  • Guard: total_vouchers = 0 -> trả 0 ở DB function hiện tại.

Nguồn: diva-backend/services/controller/migrations/ecommerce/1767400000000_add_gamification_reporting/up.sql:142-147.

FORMULA-002: Redeem rate

  • redeem_rate = vouchers_redeemed / vouchers_claimed × 100
  • Guard: vouchers_claimed = 0 -> trả 0.

Nguồn: diva-backend/services/controller/migrations/ecommerce/1767400000000_add_gamification_reporting/up.sql:149-154.

FORMULA-003: Conversion rate

  • conversion_rate = players_with_orders / total_participants × 100
  • Dùng customer nào vừa tham gia vừa có voucher redeemed.

Nguồn: diva-backend/services/controller/migrations/ecommerce/1767400000000_add_gamification_reporting/up.sql:156-170.

Migration / schema notes

ĐiểmGhi chú
gamificationSeed status dùng gf_status_draft/published/paused/ended/cancelled
gamification_mission_conditionSeed thực tế là gf_condition_login_today, gf_condition_share_success, gf_condition_order_checkin
gamification_notification_configBảng tách riêng từ migration sau, không thấy FK cứng tới template table
gamification_claim_logsCác cột sender_id, receiver_id, gift_message, gift_image_url, gift_config_id, received_at được bổ sung qua migration sau

Nguồn: diva-backend/services/controller/migrations/ecommerce/1766900000000_add_gamification/up.sql:78-167, 1766970000000_update_condition_noti/up.sql:1-34, 1766991000000_separate_gamification_notification_config/up.sql:1-13, 1766960000000_add_gift_giving/up.sql, 1767600000000_add_received_at_to_claim_logs/up.sql.

Rủi ro / Findings kỹ thuật

  1. diva-admin/src/modules/gamification/lucky-shaking/constants/master-data.ts đang lệch backend ở status và mission condition. FE ACTIVE = gf_status_active, trong khi seed/backend dùng gf_status_published; mission condition FE (order_count, order_value, product_quantity, first_order) cũng không khớp backend (gf_condition_login_today, gf_condition_share_success, gf_condition_order_checkin). Đây là drift thật, không chỉ style.
  2. changeGamificationStatus cho cancel gần như không khóa state machine. Nếu business không muốn cho cancel từ published/ended, đây là bug logic.
  3. gamification_notification_config dùng relation Hasura manual tới template tables nhưng không thấy FK vật lý trong migration ban đầu, nên dữ liệu orphan có thể xuất hiện nếu backend/action sai.
  4. gamification_claim_logs là bảng đã bị mở rộng qua nhiều migration rời nhau. Schema vẫn chạy được, nhưng đây là điểm dễ phát sinh lệch metadata khi thêm cột mới.
  5. endExpiredGamification chỉ quét status = publishedto < now, nên campaign paused có vẻ không bị auto-end bởi cron. Nếu business kỳ vọng khác, cần sửa rõ ở service hoặc migration.