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.
Files changed (304) hide show
  1. package/.claude/settings.local.json +280 -0
  2. package/CLAUDE.md +46 -0
  3. package/CONNECT4_PRODUCTION_DEPLOY.md +155 -0
  4. package/CURRENT_SESSION.md +171 -0
  5. package/CURRENT_SESSION_DRAW.md +516 -0
  6. package/MARCH_MADNESS_SURVIVOR.md +254 -0
  7. package/PANDA.md +166 -0
  8. package/Procfile +4 -0
  9. package/README.md +476 -0
  10. package/controllers/livescoresController.js +376 -0
  11. package/controllers/pickemController.js +554 -0
  12. package/controllers/survivorAdminController.js +887 -0
  13. package/controllers/survivorController.js +623 -0
  14. package/cron/oracleMonitor.js +77 -0
  15. package/cron/pickemOracleMonitor.js +73 -0
  16. package/data/jackpot-history.json +952 -0
  17. package/data/ncaaTeams.js +406 -0
  18. package/documentation/API_SECURITY_GUIDE.md +327 -0
  19. package/documentation/ARCADE_API.md +593 -0
  20. package/documentation/ARCADE_IMPLEMENTATION_SUMMARY.md +399 -0
  21. package/documentation/ARCADE_QUICKSTART.md +242 -0
  22. package/documentation/AUTOMATIC_MODE_ORACLE.md +321 -0
  23. package/documentation/BUG_FIX_COHORT_DATE_DISPLAY.md +171 -0
  24. package/documentation/CLAIM_MIGRATION_INSTRUCTIONS.md +52 -0
  25. package/documentation/CLAIM_STATUS_FIX.md +67 -0
  26. package/documentation/CLI_TOOL_GUIDE.md +372 -0
  27. package/documentation/COHORT_RETENTION_ANALYSIS.md +295 -0
  28. package/documentation/COHORT_RETENTION_IMPLEMENTATION_COMPLETE.md +461 -0
  29. package/documentation/COHORT_RETENTION_SUMMARY.md +204 -0
  30. package/documentation/COMPLETE_PROJECT_SUMMARY.md +490 -0
  31. package/documentation/DATABASE_QUERIES.md +269 -0
  32. package/documentation/DATABASE_RETENTION_POLICY.md +390 -0
  33. package/documentation/DATABASE_SETUP_GUIDE.md +361 -0
  34. package/documentation/DATABASE_SETUP_SUMMARY.md +247 -0
  35. package/documentation/DEMO_API_CURL_COMMANDS.md +656 -0
  36. package/documentation/DEPLOYMENT_SUMMARY.txt +100 -0
  37. package/documentation/DUPLICATE_NOTIFICATIONS_FIXED.md +201 -0
  38. package/documentation/EXCHANGE_RATES_INTEGRATION.md +371 -0
  39. package/documentation/FINAL_API_PROTECTION_TABLE.md +175 -0
  40. package/documentation/GAME_START_NOTIFICATIONS_DEPLOYMENT.md +256 -0
  41. package/documentation/GAME_START_NOTIFICATIONS_INTEGRATION.md +275 -0
  42. package/documentation/HEROKU_DEPLOYMENT.md +134 -0
  43. package/documentation/HEROKU_SCHEDULER_SETUP.md +271 -0
  44. package/documentation/JACKPOT_API.md +521 -0
  45. package/documentation/JACKPOT_DEPLOYMENT_GUIDE.md +362 -0
  46. package/documentation/JWT_IMPLEMENTATION_SUMMARY.md +373 -0
  47. package/documentation/JWT_QUICK_SETUP.md +268 -0
  48. package/documentation/JWT_TESTING_GUIDE.md +404 -0
  49. package/documentation/KEEPER_RECOVERY_GUIDE.md +381 -0
  50. package/documentation/KEEPER_SETUP.md +206 -0
  51. package/documentation/KEEPER_STATE_MACHINE.md +423 -0
  52. package/documentation/LATEST_PRODUCTION_SETUP.md +387 -0
  53. package/documentation/LOCAL_VOTING_TEST.md +279 -0
  54. package/documentation/ORACLE_FIXES_SUMMARY.md +188 -0
  55. package/documentation/ORACLE_POSTGRESQL_UPDATE.md +202 -0
  56. package/documentation/PAYMENT_DEPLOYMENT.md +209 -0
  57. package/documentation/PNL_TRACKING_SETUP.md +189 -0
  58. package/documentation/PREVENTING_LOCKUP_ERRORS.md +472 -0
  59. package/documentation/PRODUCTION_READY_SUMMARY.md +227 -0
  60. package/documentation/PUBLIC_VS_PRIVATE_ENDPOINTS.md +278 -0
  61. package/documentation/QUICK_AUTH_SETUP.md +99 -0
  62. package/documentation/QUICK_DEPLOY.md +224 -0
  63. package/documentation/QUICK_FIX.md +114 -0
  64. package/documentation/QUICK_START.md +152 -0
  65. package/documentation/REFEREE_MODE_GUIDE.md +392 -0
  66. package/documentation/RETENTION_CORE_ACTION_UPDATE.md +313 -0
  67. package/documentation/RETENTION_UPDATE_SUMMARY.md +108 -0
  68. package/documentation/RUN_MIGRATION_NOW.md +39 -0
  69. package/documentation/SCRIPTS_UPDATE_SUMMARY.md +251 -0
  70. package/documentation/SETUP_GUIDE.md +184 -0
  71. package/documentation/STATE_MACHINE_IMPLEMENTATION.md +250 -0
  72. package/documentation/TELEGRAM_NOTIFICATIONS_DIAGNOSIS.md +361 -0
  73. package/documentation/UNIFIED_ARCHITECTURE.md +231 -0
  74. package/documentation/VOTING_DEPLOYMENT_SUMMARY.md +392 -0
  75. package/documentation/WEBSOCKET_ARCHITECTURE.md +881 -0
  76. package/documentation/WHAT_WE_BUILT_TODAY.md +369 -0
  77. package/documentation/latest/LATEST_PRODUCTION_SETUP.md +865 -0
  78. package/ecosystem.config.js +65 -0
  79. package/env.template +125 -0
  80. package/middleware/apiKeyAuth.js +136 -0
  81. package/middleware/authenticate.js +214 -0
  82. package/middleware/developerUserAuth.js +76 -0
  83. package/middleware/socketAuth.js +69 -0
  84. package/package.json +49 -0
  85. package/postman/Dubs-API-v1-With-Voting.postman_collection.json +555 -0
  86. package/postman/Dubs-API-v1.postman_collection.json +205 -0
  87. package/postman/Dubs_Developer_API.postman_collection.json +662 -0
  88. package/postman/QUICKSTART.md +118 -0
  89. package/postman/QUICK_REFERENCE.md +246 -0
  90. package/postman/README.md +71 -0
  91. package/postman/VOTING_API_GUIDE.md +426 -0
  92. package/refactor/Animations.md +148 -0
  93. package/refactor/Chat.md +252 -0
  94. package/routes/actionsRoutes.js +699 -0
  95. package/routes/adminRoutes.js +370 -0
  96. package/routes/analyticsRoutes.js +1262 -0
  97. package/routes/arcadeRoutes.js +557 -0
  98. package/routes/authRoutes.js +2310 -0
  99. package/routes/avatarRoutes.js +85 -0
  100. package/routes/botRoutes.js +211 -0
  101. package/routes/chatRoutes.js +377 -0
  102. package/routes/cryptoPriceRoutes.js +105 -0
  103. package/routes/developerRoutes.js +4201 -0
  104. package/routes/deviceRoutes.js +214 -0
  105. package/routes/dmRoutes.js +167 -0
  106. package/routes/esportsRoutes.js +806 -0
  107. package/routes/exchangeRateRoutes.js +233 -0
  108. package/routes/gamesRoutes.js +3028 -0
  109. package/routes/jackpotRoutes.js +754 -0
  110. package/routes/keeperMonitoringRoutes.js +156 -0
  111. package/routes/keeperWebhookRoutes.js +466 -0
  112. package/routes/livescoresRoutes.js +31 -0
  113. package/routes/pickemAdminRoutes.js +199 -0
  114. package/routes/pickemRoutes.js +231 -0
  115. package/routes/playerStatsRoutes.js +147 -0
  116. package/routes/portfolioRoutes.js +217 -0
  117. package/routes/promoRoutes.js +418 -0
  118. package/routes/referralEarningsRoutes.js +392 -0
  119. package/routes/socialRoutes.js +459 -0
  120. package/routes/sportsRoutes.js +1271 -0
  121. package/routes/survivorAdminRoutes.js +345 -0
  122. package/routes/survivorRoutes.js +756 -0
  123. package/routes/uploadRoutes.js +256 -0
  124. package/routes/userProfileRoutes.js +244 -0
  125. package/routes/whatsNewRoutes.js +331 -0
  126. package/scripts/.claude/settings.local.json +15 -0
  127. package/scripts/README.md +170 -0
  128. package/scripts/RESTART_EVERYTHING.sh +104 -0
  129. package/scripts/add-claim-columns.sql +48 -0
  130. package/scripts/add-crypto-prices-cache.sql +27 -0
  131. package/scripts/add-exchange-rates-cache.sql +40 -0
  132. package/scripts/add-game-invite-column.sql +23 -0
  133. package/scripts/add-game-invite-notification.sql +33 -0
  134. package/scripts/add-game-invite-telegram-pref.sql +16 -0
  135. package/scripts/add-game-joined-notification.sql +16 -0
  136. package/scripts/add-game-joined-pref.js +40 -0
  137. package/scripts/add-game-joined-preference.sql +6 -0
  138. package/scripts/add-game-start-notifications.sql +41 -0
  139. package/scripts/add-notification-flags-to-games.sql +55 -0
  140. package/scripts/add-pending-game-dismissals.sql +19 -0
  141. package/scripts/add-preferred-currency.sql +34 -0
  142. package/scripts/add-winner-columns.js +61 -0
  143. package/scripts/add_mention_system.sql +53 -0
  144. package/scripts/add_payment_system.sql +96 -0
  145. package/scripts/add_sports_event_id_column.sql +22 -0
  146. package/scripts/analyze-cohort-data-heroku.js +276 -0
  147. package/scripts/analyze-cohort-data.js +295 -0
  148. package/scripts/analyze-prod-cohorts.sh +10 -0
  149. package/scripts/backfill-matchup-images.js +245 -0
  150. package/scripts/backfill-missing-signatures.js +175 -0
  151. package/scripts/backfill-referral-earnings.js +202 -0
  152. package/scripts/check-chat-schema.js +130 -0
  153. package/scripts/check-db.sh +14 -0
  154. package/scripts/check_oracle_in_game.js +54 -0
  155. package/scripts/cleanup-database.js +193 -0
  156. package/scripts/clear-notification-cache.js +85 -0
  157. package/scripts/convert-mnemonic.js +50 -0
  158. package/scripts/create-users-table.sql +44 -0
  159. package/scripts/debug-cohort-counts.js +248 -0
  160. package/scripts/debug-winner-calc.js +84 -0
  161. package/scripts/deploy-payment-system.sh +118 -0
  162. package/scripts/deploy-to-heroku.sh +63 -0
  163. package/scripts/diagnose-locked-round.js +143 -0
  164. package/scripts/dubs-cli.js +720 -0
  165. package/scripts/dump-account.js +65 -0
  166. package/scripts/find-vrf-offset.js +48 -0
  167. package/scripts/fix-chat-notifications-constraint.sql +122 -0
  168. package/scripts/fix-claim-columns.js +124 -0
  169. package/scripts/fix-constraint-now.js +44 -0
  170. package/scripts/fix-lock-timestamps.js +96 -0
  171. package/scripts/fix-locked-round.sh +126 -0
  172. package/scripts/fix-missing-badges.sql +91 -0
  173. package/scripts/fix-payment-notifications.sql +41 -0
  174. package/scripts/force-new-round.js +55 -0
  175. package/scripts/force-resolve-and-claim.js +278 -0
  176. package/scripts/important/README.md +115 -0
  177. package/scripts/important/authority-force-lock.js +197 -0
  178. package/scripts/important/authority-resolve-game.js +267 -0
  179. package/scripts/important/check-game-status.js +373 -0
  180. package/scripts/important/list-pending-games-by-version.js +270 -0
  181. package/scripts/important/reconcile-v1-v2-payouts.js +270 -0
  182. package/scripts/initialize-jackpot.js +111 -0
  183. package/scripts/jackpot/.claude/settings.local.json +10 -0
  184. package/scripts/jackpot/force-reset.js +84 -0
  185. package/scripts/jackpot/initialize-mainnet.js +100 -0
  186. package/scripts/jackpot/keeper.js +742 -0
  187. package/scripts/jackpot/status.js +107 -0
  188. package/scripts/jackpot/update-round-duration.js +143 -0
  189. package/scripts/keeper-bot.js +112 -0
  190. package/scripts/list-pending-games.js +131 -0
  191. package/scripts/migrate-chat-v2.js +127 -0
  192. package/scripts/migrate-chat-winners.js +84 -0
  193. package/scripts/migrate-chat.sh +17 -0
  194. package/scripts/migrate-game-invite.js +83 -0
  195. package/scripts/migrate-heroku-game-notifications.sh +159 -0
  196. package/scripts/migrations/001_analytics_tables.sql +422 -0
  197. package/scripts/migrations/002_add_matchup_image_url.sql +14 -0
  198. package/scripts/migrations/003_referral_earnings.sql +208 -0
  199. package/scripts/migrations/004_add_whats_new_notification_type.sql +62 -0
  200. package/scripts/migrations/005_add_connect4_your_turn_notification.sql +61 -0
  201. package/scripts/migrations/005_push_notifications.sql +55 -0
  202. package/scripts/migrations/006_add_draw_team_players.sql +28 -0
  203. package/scripts/migrations/006_add_game_cancelled_notification.sql +62 -0
  204. package/scripts/migrations/007_add_gif_url.sql +8 -0
  205. package/scripts/migrations/008_add_connect4_columns.sql +139 -0
  206. package/scripts/migrations/008_add_pool_tracking.sql +22 -0
  207. package/scripts/migrations/009_create_survivor_pool_tables.sql +174 -0
  208. package/scripts/migrations/010_add_survivor_pool_outcome.sql +28 -0
  209. package/scripts/migrations/011_create_developer_tables.sql +67 -0
  210. package/scripts/migrations/011_fix_keeper_tables.sql +85 -0
  211. package/scripts/migrations/012_create_developer_webhooks.sql +31 -0
  212. package/scripts/migrations/013_add_network_mode.sql +18 -0
  213. package/scripts/migrations/014_create_developer_app_users.sql +19 -0
  214. package/scripts/migrations/015_add_ui_config.sql +4 -0
  215. package/scripts/migrations/016_add_resolution_secret.sql +4 -0
  216. package/scripts/migrations/017_add_external_game_id.sql +3 -0
  217. package/scripts/migrations/018_create_pickem_tables.sql +115 -0
  218. package/scripts/migrations/019_expo_push_tokens.sql +19 -0
  219. package/scripts/migrations/create_whats_new_tables.sql +88 -0
  220. package/scripts/migrations/drop_live_games_tables.sql +34 -0
  221. package/scripts/open-jackpot-round.js +85 -0
  222. package/scripts/purge-all-data.sh +329 -0
  223. package/scripts/purge-all-data.sql +142 -0
  224. package/scripts/purge-heroku-data.sh +149 -0
  225. package/scripts/purge-heroku-data.sql +62 -0
  226. package/scripts/rebuild-heroku-database.sh +113 -0
  227. package/scripts/recover-funds.js +357 -0
  228. package/scripts/regenerate-epl-images.js +278 -0
  229. package/scripts/resize-s3-matchup-images.js +374 -0
  230. package/scripts/resolve-direct.js +88 -0
  231. package/scripts/resolve-mock-game.js +124 -0
  232. package/scripts/resolve-pickem-game.js +55 -0
  233. package/scripts/resolve-round-manual.js +83 -0
  234. package/scripts/resolve-stuck-game.js +382 -0
  235. package/scripts/resolve-stuck-round.js +42 -0
  236. package/scripts/run-connect4-migration.sh +16 -0
  237. package/scripts/run-mention-migration.sh +32 -0
  238. package/scripts/run-payment-migration.sh +51 -0
  239. package/scripts/run-preferred-currency-migration.sh +31 -0
  240. package/scripts/run-referral-earnings-migration.sh +32 -0
  241. package/scripts/run-survivor-outcome-migration.sh +16 -0
  242. package/scripts/seed-test-users.js +346 -0
  243. package/scripts/setup-auth-tables.js +78 -0
  244. package/scripts/setup-complete-database.sql +992 -0
  245. package/scripts/setup-database-fresh.sh +359 -0
  246. package/scripts/setup-heroku-keeper.sh +48 -0
  247. package/scripts/setup-keeper-database.js +83 -0
  248. package/scripts/setup-keeper-state-db.sql +110 -0
  249. package/scripts/setup-oracle.sh +39 -0
  250. package/scripts/setup-pnl-tracking.js +111 -0
  251. package/scripts/start-devnet.sh +14 -0
  252. package/scripts/test-arcade-devnet.sh +160 -0
  253. package/scripts/test-arcade-match.sh +109 -0
  254. package/scripts/test-automatic-mode.sh +239 -0
  255. package/scripts/test-connect4-cancel-claim.js +370 -0
  256. package/scripts/test-connect4-e2e.js +369 -0
  257. package/scripts/test-connect4-resolve.js +369 -0
  258. package/scripts/test-game-state-endpoint.js +136 -0
  259. package/scripts/test-invite-notification.js +86 -0
  260. package/scripts/test-jackpot-api.sh +71 -0
  261. package/scripts/test-poll-confirmation.js +267 -0
  262. package/scripts/test-resolve-game.js +271 -0
  263. package/scripts/test-resolve-signature.js +223 -0
  264. package/scripts/test-signature-preservation.js +124 -0
  265. package/scripts/test-state-machine.js +291 -0
  266. package/scripts/test-webhook-receiver.js +60 -0
  267. package/scripts/update-notification-constraint.js +52 -0
  268. package/scripts/verify-account-layout.js +145 -0
  269. package/scripts/verify-winner-algorithm.js +278 -0
  270. package/server.js +5259 -0
  271. package/services/arcadeMatchService.js +763 -0
  272. package/services/automaticGameOracle.js +1596 -0
  273. package/services/chatService.js +1612 -0
  274. package/services/connect4GameService.js +1049 -0
  275. package/services/connect4NotificationService.js +374 -0
  276. package/services/cryptoPriceService.js +223 -0
  277. package/services/customGameResolver.js +260 -0
  278. package/services/db.js +79 -0
  279. package/services/directMessageService.js +389 -0
  280. package/services/discordNotifications.js +160 -0
  281. package/services/exchangeRateService.js +289 -0
  282. package/services/expoPushService.js +314 -0
  283. package/services/gamesCacheService.js +539 -0
  284. package/services/jackpotHistory.js +331 -0
  285. package/services/jackpotService.js +856 -0
  286. package/services/keeperStateService.js +355 -0
  287. package/services/matchupImageService.js +591 -0
  288. package/services/notificationCacheService.js +407 -0
  289. package/services/pickemOracle.js +440 -0
  290. package/services/playerStatsService.js +389 -0
  291. package/services/portfolioService.js +555 -0
  292. package/services/promoService.js +757 -0
  293. package/services/promoTreasuryService.js +239 -0
  294. package/services/pushNotifications.js +353 -0
  295. package/services/redisService.js +422 -0
  296. package/services/referralEarningsService.js +728 -0
  297. package/services/s3Service.js +396 -0
  298. package/services/socialService.js +1202 -0
  299. package/services/survivorOracle.js +469 -0
  300. package/services/survivorSimulator.js +475 -0
  301. package/services/telegramNotifications.js +461 -0
  302. package/services/userProfileStatsService.js +1185 -0
  303. package/services/whatsNewService.js +388 -0
  304. 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
+