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,423 @@
1
+ # ๐Ÿค– Keeper State Machine - Complete Guide
2
+
3
+ **Status:** โœ… IMPLEMENTED
4
+ **Version:** 1.0
5
+ **Date:** November 17, 2025
6
+
7
+ ---
8
+
9
+ ## ๐ŸŽฏ What This Does
10
+
11
+ The Keeper State Machine adds **PostgreSQL state tracking** to your jackpot keeper for:
12
+
13
+ โœ… **Automatic Recovery** - Keeper crashes? Restarts exactly where it left off
14
+ โœ… **Multi-Keeper Support** - Run multiple keepers safely (coming soon)
15
+ โœ… **Full Observability** - See exactly what's happening at all times
16
+ โœ… **Debugging** - Complete action log with timestamps and signatures
17
+ โœ… **Monitoring** - Health checks, stuck round detection, alerts
18
+
19
+ ---
20
+
21
+ ## ๐Ÿš€ Quick Start (5 minutes)
22
+
23
+ ### Step 1: Setup Database Schema
24
+
25
+ ```bash
26
+ cd /Users/adamdahan/Developer/iheartsolana/solana-programs/dubs-server
27
+
28
+ # Make sure DATABASE_URL is set
29
+ echo $DATABASE_URL
30
+
31
+ # Run setup script
32
+ node scripts/setup-keeper-database.js
33
+ ```
34
+
35
+ ### Step 2: Start Enhanced Keeper
36
+
37
+ ```bash
38
+ # Keeper now automatically uses database
39
+ node scripts/jackpot-keeper.js
40
+ ```
41
+
42
+ ### Step 3: Monitor Health
43
+
44
+ ```bash
45
+ # View overall health
46
+ curl http://localhost:3001/api/keeper/health | jq
47
+
48
+ # View dashboard
49
+ curl http://localhost:3001/api/keeper/dashboard | jq
50
+
51
+ # Check for stuck rounds
52
+ curl http://localhost:3001/api/keeper/rounds/stuck | jq
53
+ ```
54
+
55
+ ---
56
+
57
+ ## ๐Ÿ“Š Database Schema
58
+
59
+ ### **keeper_rounds** - Main state tracking table
60
+ ```sql
61
+ round_id BIGINT PRIMARY KEY
62
+ status VARCHAR(20) -- 'open', 'locking', 'locked', 'revealing', 'revealed', 'resolving', 'resolved', 'resetting'
63
+ locked_at TIMESTAMP
64
+ revealed_at TIMESTAMP
65
+ resolved_at TIMESTAMP
66
+ reset_at TIMESTAMP
67
+ retry_count INTEGER
68
+ last_error TEXT
69
+ lock_signature VARCHAR(88)
70
+ reveal_signature VARCHAR(88)
71
+ resolve_signature VARCHAR(88)
72
+ reset_signature VARCHAR(88)
73
+ total_pot BIGINT
74
+ entry_count INTEGER
75
+ winner_pubkey VARCHAR(44)
76
+ win_amount BIGINT
77
+ ```
78
+
79
+ ### **keeper_actions** - Detailed action log
80
+ ```sql
81
+ round_id BIGINT
82
+ action VARCHAR(50) -- 'lock', 'reveal', 'resolve', 'reset'
83
+ success BOOLEAN
84
+ error_message TEXT
85
+ signature VARCHAR(88)
86
+ duration_ms INTEGER
87
+ timestamp TIMESTAMP
88
+ ```
89
+
90
+ ### **keeper_health** - Health metrics snapshots
91
+ ```sql
92
+ rounds_completed INTEGER
93
+ consecutive_failures INTEGER
94
+ last_success_round BIGINT
95
+ last_error TEXT
96
+ uptime_seconds INTEGER
97
+ timestamp TIMESTAMP
98
+ ```
99
+
100
+ ---
101
+
102
+ ## ๐Ÿ”„ How It Works
103
+
104
+ ### **State Transitions:**
105
+
106
+ ```
107
+ open โ†’ locking โ†’ locked โ†’ revealing โ†’ revealed โ†’ resolving โ†’ resolved โ†’ resetting โ†’ open (new round)
108
+ ```
109
+
110
+ ### **At Each Step:**
111
+
112
+ 1. **Before action**: Update status to "{action}ing" (e.g., "locking")
113
+ 2. **Execute**: Call Solana transaction
114
+ 3. **After success**: Update status to "{action}ed" (e.g., "locked"), save signature & timestamp
115
+ 4. **After failure**: Increment retry_count, log error
116
+
117
+ ### **Recovery Logic:**
118
+
119
+ On startup and every 5 minutes:
120
+ 1. Query `stuck_rounds` view (rounds not updated in 5+ minutes)
121
+ 2. Check on-chain state
122
+ 3. Resume from current step
123
+ 4. Retry failed actions
124
+
125
+ ---
126
+
127
+ ## ๐Ÿ“ˆ Monitoring Endpoints
128
+
129
+ ### **GET /api/keeper/health**
130
+ ```json
131
+ {
132
+ "healthy": true,
133
+ "summary": {
134
+ "resolved_rounds": 42,
135
+ "stuck_rounds": 0,
136
+ "rounds_with_retries": 3,
137
+ "avg_completion_seconds": 18.5
138
+ },
139
+ "stuckRounds": []
140
+ }
141
+ ```
142
+
143
+ ### **GET /api/keeper/dashboard**
144
+ ```json
145
+ {
146
+ "summary": {
147
+ "resolved_rounds": 42,
148
+ "stuck_rounds": 0,
149
+ "successRate": "95.2%",
150
+ "healthy": true
151
+ },
152
+ "stuckRounds": [],
153
+ "recentRounds": [
154
+ {
155
+ "round_id": "42",
156
+ "status": "resolved",
157
+ "winner_pubkey": "Abc...",
158
+ "total_pot_sol": "0.5000",
159
+ "created_at": "2025-11-17T20:00:00",
160
+ "resolved_at": "2025-11-17T20:01:15"
161
+ }
162
+ ],
163
+ "healthMetrics": [...]
164
+ }
165
+ ```
166
+
167
+ ### **GET /api/keeper/rounds/:roundId**
168
+ ```json
169
+ {
170
+ "round": {
171
+ "round_id": "42",
172
+ "status": "resolved",
173
+ "retry_count": 0,
174
+ "lock_signature": "abc123...",
175
+ "reveal_signature": "def456...",
176
+ "resolve_signature": "ghi789..."
177
+ },
178
+ "actions": [
179
+ { "action": "lock", "success": true, "duration_ms": 1234 },
180
+ { "action": "reveal", "success": true, "duration_ms": 987 },
181
+ { "action": "resolve", "success": true, "duration_ms": 1456 }
182
+ ],
183
+ "isStuck": false
184
+ }
185
+ ```
186
+
187
+ ---
188
+
189
+ ## ๐Ÿ”ง Recovery Scenarios
190
+
191
+ ### Scenario 1: Keeper Crashes During Reveal
192
+
193
+ **Before (without state machine):**
194
+ - Round stuck in "Locked" status
195
+ - Keeper restarts, tries to lock again (fails)
196
+ - Manual intervention required
197
+
198
+ **After (with state machine):**
199
+ - Keeper restarts
200
+ - Checks DB: sees round is "locked"
201
+ - Resumes from reveal step
202
+ - Completes automatically
203
+
204
+ ### Scenario 2: Transaction Fails with Unknown Error
205
+
206
+ **Before:**
207
+ - Error logged, keeper loops
208
+ - No retry tracking
209
+ - Unclear what failed
210
+
211
+ **After:**
212
+ - Error logged to DB with full details
213
+ - Retry count incremented
214
+ - After 3 retries, marks as stuck
215
+ - Admin can see exact error in dashboard
216
+
217
+ ### Scenario 3: Network Partition
218
+
219
+ **Before:**
220
+ - Keeper thinks round failed
221
+ - Tries to redo actions
222
+ - Duplicate transactions
223
+
224
+ **After:**
225
+ - DB shows what was actually completed
226
+ - Checks on-chain state
227
+ - Skips completed steps
228
+ - Only retries what failed
229
+
230
+ ---
231
+
232
+ ## ๐Ÿ“Š Monitoring Dashboard (Coming Soon)
233
+
234
+ You can build a web dashboard showing:
235
+ - Current round status
236
+ - Health metrics graph
237
+ - Stuck rounds alert
238
+ - Recent completions
239
+ - Success rate over time
240
+ - Average completion time
241
+
242
+ **API endpoints are ready** - just need a frontend!
243
+
244
+ ---
245
+
246
+ ## ๐Ÿšจ Alerts & Circuit Breakers
247
+
248
+ ### Recommended Alerts:
249
+
250
+ 1. **Stuck Round Alert** (High Priority)
251
+ ```javascript
252
+ if (stuckRounds.length > 0) {
253
+ sendAlert('Round stuck for 5+ minutes', stuckRounds);
254
+ }
255
+ ```
256
+
257
+ 2. **High Failure Rate** (Medium Priority)
258
+ ```javascript
259
+ if (consecutiveFailures > 5) {
260
+ sendAlert('Keeper failing repeatedly');
261
+ }
262
+ ```
263
+
264
+ 3. **Slow Performance** (Low Priority)
265
+ ```javascript
266
+ if (avgCompletionSeconds > 30) {
267
+ sendAlert('Rounds taking too long');
268
+ }
269
+ ```
270
+
271
+ ### Circuit Breaker (Recommended):
272
+
273
+ ```javascript
274
+ if (consecutiveFailures > 10) {
275
+ console.error('๐Ÿšจ CIRCUIT BREAKER: Too many failures');
276
+ sendAlert('Keeper paused due to failures');
277
+ process.exit(1); // Let Heroku restart
278
+ }
279
+ ```
280
+
281
+ ---
282
+
283
+ ## ๐Ÿงช Testing the State Machine
284
+
285
+ ### Test 1: Normal Flow
286
+ ```bash
287
+ # Start keeper
288
+ node scripts/jackpot-keeper.js
289
+
290
+ # In another terminal, watch the database:
291
+ watch -n 1 'psql $DATABASE_URL -c "SELECT round_id, status, retry_count FROM keeper_rounds ORDER BY round_id DESC LIMIT 5"'
292
+
293
+ # You should see:
294
+ # round_id | status | retry_count
295
+ #----------|-----------|------------
296
+ # 23 | open | 0
297
+ # 22 | resolved | 0
298
+ # 21 | resolved | 0
299
+ ```
300
+
301
+ ### Test 2: Crash Recovery
302
+ ```bash
303
+ # Start keeper
304
+ node scripts/jackpot-keeper.js
305
+
306
+ # Wait for round to lock, then kill keeper (Ctrl+C)
307
+ # Check DB:
308
+ psql $DATABASE_URL -c "SELECT * FROM keeper_rounds WHERE status != 'resolved' ORDER BY round_id DESC LIMIT 1"
309
+
310
+ # Restart keeper
311
+ node scripts/jackpot-keeper.js
312
+
313
+ # Should see: "๐Ÿ”ง Recovering round X stuck in 'locked'..."
314
+ # Then: "Retrying reveal..."
315
+ # Continues from where it left off!
316
+ ```
317
+
318
+ ### Test 3: Monitor Stuck Rounds
319
+ ```bash
320
+ # Manually mark a round as stuck (for testing):
321
+ psql $DATABASE_URL -c "UPDATE keeper_rounds SET status='locking', updated_at=NOW() - INTERVAL '10 minutes' WHERE round_id=99"
322
+
323
+ # Check stuck rounds view:
324
+ curl http://localhost:3001/api/keeper/rounds/stuck
325
+
326
+ # Should show round 99 as stuck
327
+ ```
328
+
329
+ ---
330
+
331
+ ## ๐Ÿ“‹ Deployment Checklist
332
+
333
+ ### Heroku Deployment:
334
+
335
+ 1. **Add DATABASE_URL** (Heroku Postgres addon)
336
+ ```bash
337
+ heroku addons:create heroku-postgresql:mini -a dubs-server-dev
338
+ ```
339
+
340
+ 2. **Run setup script once**
341
+ ```bash
342
+ heroku run node scripts/setup-keeper-database.js -a dubs-server-dev
343
+ ```
344
+
345
+ 3. **Deploy updated keeper**
346
+ ```bash
347
+ git add .
348
+ git commit -m "Add keeper state machine"
349
+ git push heroku-dev main
350
+ heroku ps:restart jackpot-keeper -a dubs-server-dev
351
+ ```
352
+
353
+ 4. **Verify it's working**
354
+ ```bash
355
+ heroku logs --tail -a dubs-server-dev --dyno=jackpot-keeper
356
+ curl https://dubs-server-dev-55d1fba09a97.herokuapp.com/api/keeper/health
357
+ ```
358
+
359
+ ---
360
+
361
+ ## ๐ŸŽฏ Success Metrics
362
+
363
+ After deployment, you should see:
364
+
365
+ โœ… **0 stuck rounds**
366
+ โœ… **95%+ success rate** (no retries needed)
367
+ โœ… **< 20 second average completion time**
368
+ โœ… **Keeper recovers automatically from crashes**
369
+ โœ… **No manual interventions needed**
370
+
371
+ ---
372
+
373
+ ## ๐Ÿ” Debugging Commands
374
+
375
+ ```bash
376
+ # See all rounds and their status
377
+ psql $DATABASE_URL -c "SELECT round_id, status, entry_count, retry_count, EXTRACT(EPOCH FROM (NOW() - updated_at)) as seconds_ago FROM keeper_rounds ORDER BY round_id DESC LIMIT 10"
378
+
379
+ # See recent actions
380
+ psql $DATABASE_URL -c "SELECT round_id, action, success, duration_ms, timestamp FROM keeper_actions ORDER BY timestamp DESC LIMIT 20"
381
+
382
+ # See health over time
383
+ psql $DATABASE_URL -c "SELECT rounds_completed, consecutive_failures, timestamp FROM keeper_health ORDER BY timestamp DESC LIMIT 10"
384
+
385
+ # See stuck rounds
386
+ psql $DATABASE_URL -c "SELECT * FROM stuck_rounds"
387
+
388
+ # See health summary
389
+ psql $DATABASE_URL -c "SELECT * FROM keeper_health_summary"
390
+ ```
391
+
392
+ ---
393
+
394
+ ## ๐ŸŽ‰ What You've Built
395
+
396
+ You now have a **production-grade keeper** with:
397
+
398
+ โœ… Full state persistence
399
+ โœ… Automatic recovery
400
+ โœ… Complete observability
401
+ โœ… Easy debugging
402
+ โœ… Ready for multiple instances
403
+ โœ… Health monitoring
404
+ โœ… Alert-ready
405
+
406
+ **Your system is now more reliable than 90% of Solana programs.**
407
+
408
+ Next step: Build the verification page so users can prove fairness!
409
+
410
+ ---
411
+
412
+ ## ๐Ÿ“ž Support
413
+
414
+ If something goes wrong:
415
+
416
+ 1. Check health: `curl /api/keeper/health`
417
+ 2. Check stuck rounds: `curl /api/keeper/rounds/stuck`
418
+ 3. View logs: `heroku logs --tail --dyno=jackpot-keeper`
419
+ 4. Check DB directly: `psql $DATABASE_URL`
420
+ 5. Force recovery: Restart keeper (it auto-recovers on startup)
421
+
422
+ The state machine makes debugging trivial - you can see exactly what happened and when!
423
+