@vatvaghool/create-ipl-dashboard 0.1.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 (108) hide show
  1. package/README.md +75 -0
  2. package/package.json +27 -0
  3. package/src/generate-template.mjs +73 -0
  4. package/src/index.mjs +98 -0
  5. package/src/prompts.mjs +78 -0
  6. package/src/scaffold.mjs +129 -0
  7. package/src/scraper.mjs +79 -0
  8. package/template/.dockerignore +13 -0
  9. package/template/AGENTS.md +5 -0
  10. package/template/Dockerfile.sync +14 -0
  11. package/template/README.md +160 -0
  12. package/template/app/api/ipl/data.ts +24 -0
  13. package/template/app/api/ipl/route.ts +505 -0
  14. package/template/app/api/ipl/transfers/route.ts +261 -0
  15. package/template/app/api/ipl/transfers/transform.ts +156 -0
  16. package/template/app/api/ipl/transform.ts +20 -0
  17. package/template/app/api/ipl/upcoming-matches/route.ts +18 -0
  18. package/template/app/api/ops/status/route.ts +225 -0
  19. package/template/app/components/AIRoasting.tsx +278 -0
  20. package/template/app/components/ColorWave.tsx +193 -0
  21. package/template/app/components/CrownBattle.tsx +207 -0
  22. package/template/app/components/DashboardContent.tsx +377 -0
  23. package/template/app/components/FantasyStockTicker.tsx +192 -0
  24. package/template/app/components/FireworksBurst.tsx +225 -0
  25. package/template/app/components/LiveMatchTicker.tsx +117 -0
  26. package/template/app/components/MatchRecapScroll.tsx +135 -0
  27. package/template/app/components/MatchStoryScrubber.tsx +274 -0
  28. package/template/app/components/PerformanceTracker.tsx +132 -0
  29. package/template/app/components/ProgressGlowRings.tsx +157 -0
  30. package/template/app/components/TeamDNAScanner.tsx +238 -0
  31. package/template/app/components/ThemeToggle.tsx +74 -0
  32. package/template/app/components/dashboard/CaptainBoard.tsx +138 -0
  33. package/template/app/components/dashboard/ChartBoard.tsx +162 -0
  34. package/template/app/components/dashboard/LatestBadge.tsx +23 -0
  35. package/template/app/components/dashboard/LedgerTable.tsx +385 -0
  36. package/template/app/components/dashboard/SectionCard.tsx +59 -0
  37. package/template/app/components/dashboard/StickyMini.tsx +20 -0
  38. package/template/app/components/dashboard/index.ts +6 -0
  39. package/template/app/components/ui/DashboardChartFrame.tsx +74 -0
  40. package/template/app/components/ui/DoodleSpinner.tsx +15 -0
  41. package/template/app/components/ui/TeamPills.tsx +41 -0
  42. package/template/app/data/match-points.ts +3 -0
  43. package/template/app/data/teams.ts +32 -0
  44. package/template/app/globals.css +1267 -0
  45. package/template/app/hooks/dashboard/index.ts +1 -0
  46. package/template/app/hooks/dashboard/useDashboardModel.ts +25 -0
  47. package/template/app/hooks/dashboardCache.ts +53 -0
  48. package/template/app/hooks/dashboardPolling.ts +53 -0
  49. package/template/app/hooks/snapshotCache.ts +47 -0
  50. package/template/app/hooks/useDashboardData.ts +28 -0
  51. package/template/app/layout.tsx +75 -0
  52. package/template/app/lib/aiAgent.ts +444 -0
  53. package/template/app/lib/config.ts +29 -0
  54. package/template/app/lib/dashboard/index.ts +1 -0
  55. package/template/app/lib/dashboard/model.ts +257 -0
  56. package/template/app/lib/dashboardData.ts +50 -0
  57. package/template/app/lib/dashboardView.ts +22 -0
  58. package/template/app/lib/detailedData.ts +112 -0
  59. package/template/app/lib/matchStatus.ts +28 -0
  60. package/template/app/lib/matches.ts +131 -0
  61. package/template/app/lib/teamBadges.ts +223 -0
  62. package/template/app/lib/upcomingMatches.ts +154 -0
  63. package/template/app/lib/useDb.ts +29 -0
  64. package/template/app/lib/utils/diff.ts +24 -0
  65. package/template/app/lib/utils/getChartColor.ts +17 -0
  66. package/template/app/lib/utils/getStdDeviation.ts +6 -0
  67. package/template/app/lib/utils/time.ts +40 -0
  68. package/template/app/lib/utils.ts +70 -0
  69. package/template/app/page.tsx +15 -0
  70. package/template/app/store/dashboardStore.ts +85 -0
  71. package/template/app/types/dashboard.ts +75 -0
  72. package/template/app/types.ts +130 -0
  73. package/template/app/utils/dashboard/index.ts +72 -0
  74. package/template/eslint.config.mjs +18 -0
  75. package/template/infra/cloud-run/README.md +68 -0
  76. package/template/infra/cloud-run/sync-job.yaml +32 -0
  77. package/template/infra/cutover/README.md +84 -0
  78. package/template/infra/vercel/README.md +57 -0
  79. package/template/next.config.ts +7 -0
  80. package/template/package-lock.json +7330 -0
  81. package/template/package.json +47 -0
  82. package/template/packages/ipl-dashboard-utils/README.md +316 -0
  83. package/template/packages/ipl-dashboard-utils/package.json +34 -0
  84. package/template/packages/ipl-dashboard-utils/src/index.ts +22 -0
  85. package/template/packages/ipl-dashboard-utils/src/transform.ts +687 -0
  86. package/template/packages/ipl-dashboard-utils/src/types.ts +88 -0
  87. package/template/packages/ipl-dashboard-utils/tsconfig.build.json +17 -0
  88. package/template/postcss.config.mjs +7 -0
  89. package/template/scripts/capture-ipl-auth.mjs +54 -0
  90. package/template/scripts/deploy-cloud-run-sync.sh +48 -0
  91. package/template/scripts/deploy-cloud-scheduler.sh +42 -0
  92. package/template/scripts/dev-simple.js +31 -0
  93. package/template/scripts/dev-welcome.mjs +38 -0
  94. package/template/scripts/monitor-ops-status.sh +50 -0
  95. package/template/scripts/seed-mongodb.ts +115 -0
  96. package/template/scripts/sync-cloud.mjs +50 -0
  97. package/template/scripts/sync-ipl.mjs +238 -0
  98. package/template/scripts/sync-transfers-daily.mjs +175 -0
  99. package/template/scripts/verify-production.mjs +108 -0
  100. package/template/tests/coverage-gaps.test.ts +290 -0
  101. package/template/tests/dashboard-polling.test.ts +96 -0
  102. package/template/tests/detailed-data.test.ts +60 -0
  103. package/template/tests/ipl-transform.test.ts +590 -0
  104. package/template/tests/transfers-route.test.ts +109 -0
  105. package/template/tests/upcoming-matches.test.ts +34 -0
  106. package/template/tests/utils-and-cache.test.ts +267 -0
  107. package/template/tsconfig.json +35 -0
  108. package/template/vercel.json +7 -0
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "ipl-dashboard",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "node scripts/dev-welcome.mjs && next dev",
8
+ "dev:simple": "node scripts/dev-simple.js",
9
+ "capture:ipl-auth": "node scripts/capture-ipl-auth.mjs",
10
+ "sync:ipl": "node scripts/sync-ipl.mjs",
11
+ "sync:ipl:watch": "node scripts/sync-ipl.mjs --watch",
12
+ "sync:ipl:transfers-daily": "node scripts/sync-transfers-daily.mjs",
13
+ "sync:cloud": "node scripts/sync-cloud.mjs",
14
+ "verify:production": "node scripts/verify-production.mjs",
15
+ "monitor:ops": "bash scripts/monitor-ops-status.sh",
16
+ "build": "next build",
17
+ "build:utils-package": "node ./node_modules/typescript/bin/tsc -p packages/ipl-dashboard-utils/tsconfig.build.json",
18
+ "start": "next start",
19
+ "lint": "eslint",
20
+ "test": "node --test --experimental-strip-types \"tests/**/*.test.ts\"",
21
+ "seed:mongodb": "node --experimental-strip-types scripts/seed-mongodb.ts",
22
+ "seed:mongodb:reset": "node --experimental-strip-types scripts/seed-mongodb.ts --reset --force"
23
+ },
24
+ "dependencies": {
25
+ "@vercel/analytics": "^2.0.1",
26
+ "framer-motion": "^12.38.0",
27
+ "mongodb": "^7.1.1",
28
+ "next": "16.2.4",
29
+ "react": "19.2.4",
30
+ "react-dom": "19.2.4",
31
+ "react-icons": "^5.6.0",
32
+ "recharts": "^3.8.1",
33
+ "zustand": "^5.0.12"
34
+ },
35
+ "devDependencies": {
36
+ "@tailwindcss/postcss": "^4.2.2",
37
+ "@types/node": "^20",
38
+ "@types/react": "^19",
39
+ "@types/react-dom": "^19",
40
+ "autoprefixer": "^10.5.0",
41
+ "eslint": "^9",
42
+ "eslint-config-next": "16.2.4",
43
+ "postcss": "^8.5.10",
44
+ "tailwindcss": "^4.2.2",
45
+ "typescript": "^5"
46
+ }
47
+ }
@@ -0,0 +1,316 @@
1
+ # `@vatvaghool/ipl-fantasy-dashboard`
2
+
3
+ TypeScript utilities extracted from the IPL fantasy dashboard project for normalizing fantasy leaderboard payloads, building dashboard-friendly data, and syncing raw match history forward from live snapshots.
4
+
5
+ This package is safe to publish publicly on npm because it does not include the private Next.js web app, MongoDB connection code, live snapshots, browser auth files, or bookmarklet secrets.
6
+
7
+ ## What This Package Is
8
+
9
+ This package contains the reusable data layer from the dashboard project:
10
+
11
+ - payload normalization
12
+ - leaderboard metric calculation
13
+ - raw-user normalization
14
+ - manual dashboard shaping
15
+ - live snapshot merge helpers
16
+ - raw-user sync helpers
17
+ - TypeScript data types
18
+
19
+ It is useful if you want to:
20
+
21
+ - normalize fantasy leaderboard payloads in your own app
22
+ - build charts or analytics from raw team/match history
23
+ - merge live standings into a historical dashboard model
24
+ - keep your own storage layer while reusing the IPL-specific transforms
25
+
26
+ ## What This Package Does Not Include
27
+
28
+ This npm package does not publish:
29
+
30
+ - the Next.js web app UI
31
+ - MongoDB connection logic
32
+ - `.env` values
33
+ - `ipl-auth.json`
34
+ - live snapshot seed files
35
+ - bookmarklet endpoint code
36
+ - local or deployed secrets
37
+
38
+ If you want the full dashboard web app with MongoDB setup and bookmarklet ingestion flow, use the source repository, not this package alone.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ npm install @vatvaghool/ipl-fantasy-dashboard
44
+ ```
45
+
46
+ ## Exported API
47
+
48
+ ### Functions
49
+
50
+ - `toFiniteNumber`
51
+ - `normalizePayload`
52
+ - `normalizeRawApiUsers`
53
+ - `addLeaderboardMetrics`
54
+ - `buildManualDashboard`
55
+ - `buildDashboardFromSnapshot`
56
+ - `syncRawUsersWithSnapshot`
57
+ - `serializeRawApiUsersModule`
58
+
59
+ ### Types
60
+
61
+ - `DailyChartRow`
62
+ - `DashboardData`
63
+ - `OverallChartItem`
64
+ - `RawApiUser`
65
+ - `RawUsersSyncResult`
66
+ - `ScrapedDashboardPayload`
67
+ - `ScrapedLeaderboardItem`
68
+ - `ScrapedSquadPlayer`
69
+ - `TransformOptions`
70
+
71
+ ## Basic Usage
72
+
73
+ ```ts
74
+ import {
75
+ buildDashboardFromSnapshot,
76
+ buildManualDashboard,
77
+ normalizePayload,
78
+ normalizeRawApiUsers,
79
+ syncRawUsersWithSnapshot,
80
+ } from "@vatvaghool/ipl-fantasy-dashboard";
81
+
82
+ const rawUsers = normalizeRawApiUsers([
83
+ {
84
+ rno: 1,
85
+ temname: "Deccan Dominators",
86
+ matches: [
87
+ { matchId: 1, points: 120 },
88
+ { matchId: 2, points: 88 },
89
+ ],
90
+ },
91
+ ]);
92
+
93
+ const snapshot = normalizePayload({
94
+ updatedAt: "2026-04-28T09:15:00.000Z",
95
+ completedMatches: 41,
96
+ leaders: [
97
+ {
98
+ rank: 1,
99
+ name: "Deccan Dominators",
100
+ points: 240,
101
+ lastMatchPoints: 32,
102
+ transfersLeft: 101,
103
+ },
104
+ ],
105
+ });
106
+
107
+ if (rawUsers && snapshot) {
108
+ const manualDashboard = buildManualDashboard(rawUsers);
109
+ const liveDashboard = buildDashboardFromSnapshot(snapshot, manualDashboard);
110
+ const syncResult = syncRawUsersWithSnapshot(rawUsers, snapshot);
111
+
112
+ console.log(liveDashboard.overall[0]);
113
+ console.log(syncResult.status);
114
+ }
115
+ ```
116
+
117
+ ## Using Team Aliases
118
+
119
+ Some fantasy exports may use one team name in raw match history and another team name in scraped live snapshots. Use `teamAliases` to map those names together.
120
+
121
+ ```ts
122
+ import { normalizePayload, syncRawUsersWithSnapshot } from "@vatvaghool/ipl-fantasy-dashboard";
123
+
124
+ const snapshot = normalizePayload(incomingPayload, {
125
+ teamAliases: {
126
+ "Team RJ": "Raviteja Jakkani",
127
+ "WATAPI11": "Rishikesh Shinde",
128
+ },
129
+ });
130
+
131
+ const result = syncRawUsersWithSnapshot(rawUsers, snapshot!, {
132
+ teamAliases: {
133
+ "Team RJ": "Raviteja Jakkani",
134
+ "WATAPI11": "Rishikesh Shinde",
135
+ },
136
+ });
137
+ ```
138
+
139
+ ## Main Functions In Detail
140
+
141
+ ### `normalizePayload(payload, options?)`
142
+
143
+ Accepts a scraped, partial, or mixed-format fantasy payload and converts it into a consistent `ScrapedDashboardPayload`.
144
+
145
+ It supports shapes such as:
146
+
147
+ - `{ leaders: [...] }`
148
+ - raw leaderboard arrays
149
+ - nested `Data.Value` payloads
150
+ - bookmarklet-style payload fields like `time`, `match`, `last`, `c`, and `v`
151
+
152
+ Returns:
153
+
154
+ - normalized payload object when valid
155
+ - `null` when the input cannot be normalized
156
+
157
+ ### `normalizeRawApiUsers(payload)`
158
+
159
+ Normalizes raw match-history users into the `RawApiUser[]` shape:
160
+
161
+ - trims names
162
+ - parses numeric values
163
+ - sorts matches by `matchId`
164
+ - recalculates total points
165
+
166
+ Returns:
167
+
168
+ - normalized array when valid
169
+ - `null` when the input is invalid
170
+
171
+ ### `buildManualDashboard(users, options?)`
172
+
173
+ Builds a full historical dashboard structure from raw match history alone.
174
+
175
+ Returns a `DashboardData` object with:
176
+
177
+ - `overall`
178
+ - `daily`
179
+ - `source: "database"`
180
+
181
+ ### `buildDashboardFromSnapshot(snapshot, manualDashboard, options?)`
182
+
183
+ Merges a live snapshot into the historical dashboard data.
184
+
185
+ If latest match points exist in the snapshot, a `Live Update` row is appended to the daily data.
186
+
187
+ ### `addLeaderboardMetrics(leaders, options?)`
188
+
189
+ Enriches leaderboard rows with:
190
+
191
+ - previous rank
192
+ - previous points
193
+ - gap to next
194
+ - gap percent
195
+ - movement
196
+ - transfer efficiency
197
+ - last-match leader flag
198
+
199
+ ### `syncRawUsersWithSnapshot(users, snapshot, options?)`
200
+
201
+ Compares live leaderboard totals against stored raw match history and tries to move the raw data forward safely.
202
+
203
+ It returns:
204
+
205
+ - `status`
206
+ - updated `users`
207
+ - `matchId`
208
+ - `mode`
209
+ - `completedMatches`
210
+ - `unmatchedNames`
211
+
212
+ Possible statuses:
213
+
214
+ - `updated`
215
+ - `unchanged`
216
+ - `skipped`
217
+
218
+ ## Transform Options
219
+
220
+ Most helpers accept an optional `TransformOptions` object:
221
+
222
+ ```ts
223
+ type TransformOptions = {
224
+ teamAliases?: Record<string, string>;
225
+ totalTransfers?: number;
226
+ };
227
+ ```
228
+
229
+ ### `teamAliases`
230
+
231
+ Use this when scraped and stored team names differ.
232
+
233
+ ### `totalTransfers`
234
+
235
+ Defaults to `210`. Override this if your fantasy rules use a different total transfer count.
236
+
237
+ ## Example Input Payload
238
+
239
+ ```json
240
+ {
241
+ "updatedAt": "2026-04-28T09:15:00.000Z",
242
+ "completedMatches": 41,
243
+ "leaders": [
244
+ {
245
+ "rank": 1,
246
+ "name": "Deccan Dominators",
247
+ "points": 7125,
248
+ "lastMatchPoints": 52.5,
249
+ "transfersLeft": 101,
250
+ "boostersUsed": "1"
251
+ }
252
+ ]
253
+ }
254
+ ```
255
+
256
+ ## Example Workflow
257
+
258
+ If you are building your own service around this package, a common flow looks like this:
259
+
260
+ 1. Read your stored raw match-history users from your database.
261
+ 2. Normalize any incoming live payload with `normalizePayload`.
262
+ 3. Build historical dashboard data using `buildManualDashboard`.
263
+ 4. Merge the live snapshot with `buildDashboardFromSnapshot`.
264
+ 5. Sync raw users forward with `syncRawUsersWithSnapshot`.
265
+ 6. Store the updated raw users and latest snapshot in your own database.
266
+
267
+ ## Relationship To The Full Web App
268
+
269
+ This npm package comes from a larger private dashboard project. The full web app includes:
270
+
271
+ - a Next.js dashboard UI
272
+ - MongoDB-backed API routes
273
+ - a bookmarklet endpoint at `/api/ipl/bookmarklet`
274
+ - local fallback seed files
275
+ - optional Playwright automation
276
+
277
+ That full app is not published in this package.
278
+
279
+ If you cloned the source repo and want to run the full dashboard locally, the web app setup is documented in the root project README and includes:
280
+
281
+ - `MONGODB_URI` setup
282
+ - `IPL_POST_SECRET` usage
283
+ - `npm run dev:simple`
284
+ - `npm run seed:mongodb`
285
+ - bookmarklet generation from `/api/ipl/bookmarklet`
286
+
287
+ ## Publish Notes
288
+
289
+ This package is already structured so that npm publishes only:
290
+
291
+ - `dist/`
292
+ - this package README
293
+ - this package `package.json`
294
+
295
+ That keeps app-private files out of the public tarball.
296
+
297
+ ## Local Publish Checklist
298
+
299
+ From the source repo root:
300
+
301
+ ```bash
302
+ npm run build:utils-package
303
+ npm run pack:utils-package
304
+ ```
305
+
306
+ Then publish from the package directory:
307
+
308
+ ```bash
309
+ cd packages/ipl-dashboard-utils
310
+ npm login
311
+ npm publish --access public
312
+ ```
313
+
314
+ ## License
315
+
316
+ `UNLICENSED`
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@vatvaghool/ipl-fantasy-dashboard",
3
+ "version": "0.1.1",
4
+ "description": "Safe, reusable IPL fantasy dashboard transformation utilities.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "build": "node ../../node_modules/typescript/bin/tsc -p tsconfig.build.json",
24
+ "prepack": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "ipl",
28
+ "fantasy-cricket",
29
+ "dashboard",
30
+ "typescript",
31
+ "transform"
32
+ ],
33
+ "license": "UNLICENSED"
34
+ }
@@ -0,0 +1,22 @@
1
+ export type {
2
+ DailyChartRow,
3
+ DashboardData,
4
+ OverallChartItem,
5
+ RawApiUser,
6
+ RawUsersSyncResult,
7
+ ScrapedDashboardPayload,
8
+ ScrapedLeaderboardItem,
9
+ ScrapedSquadPlayer,
10
+ TransformOptions,
11
+ } from "./types.js";
12
+
13
+ export {
14
+ addLeaderboardMetrics,
15
+ buildDashboardFromSnapshot,
16
+ buildManualDashboard,
17
+ normalizePayload,
18
+ normalizeRawApiUsers,
19
+ serializeRawApiUsersModule,
20
+ syncRawUsersWithSnapshot,
21
+ toFiniteNumber,
22
+ } from "./transform.js";