@opprs/db-prisma 2.2.1 → 2.5.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/dist/index.cjs +1233 -158
- package/dist/index.d.cts +1012 -106
- package/dist/index.d.ts +1012 -106
- package/dist/index.js +1117 -141
- package/package.json +1 -1
- package/prisma/migrations/20260104000000_add_player_number/migration.sql +23 -0
- package/prisma/migrations/20260104092800_add_location_model_and_tournament_fields/migration.sql +45 -0
- package/prisma/migrations/20260104210034_add_policy_acceptance_fields/migration.sql +19 -0
- package/prisma/migrations/20260104231435_split_entries_standings/migration.sql +137 -0
- package/prisma/migrations/20260105000000_add_oppr_ranking_models/migration.sql +108 -0
- package/prisma/schema.prisma +292 -37
- package/prisma/seed.ts +157 -48
package/prisma/seed.ts
CHANGED
|
@@ -13,51 +13,45 @@ async function main() {
|
|
|
13
13
|
const playerData = [
|
|
14
14
|
{
|
|
15
15
|
externalId: 'player-1',
|
|
16
|
+
playerNumber: 10001,
|
|
16
17
|
name: 'Alice Champion',
|
|
17
|
-
rating: 1850,
|
|
18
|
-
ratingDeviation: 50,
|
|
19
|
-
ranking: 5,
|
|
20
|
-
isRated: true,
|
|
21
18
|
eventCount: 25,
|
|
22
19
|
},
|
|
23
20
|
{
|
|
24
21
|
externalId: 'player-2',
|
|
22
|
+
playerNumber: 10002,
|
|
25
23
|
name: 'Bob Wizard',
|
|
26
|
-
rating: 1750,
|
|
27
|
-
ratingDeviation: 60,
|
|
28
|
-
ranking: 12,
|
|
29
|
-
isRated: true,
|
|
30
24
|
eventCount: 18,
|
|
31
25
|
},
|
|
32
26
|
{
|
|
33
27
|
externalId: 'player-3',
|
|
28
|
+
playerNumber: 10003,
|
|
34
29
|
name: 'Charlie Flipper',
|
|
35
|
-
rating: 1650,
|
|
36
|
-
ratingDeviation: 75,
|
|
37
|
-
ranking: 28,
|
|
38
|
-
isRated: true,
|
|
39
30
|
eventCount: 12,
|
|
40
31
|
},
|
|
41
32
|
{
|
|
42
33
|
externalId: 'player-4',
|
|
34
|
+
playerNumber: 10004,
|
|
43
35
|
name: 'Diana Tilt',
|
|
44
|
-
rating: 1550,
|
|
45
|
-
ratingDeviation: 100,
|
|
46
|
-
ranking: 45,
|
|
47
|
-
isRated: true,
|
|
48
36
|
eventCount: 8,
|
|
49
37
|
},
|
|
50
38
|
{
|
|
51
39
|
externalId: 'player-5',
|
|
40
|
+
playerNumber: 10005,
|
|
52
41
|
name: 'Eve Plunger',
|
|
53
|
-
rating: 1300,
|
|
54
|
-
ratingDeviation: 150,
|
|
55
|
-
ranking: null,
|
|
56
|
-
isRated: false,
|
|
57
42
|
eventCount: 3,
|
|
58
43
|
},
|
|
59
44
|
];
|
|
60
45
|
|
|
46
|
+
// OPPR ranking data for each player
|
|
47
|
+
const rankingData = [
|
|
48
|
+
{ rating: 1850, ratingDeviation: 50, ranking: 5, isRated: true },
|
|
49
|
+
{ rating: 1750, ratingDeviation: 60, ranking: 12, isRated: true },
|
|
50
|
+
{ rating: 1650, ratingDeviation: 75, ranking: 28, isRated: true },
|
|
51
|
+
{ rating: 1550, ratingDeviation: 100, ranking: 45, isRated: true },
|
|
52
|
+
{ rating: 1300, ratingDeviation: 150, ranking: null, isRated: false },
|
|
53
|
+
];
|
|
54
|
+
|
|
61
55
|
const player1 = await prisma.player.upsert({
|
|
62
56
|
where: { externalId: 'player-1' },
|
|
63
57
|
update: playerData[0],
|
|
@@ -90,27 +84,129 @@ async function main() {
|
|
|
90
84
|
|
|
91
85
|
console.log(`✓ Created ${await prisma.player.count()} players`);
|
|
92
86
|
|
|
93
|
-
// Create
|
|
94
|
-
console.log('Creating
|
|
95
|
-
const
|
|
96
|
-
|
|
87
|
+
// Create OPPR rankings for each player
|
|
88
|
+
console.log('Creating OPPR rankings...');
|
|
89
|
+
const players = [player1, player2, player3, player4, player5];
|
|
90
|
+
for (let i = 0; i < players.length; i++) {
|
|
91
|
+
await prisma.opprPlayerRanking.upsert({
|
|
92
|
+
where: { playerId: players[i].id },
|
|
93
|
+
update: rankingData[i],
|
|
94
|
+
create: { playerId: players[i].id, ...rankingData[i] },
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
console.log(`✓ Created ${await prisma.opprPlayerRanking.count()} OPPR rankings`);
|
|
98
|
+
|
|
99
|
+
// Seed users from environment variables (development only)
|
|
100
|
+
const seedAdminEmail = process.env.SEED_ADMIN_EMAIL;
|
|
101
|
+
const seedAdminPassword = process.env.SEED_ADMIN_PASSWORD;
|
|
102
|
+
const seedTestEmail = process.env.SEED_TEST_EMAIL;
|
|
103
|
+
const seedTestPassword = process.env.SEED_TEST_PASSWORD;
|
|
104
|
+
|
|
105
|
+
// Create admin user if credentials provided
|
|
106
|
+
if (seedAdminEmail && seedAdminPassword) {
|
|
107
|
+
console.log('Creating admin user...');
|
|
108
|
+
const adminPasswordHash = await bcrypt.hash(seedAdminPassword, BCRYPT_SALT_ROUNDS);
|
|
109
|
+
await prisma.user.upsert({
|
|
110
|
+
where: { email: seedAdminEmail },
|
|
111
|
+
update: { passwordHash: adminPasswordHash, role: 'ADMIN' },
|
|
112
|
+
create: { email: seedAdminEmail, passwordHash: adminPasswordHash, role: 'ADMIN' },
|
|
113
|
+
});
|
|
114
|
+
console.log(`✓ Created admin user (${seedAdminEmail})`);
|
|
115
|
+
} else {
|
|
116
|
+
console.log('⏭ Skipping admin user (SEED_ADMIN_EMAIL/SEED_ADMIN_PASSWORD not set)');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Create test user if credentials provided (linked to Alice Champion)
|
|
120
|
+
if (seedTestEmail && seedTestPassword) {
|
|
121
|
+
console.log('Creating test user...');
|
|
122
|
+
const testPasswordHash = await bcrypt.hash(seedTestPassword, BCRYPT_SALT_ROUNDS);
|
|
123
|
+
await prisma.user.upsert({
|
|
124
|
+
where: { email: seedTestEmail },
|
|
125
|
+
update: { passwordHash: testPasswordHash, role: 'USER', playerId: player1.id },
|
|
126
|
+
create: { email: seedTestEmail, passwordHash: testPasswordHash, role: 'USER', playerId: player1.id },
|
|
127
|
+
});
|
|
128
|
+
console.log(`✓ Created test user (${seedTestEmail}) linked to ${player1.name}`);
|
|
129
|
+
} else {
|
|
130
|
+
console.log('⏭ Skipping test user (SEED_TEST_EMAIL/SEED_TEST_PASSWORD not set)');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Create admin user
|
|
134
|
+
console.log('Creating admin user...');
|
|
135
|
+
const adminPassword = 'AdminPassword123!';
|
|
136
|
+
const adminPasswordHash = await bcrypt.hash(adminPassword, BCRYPT_SALT_ROUNDS);
|
|
97
137
|
|
|
98
138
|
await prisma.user.upsert({
|
|
99
|
-
where: { email: '
|
|
139
|
+
where: { email: 'admin@example.com' },
|
|
140
|
+
update: {
|
|
141
|
+
passwordHash: adminPasswordHash,
|
|
142
|
+
role: 'ADMIN',
|
|
143
|
+
},
|
|
144
|
+
create: {
|
|
145
|
+
email: 'admin@example.com',
|
|
146
|
+
passwordHash: adminPasswordHash,
|
|
147
|
+
role: 'ADMIN',
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
console.log(`✓ Created admin user (admin@example.com / ${adminPassword})`);
|
|
152
|
+
|
|
153
|
+
// Create sample locations (using upsert for idempotency)
|
|
154
|
+
console.log('Creating locations...');
|
|
155
|
+
|
|
156
|
+
const location1 = await prisma.location.upsert({
|
|
157
|
+
where: { externalId: 'location-1' },
|
|
158
|
+
update: {
|
|
159
|
+
name: 'Las Vegas Convention Center',
|
|
160
|
+
city: 'Las Vegas',
|
|
161
|
+
state: 'NV',
|
|
162
|
+
country: 'USA',
|
|
163
|
+
},
|
|
164
|
+
create: {
|
|
165
|
+
externalId: 'location-1',
|
|
166
|
+
name: 'Las Vegas Convention Center',
|
|
167
|
+
city: 'Las Vegas',
|
|
168
|
+
state: 'NV',
|
|
169
|
+
country: 'USA',
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const location2 = await prisma.location.upsert({
|
|
174
|
+
where: { externalId: 'location-2' },
|
|
175
|
+
update: {
|
|
176
|
+
name: 'Ground Kontrol',
|
|
177
|
+
address: '115 NW 5th Ave',
|
|
178
|
+
city: 'Portland',
|
|
179
|
+
state: 'OR',
|
|
180
|
+
country: 'USA',
|
|
181
|
+
},
|
|
182
|
+
create: {
|
|
183
|
+
externalId: 'location-2',
|
|
184
|
+
name: 'Ground Kontrol',
|
|
185
|
+
address: '115 NW 5th Ave',
|
|
186
|
+
city: 'Portland',
|
|
187
|
+
state: 'OR',
|
|
188
|
+
country: 'USA',
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const location3 = await prisma.location.upsert({
|
|
193
|
+
where: { externalId: 'location-3' },
|
|
100
194
|
update: {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
195
|
+
name: 'Add-a-Ball Amusements',
|
|
196
|
+
city: 'Seattle',
|
|
197
|
+
state: 'WA',
|
|
198
|
+
country: 'USA',
|
|
104
199
|
},
|
|
105
200
|
create: {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
201
|
+
externalId: 'location-3',
|
|
202
|
+
name: 'Add-a-Ball Amusements',
|
|
203
|
+
city: 'Seattle',
|
|
204
|
+
state: 'WA',
|
|
205
|
+
country: 'USA',
|
|
110
206
|
},
|
|
111
207
|
});
|
|
112
208
|
|
|
113
|
-
console.log(`✓ Created
|
|
209
|
+
console.log(`✓ Created ${await prisma.location.count()} locations`);
|
|
114
210
|
|
|
115
211
|
// Create sample tournaments (using upsert for idempotency)
|
|
116
212
|
console.log('Creating tournaments...');
|
|
@@ -118,7 +214,7 @@ async function main() {
|
|
|
118
214
|
const tournament1Data = {
|
|
119
215
|
externalId: 'tournament-1',
|
|
120
216
|
name: 'World Pinball Championship 2024',
|
|
121
|
-
|
|
217
|
+
locationId: location1.id,
|
|
122
218
|
date: new Date('2024-03-15'),
|
|
123
219
|
eventBooster: EventBoosterType.MAJOR,
|
|
124
220
|
allowsOptOut: false,
|
|
@@ -154,7 +250,7 @@ async function main() {
|
|
|
154
250
|
const tournament2Data = {
|
|
155
251
|
externalId: 'tournament-2',
|
|
156
252
|
name: 'Spring Classics 2024',
|
|
157
|
-
|
|
253
|
+
locationId: location2.id,
|
|
158
254
|
date: new Date('2024-04-20'),
|
|
159
255
|
eventBooster: EventBoosterType.CERTIFIED,
|
|
160
256
|
allowsOptOut: true,
|
|
@@ -188,7 +284,7 @@ async function main() {
|
|
|
188
284
|
const tournament3Data = {
|
|
189
285
|
externalId: 'tournament-3',
|
|
190
286
|
name: 'Monthly League Finals',
|
|
191
|
-
|
|
287
|
+
locationId: location3.id,
|
|
192
288
|
date: new Date('2024-05-10'),
|
|
193
289
|
eventBooster: EventBoosterType.NONE,
|
|
194
290
|
allowsOptOut: false,
|
|
@@ -221,11 +317,11 @@ async function main() {
|
|
|
221
317
|
|
|
222
318
|
console.log(`✓ Created ${await prisma.tournament.count()} tournaments`);
|
|
223
319
|
|
|
224
|
-
// Create tournament
|
|
225
|
-
console.log('Creating tournament
|
|
320
|
+
// Create tournament standings (delete existing first for idempotency)
|
|
321
|
+
console.log('Creating tournament standings...');
|
|
226
322
|
|
|
227
|
-
// Delete existing
|
|
228
|
-
await prisma.
|
|
323
|
+
// Delete existing standings for seeded tournaments
|
|
324
|
+
await prisma.standing.deleteMany({
|
|
229
325
|
where: {
|
|
230
326
|
tournamentId: {
|
|
231
327
|
in: [tournament1.id, tournament2.id, tournament3.id],
|
|
@@ -233,13 +329,14 @@ async function main() {
|
|
|
233
329
|
},
|
|
234
330
|
});
|
|
235
331
|
|
|
236
|
-
// World Championship
|
|
237
|
-
await prisma.
|
|
332
|
+
// World Championship standings
|
|
333
|
+
await prisma.standing.createMany({
|
|
238
334
|
data: [
|
|
239
335
|
{
|
|
240
336
|
playerId: player1.id,
|
|
241
337
|
tournamentId: tournament1.id,
|
|
242
338
|
position: 1,
|
|
339
|
+
isFinals: true,
|
|
243
340
|
totalPoints: 411.84,
|
|
244
341
|
linearPoints: 41.18,
|
|
245
342
|
dynamicPoints: 370.66,
|
|
@@ -252,6 +349,7 @@ async function main() {
|
|
|
252
349
|
playerId: player2.id,
|
|
253
350
|
tournamentId: tournament1.id,
|
|
254
351
|
position: 2,
|
|
352
|
+
isFinals: true,
|
|
255
353
|
totalPoints: 298.45,
|
|
256
354
|
linearPoints: 41.18,
|
|
257
355
|
dynamicPoints: 257.27,
|
|
@@ -264,6 +362,7 @@ async function main() {
|
|
|
264
362
|
playerId: player3.id,
|
|
265
363
|
tournamentId: tournament1.id,
|
|
266
364
|
position: 3,
|
|
365
|
+
isFinals: true,
|
|
267
366
|
totalPoints: 215.32,
|
|
268
367
|
linearPoints: 41.18,
|
|
269
368
|
dynamicPoints: 174.14,
|
|
@@ -276,6 +375,7 @@ async function main() {
|
|
|
276
375
|
playerId: player4.id,
|
|
277
376
|
tournamentId: tournament1.id,
|
|
278
377
|
position: 5,
|
|
378
|
+
isFinals: true,
|
|
279
379
|
totalPoints: 125.18,
|
|
280
380
|
linearPoints: 41.18,
|
|
281
381
|
dynamicPoints: 84.00,
|
|
@@ -287,13 +387,14 @@ async function main() {
|
|
|
287
387
|
],
|
|
288
388
|
});
|
|
289
389
|
|
|
290
|
-
// Spring Classics
|
|
291
|
-
await prisma.
|
|
390
|
+
// Spring Classics standings
|
|
391
|
+
await prisma.standing.createMany({
|
|
292
392
|
data: [
|
|
293
393
|
{
|
|
294
394
|
playerId: player2.id,
|
|
295
395
|
tournamentId: tournament2.id,
|
|
296
396
|
position: 1,
|
|
397
|
+
isFinals: true,
|
|
297
398
|
totalPoints: 87.28,
|
|
298
399
|
linearPoints: 8.73,
|
|
299
400
|
dynamicPoints: 78.55,
|
|
@@ -306,6 +407,7 @@ async function main() {
|
|
|
306
407
|
playerId: player1.id,
|
|
307
408
|
tournamentId: tournament2.id,
|
|
308
409
|
position: 2,
|
|
410
|
+
isFinals: true,
|
|
309
411
|
totalPoints: 63.25,
|
|
310
412
|
linearPoints: 8.73,
|
|
311
413
|
dynamicPoints: 54.52,
|
|
@@ -318,6 +420,7 @@ async function main() {
|
|
|
318
420
|
playerId: player4.id,
|
|
319
421
|
tournamentId: tournament2.id,
|
|
320
422
|
position: 3,
|
|
423
|
+
isFinals: true,
|
|
321
424
|
totalPoints: 45.67,
|
|
322
425
|
linearPoints: 8.73,
|
|
323
426
|
dynamicPoints: 36.94,
|
|
@@ -330,6 +433,7 @@ async function main() {
|
|
|
330
433
|
playerId: player5.id,
|
|
331
434
|
tournamentId: tournament2.id,
|
|
332
435
|
position: 6,
|
|
436
|
+
isFinals: true,
|
|
333
437
|
totalPoints: 18.52,
|
|
334
438
|
linearPoints: 8.73,
|
|
335
439
|
dynamicPoints: 9.79,
|
|
@@ -341,13 +445,14 @@ async function main() {
|
|
|
341
445
|
],
|
|
342
446
|
});
|
|
343
447
|
|
|
344
|
-
// Monthly League
|
|
345
|
-
await prisma.
|
|
448
|
+
// Monthly League standings
|
|
449
|
+
await prisma.standing.createMany({
|
|
346
450
|
data: [
|
|
347
451
|
{
|
|
348
452
|
playerId: player3.id,
|
|
349
453
|
tournamentId: tournament3.id,
|
|
350
454
|
position: 1,
|
|
455
|
+
isFinals: true,
|
|
351
456
|
totalPoints: 28.4,
|
|
352
457
|
linearPoints: 2.84,
|
|
353
458
|
dynamicPoints: 25.56,
|
|
@@ -360,6 +465,7 @@ async function main() {
|
|
|
360
465
|
playerId: player4.id,
|
|
361
466
|
tournamentId: tournament3.id,
|
|
362
467
|
position: 2,
|
|
468
|
+
isFinals: true,
|
|
363
469
|
totalPoints: 20.58,
|
|
364
470
|
linearPoints: 2.84,
|
|
365
471
|
dynamicPoints: 17.74,
|
|
@@ -372,6 +478,7 @@ async function main() {
|
|
|
372
478
|
playerId: player5.id,
|
|
373
479
|
tournamentId: tournament3.id,
|
|
374
480
|
position: 3,
|
|
481
|
+
isFinals: true,
|
|
375
482
|
totalPoints: 14.85,
|
|
376
483
|
linearPoints: 2.84,
|
|
377
484
|
dynamicPoints: 12.01,
|
|
@@ -383,16 +490,18 @@ async function main() {
|
|
|
383
490
|
],
|
|
384
491
|
});
|
|
385
492
|
|
|
386
|
-
console.log(`✓ Created ${await prisma.
|
|
493
|
+
console.log(`✓ Created ${await prisma.standing.count()} tournament standings`);
|
|
387
494
|
|
|
388
495
|
console.log('');
|
|
389
496
|
console.log('✅ Database seeded successfully!');
|
|
390
497
|
console.log('');
|
|
391
498
|
console.log('Summary:');
|
|
392
499
|
console.log(` - ${await prisma.player.count()} players`);
|
|
500
|
+
console.log(` - ${await prisma.opprPlayerRanking.count()} OPPR rankings`);
|
|
393
501
|
console.log(` - ${await prisma.user.count()} users`);
|
|
502
|
+
console.log(` - ${await prisma.location.count()} locations`);
|
|
394
503
|
console.log(` - ${await prisma.tournament.count()} tournaments`);
|
|
395
|
-
console.log(` - ${await prisma.
|
|
504
|
+
console.log(` - ${await prisma.standing.count()} standings`);
|
|
396
505
|
}
|
|
397
506
|
|
|
398
507
|
main()
|