dubs-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +280 -0
- package/CLAUDE.md +46 -0
- package/CONNECT4_PRODUCTION_DEPLOY.md +155 -0
- package/CURRENT_SESSION.md +171 -0
- package/CURRENT_SESSION_DRAW.md +516 -0
- package/MARCH_MADNESS_SURVIVOR.md +254 -0
- package/PANDA.md +166 -0
- package/Procfile +4 -0
- package/README.md +476 -0
- package/controllers/livescoresController.js +376 -0
- package/controllers/pickemController.js +554 -0
- package/controllers/survivorAdminController.js +887 -0
- package/controllers/survivorController.js +623 -0
- package/cron/oracleMonitor.js +77 -0
- package/cron/pickemOracleMonitor.js +73 -0
- package/data/jackpot-history.json +952 -0
- package/data/ncaaTeams.js +406 -0
- package/documentation/API_SECURITY_GUIDE.md +327 -0
- package/documentation/ARCADE_API.md +593 -0
- package/documentation/ARCADE_IMPLEMENTATION_SUMMARY.md +399 -0
- package/documentation/ARCADE_QUICKSTART.md +242 -0
- package/documentation/AUTOMATIC_MODE_ORACLE.md +321 -0
- package/documentation/BUG_FIX_COHORT_DATE_DISPLAY.md +171 -0
- package/documentation/CLAIM_MIGRATION_INSTRUCTIONS.md +52 -0
- package/documentation/CLAIM_STATUS_FIX.md +67 -0
- package/documentation/CLI_TOOL_GUIDE.md +372 -0
- package/documentation/COHORT_RETENTION_ANALYSIS.md +295 -0
- package/documentation/COHORT_RETENTION_IMPLEMENTATION_COMPLETE.md +461 -0
- package/documentation/COHORT_RETENTION_SUMMARY.md +204 -0
- package/documentation/COMPLETE_PROJECT_SUMMARY.md +490 -0
- package/documentation/DATABASE_QUERIES.md +269 -0
- package/documentation/DATABASE_RETENTION_POLICY.md +390 -0
- package/documentation/DATABASE_SETUP_GUIDE.md +361 -0
- package/documentation/DATABASE_SETUP_SUMMARY.md +247 -0
- package/documentation/DEMO_API_CURL_COMMANDS.md +656 -0
- package/documentation/DEPLOYMENT_SUMMARY.txt +100 -0
- package/documentation/DUPLICATE_NOTIFICATIONS_FIXED.md +201 -0
- package/documentation/EXCHANGE_RATES_INTEGRATION.md +371 -0
- package/documentation/FINAL_API_PROTECTION_TABLE.md +175 -0
- package/documentation/GAME_START_NOTIFICATIONS_DEPLOYMENT.md +256 -0
- package/documentation/GAME_START_NOTIFICATIONS_INTEGRATION.md +275 -0
- package/documentation/HEROKU_DEPLOYMENT.md +134 -0
- package/documentation/HEROKU_SCHEDULER_SETUP.md +271 -0
- package/documentation/JACKPOT_API.md +521 -0
- package/documentation/JACKPOT_DEPLOYMENT_GUIDE.md +362 -0
- package/documentation/JWT_IMPLEMENTATION_SUMMARY.md +373 -0
- package/documentation/JWT_QUICK_SETUP.md +268 -0
- package/documentation/JWT_TESTING_GUIDE.md +404 -0
- package/documentation/KEEPER_RECOVERY_GUIDE.md +381 -0
- package/documentation/KEEPER_SETUP.md +206 -0
- package/documentation/KEEPER_STATE_MACHINE.md +423 -0
- package/documentation/LATEST_PRODUCTION_SETUP.md +387 -0
- package/documentation/LOCAL_VOTING_TEST.md +279 -0
- package/documentation/ORACLE_FIXES_SUMMARY.md +188 -0
- package/documentation/ORACLE_POSTGRESQL_UPDATE.md +202 -0
- package/documentation/PAYMENT_DEPLOYMENT.md +209 -0
- package/documentation/PNL_TRACKING_SETUP.md +189 -0
- package/documentation/PREVENTING_LOCKUP_ERRORS.md +472 -0
- package/documentation/PRODUCTION_READY_SUMMARY.md +227 -0
- package/documentation/PUBLIC_VS_PRIVATE_ENDPOINTS.md +278 -0
- package/documentation/QUICK_AUTH_SETUP.md +99 -0
- package/documentation/QUICK_DEPLOY.md +224 -0
- package/documentation/QUICK_FIX.md +114 -0
- package/documentation/QUICK_START.md +152 -0
- package/documentation/REFEREE_MODE_GUIDE.md +392 -0
- package/documentation/RETENTION_CORE_ACTION_UPDATE.md +313 -0
- package/documentation/RETENTION_UPDATE_SUMMARY.md +108 -0
- package/documentation/RUN_MIGRATION_NOW.md +39 -0
- package/documentation/SCRIPTS_UPDATE_SUMMARY.md +251 -0
- package/documentation/SETUP_GUIDE.md +184 -0
- package/documentation/STATE_MACHINE_IMPLEMENTATION.md +250 -0
- package/documentation/TELEGRAM_NOTIFICATIONS_DIAGNOSIS.md +361 -0
- package/documentation/UNIFIED_ARCHITECTURE.md +231 -0
- package/documentation/VOTING_DEPLOYMENT_SUMMARY.md +392 -0
- package/documentation/WEBSOCKET_ARCHITECTURE.md +881 -0
- package/documentation/WHAT_WE_BUILT_TODAY.md +369 -0
- package/documentation/latest/LATEST_PRODUCTION_SETUP.md +865 -0
- package/ecosystem.config.js +65 -0
- package/env.template +125 -0
- package/middleware/apiKeyAuth.js +136 -0
- package/middleware/authenticate.js +214 -0
- package/middleware/developerUserAuth.js +76 -0
- package/middleware/socketAuth.js +69 -0
- package/package.json +49 -0
- package/postman/Dubs-API-v1-With-Voting.postman_collection.json +555 -0
- package/postman/Dubs-API-v1.postman_collection.json +205 -0
- package/postman/Dubs_Developer_API.postman_collection.json +662 -0
- package/postman/QUICKSTART.md +118 -0
- package/postman/QUICK_REFERENCE.md +246 -0
- package/postman/README.md +71 -0
- package/postman/VOTING_API_GUIDE.md +426 -0
- package/refactor/Animations.md +148 -0
- package/refactor/Chat.md +252 -0
- package/routes/actionsRoutes.js +699 -0
- package/routes/adminRoutes.js +370 -0
- package/routes/analyticsRoutes.js +1262 -0
- package/routes/arcadeRoutes.js +557 -0
- package/routes/authRoutes.js +2310 -0
- package/routes/avatarRoutes.js +85 -0
- package/routes/botRoutes.js +211 -0
- package/routes/chatRoutes.js +377 -0
- package/routes/cryptoPriceRoutes.js +105 -0
- package/routes/developerRoutes.js +4201 -0
- package/routes/deviceRoutes.js +214 -0
- package/routes/dmRoutes.js +167 -0
- package/routes/esportsRoutes.js +806 -0
- package/routes/exchangeRateRoutes.js +233 -0
- package/routes/gamesRoutes.js +3028 -0
- package/routes/jackpotRoutes.js +754 -0
- package/routes/keeperMonitoringRoutes.js +156 -0
- package/routes/keeperWebhookRoutes.js +466 -0
- package/routes/livescoresRoutes.js +31 -0
- package/routes/pickemAdminRoutes.js +199 -0
- package/routes/pickemRoutes.js +231 -0
- package/routes/playerStatsRoutes.js +147 -0
- package/routes/portfolioRoutes.js +217 -0
- package/routes/promoRoutes.js +418 -0
- package/routes/referralEarningsRoutes.js +392 -0
- package/routes/socialRoutes.js +459 -0
- package/routes/sportsRoutes.js +1271 -0
- package/routes/survivorAdminRoutes.js +345 -0
- package/routes/survivorRoutes.js +756 -0
- package/routes/uploadRoutes.js +256 -0
- package/routes/userProfileRoutes.js +244 -0
- package/routes/whatsNewRoutes.js +331 -0
- package/scripts/.claude/settings.local.json +15 -0
- package/scripts/README.md +170 -0
- package/scripts/RESTART_EVERYTHING.sh +104 -0
- package/scripts/add-claim-columns.sql +48 -0
- package/scripts/add-crypto-prices-cache.sql +27 -0
- package/scripts/add-exchange-rates-cache.sql +40 -0
- package/scripts/add-game-invite-column.sql +23 -0
- package/scripts/add-game-invite-notification.sql +33 -0
- package/scripts/add-game-invite-telegram-pref.sql +16 -0
- package/scripts/add-game-joined-notification.sql +16 -0
- package/scripts/add-game-joined-pref.js +40 -0
- package/scripts/add-game-joined-preference.sql +6 -0
- package/scripts/add-game-start-notifications.sql +41 -0
- package/scripts/add-notification-flags-to-games.sql +55 -0
- package/scripts/add-pending-game-dismissals.sql +19 -0
- package/scripts/add-preferred-currency.sql +34 -0
- package/scripts/add-winner-columns.js +61 -0
- package/scripts/add_mention_system.sql +53 -0
- package/scripts/add_payment_system.sql +96 -0
- package/scripts/add_sports_event_id_column.sql +22 -0
- package/scripts/analyze-cohort-data-heroku.js +276 -0
- package/scripts/analyze-cohort-data.js +295 -0
- package/scripts/analyze-prod-cohorts.sh +10 -0
- package/scripts/backfill-matchup-images.js +245 -0
- package/scripts/backfill-missing-signatures.js +175 -0
- package/scripts/backfill-referral-earnings.js +202 -0
- package/scripts/check-chat-schema.js +130 -0
- package/scripts/check-db.sh +14 -0
- package/scripts/check_oracle_in_game.js +54 -0
- package/scripts/cleanup-database.js +193 -0
- package/scripts/clear-notification-cache.js +85 -0
- package/scripts/convert-mnemonic.js +50 -0
- package/scripts/create-users-table.sql +44 -0
- package/scripts/debug-cohort-counts.js +248 -0
- package/scripts/debug-winner-calc.js +84 -0
- package/scripts/deploy-payment-system.sh +118 -0
- package/scripts/deploy-to-heroku.sh +63 -0
- package/scripts/diagnose-locked-round.js +143 -0
- package/scripts/dubs-cli.js +720 -0
- package/scripts/dump-account.js +65 -0
- package/scripts/find-vrf-offset.js +48 -0
- package/scripts/fix-chat-notifications-constraint.sql +122 -0
- package/scripts/fix-claim-columns.js +124 -0
- package/scripts/fix-constraint-now.js +44 -0
- package/scripts/fix-lock-timestamps.js +96 -0
- package/scripts/fix-locked-round.sh +126 -0
- package/scripts/fix-missing-badges.sql +91 -0
- package/scripts/fix-payment-notifications.sql +41 -0
- package/scripts/force-new-round.js +55 -0
- package/scripts/force-resolve-and-claim.js +278 -0
- package/scripts/important/README.md +115 -0
- package/scripts/important/authority-force-lock.js +197 -0
- package/scripts/important/authority-resolve-game.js +267 -0
- package/scripts/important/check-game-status.js +373 -0
- package/scripts/important/list-pending-games-by-version.js +270 -0
- package/scripts/important/reconcile-v1-v2-payouts.js +270 -0
- package/scripts/initialize-jackpot.js +111 -0
- package/scripts/jackpot/.claude/settings.local.json +10 -0
- package/scripts/jackpot/force-reset.js +84 -0
- package/scripts/jackpot/initialize-mainnet.js +100 -0
- package/scripts/jackpot/keeper.js +742 -0
- package/scripts/jackpot/status.js +107 -0
- package/scripts/jackpot/update-round-duration.js +143 -0
- package/scripts/keeper-bot.js +112 -0
- package/scripts/list-pending-games.js +131 -0
- package/scripts/migrate-chat-v2.js +127 -0
- package/scripts/migrate-chat-winners.js +84 -0
- package/scripts/migrate-chat.sh +17 -0
- package/scripts/migrate-game-invite.js +83 -0
- package/scripts/migrate-heroku-game-notifications.sh +159 -0
- package/scripts/migrations/001_analytics_tables.sql +422 -0
- package/scripts/migrations/002_add_matchup_image_url.sql +14 -0
- package/scripts/migrations/003_referral_earnings.sql +208 -0
- package/scripts/migrations/004_add_whats_new_notification_type.sql +62 -0
- package/scripts/migrations/005_add_connect4_your_turn_notification.sql +61 -0
- package/scripts/migrations/005_push_notifications.sql +55 -0
- package/scripts/migrations/006_add_draw_team_players.sql +28 -0
- package/scripts/migrations/006_add_game_cancelled_notification.sql +62 -0
- package/scripts/migrations/007_add_gif_url.sql +8 -0
- package/scripts/migrations/008_add_connect4_columns.sql +139 -0
- package/scripts/migrations/008_add_pool_tracking.sql +22 -0
- package/scripts/migrations/009_create_survivor_pool_tables.sql +174 -0
- package/scripts/migrations/010_add_survivor_pool_outcome.sql +28 -0
- package/scripts/migrations/011_create_developer_tables.sql +67 -0
- package/scripts/migrations/011_fix_keeper_tables.sql +85 -0
- package/scripts/migrations/012_create_developer_webhooks.sql +31 -0
- package/scripts/migrations/013_add_network_mode.sql +18 -0
- package/scripts/migrations/014_create_developer_app_users.sql +19 -0
- package/scripts/migrations/015_add_ui_config.sql +4 -0
- package/scripts/migrations/016_add_resolution_secret.sql +4 -0
- package/scripts/migrations/017_add_external_game_id.sql +3 -0
- package/scripts/migrations/018_create_pickem_tables.sql +115 -0
- package/scripts/migrations/019_expo_push_tokens.sql +19 -0
- package/scripts/migrations/create_whats_new_tables.sql +88 -0
- package/scripts/migrations/drop_live_games_tables.sql +34 -0
- package/scripts/open-jackpot-round.js +85 -0
- package/scripts/purge-all-data.sh +329 -0
- package/scripts/purge-all-data.sql +142 -0
- package/scripts/purge-heroku-data.sh +149 -0
- package/scripts/purge-heroku-data.sql +62 -0
- package/scripts/rebuild-heroku-database.sh +113 -0
- package/scripts/recover-funds.js +357 -0
- package/scripts/regenerate-epl-images.js +278 -0
- package/scripts/resize-s3-matchup-images.js +374 -0
- package/scripts/resolve-direct.js +88 -0
- package/scripts/resolve-mock-game.js +124 -0
- package/scripts/resolve-pickem-game.js +55 -0
- package/scripts/resolve-round-manual.js +83 -0
- package/scripts/resolve-stuck-game.js +382 -0
- package/scripts/resolve-stuck-round.js +42 -0
- package/scripts/run-connect4-migration.sh +16 -0
- package/scripts/run-mention-migration.sh +32 -0
- package/scripts/run-payment-migration.sh +51 -0
- package/scripts/run-preferred-currency-migration.sh +31 -0
- package/scripts/run-referral-earnings-migration.sh +32 -0
- package/scripts/run-survivor-outcome-migration.sh +16 -0
- package/scripts/seed-test-users.js +346 -0
- package/scripts/setup-auth-tables.js +78 -0
- package/scripts/setup-complete-database.sql +992 -0
- package/scripts/setup-database-fresh.sh +359 -0
- package/scripts/setup-heroku-keeper.sh +48 -0
- package/scripts/setup-keeper-database.js +83 -0
- package/scripts/setup-keeper-state-db.sql +110 -0
- package/scripts/setup-oracle.sh +39 -0
- package/scripts/setup-pnl-tracking.js +111 -0
- package/scripts/start-devnet.sh +14 -0
- package/scripts/test-arcade-devnet.sh +160 -0
- package/scripts/test-arcade-match.sh +109 -0
- package/scripts/test-automatic-mode.sh +239 -0
- package/scripts/test-connect4-cancel-claim.js +370 -0
- package/scripts/test-connect4-e2e.js +369 -0
- package/scripts/test-connect4-resolve.js +369 -0
- package/scripts/test-game-state-endpoint.js +136 -0
- package/scripts/test-invite-notification.js +86 -0
- package/scripts/test-jackpot-api.sh +71 -0
- package/scripts/test-poll-confirmation.js +267 -0
- package/scripts/test-resolve-game.js +271 -0
- package/scripts/test-resolve-signature.js +223 -0
- package/scripts/test-signature-preservation.js +124 -0
- package/scripts/test-state-machine.js +291 -0
- package/scripts/test-webhook-receiver.js +60 -0
- package/scripts/update-notification-constraint.js +52 -0
- package/scripts/verify-account-layout.js +145 -0
- package/scripts/verify-winner-algorithm.js +278 -0
- package/server.js +5259 -0
- package/services/arcadeMatchService.js +763 -0
- package/services/automaticGameOracle.js +1596 -0
- package/services/chatService.js +1612 -0
- package/services/connect4GameService.js +1049 -0
- package/services/connect4NotificationService.js +374 -0
- package/services/cryptoPriceService.js +223 -0
- package/services/customGameResolver.js +260 -0
- package/services/db.js +79 -0
- package/services/directMessageService.js +389 -0
- package/services/discordNotifications.js +160 -0
- package/services/exchangeRateService.js +289 -0
- package/services/expoPushService.js +314 -0
- package/services/gamesCacheService.js +539 -0
- package/services/jackpotHistory.js +331 -0
- package/services/jackpotService.js +856 -0
- package/services/keeperStateService.js +355 -0
- package/services/matchupImageService.js +591 -0
- package/services/notificationCacheService.js +407 -0
- package/services/pickemOracle.js +440 -0
- package/services/playerStatsService.js +389 -0
- package/services/portfolioService.js +555 -0
- package/services/promoService.js +757 -0
- package/services/promoTreasuryService.js +239 -0
- package/services/pushNotifications.js +353 -0
- package/services/redisService.js +422 -0
- package/services/referralEarningsService.js +728 -0
- package/services/s3Service.js +396 -0
- package/services/socialService.js +1202 -0
- package/services/survivorOracle.js +469 -0
- package/services/survivorSimulator.js +475 -0
- package/services/telegramNotifications.js +461 -0
- package/services/userProfileStatsService.js +1185 -0
- package/services/whatsNewService.js +388 -0
- package/utils/urlHelper.js +95 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# March Madness Survivor Pool - Development Notes
|
|
2
|
+
|
|
3
|
+
**Last Updated:** February 4, 2026 (Late night session - bracket connectors complete!)
|
|
4
|
+
**Status:** In Development (Core features working)
|
|
5
|
+
|
|
6
|
+
## Feature Flag
|
|
7
|
+
|
|
8
|
+
In `dubs-jackpot-spa/app/v2/page.tsx`:
|
|
9
|
+
```javascript
|
|
10
|
+
const ENABLE_MARCH_MADNESS = true; // Set to false to hide tab
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
A "Survive or Die" pool where:
|
|
18
|
+
- Users pay **once** to join (SOL entry fee)
|
|
19
|
+
- Pick **ONE team per round** to win
|
|
20
|
+
- If your team **loses** → you're **eliminated**
|
|
21
|
+
- **Last survivors split the pot**
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## What's Been Built
|
|
26
|
+
|
|
27
|
+
### Backend (dubs-server)
|
|
28
|
+
|
|
29
|
+
| File | Purpose |
|
|
30
|
+
|------|---------|
|
|
31
|
+
| `routes/survivorRoutes.js` | All API endpoints for survivor pools |
|
|
32
|
+
| `controllers/survivorController.js` | Business logic (create pool, join, pick, resolve) |
|
|
33
|
+
| `services/survivorSimulator.js` | Dev testing - mock teams, simulate rounds |
|
|
34
|
+
| `services/survivorOracle.js` | Production - fetch ESPN results, resolve picks |
|
|
35
|
+
|
|
36
|
+
### Frontend (dubs-jackpot-spa)
|
|
37
|
+
|
|
38
|
+
| File | Purpose |
|
|
39
|
+
|------|---------|
|
|
40
|
+
| `app/v2/features/survivor/components/SurvivorTabContent.tsx` | Main UI - pools list, pool detail, picks |
|
|
41
|
+
| `app/v2/features/survivor/components/bracket/BracketView.tsx` | Full tournament bracket visualization |
|
|
42
|
+
| `app/v2/features/survivor/components/bracket/BracketRegion.tsx` | Single region (16 teams → Elite 8) |
|
|
43
|
+
| `app/v2/features/survivor/components/bracket/BracketMatchup.tsx` | Single game slot (2 teams) |
|
|
44
|
+
| `app/v2/features/survivor/services/survivorService.ts` | API client for survivor endpoints |
|
|
45
|
+
| `app/v2/features/survivor/types/survivor-types.ts` | TypeScript interfaces |
|
|
46
|
+
|
|
47
|
+
### Database Tables
|
|
48
|
+
|
|
49
|
+
```sql
|
|
50
|
+
survivor_pools -- Pool settings (buy-in, current round, status)
|
|
51
|
+
survivor_entries -- User entries (is_alive, eliminated_at_round)
|
|
52
|
+
survivor_picks -- User picks per round (team, result)
|
|
53
|
+
survivor_tournament_games -- All tournament matchups (teams, scores, winner)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## How Teams/Bracket Data Works
|
|
59
|
+
|
|
60
|
+
### Current Setup (Development/Testing)
|
|
61
|
+
|
|
62
|
+
Teams are **hardcoded mock data** in `survivorSimulator.js`:
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const MOCK_TEAMS = [
|
|
66
|
+
// 68 teams total (64 + 4 First Four)
|
|
67
|
+
{ id: 'e1', name: 'Duke', seed: 1, region: 'EAST', logo: espnLogo(150) },
|
|
68
|
+
{ id: 'w1', name: 'Florida', seed: 1, region: 'WEST', logo: espnLogo(57) },
|
|
69
|
+
{ id: 's1', name: 'Auburn', seed: 1, region: 'SOUTH', logo: espnLogo(2) },
|
|
70
|
+
{ id: 'm1', name: 'Houston', seed: 1, region: 'MIDWEST', logo: espnLogo(248) },
|
|
71
|
+
// ... etc
|
|
72
|
+
];
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**To generate bracket for testing:**
|
|
76
|
+
```bash
|
|
77
|
+
curl -X POST http://localhost:3001/api/survivor/dev/pools/1/generate-bracket
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This creates Round of 64 games with standard seeding matchups (1v16, 8v9, 5v12, etc.)
|
|
81
|
+
|
|
82
|
+
### Production (Real Tournament)
|
|
83
|
+
|
|
84
|
+
After **Selection Sunday** (NCAA announces bracket):
|
|
85
|
+
|
|
86
|
+
1. **Option A:** Import from ESPN API
|
|
87
|
+
2. **Option B:** Admin uploads official bracket JSON
|
|
88
|
+
3. **Option C:** Manual database entry
|
|
89
|
+
|
|
90
|
+
The bracket structure (seeding matchups) is always the same - only team names change.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## User Flow
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
1. JOIN POOL
|
|
98
|
+
└── User pays SOL entry fee → entry created
|
|
99
|
+
|
|
100
|
+
2. MAKE PICK (each round)
|
|
101
|
+
└── Select one team to win → pick saved
|
|
102
|
+
└── Can change pick until deadline
|
|
103
|
+
|
|
104
|
+
3. ROUND RESOLVES
|
|
105
|
+
└── Oracle checks ESPN for final scores
|
|
106
|
+
└── Winners advance, losers eliminated
|
|
107
|
+
|
|
108
|
+
4. PAYOUT
|
|
109
|
+
└── After Championship, survivors split pot
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Key API Endpoints
|
|
115
|
+
|
|
116
|
+
### Public
|
|
117
|
+
- `GET /api/survivor/pools` - List all pools
|
|
118
|
+
- `GET /api/survivor/pools/:id` - Pool details
|
|
119
|
+
- `GET /api/survivor/pools/:id/games` - Tournament games
|
|
120
|
+
- `GET /api/survivor/pools/:id/alive` - Surviving entries
|
|
121
|
+
- `GET /api/survivor/pools/:id/eliminated` - Eliminated entries
|
|
122
|
+
|
|
123
|
+
### Authenticated (require JWT)
|
|
124
|
+
- `POST /api/survivor/pools/:id/join` - Join pool
|
|
125
|
+
- `GET /api/survivor/pools/:id/my-entry` - User's entry + picks
|
|
126
|
+
- `GET /api/survivor/pools/:id/teams` - Available teams to pick
|
|
127
|
+
- `POST /api/survivor/pools/:id/pick` - Submit pick
|
|
128
|
+
|
|
129
|
+
### Dev/Simulation (development only)
|
|
130
|
+
- `POST /api/survivor/dev/pools/:id/generate-bracket` - Create mock bracket
|
|
131
|
+
- `POST /api/survivor/dev/pools/:id/simulate-round` - Random results
|
|
132
|
+
- `POST /api/survivor/dev/pools/:id/activate` - Set pool to active
|
|
133
|
+
- `POST /api/survivor/dev/pools/:id/reset` - Reset to round 1
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Bracket View Features
|
|
138
|
+
|
|
139
|
+
- **4 Regions:** South, West (left side) | East, Midwest (right side)
|
|
140
|
+
- **Rounds:** R64 → R32 → Sweet 16 → Elite 8 → Final Four → Championship
|
|
141
|
+
- **Zoom controls:** Scale 40% - 120% (default 75%)
|
|
142
|
+
- **Round labels:** Each column has its own label (Round of 64, Round of 32, Sweet 16, Elite 8) that aligns with the bracket
|
|
143
|
+
- **Connecting lines:**
|
|
144
|
+
- SVG lines between rounds within each region showing bracket flow
|
|
145
|
+
- Horizontal yellow lines from Elite 8 → Final Four (using `flex-1` to stretch)
|
|
146
|
+
- Vertical yellow lines from Final Four → Championship (absolutely positioned)
|
|
147
|
+
- **Right side mirroring:** EAST/MIDWEST regions mirrored with `scaleX(-1)` so bracket flows toward center, but text flipped back to readable
|
|
148
|
+
- **Final Four/Championship layout:**
|
|
149
|
+
- FF1 (top) connects SOUTH and EAST Elite 8 winners
|
|
150
|
+
- FF2 (bottom) connects WEST and MIDWEST Elite 8 winners
|
|
151
|
+
- Championship in center with vertical connectors from both Final Four games
|
|
152
|
+
- Vertical connector heights: FF1→Champ = 250px, FF2→Champ = 310px
|
|
153
|
+
- **Visual states:**
|
|
154
|
+
- Green highlight = winner
|
|
155
|
+
- Grayed out = eliminated
|
|
156
|
+
- Red pulse = live game
|
|
157
|
+
- "TBD" = future matchup
|
|
158
|
+
- Yellow lines = Final Four/Championship connectors
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Testing Commands
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# Create a test pool
|
|
166
|
+
curl -X POST http://localhost:3001/api/survivor/pools \
|
|
167
|
+
-H "Content-Type: application/json" \
|
|
168
|
+
-d '{"name":"Test Pool 2025","year":2025,"buyInLamports":"100000000"}'
|
|
169
|
+
|
|
170
|
+
# Generate bracket for pool ID 1
|
|
171
|
+
curl -X POST http://localhost:3001/api/survivor/dev/pools/1/generate-bracket
|
|
172
|
+
|
|
173
|
+
# Activate pool (move to round 2)
|
|
174
|
+
curl -X POST http://localhost:3001/api/survivor/dev/pools/1/activate
|
|
175
|
+
|
|
176
|
+
# Simulate round with 20% upset chance
|
|
177
|
+
curl -X POST http://localhost:3001/api/survivor/dev/pools/1/simulate-round \
|
|
178
|
+
-H "Content-Type: application/json" \
|
|
179
|
+
-d '{"upsetChance":0.2}'
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## What's Left To Do
|
|
185
|
+
|
|
186
|
+
### High Priority
|
|
187
|
+
- [ ] **Real bracket import** - Admin endpoint to import actual NCAA bracket after Selection Sunday
|
|
188
|
+
- [ ] **Round advancement** - Auto-create next round games when current round completes
|
|
189
|
+
- [ ] **Oracle integration** - Connect to ESPN API for live scores
|
|
190
|
+
- [ ] **Deadline enforcement** - Auto-eliminate users who don't pick before deadline
|
|
191
|
+
- [ ] **Payout logic** - Distribute pot to survivors via Solana
|
|
192
|
+
|
|
193
|
+
### Medium Priority
|
|
194
|
+
- [ ] **Pick history display** - Show user's picks from previous rounds
|
|
195
|
+
- [ ] **Leaderboard** - Show all alive/eliminated entries
|
|
196
|
+
- [ ] **Notifications** - Email/push for deadlines, results
|
|
197
|
+
- [ ] **Multiple entries** - Allow users to buy multiple entries
|
|
198
|
+
|
|
199
|
+
### Polish
|
|
200
|
+
- [x] **Bracket connector lines** - Visual lines connecting matchups ✓
|
|
201
|
+
- [x] **Final Four/Championship connectors** - Vertical lines connecting FF to Championship ✓
|
|
202
|
+
- [x] **Round column labels** - Labels aligned with each bracket column ✓
|
|
203
|
+
- [ ] **Mobile responsive** - Better mobile bracket view
|
|
204
|
+
- [ ] **Animations** - Transitions when winners revealed
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## ESPN Team Logo URLs
|
|
209
|
+
|
|
210
|
+
Logos come from ESPN CDN:
|
|
211
|
+
```
|
|
212
|
+
https://a.espncdn.com/i/teamlogos/ncaa/500/{espn_team_id}.png
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Example ESPN team IDs:
|
|
216
|
+
- Duke: 150
|
|
217
|
+
- Florida: 57
|
|
218
|
+
- Auburn: 2
|
|
219
|
+
- Houston: 248
|
|
220
|
+
|
|
221
|
+
Full list in `survivorSimulator.js` → `MOCK_TEAMS` array.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Round Names
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
const ROUND_NAMES = {
|
|
229
|
+
1: 'First Four',
|
|
230
|
+
2: 'Round of 64',
|
|
231
|
+
3: 'Round of 32',
|
|
232
|
+
4: 'Sweet 16',
|
|
233
|
+
5: 'Elite 8',
|
|
234
|
+
6: 'Final Four',
|
|
235
|
+
7: 'Championship',
|
|
236
|
+
};
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Questions for Tomorrow
|
|
242
|
+
|
|
243
|
+
1. How should we import the real bracket after Selection Sunday?
|
|
244
|
+
2. Should users be able to change their pick before the deadline?
|
|
245
|
+
3. What happens if all remaining users pick the same losing team?
|
|
246
|
+
4. Refund policy if tournament is cancelled?
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Related Files
|
|
251
|
+
|
|
252
|
+
- **Plan document:** `~/.claude/plans/glittery-leaping-cocoa.md`
|
|
253
|
+
- **Frontend:** `~/Developer/iheartsolana/dubs-jackpot-spa/app/v2/features/survivor/`
|
|
254
|
+
- **Backend:** `~/Developer/iheartsolana/solana-programs/dubs-server/`
|
package/PANDA.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# PandaScore Data Structure
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
PandaScore uses an opinionated, hierarchical data structure to map esports competitions across all video games. Understanding this hierarchy is critical for building betting features on top of it.
|
|
6
|
+
|
|
7
|
+
## Hierarchy
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Videogame (Valorant, CS2, LoL, Dota 2)
|
|
11
|
+
└── League (recurring competition — e.g. VCT Champions, ESL Pro League)
|
|
12
|
+
└── Series (single occurrence — e.g. VCT Champions 2026)
|
|
13
|
+
└── Tournament (stage — e.g. Group Stage, Playoffs)
|
|
14
|
+
└── Match (confrontation — e.g. Team A vs Team B)
|
|
15
|
+
└── Game (individual map/round)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Levels Explained
|
|
19
|
+
|
|
20
|
+
### Videogame
|
|
21
|
+
The game itself. Each has a unique ID and slug.
|
|
22
|
+
|
|
23
|
+
| ID | Name | Slug |
|
|
24
|
+
|----|------|------|
|
|
25
|
+
| 1 | League of Legends | league-of-legends |
|
|
26
|
+
| 3 | Counter-Strike | cs-go |
|
|
27
|
+
| 4 | Dota 2 | dota-2 |
|
|
28
|
+
| 14 | Overwatch | ow |
|
|
29
|
+
| 20 | PUBG | pubg |
|
|
30
|
+
| 22 | Rocket League | rl |
|
|
31
|
+
| 23 | Call of Duty | cod-mw |
|
|
32
|
+
| 24 | Rainbow 6 Siege | r6-siege |
|
|
33
|
+
| 25 | EA Sports FC | fifa |
|
|
34
|
+
| 26 | Valorant | valorant |
|
|
35
|
+
| 27 | King of Glory | kog |
|
|
36
|
+
| 28 | LoL Wild Rift | lol-wild-rift |
|
|
37
|
+
| 29 | StarCraft 2 | starcraft-2 |
|
|
38
|
+
| 30 | StarCraft Brood War | starcraft-brood-war |
|
|
39
|
+
| 34 | Mobile Legends | mlbb |
|
|
40
|
+
|
|
41
|
+
### League
|
|
42
|
+
The top-level competition. Think of it as the brand/name of a recurring event.
|
|
43
|
+
- **Sports analogy**: FIFA World Cup, UEFA Champions League, NFL
|
|
44
|
+
- **Esports examples**: VCT Champions, ESL Pro League, LCK, The International
|
|
45
|
+
|
|
46
|
+
Key fields: `id`, `name`, `slug`, `image_url`, `videogame`, `series[]`
|
|
47
|
+
|
|
48
|
+
### Series
|
|
49
|
+
A single timely occurrence of a league. One league has many series over the years.
|
|
50
|
+
- **Sports analogy**: FIFA World Cup 2022, NFL Season 2024
|
|
51
|
+
- **Esports examples**: VCT Champions 2026, ESL Pro League Season 21
|
|
52
|
+
|
|
53
|
+
Key fields: `id`, `full_name`, `year`, `season`, `begin_at`, `end_at`, `winner_id`, `league_id`
|
|
54
|
+
|
|
55
|
+
### Tournament
|
|
56
|
+
A stage or phase within a series. This is where standings and brackets live.
|
|
57
|
+
- **Sports analogy**: FIFA World Cup 2022 — Group C, NFL 2024 — Playoffs
|
|
58
|
+
- **Esports examples**: VCT Champions 2026 — Group Stage, The International 2026 — Playoffs
|
|
59
|
+
|
|
60
|
+
Key fields: `id`, `name`, `type` (bracket type), `matches[]`, `teams[]`, `standings`
|
|
61
|
+
|
|
62
|
+
### Match
|
|
63
|
+
A confrontation between two opponents. **This is the betting level** — where you have two sides and an outcome.
|
|
64
|
+
- **Sports analogy**: Denmark vs Australia
|
|
65
|
+
- **Esports examples**: OG vs PSG.LGD (best of 5)
|
|
66
|
+
|
|
67
|
+
Key fields: `id`, `name`, `status` (not_started/running/finished), `opponents[]`, `results[]`, `winner`, `begin_at`, `number_of_games`, `tournament_id`
|
|
68
|
+
|
|
69
|
+
Match statuses:
|
|
70
|
+
- `not_started` — scheduled, not yet live
|
|
71
|
+
- `running` — currently being played
|
|
72
|
+
- `finished` — completed with results
|
|
73
|
+
- `canceled` — won't happen
|
|
74
|
+
|
|
75
|
+
### Game
|
|
76
|
+
An individual map or round within a match. Data structure varies per videogame.
|
|
77
|
+
- **Sports analogy**: A single match has one game (Denmark vs Australia = 1 game)
|
|
78
|
+
- **Esports examples**: A CS2 best-of-3 match has up to 3 games (maps)
|
|
79
|
+
|
|
80
|
+
Game-level data is videogame-specific and only available for games supporting Historical Data.
|
|
81
|
+
|
|
82
|
+
## Key Differences from Traditional Sports
|
|
83
|
+
|
|
84
|
+
| Concept | Traditional Sports | Esports (PandaScore) |
|
|
85
|
+
|---------|-------------------|----------------------|
|
|
86
|
+
| Season structure | Fixed schedule (82 games, 17 weeks, etc.) | Tournament-based, variable |
|
|
87
|
+
| "League" means | A fixed set of teams playing a season | Any recurring competition |
|
|
88
|
+
| Regular season | Yes (months of scheduled games) | Rare — mostly events/tournaments |
|
|
89
|
+
| Betting level | Individual game in the schedule | Match (within a tournament) |
|
|
90
|
+
| Nesting depth | League → Season → Game | League → Series → Tournament → Match → Game |
|
|
91
|
+
|
|
92
|
+
## For Dubs Betting
|
|
93
|
+
|
|
94
|
+
The path to a bettable event:
|
|
95
|
+
1. Pick relevant **Leagues** (curate a whitelist of league IDs worth betting on)
|
|
96
|
+
2. Find active **Series** within those leagues (current year/season)
|
|
97
|
+
3. Get **Tournaments** within those series (group stage, playoffs, etc.)
|
|
98
|
+
4. List **Matches** within those tournaments — these are what users bet on
|
|
99
|
+
5. Match `status: "not_started"` = upcoming and bettable
|
|
100
|
+
|
|
101
|
+
## API Endpoints (Our Server)
|
|
102
|
+
|
|
103
|
+
Current endpoints at `/api/esports`:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
GET /api/esports/leagues — List all leagues
|
|
107
|
+
GET /api/esports/leagues/:leagueId — Get single league
|
|
108
|
+
GET /api/esports/videogames/:videogameId/leagues — Leagues by game
|
|
109
|
+
GET /api/esports/leagues/:id/series — Series within a league
|
|
110
|
+
GET /api/esports/leagues/:id/tournaments — Tournaments within a league
|
|
111
|
+
GET /api/esports/leagues/:id/matches/upcoming — Upcoming (bettable) matches
|
|
112
|
+
GET /api/esports/leagues/:id/matches/running — Currently live matches
|
|
113
|
+
GET /api/esports/leagues/:id/matches — All matches (rich filtering)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Key Response Fields by Endpoint
|
|
117
|
+
|
|
118
|
+
**Series** — `full_name`, `year`, `season`, `begin_at`, `end_at`, `winner_id`, `tournaments[]`
|
|
119
|
+
|
|
120
|
+
**Tournaments** — `name`, `tier` (s/a/b/c/d/unranked), `type` (online/offline), `prizepool`, `region`, `teams[]`, `matches[]`, `expected_roster[]`, `begin_at`, `end_at`
|
|
121
|
+
|
|
122
|
+
**Matches** — `name`, `status`, `opponents[]`, `results[]`, `winner`, `begin_at`, `number_of_games`, `match_type` (best_of), `tournament`, `streams_list[]`, `games[]`, `live.url` (WebSocket), `serie`, `rescheduled`, `forfeit`, `draw`, `videogame_title`
|
|
123
|
+
|
|
124
|
+
### Match Filtering (General `/matches` Endpoint)
|
|
125
|
+
|
|
126
|
+
The general matches endpoint supports powerful filtering:
|
|
127
|
+
- `filter[status]=running` — Live matches only
|
|
128
|
+
- `filter[status]=not_started` — Upcoming only
|
|
129
|
+
- `filter[status]=finished` — Completed only
|
|
130
|
+
- `filter[future]=true` — Future matches (by begin_at)
|
|
131
|
+
- `filter[past]=true` — Past matches
|
|
132
|
+
- `filter[opponent_id]=123` — Matches involving a specific team/player
|
|
133
|
+
- `filter[tournament_id]=456` — Matches in a specific tournament
|
|
134
|
+
- `filter[serie_id]=789` — Matches in a specific series
|
|
135
|
+
- `filter[opponents_filled]=true` — Only matches with known opponents (not TBD)
|
|
136
|
+
- `filter[match_type]=best_of` — Filter by match format
|
|
137
|
+
- `range[begin_at]=2026-01-01,2026-12-31` — Date range filter
|
|
138
|
+
- `sort=-scheduled_at` — Sort by scheduled date (descending)
|
|
139
|
+
|
|
140
|
+
## API Authentication
|
|
141
|
+
|
|
142
|
+
PandaScore uses Bearer token auth:
|
|
143
|
+
```
|
|
144
|
+
Authorization: Bearer <PANDASCORE_API_KEY>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Environment variable: `PANDASCORE_API_KEY`
|
|
148
|
+
|
|
149
|
+
## Pagination
|
|
150
|
+
|
|
151
|
+
All list endpoints support:
|
|
152
|
+
- `page` — page number (default: 1)
|
|
153
|
+
- `per_page` — results per page (default: 50, max: 100)
|
|
154
|
+
- `sort` — field to sort by (prefix with `-` for descending, e.g. `-modified_at`)
|
|
155
|
+
|
|
156
|
+
## Filtering & Search
|
|
157
|
+
|
|
158
|
+
- `filter[field]=value` — exact match filter
|
|
159
|
+
- `search[field]=value` — fuzzy text search
|
|
160
|
+
- `range[field]=min,max` — range filter
|
|
161
|
+
|
|
162
|
+
## References
|
|
163
|
+
|
|
164
|
+
- [PandaScore API Docs](https://developers.pandascore.co/docs/introduction)
|
|
165
|
+
- [Data Structure Fundamentals](https://developers.pandascore.co/docs/fundamentals)
|
|
166
|
+
- [Filtering & Sorting](https://developers.pandascore.co/docs/filtering-and-sorting)
|
package/Procfile
ADDED