@opprs/db-prisma 0.5.2-canary.16741f5

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.js ADDED
@@ -0,0 +1,500 @@
1
+ // src/client.ts
2
+ import { PrismaClient } from "@prisma/client";
3
+ var globalForPrisma = globalThis;
4
+ var prisma = globalForPrisma.prisma ?? new PrismaClient({
5
+ log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"]
6
+ });
7
+ if (process.env.NODE_ENV !== "production") {
8
+ globalForPrisma.prisma = prisma;
9
+ }
10
+ async function disconnect() {
11
+ await prisma.$disconnect();
12
+ }
13
+ async function connect() {
14
+ await prisma.$connect();
15
+ }
16
+ async function testConnection() {
17
+ try {
18
+ await prisma.$queryRaw`SELECT 1`;
19
+ return true;
20
+ } catch (error) {
21
+ console.error("Database connection test failed:", error);
22
+ return false;
23
+ }
24
+ }
25
+
26
+ // src/players.ts
27
+ async function createPlayer(data) {
28
+ return prisma.player.create({
29
+ data
30
+ });
31
+ }
32
+ async function findPlayerById(id, include) {
33
+ return prisma.player.findUnique({
34
+ where: { id },
35
+ include
36
+ });
37
+ }
38
+ async function findPlayerByExternalId(externalId, include) {
39
+ return prisma.player.findUnique({
40
+ where: { externalId },
41
+ include
42
+ });
43
+ }
44
+ async function findPlayerByEmail(email, include) {
45
+ return prisma.player.findUnique({
46
+ where: { email },
47
+ include
48
+ });
49
+ }
50
+ async function findPlayers(options = {}) {
51
+ return prisma.player.findMany({
52
+ take: options.take,
53
+ skip: options.skip,
54
+ where: options.where,
55
+ orderBy: options.orderBy,
56
+ include: options.include
57
+ });
58
+ }
59
+ async function getRatedPlayers(options = {}) {
60
+ return findPlayers({
61
+ ...options,
62
+ where: { isRated: true }
63
+ });
64
+ }
65
+ async function getTopPlayersByRating(limit = 50) {
66
+ return findPlayers({
67
+ take: limit,
68
+ orderBy: { rating: "desc" },
69
+ where: { isRated: true }
70
+ });
71
+ }
72
+ async function getTopPlayersByRanking(limit = 50) {
73
+ return findPlayers({
74
+ take: limit,
75
+ orderBy: { ranking: "asc" },
76
+ where: {
77
+ isRated: true,
78
+ ranking: { not: null }
79
+ }
80
+ });
81
+ }
82
+ async function updatePlayer(id, data) {
83
+ return prisma.player.update({
84
+ where: { id },
85
+ data
86
+ });
87
+ }
88
+ async function updatePlayerRating(id, rating, ratingDeviation, eventCount) {
89
+ const updateData = {
90
+ rating,
91
+ ratingDeviation,
92
+ lastRatingUpdate: /* @__PURE__ */ new Date(),
93
+ lastEventDate: /* @__PURE__ */ new Date()
94
+ };
95
+ if (eventCount !== void 0) {
96
+ updateData.eventCount = eventCount;
97
+ updateData.isRated = eventCount >= 5;
98
+ }
99
+ return updatePlayer(id, updateData);
100
+ }
101
+ async function deletePlayer(id) {
102
+ return prisma.player.delete({
103
+ where: { id }
104
+ });
105
+ }
106
+ async function countPlayers(where) {
107
+ return prisma.player.count({ where });
108
+ }
109
+ async function getPlayerWithResults(id) {
110
+ const player = await prisma.player.findUnique({
111
+ where: { id },
112
+ include: {
113
+ tournamentResults: {
114
+ include: {
115
+ tournament: true
116
+ },
117
+ orderBy: {
118
+ tournament: {
119
+ date: "desc"
120
+ }
121
+ }
122
+ }
123
+ }
124
+ });
125
+ if (!player) {
126
+ return null;
127
+ }
128
+ return {
129
+ ...player,
130
+ results: player.tournamentResults
131
+ };
132
+ }
133
+ async function searchPlayers(query, limit = 20) {
134
+ return findPlayers({
135
+ take: limit,
136
+ where: {
137
+ OR: [
138
+ { name: { contains: query, mode: "insensitive" } },
139
+ { email: { contains: query, mode: "insensitive" } }
140
+ ]
141
+ }
142
+ });
143
+ }
144
+
145
+ // src/tournaments.ts
146
+ async function createTournament(data) {
147
+ return prisma.tournament.create({
148
+ data: {
149
+ ...data,
150
+ eventBooster: data.eventBooster ?? "NONE"
151
+ }
152
+ });
153
+ }
154
+ async function findTournamentById(id, include) {
155
+ return prisma.tournament.findUnique({
156
+ where: { id },
157
+ include
158
+ });
159
+ }
160
+ async function findTournamentByExternalId(externalId, include) {
161
+ return prisma.tournament.findUnique({
162
+ where: { externalId },
163
+ include
164
+ });
165
+ }
166
+ async function findTournaments(options = {}) {
167
+ return prisma.tournament.findMany({
168
+ take: options.take,
169
+ skip: options.skip,
170
+ where: options.where,
171
+ orderBy: options.orderBy,
172
+ include: options.include
173
+ });
174
+ }
175
+ async function getRecentTournaments(limit = 20, include) {
176
+ return findTournaments({
177
+ take: limit,
178
+ orderBy: { date: "desc" },
179
+ include
180
+ });
181
+ }
182
+ async function getTournamentsByDateRange(startDate, endDate, options = {}) {
183
+ return findTournaments({
184
+ ...options,
185
+ where: {
186
+ date: {
187
+ gte: startDate,
188
+ lte: endDate
189
+ }
190
+ }
191
+ });
192
+ }
193
+ async function getTournamentsByBoosterType(boosterType, options = {}) {
194
+ return findTournaments({
195
+ ...options,
196
+ where: { eventBooster: boosterType }
197
+ });
198
+ }
199
+ async function getMajorTournaments(limit) {
200
+ return findTournaments({
201
+ take: limit,
202
+ where: { eventBooster: "MAJOR" },
203
+ orderBy: { date: "desc" }
204
+ });
205
+ }
206
+ async function updateTournament(id, data) {
207
+ return prisma.tournament.update({
208
+ where: { id },
209
+ data
210
+ });
211
+ }
212
+ async function deleteTournament(id) {
213
+ return prisma.tournament.delete({
214
+ where: { id }
215
+ });
216
+ }
217
+ async function countTournaments(where) {
218
+ return prisma.tournament.count({ where });
219
+ }
220
+ async function getTournamentWithResults(id) {
221
+ return prisma.tournament.findUnique({
222
+ where: { id },
223
+ include: {
224
+ results: {
225
+ include: {
226
+ player: true
227
+ },
228
+ orderBy: {
229
+ position: "asc"
230
+ }
231
+ }
232
+ }
233
+ });
234
+ }
235
+ async function searchTournaments(query, limit = 20) {
236
+ return findTournaments({
237
+ take: limit,
238
+ where: {
239
+ OR: [
240
+ { name: { contains: query, mode: "insensitive" } },
241
+ { location: { contains: query, mode: "insensitive" } }
242
+ ]
243
+ },
244
+ orderBy: { date: "desc" }
245
+ });
246
+ }
247
+ async function getTournamentStats(id) {
248
+ const tournament = await getTournamentWithResults(id);
249
+ if (!tournament) {
250
+ return null;
251
+ }
252
+ const playerCount = tournament.results.length;
253
+ if (playerCount === 0) {
254
+ return {
255
+ tournament,
256
+ playerCount: 0,
257
+ averagePoints: 0,
258
+ averageEfficiency: 0,
259
+ highestPoints: 0,
260
+ lowestPoints: 0
261
+ };
262
+ }
263
+ const totalPoints = tournament.results.reduce((sum, r) => sum + (r.totalPoints || 0), 0);
264
+ const totalEfficiency = tournament.results.reduce((sum, r) => sum + (r.efficiency || 0), 0);
265
+ const allPoints = tournament.results.map((r) => r.totalPoints || 0);
266
+ return {
267
+ tournament,
268
+ playerCount,
269
+ averagePoints: totalPoints / playerCount,
270
+ averageEfficiency: totalEfficiency / playerCount,
271
+ highestPoints: Math.max(...allPoints),
272
+ lowestPoints: Math.min(...allPoints)
273
+ };
274
+ }
275
+
276
+ // src/results.ts
277
+ async function createResult(data) {
278
+ const resultData = {
279
+ ...data,
280
+ decayedPoints: data.decayedPoints ?? data.totalPoints ?? 0
281
+ };
282
+ return prisma.tournamentResult.create({
283
+ data: resultData
284
+ });
285
+ }
286
+ async function createManyResults(data) {
287
+ const resultsData = data.map((item) => ({
288
+ ...item,
289
+ decayedPoints: item.decayedPoints ?? item.totalPoints ?? 0
290
+ }));
291
+ return prisma.tournamentResult.createMany({
292
+ data: resultsData
293
+ });
294
+ }
295
+ async function findResultById(id, include) {
296
+ return prisma.tournamentResult.findUnique({
297
+ where: { id },
298
+ include
299
+ });
300
+ }
301
+ async function findResultByPlayerAndTournament(playerId, tournamentId, include) {
302
+ return prisma.tournamentResult.findUnique({
303
+ where: {
304
+ playerId_tournamentId: {
305
+ playerId,
306
+ tournamentId
307
+ }
308
+ },
309
+ include
310
+ });
311
+ }
312
+ async function findResults(options = {}) {
313
+ return prisma.tournamentResult.findMany({
314
+ take: options.take,
315
+ skip: options.skip,
316
+ where: options.where,
317
+ orderBy: options.orderBy,
318
+ include: options.include
319
+ });
320
+ }
321
+ async function getPlayerResults(playerId, options = {}) {
322
+ return findResults({
323
+ ...options,
324
+ where: { playerId },
325
+ include: { tournament: true, ...options.include },
326
+ orderBy: { tournament: { date: "desc" } }
327
+ });
328
+ }
329
+ async function getTournamentResults(tournamentId, options = {}) {
330
+ return findResults({
331
+ ...options,
332
+ where: { tournamentId },
333
+ include: { player: true, ...options.include },
334
+ orderBy: { position: "asc" }
335
+ });
336
+ }
337
+ async function getPlayerTopFinishes(playerId, limit = 15) {
338
+ return findResults({
339
+ where: { playerId },
340
+ take: limit,
341
+ include: { tournament: true },
342
+ orderBy: { decayedPoints: "desc" }
343
+ });
344
+ }
345
+ async function updateResult(id, data) {
346
+ return prisma.tournamentResult.update({
347
+ where: { id },
348
+ data
349
+ });
350
+ }
351
+ async function updateResultPoints(id, linearPoints, dynamicPoints, totalPoints) {
352
+ const result = await findResultById(id, {
353
+ tournament: true
354
+ });
355
+ if (!result) {
356
+ throw new Error(`Result with id ${id} not found`);
357
+ }
358
+ const now = /* @__PURE__ */ new Date();
359
+ const tournamentDate = result.tournament.date;
360
+ const ageInDays = Math.floor((now.getTime() - tournamentDate.getTime()) / (1e3 * 60 * 60 * 24));
361
+ const ageInYears = ageInDays / 365;
362
+ let decayMultiplier = 0;
363
+ if (ageInYears < 1) {
364
+ decayMultiplier = 1;
365
+ } else if (ageInYears < 2) {
366
+ decayMultiplier = 0.75;
367
+ } else if (ageInYears < 3) {
368
+ decayMultiplier = 0.5;
369
+ } else {
370
+ decayMultiplier = 0;
371
+ }
372
+ const decayedPoints = totalPoints * decayMultiplier;
373
+ return updateResult(id, {
374
+ linearPoints,
375
+ dynamicPoints,
376
+ totalPoints,
377
+ ageInDays,
378
+ decayMultiplier,
379
+ decayedPoints
380
+ });
381
+ }
382
+ async function deleteResult(id) {
383
+ return prisma.tournamentResult.delete({
384
+ where: { id }
385
+ });
386
+ }
387
+ async function deleteResultsByTournament(tournamentId) {
388
+ return prisma.tournamentResult.deleteMany({
389
+ where: { tournamentId }
390
+ });
391
+ }
392
+ async function countResults(where) {
393
+ return prisma.tournamentResult.count({ where });
394
+ }
395
+ async function getPlayerStats(playerId) {
396
+ const results = await getPlayerResults(playerId);
397
+ if (results.length === 0) {
398
+ return null;
399
+ }
400
+ const totalPoints = results.reduce((sum, r) => sum + (r.totalPoints || 0), 0);
401
+ const totalDecayedPoints = results.reduce((sum, r) => sum + (r.decayedPoints || 0), 0);
402
+ const averagePosition = results.reduce((sum, r) => sum + r.position, 0) / results.length;
403
+ const averageEfficiency = results.reduce((sum, r) => sum + (r.efficiency || 0), 0) / results.length;
404
+ const firstPlaceFinishes = results.filter((r) => r.position === 1).length;
405
+ const topThreeFinishes = results.filter((r) => r.position <= 3).length;
406
+ return {
407
+ totalEvents: results.length,
408
+ totalPoints,
409
+ totalDecayedPoints,
410
+ averagePoints: totalPoints / results.length,
411
+ averagePosition,
412
+ averageFinish: averagePosition,
413
+ averageEfficiency,
414
+ firstPlaceFinishes,
415
+ topThreeFinishes,
416
+ bestFinish: Math.min(...results.map((r) => r.position)),
417
+ highestPoints: Math.max(...results.map((r) => r.totalPoints || 0))
418
+ };
419
+ }
420
+ async function recalculateTimeDecay(referenceDate = /* @__PURE__ */ new Date()) {
421
+ const results = await findResults({
422
+ include: { tournament: true }
423
+ });
424
+ const updates = results.map((result) => {
425
+ const tournamentDate = result.tournament.date;
426
+ const ageInDays = Math.floor(
427
+ (referenceDate.getTime() - tournamentDate.getTime()) / (1e3 * 60 * 60 * 24)
428
+ );
429
+ const ageInYears = ageInDays / 365;
430
+ let decayMultiplier = 0;
431
+ if (ageInYears < 1) {
432
+ decayMultiplier = 1;
433
+ } else if (ageInYears < 2) {
434
+ decayMultiplier = 0.75;
435
+ } else if (ageInYears < 3) {
436
+ decayMultiplier = 0.5;
437
+ } else {
438
+ decayMultiplier = 0;
439
+ }
440
+ const decayedPoints = (result.totalPoints || 0) * decayMultiplier;
441
+ return prisma.tournamentResult.update({
442
+ where: { id: result.id },
443
+ data: {
444
+ ageInDays,
445
+ decayMultiplier,
446
+ decayedPoints
447
+ }
448
+ });
449
+ });
450
+ return Promise.all(updates);
451
+ }
452
+ export {
453
+ connect,
454
+ countPlayers,
455
+ countResults,
456
+ countTournaments,
457
+ createManyResults,
458
+ createPlayer,
459
+ createResult,
460
+ createTournament,
461
+ deletePlayer,
462
+ deleteResult,
463
+ deleteResultsByTournament,
464
+ deleteTournament,
465
+ disconnect,
466
+ findPlayerByEmail,
467
+ findPlayerByExternalId,
468
+ findPlayerById,
469
+ findPlayers,
470
+ findResultById,
471
+ findResultByPlayerAndTournament,
472
+ findResults,
473
+ findTournamentByExternalId,
474
+ findTournamentById,
475
+ findTournaments,
476
+ getMajorTournaments,
477
+ getPlayerResults,
478
+ getPlayerStats,
479
+ getPlayerTopFinishes,
480
+ getPlayerWithResults,
481
+ getRatedPlayers,
482
+ getRecentTournaments,
483
+ getTopPlayersByRanking,
484
+ getTopPlayersByRating,
485
+ getTournamentResults,
486
+ getTournamentStats,
487
+ getTournamentWithResults,
488
+ getTournamentsByBoosterType,
489
+ getTournamentsByDateRange,
490
+ prisma,
491
+ recalculateTimeDecay,
492
+ searchPlayers,
493
+ searchTournaments,
494
+ testConnection,
495
+ updatePlayer,
496
+ updatePlayerRating,
497
+ updateResult,
498
+ updateResultPoints,
499
+ updateTournament
500
+ };
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@opprs/db-prisma",
3
+ "version": "0.5.2-canary.16741f5",
4
+ "description": "Database backend for OPPR (Open Pinball Player Ranking System) using Prisma and PostgreSQL",
5
+ "keywords": [
6
+ "oppr",
7
+ "pinball",
8
+ "ranking",
9
+ "database",
10
+ "prisma",
11
+ "postgresql",
12
+ "tournament"
13
+ ],
14
+ "author": "Mitch McAffee",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/themcaffee/OPPR",
19
+ "directory": "packages/db-prisma"
20
+ },
21
+ "type": "module",
22
+ "main": "./dist/index.cjs",
23
+ "module": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js",
29
+ "require": "./dist/index.cjs"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "prisma",
35
+ "README.md",
36
+ "LICENSE"
37
+ ],
38
+ "dependencies": {
39
+ "@prisma/client": "^6.2.0"
40
+ },
41
+ "devDependencies": {
42
+ "@testcontainers/postgresql": "^11.11.0",
43
+ "@types/node": "^22.10.5",
44
+ "@typescript-eslint/eslint-plugin": "^8.19.1",
45
+ "@typescript-eslint/parser": "^8.19.1",
46
+ "@vitest/coverage-v8": "^4.0.16",
47
+ "@vitest/ui": "^4.0.16",
48
+ "eslint": "^9.17.0",
49
+ "prettier": "^3.4.2",
50
+ "prisma": "^6.2.0",
51
+ "tsup": "^8.3.5",
52
+ "tsx": "^4.19.2",
53
+ "typescript": "^5.7.2",
54
+ "vitest": "^4.0.16"
55
+ },
56
+ "peerDependencies": {
57
+ "@opprs/core": "^0.5.2-canary.16741f5"
58
+ },
59
+ "engines": {
60
+ "node": ">=18.0.0"
61
+ },
62
+ "prisma": {
63
+ "seed": "tsx prisma/seed.ts"
64
+ },
65
+ "scripts": {
66
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
67
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
68
+ "typecheck": "tsc --noEmit",
69
+ "lint": "eslint src --ext .ts",
70
+ "lint:fix": "eslint src --ext .ts --fix",
71
+ "format": "prettier --write \"src/**/*.ts\"",
72
+ "format:check": "prettier --check \"src/**/*.ts\"",
73
+ "test": "vitest run",
74
+ "test:watch": "vitest watch",
75
+ "test:ui": "vitest --ui",
76
+ "test:coverage": "vitest run --coverage",
77
+ "db:generate": "prisma generate",
78
+ "db:push": "prisma db push",
79
+ "db:migrate": "prisma migrate dev",
80
+ "db:migrate:prod": "prisma migrate deploy",
81
+ "db:studio": "prisma studio",
82
+ "db:seed": "tsx prisma/seed.ts",
83
+ "db:reset": "prisma migrate reset"
84
+ }
85
+ }
@@ -0,0 +1,112 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "EventBoosterType" AS ENUM ('NONE', 'CERTIFIED', 'CERTIFIED_PLUS', 'CHAMPIONSHIP_SERIES', 'MAJOR');
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "Player" (
6
+ "id" TEXT NOT NULL,
7
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
+ "updatedAt" TIMESTAMP(3) NOT NULL,
9
+ "externalId" TEXT,
10
+ "name" TEXT,
11
+ "email" TEXT,
12
+ "rating" DOUBLE PRECISION NOT NULL DEFAULT 1500,
13
+ "ratingDeviation" DOUBLE PRECISION NOT NULL DEFAULT 200,
14
+ "ranking" INTEGER,
15
+ "isRated" BOOLEAN NOT NULL DEFAULT false,
16
+ "eventCount" INTEGER NOT NULL DEFAULT 0,
17
+ "lastRatingUpdate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
18
+ "lastEventDate" TIMESTAMP(3),
19
+
20
+ CONSTRAINT "Player_pkey" PRIMARY KEY ("id")
21
+ );
22
+
23
+ -- CreateTable
24
+ CREATE TABLE "Tournament" (
25
+ "id" TEXT NOT NULL,
26
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
27
+ "updatedAt" TIMESTAMP(3) NOT NULL,
28
+ "externalId" TEXT,
29
+ "name" TEXT NOT NULL,
30
+ "location" TEXT,
31
+ "date" TIMESTAMP(3) NOT NULL,
32
+ "tgpConfig" JSONB,
33
+ "eventBooster" "EventBoosterType" NOT NULL DEFAULT 'NONE',
34
+ "allowsOptOut" BOOLEAN NOT NULL DEFAULT false,
35
+ "baseValue" DOUBLE PRECISION,
36
+ "tvaRating" DOUBLE PRECISION,
37
+ "tvaRanking" DOUBLE PRECISION,
38
+ "totalTVA" DOUBLE PRECISION,
39
+ "tgp" DOUBLE PRECISION,
40
+ "eventBoosterMultiplier" DOUBLE PRECISION,
41
+ "firstPlaceValue" DOUBLE PRECISION,
42
+
43
+ CONSTRAINT "Tournament_pkey" PRIMARY KEY ("id")
44
+ );
45
+
46
+ -- CreateTable
47
+ CREATE TABLE "TournamentResult" (
48
+ "id" TEXT NOT NULL,
49
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
50
+ "updatedAt" TIMESTAMP(3) NOT NULL,
51
+ "playerId" TEXT NOT NULL,
52
+ "tournamentId" TEXT NOT NULL,
53
+ "position" INTEGER NOT NULL,
54
+ "optedOut" BOOLEAN NOT NULL DEFAULT false,
55
+ "linearPoints" DOUBLE PRECISION DEFAULT 0,
56
+ "dynamicPoints" DOUBLE PRECISION DEFAULT 0,
57
+ "totalPoints" DOUBLE PRECISION,
58
+ "ageInDays" INTEGER DEFAULT 0,
59
+ "decayMultiplier" DOUBLE PRECISION DEFAULT 1.0,
60
+ "decayedPoints" DOUBLE PRECISION,
61
+ "efficiency" DOUBLE PRECISION,
62
+
63
+ CONSTRAINT "TournamentResult_pkey" PRIMARY KEY ("id")
64
+ );
65
+
66
+ -- CreateIndex
67
+ CREATE UNIQUE INDEX "Player_externalId_key" ON "Player"("externalId");
68
+
69
+ -- CreateIndex
70
+ CREATE UNIQUE INDEX "Player_email_key" ON "Player"("email");
71
+
72
+ -- CreateIndex
73
+ CREATE INDEX "Player_email_idx" ON "Player"("email");
74
+
75
+ -- CreateIndex
76
+ CREATE INDEX "Player_externalId_idx" ON "Player"("externalId");
77
+
78
+ -- CreateIndex
79
+ CREATE INDEX "Player_rating_idx" ON "Player"("rating");
80
+
81
+ -- CreateIndex
82
+ CREATE INDEX "Player_ranking_idx" ON "Player"("ranking");
83
+
84
+ -- CreateIndex
85
+ CREATE UNIQUE INDEX "Tournament_externalId_key" ON "Tournament"("externalId");
86
+
87
+ -- CreateIndex
88
+ CREATE INDEX "Tournament_date_idx" ON "Tournament"("date");
89
+
90
+ -- CreateIndex
91
+ CREATE INDEX "Tournament_eventBooster_idx" ON "Tournament"("eventBooster");
92
+
93
+ -- CreateIndex
94
+ CREATE INDEX "Tournament_externalId_idx" ON "Tournament"("externalId");
95
+
96
+ -- CreateIndex
97
+ CREATE INDEX "TournamentResult_playerId_idx" ON "TournamentResult"("playerId");
98
+
99
+ -- CreateIndex
100
+ CREATE INDEX "TournamentResult_tournamentId_idx" ON "TournamentResult"("tournamentId");
101
+
102
+ -- CreateIndex
103
+ CREATE INDEX "TournamentResult_position_idx" ON "TournamentResult"("position");
104
+
105
+ -- CreateIndex
106
+ CREATE UNIQUE INDEX "TournamentResult_playerId_tournamentId_key" ON "TournamentResult"("playerId", "tournamentId");
107
+
108
+ -- AddForeignKey
109
+ ALTER TABLE "TournamentResult" ADD CONSTRAINT "TournamentResult_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE CASCADE ON UPDATE CASCADE;
110
+
111
+ -- AddForeignKey
112
+ ALTER TABLE "TournamentResult" ADD CONSTRAINT "TournamentResult_tournamentId_fkey" FOREIGN KEY ("tournamentId") REFERENCES "Tournament"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"