@opprs/db-prisma 2.1.0 → 2.2.1-canary.2db0cbb
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/package.json +5 -3
- package/prisma/seed.ts +186 -109
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opprs/db-prisma",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.2.1-canary.2db0cbb",
|
|
4
4
|
"description": "Database backend for OPPR (Open Pinball Player Ranking System) using Prisma and PostgreSQL",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"oppr",
|
|
@@ -40,7 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@testcontainers/postgresql": "^11.11.0",
|
|
43
|
+
"@types/bcrypt": "^6.0.0",
|
|
43
44
|
"@types/node": "^22.10.5",
|
|
45
|
+
"bcrypt": "^6.0.0",
|
|
44
46
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
45
47
|
"@typescript-eslint/parser": "^8.19.1",
|
|
46
48
|
"@vitest/coverage-v8": "^4.0.16",
|
|
@@ -54,10 +56,10 @@
|
|
|
54
56
|
"vitest": "^4.0.16"
|
|
55
57
|
},
|
|
56
58
|
"peerDependencies": {
|
|
57
|
-
"@opprs/core": "^
|
|
59
|
+
"@opprs/core": "^2.2.1-canary.2db0cbb"
|
|
58
60
|
},
|
|
59
61
|
"engines": {
|
|
60
|
-
"node": ">=
|
|
62
|
+
"node": ">=20.9.0"
|
|
61
63
|
},
|
|
62
64
|
"prisma": {
|
|
63
65
|
"seed": "tsx prisma/seed.ts"
|
package/prisma/seed.ts
CHANGED
|
@@ -1,182 +1,258 @@
|
|
|
1
1
|
import { PrismaClient, EventBoosterType } from '@prisma/client';
|
|
2
|
+
import bcrypt from 'bcrypt';
|
|
2
3
|
|
|
3
4
|
const prisma = new PrismaClient();
|
|
4
5
|
|
|
6
|
+
const BCRYPT_SALT_ROUNDS = 12;
|
|
7
|
+
|
|
5
8
|
async function main() {
|
|
6
9
|
console.log('🌱 Seeding database...');
|
|
7
10
|
|
|
8
|
-
// Create sample players
|
|
11
|
+
// Create sample players (using upsert for idempotency)
|
|
9
12
|
console.log('Creating players...');
|
|
10
|
-
const
|
|
11
|
-
|
|
13
|
+
const playerData = [
|
|
14
|
+
{
|
|
12
15
|
externalId: 'player-1',
|
|
13
16
|
name: 'Alice Champion',
|
|
14
|
-
email: 'alice@example.com',
|
|
15
17
|
rating: 1850,
|
|
16
18
|
ratingDeviation: 50,
|
|
17
19
|
ranking: 5,
|
|
18
20
|
isRated: true,
|
|
19
21
|
eventCount: 25,
|
|
20
22
|
},
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const player2 = await prisma.player.create({
|
|
24
|
-
data: {
|
|
23
|
+
{
|
|
25
24
|
externalId: 'player-2',
|
|
26
25
|
name: 'Bob Wizard',
|
|
27
|
-
email: 'bob@example.com',
|
|
28
26
|
rating: 1750,
|
|
29
27
|
ratingDeviation: 60,
|
|
30
28
|
ranking: 12,
|
|
31
29
|
isRated: true,
|
|
32
30
|
eventCount: 18,
|
|
33
31
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const player3 = await prisma.player.create({
|
|
37
|
-
data: {
|
|
32
|
+
{
|
|
38
33
|
externalId: 'player-3',
|
|
39
34
|
name: 'Charlie Flipper',
|
|
40
|
-
email: 'charlie@example.com',
|
|
41
35
|
rating: 1650,
|
|
42
36
|
ratingDeviation: 75,
|
|
43
37
|
ranking: 28,
|
|
44
38
|
isRated: true,
|
|
45
39
|
eventCount: 12,
|
|
46
40
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const player4 = await prisma.player.create({
|
|
50
|
-
data: {
|
|
41
|
+
{
|
|
51
42
|
externalId: 'player-4',
|
|
52
43
|
name: 'Diana Tilt',
|
|
53
|
-
email: 'diana@example.com',
|
|
54
44
|
rating: 1550,
|
|
55
45
|
ratingDeviation: 100,
|
|
56
46
|
ranking: 45,
|
|
57
47
|
isRated: true,
|
|
58
48
|
eventCount: 8,
|
|
59
49
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const player5 = await prisma.player.create({
|
|
63
|
-
data: {
|
|
50
|
+
{
|
|
64
51
|
externalId: 'player-5',
|
|
65
52
|
name: 'Eve Plunger',
|
|
66
|
-
email: 'eve@example.com',
|
|
67
53
|
rating: 1300,
|
|
68
54
|
ratingDeviation: 150,
|
|
69
55
|
ranking: null,
|
|
70
56
|
isRated: false,
|
|
71
57
|
eventCount: 3,
|
|
72
58
|
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
const player1 = await prisma.player.upsert({
|
|
62
|
+
where: { externalId: 'player-1' },
|
|
63
|
+
update: playerData[0],
|
|
64
|
+
create: playerData[0],
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const player2 = await prisma.player.upsert({
|
|
68
|
+
where: { externalId: 'player-2' },
|
|
69
|
+
update: playerData[1],
|
|
70
|
+
create: playerData[1],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const player3 = await prisma.player.upsert({
|
|
74
|
+
where: { externalId: 'player-3' },
|
|
75
|
+
update: playerData[2],
|
|
76
|
+
create: playerData[2],
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const player4 = await prisma.player.upsert({
|
|
80
|
+
where: { externalId: 'player-4' },
|
|
81
|
+
update: playerData[3],
|
|
82
|
+
create: playerData[3],
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const player5 = await prisma.player.upsert({
|
|
86
|
+
where: { externalId: 'player-5' },
|
|
87
|
+
update: playerData[4],
|
|
88
|
+
create: playerData[4],
|
|
73
89
|
});
|
|
74
90
|
|
|
75
91
|
console.log(`✓ Created ${await prisma.player.count()} players`);
|
|
76
92
|
|
|
77
|
-
// Create
|
|
93
|
+
// Create test user for e2e tests (linked to Alice Champion)
|
|
94
|
+
console.log('Creating test user...');
|
|
95
|
+
const testPassword = 'TestPassword123!';
|
|
96
|
+
const passwordHash = await bcrypt.hash(testPassword, BCRYPT_SALT_ROUNDS);
|
|
97
|
+
|
|
98
|
+
await prisma.user.upsert({
|
|
99
|
+
where: { email: 'e2e-test@example.com' },
|
|
100
|
+
update: {
|
|
101
|
+
passwordHash,
|
|
102
|
+
role: 'USER',
|
|
103
|
+
playerId: player1.id,
|
|
104
|
+
},
|
|
105
|
+
create: {
|
|
106
|
+
email: 'e2e-test@example.com',
|
|
107
|
+
passwordHash,
|
|
108
|
+
role: 'USER',
|
|
109
|
+
playerId: player1.id,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
console.log(`✓ Created test user (e2e-test@example.com / ${testPassword})`);
|
|
114
|
+
|
|
115
|
+
// Create admin user
|
|
116
|
+
console.log('Creating admin user...');
|
|
117
|
+
const adminPassword = 'AdminPassword123!';
|
|
118
|
+
const adminPasswordHash = await bcrypt.hash(adminPassword, BCRYPT_SALT_ROUNDS);
|
|
119
|
+
|
|
120
|
+
await prisma.user.upsert({
|
|
121
|
+
where: { email: 'admin@example.com' },
|
|
122
|
+
update: {
|
|
123
|
+
passwordHash: adminPasswordHash,
|
|
124
|
+
role: 'ADMIN',
|
|
125
|
+
},
|
|
126
|
+
create: {
|
|
127
|
+
email: 'admin@example.com',
|
|
128
|
+
passwordHash: adminPasswordHash,
|
|
129
|
+
role: 'ADMIN',
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
console.log(`✓ Created admin user (admin@example.com / ${adminPassword})`);
|
|
134
|
+
|
|
135
|
+
// Create sample tournaments (using upsert for idempotency)
|
|
78
136
|
console.log('Creating tournaments...');
|
|
79
137
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
meaningfulGames: 12,
|
|
93
|
-
fourPlayerGroups: true,
|
|
94
|
-
},
|
|
95
|
-
finals: {
|
|
96
|
-
formatType: 'match-play',
|
|
97
|
-
meaningfulGames: 20,
|
|
98
|
-
fourPlayerGroups: true,
|
|
99
|
-
finalistCount: 16,
|
|
100
|
-
},
|
|
101
|
-
ballCountAdjustment: 1.0,
|
|
138
|
+
const tournament1Data = {
|
|
139
|
+
externalId: 'tournament-1',
|
|
140
|
+
name: 'World Pinball Championship 2024',
|
|
141
|
+
location: 'Las Vegas, NV',
|
|
142
|
+
date: new Date('2024-03-15'),
|
|
143
|
+
eventBooster: EventBoosterType.MAJOR,
|
|
144
|
+
allowsOptOut: false,
|
|
145
|
+
tgpConfig: {
|
|
146
|
+
qualifying: {
|
|
147
|
+
type: 'limited',
|
|
148
|
+
meaningfulGames: 12,
|
|
149
|
+
fourPlayerGroups: true,
|
|
102
150
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
151
|
+
finals: {
|
|
152
|
+
formatType: 'match-play',
|
|
153
|
+
meaningfulGames: 20,
|
|
154
|
+
fourPlayerGroups: true,
|
|
155
|
+
finalistCount: 16,
|
|
156
|
+
},
|
|
157
|
+
ballCountAdjustment: 1.0,
|
|
110
158
|
},
|
|
159
|
+
baseValue: 32.0,
|
|
160
|
+
tvaRating: 25.0,
|
|
161
|
+
tvaRanking: 50.0,
|
|
162
|
+
totalTVA: 75.0,
|
|
163
|
+
tgp: 1.92,
|
|
164
|
+
eventBoosterMultiplier: 2.0,
|
|
165
|
+
firstPlaceValue: 411.84,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const tournament1 = await prisma.tournament.upsert({
|
|
169
|
+
where: { externalId: 'tournament-1' },
|
|
170
|
+
update: tournament1Data,
|
|
171
|
+
create: tournament1Data,
|
|
111
172
|
});
|
|
112
173
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
fourPlayerGroups: false,
|
|
131
|
-
finalistCount: 8,
|
|
132
|
-
},
|
|
174
|
+
const tournament2Data = {
|
|
175
|
+
externalId: 'tournament-2',
|
|
176
|
+
name: 'Spring Classics 2024',
|
|
177
|
+
location: 'Portland, OR',
|
|
178
|
+
date: new Date('2024-04-20'),
|
|
179
|
+
eventBooster: EventBoosterType.CERTIFIED,
|
|
180
|
+
allowsOptOut: true,
|
|
181
|
+
tgpConfig: {
|
|
182
|
+
qualifying: {
|
|
183
|
+
type: 'limited',
|
|
184
|
+
meaningfulGames: 7,
|
|
185
|
+
},
|
|
186
|
+
finals: {
|
|
187
|
+
formatType: 'double-elimination',
|
|
188
|
+
meaningfulGames: 15,
|
|
189
|
+
fourPlayerGroups: false,
|
|
190
|
+
finalistCount: 8,
|
|
133
191
|
},
|
|
134
|
-
baseValue: 28.0,
|
|
135
|
-
tvaRating: 18.5,
|
|
136
|
-
tvaRanking: 32.0,
|
|
137
|
-
totalTVA: 50.5,
|
|
138
|
-
tgp: 0.88,
|
|
139
|
-
eventBoosterMultiplier: 1.25,
|
|
140
|
-
firstPlaceValue: 87.28,
|
|
141
192
|
},
|
|
193
|
+
baseValue: 28.0,
|
|
194
|
+
tvaRating: 18.5,
|
|
195
|
+
tvaRanking: 32.0,
|
|
196
|
+
totalTVA: 50.5,
|
|
197
|
+
tgp: 0.88,
|
|
198
|
+
eventBoosterMultiplier: 1.25,
|
|
199
|
+
firstPlaceValue: 87.28,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const tournament2 = await prisma.tournament.upsert({
|
|
203
|
+
where: { externalId: 'tournament-2' },
|
|
204
|
+
update: tournament2Data,
|
|
205
|
+
create: tournament2Data,
|
|
142
206
|
});
|
|
143
207
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
fourPlayerGroups: true,
|
|
162
|
-
finalistCount: 8,
|
|
163
|
-
},
|
|
208
|
+
const tournament3Data = {
|
|
209
|
+
externalId: 'tournament-3',
|
|
210
|
+
name: 'Monthly League Finals',
|
|
211
|
+
location: 'Seattle, WA',
|
|
212
|
+
date: new Date('2024-05-10'),
|
|
213
|
+
eventBooster: EventBoosterType.NONE,
|
|
214
|
+
allowsOptOut: false,
|
|
215
|
+
tgpConfig: {
|
|
216
|
+
qualifying: {
|
|
217
|
+
type: 'none',
|
|
218
|
+
meaningfulGames: 0,
|
|
219
|
+
},
|
|
220
|
+
finals: {
|
|
221
|
+
formatType: 'match-play',
|
|
222
|
+
meaningfulGames: 10,
|
|
223
|
+
fourPlayerGroups: true,
|
|
224
|
+
finalistCount: 8,
|
|
164
225
|
},
|
|
165
|
-
baseValue: 15.0,
|
|
166
|
-
tvaRating: 8.5,
|
|
167
|
-
tvaRanking: 12.0,
|
|
168
|
-
totalTVA: 20.5,
|
|
169
|
-
tgp: 0.80,
|
|
170
|
-
eventBoosterMultiplier: 1.0,
|
|
171
|
-
firstPlaceValue: 28.4,
|
|
172
226
|
},
|
|
227
|
+
baseValue: 15.0,
|
|
228
|
+
tvaRating: 8.5,
|
|
229
|
+
tvaRanking: 12.0,
|
|
230
|
+
totalTVA: 20.5,
|
|
231
|
+
tgp: 0.80,
|
|
232
|
+
eventBoosterMultiplier: 1.0,
|
|
233
|
+
firstPlaceValue: 28.4,
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const tournament3 = await prisma.tournament.upsert({
|
|
237
|
+
where: { externalId: 'tournament-3' },
|
|
238
|
+
update: tournament3Data,
|
|
239
|
+
create: tournament3Data,
|
|
173
240
|
});
|
|
174
241
|
|
|
175
242
|
console.log(`✓ Created ${await prisma.tournament.count()} tournaments`);
|
|
176
243
|
|
|
177
|
-
// Create tournament results
|
|
244
|
+
// Create tournament results (delete existing first for idempotency)
|
|
178
245
|
console.log('Creating tournament results...');
|
|
179
246
|
|
|
247
|
+
// Delete existing results for seeded tournaments
|
|
248
|
+
await prisma.tournamentResult.deleteMany({
|
|
249
|
+
where: {
|
|
250
|
+
tournamentId: {
|
|
251
|
+
in: [tournament1.id, tournament2.id, tournament3.id],
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
|
|
180
256
|
// World Championship results
|
|
181
257
|
await prisma.tournamentResult.createMany({
|
|
182
258
|
data: [
|
|
@@ -334,6 +410,7 @@ async function main() {
|
|
|
334
410
|
console.log('');
|
|
335
411
|
console.log('Summary:');
|
|
336
412
|
console.log(` - ${await prisma.player.count()} players`);
|
|
413
|
+
console.log(` - ${await prisma.user.count()} users`);
|
|
337
414
|
console.log(` - ${await prisma.tournament.count()} tournaments`);
|
|
338
415
|
console.log(` - ${await prisma.tournamentResult.count()} tournament results`);
|
|
339
416
|
}
|