dubs-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +280 -0
- package/CLAUDE.md +46 -0
- package/CONNECT4_PRODUCTION_DEPLOY.md +155 -0
- package/CURRENT_SESSION.md +171 -0
- package/CURRENT_SESSION_DRAW.md +516 -0
- package/MARCH_MADNESS_SURVIVOR.md +254 -0
- package/PANDA.md +166 -0
- package/Procfile +4 -0
- package/README.md +476 -0
- package/controllers/livescoresController.js +376 -0
- package/controllers/pickemController.js +554 -0
- package/controllers/survivorAdminController.js +887 -0
- package/controllers/survivorController.js +623 -0
- package/cron/oracleMonitor.js +77 -0
- package/cron/pickemOracleMonitor.js +73 -0
- package/data/jackpot-history.json +952 -0
- package/data/ncaaTeams.js +406 -0
- package/documentation/API_SECURITY_GUIDE.md +327 -0
- package/documentation/ARCADE_API.md +593 -0
- package/documentation/ARCADE_IMPLEMENTATION_SUMMARY.md +399 -0
- package/documentation/ARCADE_QUICKSTART.md +242 -0
- package/documentation/AUTOMATIC_MODE_ORACLE.md +321 -0
- package/documentation/BUG_FIX_COHORT_DATE_DISPLAY.md +171 -0
- package/documentation/CLAIM_MIGRATION_INSTRUCTIONS.md +52 -0
- package/documentation/CLAIM_STATUS_FIX.md +67 -0
- package/documentation/CLI_TOOL_GUIDE.md +372 -0
- package/documentation/COHORT_RETENTION_ANALYSIS.md +295 -0
- package/documentation/COHORT_RETENTION_IMPLEMENTATION_COMPLETE.md +461 -0
- package/documentation/COHORT_RETENTION_SUMMARY.md +204 -0
- package/documentation/COMPLETE_PROJECT_SUMMARY.md +490 -0
- package/documentation/DATABASE_QUERIES.md +269 -0
- package/documentation/DATABASE_RETENTION_POLICY.md +390 -0
- package/documentation/DATABASE_SETUP_GUIDE.md +361 -0
- package/documentation/DATABASE_SETUP_SUMMARY.md +247 -0
- package/documentation/DEMO_API_CURL_COMMANDS.md +656 -0
- package/documentation/DEPLOYMENT_SUMMARY.txt +100 -0
- package/documentation/DUPLICATE_NOTIFICATIONS_FIXED.md +201 -0
- package/documentation/EXCHANGE_RATES_INTEGRATION.md +371 -0
- package/documentation/FINAL_API_PROTECTION_TABLE.md +175 -0
- package/documentation/GAME_START_NOTIFICATIONS_DEPLOYMENT.md +256 -0
- package/documentation/GAME_START_NOTIFICATIONS_INTEGRATION.md +275 -0
- package/documentation/HEROKU_DEPLOYMENT.md +134 -0
- package/documentation/HEROKU_SCHEDULER_SETUP.md +271 -0
- package/documentation/JACKPOT_API.md +521 -0
- package/documentation/JACKPOT_DEPLOYMENT_GUIDE.md +362 -0
- package/documentation/JWT_IMPLEMENTATION_SUMMARY.md +373 -0
- package/documentation/JWT_QUICK_SETUP.md +268 -0
- package/documentation/JWT_TESTING_GUIDE.md +404 -0
- package/documentation/KEEPER_RECOVERY_GUIDE.md +381 -0
- package/documentation/KEEPER_SETUP.md +206 -0
- package/documentation/KEEPER_STATE_MACHINE.md +423 -0
- package/documentation/LATEST_PRODUCTION_SETUP.md +387 -0
- package/documentation/LOCAL_VOTING_TEST.md +279 -0
- package/documentation/ORACLE_FIXES_SUMMARY.md +188 -0
- package/documentation/ORACLE_POSTGRESQL_UPDATE.md +202 -0
- package/documentation/PAYMENT_DEPLOYMENT.md +209 -0
- package/documentation/PNL_TRACKING_SETUP.md +189 -0
- package/documentation/PREVENTING_LOCKUP_ERRORS.md +472 -0
- package/documentation/PRODUCTION_READY_SUMMARY.md +227 -0
- package/documentation/PUBLIC_VS_PRIVATE_ENDPOINTS.md +278 -0
- package/documentation/QUICK_AUTH_SETUP.md +99 -0
- package/documentation/QUICK_DEPLOY.md +224 -0
- package/documentation/QUICK_FIX.md +114 -0
- package/documentation/QUICK_START.md +152 -0
- package/documentation/REFEREE_MODE_GUIDE.md +392 -0
- package/documentation/RETENTION_CORE_ACTION_UPDATE.md +313 -0
- package/documentation/RETENTION_UPDATE_SUMMARY.md +108 -0
- package/documentation/RUN_MIGRATION_NOW.md +39 -0
- package/documentation/SCRIPTS_UPDATE_SUMMARY.md +251 -0
- package/documentation/SETUP_GUIDE.md +184 -0
- package/documentation/STATE_MACHINE_IMPLEMENTATION.md +250 -0
- package/documentation/TELEGRAM_NOTIFICATIONS_DIAGNOSIS.md +361 -0
- package/documentation/UNIFIED_ARCHITECTURE.md +231 -0
- package/documentation/VOTING_DEPLOYMENT_SUMMARY.md +392 -0
- package/documentation/WEBSOCKET_ARCHITECTURE.md +881 -0
- package/documentation/WHAT_WE_BUILT_TODAY.md +369 -0
- package/documentation/latest/LATEST_PRODUCTION_SETUP.md +865 -0
- package/ecosystem.config.js +65 -0
- package/env.template +125 -0
- package/middleware/apiKeyAuth.js +136 -0
- package/middleware/authenticate.js +214 -0
- package/middleware/developerUserAuth.js +76 -0
- package/middleware/socketAuth.js +69 -0
- package/package.json +49 -0
- package/postman/Dubs-API-v1-With-Voting.postman_collection.json +555 -0
- package/postman/Dubs-API-v1.postman_collection.json +205 -0
- package/postman/Dubs_Developer_API.postman_collection.json +662 -0
- package/postman/QUICKSTART.md +118 -0
- package/postman/QUICK_REFERENCE.md +246 -0
- package/postman/README.md +71 -0
- package/postman/VOTING_API_GUIDE.md +426 -0
- package/refactor/Animations.md +148 -0
- package/refactor/Chat.md +252 -0
- package/routes/actionsRoutes.js +699 -0
- package/routes/adminRoutes.js +370 -0
- package/routes/analyticsRoutes.js +1262 -0
- package/routes/arcadeRoutes.js +557 -0
- package/routes/authRoutes.js +2310 -0
- package/routes/avatarRoutes.js +85 -0
- package/routes/botRoutes.js +211 -0
- package/routes/chatRoutes.js +377 -0
- package/routes/cryptoPriceRoutes.js +105 -0
- package/routes/developerRoutes.js +4201 -0
- package/routes/deviceRoutes.js +214 -0
- package/routes/dmRoutes.js +167 -0
- package/routes/esportsRoutes.js +806 -0
- package/routes/exchangeRateRoutes.js +233 -0
- package/routes/gamesRoutes.js +3028 -0
- package/routes/jackpotRoutes.js +754 -0
- package/routes/keeperMonitoringRoutes.js +156 -0
- package/routes/keeperWebhookRoutes.js +466 -0
- package/routes/livescoresRoutes.js +31 -0
- package/routes/pickemAdminRoutes.js +199 -0
- package/routes/pickemRoutes.js +231 -0
- package/routes/playerStatsRoutes.js +147 -0
- package/routes/portfolioRoutes.js +217 -0
- package/routes/promoRoutes.js +418 -0
- package/routes/referralEarningsRoutes.js +392 -0
- package/routes/socialRoutes.js +459 -0
- package/routes/sportsRoutes.js +1271 -0
- package/routes/survivorAdminRoutes.js +345 -0
- package/routes/survivorRoutes.js +756 -0
- package/routes/uploadRoutes.js +256 -0
- package/routes/userProfileRoutes.js +244 -0
- package/routes/whatsNewRoutes.js +331 -0
- package/scripts/.claude/settings.local.json +15 -0
- package/scripts/README.md +170 -0
- package/scripts/RESTART_EVERYTHING.sh +104 -0
- package/scripts/add-claim-columns.sql +48 -0
- package/scripts/add-crypto-prices-cache.sql +27 -0
- package/scripts/add-exchange-rates-cache.sql +40 -0
- package/scripts/add-game-invite-column.sql +23 -0
- package/scripts/add-game-invite-notification.sql +33 -0
- package/scripts/add-game-invite-telegram-pref.sql +16 -0
- package/scripts/add-game-joined-notification.sql +16 -0
- package/scripts/add-game-joined-pref.js +40 -0
- package/scripts/add-game-joined-preference.sql +6 -0
- package/scripts/add-game-start-notifications.sql +41 -0
- package/scripts/add-notification-flags-to-games.sql +55 -0
- package/scripts/add-pending-game-dismissals.sql +19 -0
- package/scripts/add-preferred-currency.sql +34 -0
- package/scripts/add-winner-columns.js +61 -0
- package/scripts/add_mention_system.sql +53 -0
- package/scripts/add_payment_system.sql +96 -0
- package/scripts/add_sports_event_id_column.sql +22 -0
- package/scripts/analyze-cohort-data-heroku.js +276 -0
- package/scripts/analyze-cohort-data.js +295 -0
- package/scripts/analyze-prod-cohorts.sh +10 -0
- package/scripts/backfill-matchup-images.js +245 -0
- package/scripts/backfill-missing-signatures.js +175 -0
- package/scripts/backfill-referral-earnings.js +202 -0
- package/scripts/check-chat-schema.js +130 -0
- package/scripts/check-db.sh +14 -0
- package/scripts/check_oracle_in_game.js +54 -0
- package/scripts/cleanup-database.js +193 -0
- package/scripts/clear-notification-cache.js +85 -0
- package/scripts/convert-mnemonic.js +50 -0
- package/scripts/create-users-table.sql +44 -0
- package/scripts/debug-cohort-counts.js +248 -0
- package/scripts/debug-winner-calc.js +84 -0
- package/scripts/deploy-payment-system.sh +118 -0
- package/scripts/deploy-to-heroku.sh +63 -0
- package/scripts/diagnose-locked-round.js +143 -0
- package/scripts/dubs-cli.js +720 -0
- package/scripts/dump-account.js +65 -0
- package/scripts/find-vrf-offset.js +48 -0
- package/scripts/fix-chat-notifications-constraint.sql +122 -0
- package/scripts/fix-claim-columns.js +124 -0
- package/scripts/fix-constraint-now.js +44 -0
- package/scripts/fix-lock-timestamps.js +96 -0
- package/scripts/fix-locked-round.sh +126 -0
- package/scripts/fix-missing-badges.sql +91 -0
- package/scripts/fix-payment-notifications.sql +41 -0
- package/scripts/force-new-round.js +55 -0
- package/scripts/force-resolve-and-claim.js +278 -0
- package/scripts/important/README.md +115 -0
- package/scripts/important/authority-force-lock.js +197 -0
- package/scripts/important/authority-resolve-game.js +267 -0
- package/scripts/important/check-game-status.js +373 -0
- package/scripts/important/list-pending-games-by-version.js +270 -0
- package/scripts/important/reconcile-v1-v2-payouts.js +270 -0
- package/scripts/initialize-jackpot.js +111 -0
- package/scripts/jackpot/.claude/settings.local.json +10 -0
- package/scripts/jackpot/force-reset.js +84 -0
- package/scripts/jackpot/initialize-mainnet.js +100 -0
- package/scripts/jackpot/keeper.js +742 -0
- package/scripts/jackpot/status.js +107 -0
- package/scripts/jackpot/update-round-duration.js +143 -0
- package/scripts/keeper-bot.js +112 -0
- package/scripts/list-pending-games.js +131 -0
- package/scripts/migrate-chat-v2.js +127 -0
- package/scripts/migrate-chat-winners.js +84 -0
- package/scripts/migrate-chat.sh +17 -0
- package/scripts/migrate-game-invite.js +83 -0
- package/scripts/migrate-heroku-game-notifications.sh +159 -0
- package/scripts/migrations/001_analytics_tables.sql +422 -0
- package/scripts/migrations/002_add_matchup_image_url.sql +14 -0
- package/scripts/migrations/003_referral_earnings.sql +208 -0
- package/scripts/migrations/004_add_whats_new_notification_type.sql +62 -0
- package/scripts/migrations/005_add_connect4_your_turn_notification.sql +61 -0
- package/scripts/migrations/005_push_notifications.sql +55 -0
- package/scripts/migrations/006_add_draw_team_players.sql +28 -0
- package/scripts/migrations/006_add_game_cancelled_notification.sql +62 -0
- package/scripts/migrations/007_add_gif_url.sql +8 -0
- package/scripts/migrations/008_add_connect4_columns.sql +139 -0
- package/scripts/migrations/008_add_pool_tracking.sql +22 -0
- package/scripts/migrations/009_create_survivor_pool_tables.sql +174 -0
- package/scripts/migrations/010_add_survivor_pool_outcome.sql +28 -0
- package/scripts/migrations/011_create_developer_tables.sql +67 -0
- package/scripts/migrations/011_fix_keeper_tables.sql +85 -0
- package/scripts/migrations/012_create_developer_webhooks.sql +31 -0
- package/scripts/migrations/013_add_network_mode.sql +18 -0
- package/scripts/migrations/014_create_developer_app_users.sql +19 -0
- package/scripts/migrations/015_add_ui_config.sql +4 -0
- package/scripts/migrations/016_add_resolution_secret.sql +4 -0
- package/scripts/migrations/017_add_external_game_id.sql +3 -0
- package/scripts/migrations/018_create_pickem_tables.sql +115 -0
- package/scripts/migrations/019_expo_push_tokens.sql +19 -0
- package/scripts/migrations/create_whats_new_tables.sql +88 -0
- package/scripts/migrations/drop_live_games_tables.sql +34 -0
- package/scripts/open-jackpot-round.js +85 -0
- package/scripts/purge-all-data.sh +329 -0
- package/scripts/purge-all-data.sql +142 -0
- package/scripts/purge-heroku-data.sh +149 -0
- package/scripts/purge-heroku-data.sql +62 -0
- package/scripts/rebuild-heroku-database.sh +113 -0
- package/scripts/recover-funds.js +357 -0
- package/scripts/regenerate-epl-images.js +278 -0
- package/scripts/resize-s3-matchup-images.js +374 -0
- package/scripts/resolve-direct.js +88 -0
- package/scripts/resolve-mock-game.js +124 -0
- package/scripts/resolve-pickem-game.js +55 -0
- package/scripts/resolve-round-manual.js +83 -0
- package/scripts/resolve-stuck-game.js +382 -0
- package/scripts/resolve-stuck-round.js +42 -0
- package/scripts/run-connect4-migration.sh +16 -0
- package/scripts/run-mention-migration.sh +32 -0
- package/scripts/run-payment-migration.sh +51 -0
- package/scripts/run-preferred-currency-migration.sh +31 -0
- package/scripts/run-referral-earnings-migration.sh +32 -0
- package/scripts/run-survivor-outcome-migration.sh +16 -0
- package/scripts/seed-test-users.js +346 -0
- package/scripts/setup-auth-tables.js +78 -0
- package/scripts/setup-complete-database.sql +992 -0
- package/scripts/setup-database-fresh.sh +359 -0
- package/scripts/setup-heroku-keeper.sh +48 -0
- package/scripts/setup-keeper-database.js +83 -0
- package/scripts/setup-keeper-state-db.sql +110 -0
- package/scripts/setup-oracle.sh +39 -0
- package/scripts/setup-pnl-tracking.js +111 -0
- package/scripts/start-devnet.sh +14 -0
- package/scripts/test-arcade-devnet.sh +160 -0
- package/scripts/test-arcade-match.sh +109 -0
- package/scripts/test-automatic-mode.sh +239 -0
- package/scripts/test-connect4-cancel-claim.js +370 -0
- package/scripts/test-connect4-e2e.js +369 -0
- package/scripts/test-connect4-resolve.js +369 -0
- package/scripts/test-game-state-endpoint.js +136 -0
- package/scripts/test-invite-notification.js +86 -0
- package/scripts/test-jackpot-api.sh +71 -0
- package/scripts/test-poll-confirmation.js +267 -0
- package/scripts/test-resolve-game.js +271 -0
- package/scripts/test-resolve-signature.js +223 -0
- package/scripts/test-signature-preservation.js +124 -0
- package/scripts/test-state-machine.js +291 -0
- package/scripts/test-webhook-receiver.js +60 -0
- package/scripts/update-notification-constraint.js +52 -0
- package/scripts/verify-account-layout.js +145 -0
- package/scripts/verify-winner-algorithm.js +278 -0
- package/server.js +5259 -0
- package/services/arcadeMatchService.js +763 -0
- package/services/automaticGameOracle.js +1596 -0
- package/services/chatService.js +1612 -0
- package/services/connect4GameService.js +1049 -0
- package/services/connect4NotificationService.js +374 -0
- package/services/cryptoPriceService.js +223 -0
- package/services/customGameResolver.js +260 -0
- package/services/db.js +79 -0
- package/services/directMessageService.js +389 -0
- package/services/discordNotifications.js +160 -0
- package/services/exchangeRateService.js +289 -0
- package/services/expoPushService.js +314 -0
- package/services/gamesCacheService.js +539 -0
- package/services/jackpotHistory.js +331 -0
- package/services/jackpotService.js +856 -0
- package/services/keeperStateService.js +355 -0
- package/services/matchupImageService.js +591 -0
- package/services/notificationCacheService.js +407 -0
- package/services/pickemOracle.js +440 -0
- package/services/playerStatsService.js +389 -0
- package/services/portfolioService.js +555 -0
- package/services/promoService.js +757 -0
- package/services/promoTreasuryService.js +239 -0
- package/services/pushNotifications.js +353 -0
- package/services/redisService.js +422 -0
- package/services/referralEarningsService.js +728 -0
- package/services/s3Service.js +396 -0
- package/services/socialService.js +1202 -0
- package/services/survivorOracle.js +469 -0
- package/services/survivorSimulator.js +475 -0
- package/services/telegramNotifications.js +461 -0
- package/services/userProfileStatsService.js +1185 -0
- package/services/whatsNewService.js +388 -0
- package/utils/urlHelper.js +95 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# ⚖️ Referee Mode - Complete Guide
|
|
2
|
+
|
|
3
|
+
## 🎯 **What is Referee Mode?**
|
|
4
|
+
|
|
5
|
+
**Hire an expert to judge your competition and earn a commission!**
|
|
6
|
+
|
|
7
|
+
Referee Mode is the **3rd game mode** alongside Manual and Democratic voting, enabling professional judging for competitions where an expert's opinion matters.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🏗️ **3 Game Modes:**
|
|
12
|
+
|
|
13
|
+
| Mode | Who Decides | Best For | Commission |
|
|
14
|
+
|------|-------------|----------|------------|
|
|
15
|
+
| **👑 Manual** | Creator chooses | Friends, casual | 0% |
|
|
16
|
+
| **🗳️ Democratic** | Players vote (majority) | 3+ players, community | 0% |
|
|
17
|
+
| **⚖️ Referee** | Expert judge | Competitions, any size | 10-20% |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## ⚖️ **How Referee Mode Works:**
|
|
22
|
+
|
|
23
|
+
### **Setup:**
|
|
24
|
+
```
|
|
25
|
+
Creator creates game:
|
|
26
|
+
├── Game Mode: 2 (Referee)
|
|
27
|
+
├── Referee Address: ExpertJudgeAddress
|
|
28
|
+
├── Referee Commission: 15%
|
|
29
|
+
├── Operator Fee: 10%
|
|
30
|
+
├── Buy-in: 1 SOL
|
|
31
|
+
└── Max Players: 5
|
|
32
|
+
|
|
33
|
+
Economics (5 players):
|
|
34
|
+
Total Pot: 5 SOL
|
|
35
|
+
- Operator Fee (10%): 0.5 SOL
|
|
36
|
+
- Referee Commission (15%): 0.75 SOL
|
|
37
|
+
- Prize Pool: 3.75 SOL
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### **Flow:**
|
|
41
|
+
```
|
|
42
|
+
1. Creator sets referee & commission
|
|
43
|
+
2. Players join (referee CANNOT join!)
|
|
44
|
+
3. Competition happens
|
|
45
|
+
4. ONLY referee can vote/judge
|
|
46
|
+
5. Referee picks winner
|
|
47
|
+
6. Distribution:
|
|
48
|
+
- Winner: 3.75 SOL
|
|
49
|
+
- Referee: 0.75 SOL
|
|
50
|
+
- Operator: 0.5 SOL
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 🔒 **Critical Rules:**
|
|
56
|
+
|
|
57
|
+
### **1. Referee Cannot Join as Player** ✅
|
|
58
|
+
```
|
|
59
|
+
Smart contract enforces:
|
|
60
|
+
- If player address === referee address
|
|
61
|
+
→ Join transaction fails
|
|
62
|
+
→ Prevents conflict of interest!
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### **2. Only Referee Can Vote** ✅
|
|
66
|
+
```
|
|
67
|
+
In Referee mode:
|
|
68
|
+
- Players try to vote → Transaction fails
|
|
69
|
+
- Referee votes → Success!
|
|
70
|
+
→ Expert decision only!
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### **3. Referee Must Earn Commission** ✅
|
|
74
|
+
```
|
|
75
|
+
Validation:
|
|
76
|
+
- refereeCommission must be > 0
|
|
77
|
+
- operatorFee + refereeCommission ≤ 100%
|
|
78
|
+
→ Fair compensation guaranteed!
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### **4. No Creator Override in Referee Mode** ✅
|
|
82
|
+
```
|
|
83
|
+
If you hire a referee, you trust them:
|
|
84
|
+
- Creator CANNOT override in Referee mode
|
|
85
|
+
- Referee's decision is final
|
|
86
|
+
→ Maintains referee credibility!
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 📡 **API Endpoints:**
|
|
92
|
+
|
|
93
|
+
### **Create Referee Game:**
|
|
94
|
+
```javascript
|
|
95
|
+
POST /api/v1/prod/transaction/build/create
|
|
96
|
+
|
|
97
|
+
Body:
|
|
98
|
+
{
|
|
99
|
+
"creatorAddress": "YOUR_ADDRESS",
|
|
100
|
+
"buyIn": 1.0,
|
|
101
|
+
"maxPlayers": 5,
|
|
102
|
+
"operatorFee": 10,
|
|
103
|
+
"votingEnabled": true,
|
|
104
|
+
"gameMode": 2, ← Referee mode!
|
|
105
|
+
"refereeAddress": "EXPERT_JUDGE_ADDRESS",
|
|
106
|
+
"refereeCommission": 15
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Response:
|
|
110
|
+
{
|
|
111
|
+
"success": true,
|
|
112
|
+
"gameId": "uuid",
|
|
113
|
+
"transaction": "base64_unsigned_tx",
|
|
114
|
+
"gameAddress": "PDA"
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### **Referee Casts Vote:**
|
|
119
|
+
```javascript
|
|
120
|
+
POST /api/v1/prod/transaction/build/cast-vote
|
|
121
|
+
|
|
122
|
+
Body:
|
|
123
|
+
{
|
|
124
|
+
"voterAddress": "REFEREE_ADDRESS", ← Must be the referee!
|
|
125
|
+
"gameId": "uuid",
|
|
126
|
+
"votedFor": "WINNING_PLAYER_ADDRESS"
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
Response:
|
|
130
|
+
{
|
|
131
|
+
"success": true,
|
|
132
|
+
"transaction": "base64_unsigned_tx"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### **Distribute (After Referee Decides):**
|
|
137
|
+
```javascript
|
|
138
|
+
POST /api/v1/prod/transaction/build/distribute-by-vote
|
|
139
|
+
|
|
140
|
+
Body:
|
|
141
|
+
{
|
|
142
|
+
"playerAddress": "ANY_PLAYER_ADDRESS", ← Anyone can trigger!
|
|
143
|
+
"gameId": "uuid"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Response:
|
|
147
|
+
{
|
|
148
|
+
"success": true,
|
|
149
|
+
"transaction": "base64_unsigned_tx",
|
|
150
|
+
"winners": ["WinnerAddress"],
|
|
151
|
+
"voteCounts": {
|
|
152
|
+
"WinnerAddress": 1
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### **Get Game Info:**
|
|
158
|
+
```javascript
|
|
159
|
+
GET /api/v1/prod/game/:gameId
|
|
160
|
+
|
|
161
|
+
Response (Referee Mode):
|
|
162
|
+
{
|
|
163
|
+
"exists": true,
|
|
164
|
+
"game": {
|
|
165
|
+
"gameId": "uuid",
|
|
166
|
+
"authority": "Creator...",
|
|
167
|
+
"buyIn": 1.0,
|
|
168
|
+
"maxPlayers": 5,
|
|
169
|
+
"players": ["P1", "P2", "P3"],
|
|
170
|
+
"totalPot": 3.0,
|
|
171
|
+
"isActive": true,
|
|
172
|
+
"votes": [
|
|
173
|
+
{"voter": "Referee...", "votedFor": "P2"}
|
|
174
|
+
],
|
|
175
|
+
"votingEnabled": true,
|
|
176
|
+
"gameMode": 2, ← Referee mode!
|
|
177
|
+
"referee": "RefereeAddress...",
|
|
178
|
+
"refereeCommission": 15
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 🎮 **Use Cases:**
|
|
186
|
+
|
|
187
|
+
### **🎨 Art Contest:**
|
|
188
|
+
```
|
|
189
|
+
Setup:
|
|
190
|
+
- 10 artists pay 2 SOL each = 20 SOL
|
|
191
|
+
- Famous artist as referee
|
|
192
|
+
- Referee commission: 15%
|
|
193
|
+
- Operator: 5%
|
|
194
|
+
|
|
195
|
+
Payout:
|
|
196
|
+
- Winner: 16 SOL (80%)
|
|
197
|
+
- Referee: 3 SOL (15%)
|
|
198
|
+
- Operator: 1 SOL (5%)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### **🎤 Talent Show:**
|
|
202
|
+
```
|
|
203
|
+
Setup:
|
|
204
|
+
- 20 performers pay 0.5 SOL = 10 SOL
|
|
205
|
+
- Celebrity judge
|
|
206
|
+
- Referee commission: 20%
|
|
207
|
+
- Top 3 winners
|
|
208
|
+
|
|
209
|
+
Payout:
|
|
210
|
+
- 1st: 4 SOL (50%)
|
|
211
|
+
- 2nd: 2 SOL (25%)
|
|
212
|
+
- 3rd: 2 SOL (25%)
|
|
213
|
+
- Celebrity: 2 SOL (20%)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### **⚽ Sports Match:**
|
|
217
|
+
```
|
|
218
|
+
Setup:
|
|
219
|
+
- 2 teams pay 5 SOL = 10 SOL
|
|
220
|
+
- Certified referee
|
|
221
|
+
- Referee commission: 10%
|
|
222
|
+
|
|
223
|
+
Payout:
|
|
224
|
+
- Winner: 8 SOL (80%)
|
|
225
|
+
- Referee: 1 SOL (10%)
|
|
226
|
+
- Operator: 1 SOL (10%)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 🔄 **Complete Workflow:**
|
|
232
|
+
|
|
233
|
+
### **Creator Side:**
|
|
234
|
+
```
|
|
235
|
+
1. Create game with gameMode: 2
|
|
236
|
+
2. Set referee address
|
|
237
|
+
3. Set referee commission (15%)
|
|
238
|
+
4. Share game ID with:
|
|
239
|
+
- Referee (so they can view/judge)
|
|
240
|
+
- Players (so they can join)
|
|
241
|
+
5. Wait for competition
|
|
242
|
+
6. After referee judges → Distribution happens
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### **Referee Side:**
|
|
246
|
+
```
|
|
247
|
+
1. Receive game ID from creator
|
|
248
|
+
2. Paste in "Join Game"
|
|
249
|
+
3. See "⚖️ View as Referee" button
|
|
250
|
+
4. Tap → Game added to list (no payment!)
|
|
251
|
+
5. Monitor game (see players join)
|
|
252
|
+
6. When ready, tap "⚖️ Judge Winner"
|
|
253
|
+
7. Select winner
|
|
254
|
+
8. Distribution happens → Earn commission!
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### **Player Side:**
|
|
258
|
+
```
|
|
259
|
+
1. Receive game ID
|
|
260
|
+
2. Join game (pay buy-in)
|
|
261
|
+
3. Compete
|
|
262
|
+
4. See golden referee card (who's judging)
|
|
263
|
+
5. Wait for referee decision
|
|
264
|
+
6. Winner gets prize!
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## 🎯 **Key Features:**
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
✅ Referee cannot join as player (conflict of interest protection)
|
|
273
|
+
✅ Only referee can vote (expert opinion only)
|
|
274
|
+
✅ Referee earns automatic commission
|
|
275
|
+
✅ Any player can trigger distribution (trustless)
|
|
276
|
+
✅ Creator cannot override (referee decision is final)
|
|
277
|
+
✅ All on-chain and transparent
|
|
278
|
+
✅ Commission paid automatically
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 💰 **Economics:**
|
|
284
|
+
|
|
285
|
+
### **Fee Breakdown:**
|
|
286
|
+
```
|
|
287
|
+
Total Pot: 10 SOL
|
|
288
|
+
|
|
289
|
+
Fees:
|
|
290
|
+
- Operator: 10% = 1 SOL
|
|
291
|
+
- Referee: 15% = 1.5 SOL
|
|
292
|
+
- Prize Pool: 75% = 7.5 SOL
|
|
293
|
+
|
|
294
|
+
Validation:
|
|
295
|
+
✅ operator + referee ≤ 100%
|
|
296
|
+
✅ referee > 0 in Referee mode
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## 🧪 **Testing Referee Mode:**
|
|
302
|
+
|
|
303
|
+
### **With CLI:**
|
|
304
|
+
```bash
|
|
305
|
+
npm run cli
|
|
306
|
+
|
|
307
|
+
# Create referee game
|
|
308
|
+
curl -X POST http://localhost:3001/api/v1/demo/game/create \
|
|
309
|
+
-H "Content-Type: application/json" \
|
|
310
|
+
-d '{
|
|
311
|
+
"player": "creator",
|
|
312
|
+
"buyIn": 0.5,
|
|
313
|
+
"maxPlayers": 3,
|
|
314
|
+
"gameMode": 2,
|
|
315
|
+
"refereePlayer": "jelli",
|
|
316
|
+
"refereeCommission": 15
|
|
317
|
+
}'
|
|
318
|
+
|
|
319
|
+
# Players join
|
|
320
|
+
# Referee votes (as "jelli")
|
|
321
|
+
# Distribute by vote
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## 🚀 **Deployment Status:**
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
✅ Smart Contract: Deployed to devnet
|
|
330
|
+
✅ Server Endpoints: Live on Heroku v10
|
|
331
|
+
✅ Mobile SDK: Complete with UI
|
|
332
|
+
✅ Documentation: Updated
|
|
333
|
+
✅ Postman: Examples included
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 📊 **Error Codes:**
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
RefereeCannotBePlayer: Referee tried to join
|
|
342
|
+
OnlyRefereeCanVote: Player tried to vote in Referee mode
|
|
343
|
+
RefereeModeRequiresReferee: No referee address provided
|
|
344
|
+
InvalidRefereeCommission: Commission not 0-100
|
|
345
|
+
TotalFeesExceed100: operator + referee > 100%
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 🎊 **Why Referee Mode is Genius:**
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
✅ Solves 2-player voting problem
|
|
354
|
+
✅ Enables expert monetization
|
|
355
|
+
✅ Professional competitions possible
|
|
356
|
+
✅ Influencer economy
|
|
357
|
+
✅ Still 100% on-chain
|
|
358
|
+
✅ Still transparent
|
|
359
|
+
✅ Still trustless (referee can't steal)
|
|
360
|
+
✅ Creates new use cases
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## 🌟 **Examples:**
|
|
366
|
+
|
|
367
|
+
### **Crypto Art Contest:**
|
|
368
|
+
```
|
|
369
|
+
- 20 artists × 2 SOL = 40 SOL pot
|
|
370
|
+
- Famous crypto artist judges
|
|
371
|
+
- 20% referee commission = 8 SOL
|
|
372
|
+
- Winner gets 28 SOL (after 10% operator fee)
|
|
373
|
+
- Referee earns 8 SOL for their expertise!
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### **Gaming Tournament:**
|
|
377
|
+
```
|
|
378
|
+
- 100 players × 0.1 SOL = 10 SOL pot
|
|
379
|
+
- Pro gamer as referee
|
|
380
|
+
- 10% referee commission = 1 SOL
|
|
381
|
+
- Top 10 split 8.5 SOL
|
|
382
|
+
- Referee earns 1 SOL
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
**Referee Mode enables a whole new economy of expert judges earning from their expertise! ⚖️💰**
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
**Built with ❤️ - Making decentralized gaming fair and professional!**
|
|
392
|
+
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# 🎯 Retention Metric Update: Core Action Retention
|
|
2
|
+
|
|
3
|
+
## Change Summary
|
|
4
|
+
|
|
5
|
+
**Updated:** Cohort retention calculation to use **Core Action Retention** instead of generic activity.
|
|
6
|
+
|
|
7
|
+
**Impact:** Retention percentages will be **lower but more meaningful** - only users who actually place bets count as "retained."
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What Changed
|
|
12
|
+
|
|
13
|
+
### **Before (Generic Activity Retention):**
|
|
14
|
+
|
|
15
|
+
A user was counted as "retained" if they did **ANY** activity:
|
|
16
|
+
- ✅ Opened the app
|
|
17
|
+
- ✅ Viewed a page
|
|
18
|
+
- ✅ Sent a chat message
|
|
19
|
+
- ✅ Placed a bet
|
|
20
|
+
|
|
21
|
+
**Problem:** Non-revenue-generating activity inflated retention numbers.
|
|
22
|
+
|
|
23
|
+
### **After (Core Action Retention):**
|
|
24
|
+
|
|
25
|
+
A user is ONLY counted as "retained" if they do **revenue-generating actions**:
|
|
26
|
+
- ✅ `bet_creation_completed` - Created a sports bet
|
|
27
|
+
- ✅ `join_game_completed` - Joined an existing bet
|
|
28
|
+
- ✅ `billiards_create_completed` - Created a pool game
|
|
29
|
+
- ✅ `billiards_join_completed` - Joined a pool game
|
|
30
|
+
|
|
31
|
+
**Benefit:** Measures **true business value** and user engagement.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Why This Matters
|
|
36
|
+
|
|
37
|
+
### For a Betting/Gaming App:
|
|
38
|
+
|
|
39
|
+
**Generic Activity:**
|
|
40
|
+
```
|
|
41
|
+
User signs up → Opens app next day → Looks around → Leaves
|
|
42
|
+
❌ Counted as "retained" but generated $0 revenue
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Core Action:**
|
|
46
|
+
```
|
|
47
|
+
User signs up → Opens app next day → Looks around → Leaves
|
|
48
|
+
✅ NOT counted as retained (correct!)
|
|
49
|
+
|
|
50
|
+
User signs up → Opens app next day → Places a bet
|
|
51
|
+
✅ Counted as retained (generates revenue!)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Expected Impact on Numbers:
|
|
55
|
+
|
|
56
|
+
| Metric | Before (Any Activity) | After (Bets Only) | Change |
|
|
57
|
+
|--------|----------------------|-------------------|--------|
|
|
58
|
+
| D1 | 45% | 30% | ↓ 15% |
|
|
59
|
+
| D7 | 25% | 15% | ↓ 10% |
|
|
60
|
+
| D14 | 20% | 12% | ↓ 8% |
|
|
61
|
+
| D30 | 15% | 10% | ↓ 5% |
|
|
62
|
+
|
|
63
|
+
**Numbers will drop, but they're now accurate!**
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Events Counted as "Retained"
|
|
68
|
+
|
|
69
|
+
### **Sports Betting:**
|
|
70
|
+
```sql
|
|
71
|
+
'bet_creation_completed' -- User created a bet
|
|
72
|
+
'join_game_completed' -- User joined someone else's bet
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### **Pool/Billiards:**
|
|
76
|
+
```sql
|
|
77
|
+
'billiards_create_completed' -- User created a pool game
|
|
78
|
+
'billiards_join_completed' -- User joined a pool game
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### **NOT Counted:**
|
|
82
|
+
- ❌ Page views
|
|
83
|
+
- ❌ Chat messages
|
|
84
|
+
- ❌ Profile updates
|
|
85
|
+
- ❌ Social interactions
|
|
86
|
+
- ❌ Just opening the app
|
|
87
|
+
- ❌ Failed bet attempts
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Code Changes
|
|
92
|
+
|
|
93
|
+
### File: `routes/analyticsRoutes.js`
|
|
94
|
+
|
|
95
|
+
**Before:**
|
|
96
|
+
```sql
|
|
97
|
+
LEFT JOIN audit_logs al ON al.user_id = c.user_id
|
|
98
|
+
AND DATE(al.created_at) >= c.signup_date
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**After:**
|
|
102
|
+
```sql
|
|
103
|
+
LEFT JOIN audit_logs al ON al.user_id = c.user_id
|
|
104
|
+
AND DATE(al.created_at) >= c.signup_date
|
|
105
|
+
-- ONLY count bet-related actions as "retained"
|
|
106
|
+
AND al.log_type IN (
|
|
107
|
+
'bet_creation_completed',
|
|
108
|
+
'join_game_completed',
|
|
109
|
+
'billiards_create_completed',
|
|
110
|
+
'billiards_join_completed'
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Updated Endpoints:**
|
|
115
|
+
1. `GET /api/analytics/cohort-retention` (line ~921-940)
|
|
116
|
+
2. `GET /api/analytics/cohort-retention/csv` (line ~1087-1106)
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Comparison Chart
|
|
121
|
+
|
|
122
|
+
### Example Cohort (10 users signed up):
|
|
123
|
+
|
|
124
|
+
| User | Day 1 Activity | Day 7 Activity | Old D1 | New D1 | Old D7 | New D7 |
|
|
125
|
+
|------|---------------|----------------|--------|--------|--------|--------|
|
|
126
|
+
| User A | Opened app | Placed bet | ✅ | ❌ | ✅ | ✅ |
|
|
127
|
+
| User B | Placed bet | Opened app | ✅ | ✅ | ✅ | ❌ |
|
|
128
|
+
| User C | Chat message | Nothing | ✅ | ❌ | ❌ | ❌ |
|
|
129
|
+
| User D | Placed bet | Placed bet | ✅ | ✅ | ✅ | ✅ |
|
|
130
|
+
| User E | Nothing | Nothing | ❌ | ❌ | ❌ | ❌ |
|
|
131
|
+
|
|
132
|
+
**Old Method:**
|
|
133
|
+
- D1 = 80% (4/5 did something)
|
|
134
|
+
- D7 = 60% (3/5 did something)
|
|
135
|
+
|
|
136
|
+
**New Method:**
|
|
137
|
+
- D1 = 40% (2/5 placed bets) ✅ More accurate!
|
|
138
|
+
- D7 = 40% (2/5 placed bets) ✅ Shows true engagement!
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Industry Best Practices
|
|
143
|
+
|
|
144
|
+
### What Other Gaming Apps Track:
|
|
145
|
+
|
|
146
|
+
**Casual Games:**
|
|
147
|
+
- Core Action = "Completed a level"
|
|
148
|
+
- Not: Just opened the game
|
|
149
|
+
|
|
150
|
+
**Social Apps:**
|
|
151
|
+
- Core Action = "Sent a message" or "Made a post"
|
|
152
|
+
- Not: Just scrolled the feed
|
|
153
|
+
|
|
154
|
+
**Betting Apps (like Dubs):**
|
|
155
|
+
- Core Action = "Placed a bet"
|
|
156
|
+
- Not: Just browsed games
|
|
157
|
+
|
|
158
|
+
**This is the industry standard!**
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Benchmarks (Updated)
|
|
163
|
+
|
|
164
|
+
### With Core Action Retention:
|
|
165
|
+
|
|
166
|
+
| Metric | Poor | Average | Good | Excellent |
|
|
167
|
+
|--------|------|---------|------|-----------|
|
|
168
|
+
| **D1 Betting** | <20% | 20-30% | 30-45% | 45%+ |
|
|
169
|
+
| **D7 Betting** | <10% | 10-20% | 20-30% | 30%+ |
|
|
170
|
+
| **D14 Betting** | <8% | 8-15% | 15-25% | 25%+ |
|
|
171
|
+
| **D30 Betting** | <5% | 5-12% | 12-20% | 20%+ |
|
|
172
|
+
|
|
173
|
+
**Note:** These are lower than generic activity benchmarks, but more valuable!
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## How to Interpret New Data
|
|
178
|
+
|
|
179
|
+
### Scenario 1: High Activity, Low Betting
|
|
180
|
+
```
|
|
181
|
+
Old D1 = 60% (generic activity)
|
|
182
|
+
New D1 = 25% (bets only)
|
|
183
|
+
|
|
184
|
+
→ Users open the app but don't place bets
|
|
185
|
+
→ ACTION: Improve onboarding, reduce friction, add incentives
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Scenario 2: Both Low
|
|
189
|
+
```
|
|
190
|
+
Old D1 = 30% (generic activity)
|
|
191
|
+
New D1 = 15% (bets only)
|
|
192
|
+
|
|
193
|
+
→ Users aren't even opening the app
|
|
194
|
+
→ ACTION: Fix notifications, improve value prop
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Scenario 3: Both High
|
|
198
|
+
```
|
|
199
|
+
Old D1 = 70% (generic activity)
|
|
200
|
+
New D1 = 55% (bets only)
|
|
201
|
+
|
|
202
|
+
→ Users return AND place bets - excellent!
|
|
203
|
+
→ ACTION: Keep doing what you're doing
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Testing the Change
|
|
209
|
+
|
|
210
|
+
### 1. Check Current Dev Data:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
cd /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server
|
|
214
|
+
heroku config:get DATABASE_URL --app dubs-server-dev | \
|
|
215
|
+
xargs -I {} env DATABASE_URL={} node -e "
|
|
216
|
+
const { Pool } = require('pg');
|
|
217
|
+
const pool = new Pool({ connectionString: '{}', ssl: { rejectUnauthorized: false } });
|
|
218
|
+
|
|
219
|
+
// Count users with ANY activity on D1
|
|
220
|
+
pool.query(\`
|
|
221
|
+
SELECT COUNT(DISTINCT user_id) FROM audit_logs
|
|
222
|
+
WHERE DATE(created_at) = CURRENT_DATE - 1
|
|
223
|
+
\`).then(r => console.log('Any activity:', r.rows[0].count));
|
|
224
|
+
|
|
225
|
+
// Count users with BET activity on D1
|
|
226
|
+
pool.query(\`
|
|
227
|
+
SELECT COUNT(DISTINCT user_id) FROM audit_logs
|
|
228
|
+
WHERE DATE(created_at) = CURRENT_DATE - 1
|
|
229
|
+
AND log_type IN ('bet_creation_completed', 'join_game_completed',
|
|
230
|
+
'billiards_create_completed', 'billiards_join_completed')
|
|
231
|
+
\`).then(r => {
|
|
232
|
+
console.log('Bet activity:', r.rows[0].count);
|
|
233
|
+
pool.end();
|
|
234
|
+
});
|
|
235
|
+
"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### 2. Compare Before/After:
|
|
239
|
+
|
|
240
|
+
Deploy and compare cohort metrics:
|
|
241
|
+
- Old system: Higher percentages
|
|
242
|
+
- New system: Lower but more accurate percentages
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## FAQ
|
|
247
|
+
|
|
248
|
+
### Q: Why did my retention numbers drop?
|
|
249
|
+
**A:** They didn't drop - they're now **accurate**. Before, we were counting "window shoppers" as engaged users.
|
|
250
|
+
|
|
251
|
+
### Q: What if I want to see both metrics?
|
|
252
|
+
**A:** You can add a toggle in the dashboard:
|
|
253
|
+
- "Core Action Retention" (bets only) - Default
|
|
254
|
+
- "Activation Retention" (any activity) - Optional view
|
|
255
|
+
|
|
256
|
+
### Q: Should I track other actions too (chat, social)?
|
|
257
|
+
**A:** Those are important, but for **business metrics** (retention, LTV, ROI), bet actions matter most. You can track engagement separately.
|
|
258
|
+
|
|
259
|
+
### Q: What about users who onboard but never bet?
|
|
260
|
+
**A:** They'll show up in signups but 0% retention. This is correct - they're not retained users if they don't use the core feature!
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Migration Notes
|
|
265
|
+
|
|
266
|
+
### No Database Changes Needed ✅
|
|
267
|
+
- Only the query logic changed
|
|
268
|
+
- All data is already in `audit_logs`
|
|
269
|
+
- Backward compatible
|
|
270
|
+
|
|
271
|
+
### What to Tell Your Community Manager:
|
|
272
|
+
|
|
273
|
+
> "We updated retention metrics to only count users who **actually place bets**, not just open the app. Numbers may appear lower, but they're now accurate and align with industry standards. This helps us focus on real user engagement and revenue."
|
|
274
|
+
|
|
275
|
+
### What to Tell Stakeholders:
|
|
276
|
+
|
|
277
|
+
> "We shifted from vanity metrics (any activity) to actionable metrics (revenue-generating actions). This gives us better insights into product-market fit and helps prioritize features that drive actual usage."
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Deployment
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# Backend
|
|
285
|
+
cd /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server
|
|
286
|
+
git add routes/analyticsRoutes.js
|
|
287
|
+
git commit -m "feat: Update cohort retention to core action (bets only)
|
|
288
|
+
|
|
289
|
+
- Change retention definition from any activity to bet placement
|
|
290
|
+
- Only count: bet_creation_completed, join_game_completed, billiards_*_completed
|
|
291
|
+
- Aligns with industry best practices for gaming apps
|
|
292
|
+
- Provides more accurate business metrics"
|
|
293
|
+
git push heroku-dev main
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Impact Summary
|
|
299
|
+
|
|
300
|
+
| Aspect | Change |
|
|
301
|
+
|--------|--------|
|
|
302
|
+
| **Accuracy** | ↑ Much more accurate |
|
|
303
|
+
| **Percentages** | ↓ Will be lower (but real) |
|
|
304
|
+
| **Business Value** | ↑ Directly tied to revenue |
|
|
305
|
+
| **Actionability** | ↑ Can optimize for bets, not just opens |
|
|
306
|
+
| **Industry Alignment** | ✅ Matches gaming app standards |
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
**Status:** ✅ IMPLEMENTED
|
|
311
|
+
**Recommended By:** Product best practices + User feedback
|
|
312
|
+
**Breaking Change:** No (only changes calculation, not data structure)
|
|
313
|
+
|