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,280 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(heroku addons:*)",
5
+ "Bash(heroku pg:reset:*)",
6
+ "Bash(heroku logs:*)",
7
+ "Bash(heroku ps:*)",
8
+ "Bash(heroku pg:psql:*)",
9
+ "Bash(git add:*)",
10
+ "Bash(git commit:*)",
11
+ "Bash(git push:*)",
12
+ "Bash(curl:*)",
13
+ "Bash(heroku redis:cli:*)",
14
+ "Bash(heroku run:*)",
15
+ "Bash(grep:*)",
16
+ "Bash(pm2 start:*)",
17
+ "Bash(heroku config:*)",
18
+ "Bash(npm run oracle:dev:*)",
19
+ "Bash(heroku config:set:*)",
20
+ "Bash(heroku config:get:*)",
21
+ "Bash(head:*)",
22
+ "Bash(find:*)",
23
+ "Bash(npm install)",
24
+ "Bash(npm run build:v2:*)",
25
+ "Bash(npm install:*)",
26
+ "Bash(npm run test:v2:*)",
27
+ "Bash(npm run db:migrate:v2:*)",
28
+ "Bash(ls:*)",
29
+ "Bash(source .env)",
30
+ "Bash(psql:*)",
31
+ "Bash(npm run build:*)",
32
+ "Bash(npm run:*)",
33
+ "Bash(node:*)",
34
+ "Bash(shasum:*)",
35
+ "Bash(git rm:*)",
36
+ "Bash(python3:*)",
37
+ "Bash(git checkout:*)",
38
+ "Bash(heroku apps:*)",
39
+ "Bash(heroku releases:*)",
40
+ "Bash(lsof:*)",
41
+ "Bash(git fetch:*)",
42
+ "Bash(git stash:*)",
43
+ "Bash(git branch:*)",
44
+ "Bash(chmod:*)",
45
+ "Bash(/Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server/scripts/player-game-stats.sh)",
46
+ "Bash(__NEW_LINE_5413c0b164db93cd__ psql postgresql://adamdahan@localhost:5432/dubs_db -c \"\nSELECT ''V2'' as version, * FROM referral_earnings_v2 ORDER BY id;\n\")",
47
+ "Bash(__NEW_LINE_c3785ae6537f2bed__ psql postgresql://adamdahan@localhost:5432/dubs_db -c \"\n-- Check V1 games\nSELECT id, game_id, game_mode, title, buy_in, is_locked, is_resolved, created_by,\n array_length\\(home_team_players, 1\\) as home_count,\n array_length\\(away_team_players, 1\\) as away_count,\n home_team_players, away_team_players\nFROM games ORDER BY id;\n\")",
48
+ "Bash(__NEW_LINE_c3785ae6537f2bed__ psql postgresql://adamdahan@localhost:5432/dubs_db -c \"\n-- Check V2 games\nSELECT game_id, status, position_count, created_by FROM games_v2 ORDER BY game_id;\n\")",
49
+ "Bash(__NEW_LINE_a2232bbcd7e0e3e3__ psql postgresql://adamdahan@localhost:5432/dubs_db -c \"\n-- Auto-friends check\nSELECT ur.user_id, u1.username as user, ur.target_user_id, u2.username as friend, ur.relationship_type\nFROM user_relationships ur\nJOIN users u1 ON ur.user_id = u1.id\nJOIN users u2 ON ur.target_user_id = u2.id;\n\")",
50
+ "Bash(__NEW_LINE_a2232bbcd7e0e3e3__ psql postgresql://adamdahan@localhost:5432/dubs_db -c \"\n-- V1 Games\nSELECT id, game_id, game_address, title, buy_in, is_locked, is_resolved, \n created_by, game_mode,\n array_length\\(home_team_players, 1\\) as home_count,\n array_length\\(away_team_players, 1\\) as away_count\nFROM games ORDER BY id;\n\")",
51
+ "Bash(__NEW_LINE_a2232bbcd7e0e3e3__ psql postgresql://adamdahan@localhost:5432/dubs_db -c \"\n-- V2 Games\nSELECT game_id, status, position_count, total_pool, created_by FROM games_v2;\n\")",
52
+ "Bash(# Check what the V1 oracle would see curl -s \"\"http://localhost:3001/api/games/automatic/pending\"\")",
53
+ "Bash(# Check V1 oracle config echo \"\"=== V1 Oracle Config \\(.env\\) ===\"\" grep -E \"\"LIVE_SCORES.*V1|LIVE_SCORES_API_URL\"\" /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server/.env echo \"\"\"\" echo \"\"=== Testing port 3001 ===\"\" curl -s \"\"http://localhost:3001/api/livescores/NBA\"\")",
54
+ "Bash(__NEW_LINE_34768621ade711c4__ psql postgresql://adamdahan@localhost:5432/dubs_db -c \"\nSELECT u.username, \n CASE WHEN g.home_team_players @> ARRAY[u.wallet_address] THEN ''HOME \\(Adam\\)''\n WHEN g.away_team_players @> ARRAY[u.wallet_address] THEN ''AWAY \\(Amy\\)''\n ELSE ''Not in game'' END as team_pick\nFROM users u\nCROSS JOIN games g\nWHERE g.game_id = ''sport-1768606573428-oy6zc0j6o''\nORDER BY u.id;\n\")",
55
+ "Bash(__NEW_LINE_ee0f4894039ad260__ echo \"\")",
56
+ "Bash(__NEW_LINE_bea390dedeb1c82b__ echo \"\")",
57
+ "Bash(__NEW_LINE_55e985589c1f6878__ echo \"\")",
58
+ "Bash(sqlite3:*)",
59
+ "Bash(pkill:*)",
60
+ "Bash(heroku:*)",
61
+ "Bash(git reset:*)",
62
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa fetch --all)",
63
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa branch:*)",
64
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa status:*)",
65
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa log --oneline -1 main)",
66
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa log --oneline -1 develop)",
67
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa log --oneline main..develop)",
68
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa log --oneline -1 origin/main)",
69
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa log --oneline -1 origin/develop)",
70
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa log --oneline -1 v2-develop-backup-2025-01-17)",
71
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa stash push -m \"v2-uncommitted-changes-backup-2025-01-17\")",
72
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa stash list)",
73
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa reset --hard main)",
74
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa log:*)",
75
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa push origin develop --force)",
76
+ "Bash(git -C ~/Developer/iheartsolana/dubs-jackpot-spa fetch origin)",
77
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api fetch --all)",
78
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api remote -v)",
79
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api status)",
80
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api branch -a)",
81
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api log --oneline -1 HEAD)",
82
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api log --oneline -1 production/main)",
83
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api log --oneline -1 development/main)",
84
+ "Bash(git -C ~/Developer/iheartsolana/dubs-api log --oneline -1 origin/main)",
85
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs status:*)",
86
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs remote:*)",
87
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs fetch --all)",
88
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs log --oneline -15)",
89
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs log --oneline --all)",
90
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs branch:*)",
91
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs show:*)",
92
+ "Bash(solana --version:*)",
93
+ "Bash(anchor:*)",
94
+ "Bash(solana config:*)",
95
+ "Bash(solana-keygen pubkey:*)",
96
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs log --oneline -1 v2-contract-backup-2025-01-17)",
97
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs reset:*)",
98
+ "Bash(cargo build-sbf:*)",
99
+ "Bash(solana program deploy:*)",
100
+ "Bash(solana program show:*)",
101
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs push origin main --force)",
102
+ "Bash(git -C ~/Developer/iheartsolana/solana-programs/dubs fetch origin)",
103
+ "Bash(xargs kill -9)",
104
+ "Bash(kill:*)",
105
+ "Bash(git ls-tree:*)",
106
+ "Bash(APP_NAME=dubs-server-dev bash:*)",
107
+ "Bash(solana account:*)",
108
+ "Bash(for pda in \"8t5TMoFbxRTNB9puA9dQCud6WaLX9CxBRiUn5rDcdg4c\" \"Ftj5hqky2XwHo5sFMncvCVkGwDwjb2wJ8ZXRx1gAHVGU\" \"7re8HYQncrbBNginVx4hmmsaGqZSxmRaLSg7eerQ6tGe\")",
109
+ "Bash(do)",
110
+ "Bash(echo:*)",
111
+ "Bash(done)",
112
+ "Bash(tree:*)",
113
+ "Bash(npx tsc:*)",
114
+ "Bash(PGPASSWORD=postgres psql:*)",
115
+ "Bash(for f in /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server/wallets/*.json)",
116
+ "Bash(git merge:*)",
117
+ "Bash(git pull:*)",
118
+ "Bash(ALCHEMY_API_KEY=M7pyy3QL4xYOndpcYukNhf-yq2IG6eyl SOLANA_NETWORK=devnet node:*)",
119
+ "WebFetch(domain:site.api.espn.com)",
120
+ "Bash(xargs basename:*)",
121
+ "WebSearch",
122
+ "WebFetch(domain:www.foxsports.com)",
123
+ "WebFetch(domain:www.nhl.com)",
124
+ "Bash(cargo check:*)",
125
+ "Bash(/opt/homebrew/bin/anchor build:*)",
126
+ "Bash(/opt/homebrew/bin/anchor:*)",
127
+ "Bash(solana balance:*)",
128
+ "Bash(solana address:*)",
129
+ "Bash(solana-keygen new:*)",
130
+ "Bash(solana transfer:*)",
131
+ "Bash(if [ -n \"$DATABASE_URL\" ])",
132
+ "Bash(then psql \"$DATABASE_URL\" -f scripts/migrations/006_add_draw_team_players.sql)",
133
+ "Bash(fi)",
134
+ "Bash(aws s3 cp:*)",
135
+ "Bash(aws s3 ls:*)",
136
+ "Bash(aws s3api put-object-acl:*)",
137
+ "Bash(aws s3api get-bucket-policy:*)",
138
+ "Bash(aws s3api put-bucket-policy:*)",
139
+ "Bash(aws s3api get-bucket-location:*)",
140
+ "Bash(git cherry-pick:*)",
141
+ "Bash(solana slot:*)",
142
+ "Bash(PGPASSWORD=\"\" psql:*)",
143
+ "Bash(cat:*)",
144
+ "Bash(solana confirm:*)",
145
+ "Bash(solana transaction-history 6C7VDz74iZJwfW2ojUbi3WnyMqwcKFTAdEWc3G1pGY1x --url https://solana-mainnet.g.alchemy.com/v2/M7pyy3QL4xYOndpcYukNhf-yq2IG6eyl --limit 10)",
146
+ "Bash(git remote add:*)",
147
+ "Bash(netlify --version:*)",
148
+ "Bash(netlify status:*)",
149
+ "Bash(netlify sites:list:*)",
150
+ "Bash(netlify unlink:*)",
151
+ "Bash(netlify link:*)",
152
+ "Bash(netlify env:set:*)",
153
+ "Bash(netlify env:list:*)",
154
+ "Bash(netlify deploy:*)",
155
+ "Bash(__NEW_LINE_245cedaae0ad1253__ node -e \"\nconst { PublicKey } = require\\(''@solana/web3.js''\\);\nconst PROGRAM_ID = new PublicKey\\(''85wJGp9uc8w2FeKX9CEHsudTo1UVCrmuRFy37oCcaoG1''\\);\n\nfunction getGamePDA\\(gameId\\) {\n const gameIdBuffer = Buffer.alloc\\(8\\);\n gameIdBuffer.writeBigUInt64LE\\(BigInt\\(gameId\\)\\);\n return PublicKey.findProgramAddressSync\\(\n [Buffer.from\\(''game''\\), gameIdBuffer],\n PROGRAM_ID\n \\);\n}\n\n// What we expect from the game ID\nconst expectedId = 1769366095299n;\nconst [expectedPDA] = getGamePDA\\(expectedId\\);\nconsole.log\\(''Expected PDA from game_id 1769366095299:'', expectedPDA.toString\\(\\)\\);\n\n// The actual on-chain game_id\nconst actualId = 10261194552452595202n;\nconst [actualPDA] = getGamePDA\\(actualId\\);\nconsole.log\\(''PDA from on-chain game_id:'', actualPDA.toString\\(\\)\\);\n\n// What the database has\nconsole.log\\(''Database game_address:'', ''5Cn914joZ79RBGbCQ3EPkKsMEpPBi29j1ZMD7Zi7ytL3''\\);\n\")",
156
+ "Bash(SOLANA_RPC_URL=\"https://solana-mainnet.g.alchemy.com/v2/M7pyy3QL4xYOndpcYukNhf-yq2IG6eyl\" node:*)",
157
+ "Bash(solana airdrop:*)",
158
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa log --oneline -5)",
159
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa add app/v2/features/connect4/components/Connect4GameOverlay.tsx app/v2/features/sports/components/bet-flow/FriendSelector.tsx public/Dubsy-cat.webp public/cat_bubble_only_outside_bg_transparent.png public/dubsy_ledge.png)",
160
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa commit -m \"$\\(cat <<''EOF''\nAdd mobile Dubsy footer and light/dark mode cat mascot support\n\n- Connect4GameOverlay: Add mobile-specific Dubsy in footer \\(hidden on desktop\\)\n- FriendSelector: Add light/dark mode support for cat mascot image\n- Add new image assets for Dubsy and cat mascot variants\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
161
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa status)",
162
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa checkout main)",
163
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa pull)",
164
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa merge develop)",
165
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa push origin main)",
166
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa checkout develop)",
167
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa grep -l \"c4-\\\\|connect4\\\\|JoinGameOverlay\" --include=\"*.tsx\" --include=\"*.ts\")",
168
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa add app/game/[gameId]/RedirectToV2.tsx)",
169
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa commit -m \"$\\(cat <<''EOF''\nFix Connect4 deep links opening wrong overlay\n\nDetect c4- prefix in gameId and use ''connect4'' gameType with\npendingConnect4 URL param instead of always using ''sports''.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
170
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa push)",
171
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa fetch --all)",
172
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa log --oneline -3 origin/main)",
173
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa log --oneline -3 origin/develop)",
174
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server fetch --all)",
175
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server log --oneline -3 origin/main)",
176
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server log --oneline -3 origin/develop)",
177
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server log --oneline origin/main...origin/develop)",
178
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server status)",
179
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server branch:*)",
180
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server checkout develop)",
181
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server pull)",
182
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server merge origin/main)",
183
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server push)",
184
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server log --oneline -1 origin/main)",
185
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server log --oneline -1 origin/develop)",
186
+ "Bash(APP_NAME=dubs-server-dev ./scripts/purge-heroku-data.sh:*)",
187
+ "Bash(bash:*)",
188
+ "Bash(PGPASSWORD=p776d3a60ef2f7b5364193ab26dec1cf0d228e372ad3f46e9db4df01f498cd192 psql:*)",
189
+ "Bash(claude mcp add:*)",
190
+ "WebFetch(domain:solana.com)",
191
+ "WebFetch(domain:github.com)",
192
+ "Bash(__NEW_LINE_63c7ae605d7d334e__ echo \"\")",
193
+ "WebFetch(domain:elements.heroku.com)",
194
+ "Bash(TZ='America/New_York' date:*)",
195
+ "Bash(TZ='UTC' date:*)",
196
+ "Bash(tee:*)",
197
+ "Bash(wc:*)",
198
+ "WebFetch(domain:jelli-portfolio-api-67fffef6d39a.herokuapp.com)",
199
+ "Bash(npx next lint:*)",
200
+ "mcp__solana-mcp-server__Solana_Expert__Ask_For_Help",
201
+ "Bash(__NEW_LINE_5bb2bcce7486b08c__ echo -e \"\\\\n=== Feb 5 ===\")",
202
+ "Bash(__NEW_LINE_e57ab3ce27b3941b__ echo -e \"\\\\n=== Feb 6 ===\")",
203
+ "Bash(__NEW_LINE_c903921266eee48d__ echo -e \"\\\\n=== Feb 7 ===\")",
204
+ "Bash(for page in 1 2 3 4)",
205
+ "Bash(./scripts/download-ncaab-logos.sh:*)",
206
+ "Bash(__NEW_LINE_56a90b3f74879917__ echo \"\")",
207
+ "mcp__solana-mcp-server__Ask_Solana_Anchor_Framework_Expert",
208
+ "mcp__solana-mcp-server__Solana_Documentation_Search",
209
+ "Bash(__NEW_LINE_3cb8e6f393081f5d__ echo \"\")",
210
+ "Bash(__NEW_LINE_5ceec0d06d272040__ echo \"\")",
211
+ "Bash(__NEW_LINE_c0b44a9e4ccb4677__ echo \"\")",
212
+ "Bash(./scripts/download-ufc-logos.sh:*)",
213
+ "Bash(./scripts/run-survivor-outcome-migration.sh:*)",
214
+ "Bash(npx next build)",
215
+ "WebFetch(domain:developers.pandascore.co)",
216
+ "WebFetch(domain:www.npmjs.com)",
217
+ "Bash(source:*)",
218
+ "Bash(npx next build:*)",
219
+ "Bash(awk:*)",
220
+ "Bash(solana transaction-history:*)",
221
+ "Bash(ps:*)",
222
+ "Bash('' FROM developer_api_keys LIMIT 1)",
223
+ "Bash(\")",
224
+ "Bash(while read commit msg)",
225
+ "Bash(do echo \"=== $msg ===\")",
226
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server log --oneline -10)",
227
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa log --oneline -10)",
228
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server diff --stat)",
229
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa diff --stat)",
230
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server diff routes/gamesRoutes.js)",
231
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server diff server.js)",
232
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa diff)",
233
+ "Bash(redis-cli:*)",
234
+ "Bash(npx:*)",
235
+ "Bash(./node_modules/.bin/tsc:*)",
236
+ "Bash(/Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa/node_modules/.bin/tsc:*)",
237
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa log --oneline -5 main)",
238
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa log --oneline --all --grep=\"useMyGames\\\\|my-games\\\\|Load More\\\\|pagination\\\\|paginated\\\\|cache\")",
239
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa diff main -- app/v2/features/sports/components/my-games/useMyGames.ts)",
240
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa log --oneline main..cleanup -- app/v2/features/sports/components/my-games/)",
241
+ "Bash(git -C /Users/adamdahan/Developer/iheartsolana/dubs-jackpot-spa diff main..cleanup -- app/v2/features/sports/components/my-games/useMyGames.ts)",
242
+ "Bash(git show:*)",
243
+ "Bash(git mv:*)",
244
+ "Bash(pgrep:*)",
245
+ "Bash(pm2 logs:*)",
246
+ "Bash(solana rent:*)",
247
+ "Bash(~/.cargo/bin/anchor:*)",
248
+ "Bash(~/.avm/bin/anchor:*)",
249
+ "Bash(PATH=\"/opt/homebrew/bin:$PATH\" anchor build:*)",
250
+ "Bash(SOLANA_RPC_URL=https://solana-mainnet.g.alchemy.com/v2/M7pyy3QL4xYOndpcYukNhf-yq2IG6eyl API_BASE=https://dubs-server-prod-9c91d3f01199.herokuapp.com node -e \"\nconst { Connection, Keypair, Transaction, PublicKey, SystemProgram, TransactionInstruction } = require\\(''@solana/web3.js''\\);\nconst fs = require\\(''fs''\\);\nconst path = require\\(''path''\\);\n\nconst RPC_URL = process.env.SOLANA_RPC_URL;\nconst API_BASE = process.env.API_BASE;\nconst PROGRAM_ID = new PublicKey\\(''BHidyz25KWkNPdTHgeANzMg25MM2KEiNnG4yE5F46XUz''\\);\n\n// Load admin wallet \\(upgrade authority\\)\nconst walletPath = path.join\\(require\\(''os''\\).homedir\\(\\), ''.config/solana/id.json''\\);\nconst admin = Keypair.fromSecretKey\\(Uint8Array.from\\(JSON.parse\\(fs.readFileSync\\(walletPath, ''utf-8''\\)\\)\\)\\);\nconst connection = new Connection\\(RPC_URL, ''confirmed''\\);\n\nconsole.log\\(''Authority:'', admin.publicKey.toString\\(\\)\\);\n\n// But the admin wallet might not have enough SOL for tx fees\n\\(async \\(\\) => {\n const bal = await connection.getBalance\\(admin.publicKey\\);\n console.log\\(''Balance:'', \\(bal / 1e9\\).toFixed\\(6\\), ''SOL''\\);\n}\\)\\(\\);\n\")",
251
+ "Bash(solana program close:*)",
252
+ "Bash(solana program extend:*)",
253
+ "Bash(solana program write-buffer:*)",
254
+ "Bash(solana program upgrade:*)",
255
+ "Bash(identify:*)",
256
+ "Bash(test:*)",
257
+ "Bash(SOLANA_RPC_URL=https://solana-mainnet.g.alchemy.com/v2/M7pyy3QL4xYOndpcYukNhf-yq2IG6eyl API_BASE=https://dubs-server-prod-9c91d3f01199.herokuapp.com node:*)",
258
+ "Bash(gh pr view:*)",
259
+ "Bash(export PATH=\"/opt/homebrew/bin:/usr/local/bin:$PATH\":*)",
260
+ "Bash(ipconfig getifaddr:*)",
261
+ "Bash(./node_modules/.bin/tsup:*)",
262
+ "Bash(eas build:*)",
263
+ "Bash(npm pack:*)",
264
+ "Bash(eas build:view:*)",
265
+ "Bash(eas build:list:*)",
266
+ "Bash(eas diagnostics:*)",
267
+ "WebFetch(domain:expo.dev)",
268
+ "Bash(npm whoami:*)",
269
+ "Bash(npm publish:*)",
270
+ "Bash(npm config set:*)",
271
+ "Bash(npm version:*)",
272
+ "Bash(npm cache clean:*)",
273
+ "Bash(npm pkg:*)",
274
+ "Bash(/tmp/phone_mockup_report.txt:*)",
275
+ "Bash(git config:*)",
276
+ "Bash(sed:*)",
277
+ "Bash(git revert:*)"
278
+ ]
279
+ }
280
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,46 @@
1
+ # Claude Instructions
2
+
3
+ ## First Steps
4
+ **Always read `CURRENT_SESSION.md` first.** It contains the current work context, recent changes, and important notes for ongoing tasks.
5
+
6
+ ## Project Overview
7
+ dubs-server is the main backend for the Dubs betting platform.
8
+
9
+ ## Tech Stack
10
+ - Node.js / Express
11
+ - PostgreSQL
12
+ - Socket.io (WebSocket)
13
+ - Solana Web3.js
14
+
15
+ ## Key Services
16
+ - **Oracle** (`services/automaticGameOracle.js`) - Resolves sports bets based on live scores
17
+ - **Live Scores** (`controllers/livescoresController.js`) - ESPN API wrapper
18
+ - **Auth** (`routes/authRoutes.js`) - User registration, login, referrals
19
+ - **Games** (`routes/gamesRoutes.js`) - Game creation, joining, resolution
20
+
21
+ ## Related Repositories
22
+ - **Frontend**: `~/Developer/iheartsolana/dubs-jackpot-spa`
23
+ - **Solana Program**: `~/Developer/iheartsolana/dubs-solana-program`
24
+ - **dubs-api**: `~/Developer/iheartsolana/dubs-api` (legacy, being phased out)
25
+
26
+ ## Local Development Ports
27
+ - Frontend: 3000
28
+ - dubs-server: 3001
29
+ - dubs-api: 3003 (if needed)
30
+
31
+ ## Key Commands
32
+ ```bash
33
+ # Start server
34
+ npm run dev
35
+
36
+ # Run database migrations
37
+ npm run migrate
38
+
39
+ # Purge all data (development only)
40
+ ./scripts/purge-all-data.sh
41
+ ```
42
+
43
+ ## Environment
44
+ - `.env` - Local development config
45
+ - `LIVE_SCORES_API_URL` - Points to localhost:3001 (itself) for live scores
46
+ - `NODE_ENV=development` - Enables mock data in live scores
@@ -0,0 +1,155 @@
1
+ # Connect4 Production Deployment Strategy
2
+
3
+ ## Overview
4
+ This document outlines the safe deployment strategy for Connect4 to production.
5
+
6
+ ---
7
+
8
+ ## Pre-Deployment Checklist
9
+
10
+ ### 1. Database Migrations (Run BEFORE code deploy)
11
+ These columns must exist before the new code runs:
12
+
13
+ ```sql
14
+ -- Run on dubs-server-prod database
15
+ ALTER TABLE games ADD COLUMN IF NOT EXISTS resolved_at TIMESTAMP;
16
+ ALTER TABLE games ADD COLUMN IF NOT EXISTS claim_signature TEXT;
17
+ ```
18
+
19
+ Also run the notification migration:
20
+ ```bash
21
+ heroku pg:psql --app dubs-server-prod < migrations/005_add_connect4_your_turn_notification.sql
22
+ ```
23
+
24
+ ### 2. Verify Migrations Succeeded
25
+ ```sql
26
+ -- Check columns exist
27
+ SELECT column_name FROM information_schema.columns
28
+ WHERE table_name = 'games' AND column_name IN ('resolved_at', 'claim_signature');
29
+
30
+ -- Check notification type exists
31
+ SELECT * FROM pg_enum WHERE enumlabel = 'connect4_your_turn';
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Deployment Steps
37
+
38
+ ### Step 1: Backup (Optional but Recommended)
39
+ ```bash
40
+ heroku pg:backups:capture --app dubs-server-prod
41
+ ```
42
+
43
+ ### Step 2: Run Database Migrations
44
+ ```bash
45
+ # Connect to prod database
46
+ heroku pg:psql --app dubs-server-prod
47
+
48
+ # Run migrations (copy/paste each)
49
+ ALTER TABLE games ADD COLUMN IF NOT EXISTS resolved_at TIMESTAMP;
50
+ ALTER TABLE games ADD COLUMN IF NOT EXISTS claim_signature TEXT;
51
+ \q
52
+
53
+ # Run notification migration
54
+ heroku pg:psql --app dubs-server-prod < migrations/005_add_connect4_your_turn_notification.sql
55
+ ```
56
+
57
+ ### Step 3: Deploy Code
58
+ ```bash
59
+ # Ensure main branch is up to date
60
+ git checkout main
61
+ git pull origin main
62
+
63
+ # Deploy to production
64
+ git push heroku-prod main:main
65
+ ```
66
+
67
+ ### Step 4: Verify Deployment
68
+ ```bash
69
+ # Check app is running
70
+ heroku logs --tail --app dubs-server-prod
71
+
72
+ # Test health endpoint
73
+ curl https://dubs-server-prod.herokuapp.com/api/games/health
74
+
75
+ # Test Connect4 endpoints respond (should return auth error, not 500)
76
+ curl -X POST https://dubs-server-prod.herokuapp.com/api/connect4/claim \
77
+ -H "Content-Type: application/json" \
78
+ -d '{"gameId":"test"}'
79
+ # Expected: {"error":"Authentication required"} with status 401
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Rollback Plan
85
+
86
+ ### If Something Breaks:
87
+
88
+ **Option A: Quick Rollback (Code Only)**
89
+ ```bash
90
+ # Find previous working release
91
+ heroku releases --app dubs-server-prod
92
+
93
+ # Rollback to specific version
94
+ heroku rollback v[NUMBER] --app dubs-server-prod
95
+ ```
96
+
97
+ **Option B: Full Rollback (If DB Issues)**
98
+ ```bash
99
+ # Rollback code first
100
+ heroku rollback v[NUMBER] --app dubs-server-prod
101
+
102
+ # The new columns (resolved_at, claim_signature) are safe to leave
103
+ # They won't affect old code - old code just ignores them
104
+ ```
105
+
106
+ ---
107
+
108
+ ## What's Safe / What's Risky
109
+
110
+ ### Safe (Low Risk):
111
+ - New columns with `ADD COLUMN IF NOT EXISTS` - won't affect existing data
112
+ - New `/api/connect4/*` endpoints - completely separate from sports betting
113
+ - CORS changes - only adds headers, doesn't remove any
114
+
115
+ ### Medium Risk:
116
+ - Referral earnings integration - shares code with sports betting
117
+ - Notification system changes - shares notification infrastructure
118
+
119
+ ### Verification After Deploy:
120
+ 1. Create a sports bet - verify it still works
121
+ 2. Check referral earnings page loads
122
+ 3. Create a Connect4 game on production
123
+ 4. Have someone join and play through
124
+ 5. Verify claim works
125
+
126
+ ---
127
+
128
+ ## Monitoring
129
+
130
+ ### Watch For:
131
+ ```bash
132
+ # Monitor logs for errors
133
+ heroku logs --tail --app dubs-server-prod | grep -i "error\|503\|timeout"
134
+ ```
135
+
136
+ ### Key Metrics:
137
+ - No increase in 5xx errors
138
+ - Response times stay under 1s
139
+ - Database connections stable (watch for pool exhaustion)
140
+
141
+ ---
142
+
143
+ ## Timeline Recommendation
144
+
145
+ 1. **Off-peak hours**: Deploy during low traffic (early morning or late night)
146
+ 2. **Staged rollout**:
147
+ - Deploy to prod but don't announce Connect4 yet
148
+ - Test internally with a few users
149
+ - Once verified, announce feature
150
+
151
+ ---
152
+
153
+ ## Emergency Contacts
154
+ - Heroku Status: status.heroku.com
155
+ - Solana Status: status.solana.com
@@ -0,0 +1,171 @@
1
+ # Current Session - February 9, 2026
2
+
3
+ ## Session Focus: Developer API Playground UX Polish
4
+
5
+ Continued refining the **Developer Portal API Playground** — layout redesign, simulator improvements, response panel cleanup, and collapsible navigation.
6
+
7
+ ---
8
+
9
+ ## What's Done (Uncommitted, branch `panda`)
10
+
11
+ ### Developer Portal Playground (`dubs-jackpot-spa`)
12
+
13
+ **File: `app/developer/portal/apps/[appId]/page.tsx`**
14
+
15
+ #### Layout Refactor
16
+ - **Collapsible app navigation sidebar** — outer nav (`AppSidebar`) collapses from `w-72` to `w-16`, showing just icons with tooltips. Toggle button at bottom (PanelLeftClose/PanelLeft). Main content margin transitions smoothly.
17
+ - **3-column layout for create/join** — `[Sidebar] | [Preview w-380px] | [Request flex-1 | Response flex-1]`. Preview column appears between endpoint list and request/response panels for create/join endpoints only.
18
+ - **Simulator + List view toggle** — preview column header has "Simulator" (phone frame) and "List" (compact rows) views
19
+ - **Request + Response side by side** — always `lg:flex-row`, no more vertical stacking for create/join
20
+
21
+ #### Simulator Improvements
22
+ - **NHL games only in create simulator** — fetches `?type=sports&game=NHL&per_page=30` for simplicity
23
+ - **Create flow populates response panel** — `handleCreateFromPreview` and `handleJoinFromPreview` now call `setResponse()` at each API step, so the JSON response shows in the response panel just like the Send button
24
+ - **Send button reflects simulator status** — when create flow is active, Send button changes to show status ("Sent — Building transaction...", "Signing...", green "Sent" on success, red "Failed" on error)
25
+ - **Reset button** — refresh icon next to the status pill resets the entire create flow (selected event, team, wager, flow status, response panel)
26
+
27
+ #### Response Panel Cleanup
28
+ - **Removed iPhone preview from response panel entirely** — no more phone frame or Raw/Preview toggle in the response area
29
+ - **Always shows raw JSON** — response panel is just the `<pre>` block with syntax-colored JSON
30
+
31
+ #### Previous Session Work (still uncommitted)
32
+ - Past events filter fix (time-based filtering in `/v1/events/upcoming`)
33
+ - Create game preview with full Solana tx flow (pick event → create → sign → submit → confirm)
34
+ - iPhone preview enlarged (340x700)
35
+ - Error Codes glossary modal (API errors + Solana program errors)
36
+ - Removed Fetch widgets from request panel
37
+ - Preview column with Simulator/List toggle
38
+
39
+ ### Backend (`dubs-server`)
40
+ - **`routes/developerRoutes.js`** — `/v1/events/upcoming` now filters out past-start-time events even if upstream status is still "upcoming"
41
+
42
+ ---
43
+
44
+ ## Esports Betting (Previous Session — Still Uncommitted)
45
+
46
+ ### Backend (`dubs-server`)
47
+
48
+ | File | Status | Summary |
49
+ |---|---|---|
50
+ | `routes/esportsRoutes.js` | **NEW** (781 lines) | Full PandaScore proxy: leagues, matches, tournaments, videogame endpoints, `POST /games/validate`, `GET /games/upcoming`, `GET /games/pending` |
51
+ | `services/automaticGameOracle.js` | Modified (+352 lines) | `checkEsportsGameResult()` — PandaScore match resolution via `winner_id`. Esports-specific notification handlers. Oracle routes gameMode=5 to esports path. |
52
+ | `routes/gamesRoutes.js` | Modified | All `WHERE game_mode = 4` → `WHERE game_mode IN (4, 5)` |
53
+ | `server.js` | Modified | Mounts `/api/esports`, Socket.IO injection, startup banner |
54
+ | `env.template` | Modified | Added `PANDASCORE_API_KEY` |
55
+ | `PANDA.md` | **NEW** | PandaScore API reference doc |
56
+
57
+ ### Frontend (`dubs-jackpot-spa`)
58
+
59
+ | File | Status | Summary |
60
+ |---|---|---|
61
+ | `app/v2/features/esports/` | **NEW** (entire module) | 11 files — types, service, hooks, components, utils, barrel exports |
62
+ | `app/v2/components/AnimatedCSLabel.tsx` | **NEW** | Tab label with cycling CS emojis |
63
+ | `app/v2/page.tsx` | Modified | Added `counter-strike` tab |
64
+ | `BetCreationModal.tsx` | Modified | `esportsMatch` prop → routes to esportsBettingService |
65
+ | Multiple display components | Modified | CS2 display: home-first, no labels, cyan theme |
66
+
67
+ ---
68
+
69
+ ## Architecture
70
+
71
+ ```
72
+ Developer API Playground Layout:
73
+ [App Nav Sidebar (collapsible)] | [Endpoint List w-64] | [Preview w-380 (create/join only)] | [Request flex-1] | [Response flex-1]
74
+
75
+ Create Flow (Simulator):
76
+ 1. Simulator shows NHL events (phone frame or list view)
77
+ 2. User picks event → bottom sheet with team choice + wager
78
+ 3. Tap "Create Game" → handleCreateFromPreview:
79
+ a. POST /v1/games/create → response panel updates with JSON
80
+ b. Wallet sign prompt
81
+ c. Submit to Solana → confirm on-chain
82
+ d. POST /v1/games/confirm → response panel updates with final JSON
83
+ 4. Send button shows "Sent" (green), reset button available
84
+
85
+ Bet Placement (Main App):
86
+ CounterStrikeContent → BetCreationModal(esportsMatch) → esportsBettingService:
87
+ 1. POST /api/esports/games/validate → sportsEvent + lockTimestamp
88
+ 2. POST /api/v1/prod/transaction/build/create-and-join-automatic → unsigned tx
89
+ 3. User signs → Solana → poll confirmation
90
+ 4. POST /api/auth/games/save (gameMode=5) → DB
91
+
92
+ Game Resolution (Backend Oracle):
93
+ AutomaticGameOracle polls games WHERE game_mode IN (4, 5)
94
+ gameMode=5 → checkEsportsGameResult() via PandaScore winner_id
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Key Design Decisions
100
+
101
+ - **Collapsible outer nav** — icons-only mode saves ~256px horizontal space for playground
102
+ - **Preview as input, not output** — moved phone simulator from response panel to its own column (it's part of creating, not viewing responses)
103
+ - **NHL-only simulator** — keeps create demo focused; full league support available via Send button
104
+ - **Response panel always raw JSON** — removed all phone frame previews from response area
105
+ - **gameMode=5** — reuses existing game infra for esports, no new tables
106
+ - **PandaScore `winner_id`** — no fuzzy team name matching
107
+
108
+ ---
109
+
110
+ ## What's NOT Done / Known Gaps
111
+
112
+ 1. **Nothing committed** — all changes unstaged on branch `panda`
113
+ 2. **No Valorant tab** — backend supports it, frontend only has CS2
114
+ 3. **Stream links** — data fetched but not shown in UI
115
+ 4. **No tests** for esports oracle resolution path
116
+ 5. **Pre-existing TS error** — line 454 `'app' is possibly 'null'` in `handleToggleNetworkMode` (not from our changes)
117
+ 6. **Dead code cleanup** — `previewMode`, `previewGames`, `isPreviewable`, `isGamesListPreviewable` and `{false && ...}` phone frame blocks can be removed
118
+
119
+ ---
120
+
121
+ ## Previous Sessions
122
+
123
+ <details>
124
+ <summary>February 8 — Esports Betting (CS2 + Valorant)</summary>
125
+
126
+ - Full PandaScore integration (backend routes + oracle)
127
+ - CS2 frontend module (11 files)
128
+ - Developer API platform (webhooks, network mode, API playground, simulator)
129
+ - API spec document generation
130
+
131
+ </details>
132
+
133
+ <details>
134
+ <summary>February 3 — Survivor Pool (Phase 1+2)</summary>
135
+
136
+ - 5 new DB tables, controller, routes, oracle, simulator
137
+ - Solana: `distribute_survivor_winnings` deployed to devnet
138
+ - Phase 3 TODO: wire backend to Solana instruction, frontend UI
139
+
140
+ </details>
141
+
142
+ <details>
143
+ <summary>January 26 — Pari-Mutuel Fixes</summary>
144
+
145
+ - Recent Games P&L fix, LivePoolsWidget, refund calculation, formatSOL()
146
+
147
+ </details>
148
+
149
+ <details>
150
+ <summary>January 25 — Invite Links & Notifications</summary>
151
+
152
+ - Sports game invite routes, OG images, PlayersWidget, pari-mutuel notifications
153
+
154
+ </details>
155
+
156
+ <details>
157
+ <summary>Production Fixes & Scripts</summary>
158
+
159
+ - Connect4 fixes, branch sync, postponed game refund, authority-resolve script, Papertrail
160
+
161
+ </details>
162
+
163
+ ---
164
+
165
+ ## Environment Notes
166
+
167
+ - **Local .env uses devnet** — override SOLANA_RPC_URL for mainnet
168
+ - **Program ID**: `85wJGp9uc8w2FeKX9CEHsudTo1UVCrmuRFy37oCcaoG1`
169
+ - **Program Authority**: `57voP1Y8U4ztX2YAcHveK3JFvVRn1n6T6iUnHdAW6xr9`
170
+ - **Fee Structure**: 6% total (5% platform + 1% oracle)
171
+ - **PandaScore API Key**: in `.env` as `PANDASCORE_API_KEY`