@opprs/db-prisma 2.2.0 → 2.2.1-canary.090cc41
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/LICENSE +12 -18
- package/dist/index.cjs +1233 -158
- package/dist/index.d.cts +1028 -106
- package/dist/index.d.ts +1028 -106
- package/dist/index.js +1117 -141
- package/package.json +5 -4
- 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/migrations/20260105010000_add_qualifying_format/migration.sql +5 -0
- package/prisma/migrations/20260105010000_add_tournament_external_url/migration.sql +2 -0
- package/prisma/migrations/20260105020000_add_blog_post_model/migration.sql +81 -0
- package/prisma/schema.prisma +309 -37
- package/prisma/seed.ts +157 -48
package/dist/index.js
CHANGED
|
@@ -23,10 +23,40 @@ async function testConnection() {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// src/player-number.ts
|
|
27
|
+
var MIN_PLAYER_NUMBER = 1e4;
|
|
28
|
+
var MAX_PLAYER_NUMBER = 99999;
|
|
29
|
+
var MAX_RETRIES = 10;
|
|
30
|
+
function generateRandomPlayerNumber() {
|
|
31
|
+
return Math.floor(Math.random() * (MAX_PLAYER_NUMBER - MIN_PLAYER_NUMBER + 1)) + MIN_PLAYER_NUMBER;
|
|
32
|
+
}
|
|
33
|
+
async function generateUniquePlayerNumber() {
|
|
34
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
35
|
+
const candidate = generateRandomPlayerNumber();
|
|
36
|
+
const existing = await prisma.player.findUnique({
|
|
37
|
+
where: { playerNumber: candidate },
|
|
38
|
+
select: { id: true }
|
|
39
|
+
});
|
|
40
|
+
if (!existing) {
|
|
41
|
+
return candidate;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Failed to generate unique player number after ${MAX_RETRIES} attempts. Consider increasing the number range or implementing a different allocation strategy.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function isValidPlayerNumber(playerNumber) {
|
|
49
|
+
return Number.isInteger(playerNumber) && playerNumber >= MIN_PLAYER_NUMBER && playerNumber <= MAX_PLAYER_NUMBER;
|
|
50
|
+
}
|
|
51
|
+
|
|
26
52
|
// src/players.ts
|
|
27
53
|
async function createPlayer(data) {
|
|
54
|
+
const playerNumber = data.playerNumber ?? await generateUniquePlayerNumber();
|
|
28
55
|
return prisma.player.create({
|
|
29
|
-
data
|
|
56
|
+
data: {
|
|
57
|
+
...data,
|
|
58
|
+
playerNumber
|
|
59
|
+
}
|
|
30
60
|
});
|
|
31
61
|
}
|
|
32
62
|
async function findPlayerById(id, include) {
|
|
@@ -41,6 +71,12 @@ async function findPlayerByExternalId(externalId, include) {
|
|
|
41
71
|
include
|
|
42
72
|
});
|
|
43
73
|
}
|
|
74
|
+
async function findPlayerByPlayerNumber(playerNumber, include) {
|
|
75
|
+
return prisma.player.findUnique({
|
|
76
|
+
where: { playerNumber },
|
|
77
|
+
include
|
|
78
|
+
});
|
|
79
|
+
}
|
|
44
80
|
async function findPlayerByUserEmail(email, include) {
|
|
45
81
|
const user = await prisma.user.findUnique({
|
|
46
82
|
where: { email },
|
|
@@ -57,48 +93,12 @@ async function findPlayers(options = {}) {
|
|
|
57
93
|
include: options.include
|
|
58
94
|
});
|
|
59
95
|
}
|
|
60
|
-
async function getRatedPlayers(options = {}) {
|
|
61
|
-
return findPlayers({
|
|
62
|
-
...options,
|
|
63
|
-
where: { isRated: true }
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
async function getTopPlayersByRating(limit = 50) {
|
|
67
|
-
return findPlayers({
|
|
68
|
-
take: limit,
|
|
69
|
-
orderBy: { rating: "desc" },
|
|
70
|
-
where: { isRated: true }
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
async function getTopPlayersByRanking(limit = 50) {
|
|
74
|
-
return findPlayers({
|
|
75
|
-
take: limit,
|
|
76
|
-
orderBy: { ranking: "asc" },
|
|
77
|
-
where: {
|
|
78
|
-
isRated: true,
|
|
79
|
-
ranking: { not: null }
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
96
|
async function updatePlayer(id, data) {
|
|
84
97
|
return prisma.player.update({
|
|
85
98
|
where: { id },
|
|
86
99
|
data
|
|
87
100
|
});
|
|
88
101
|
}
|
|
89
|
-
async function updatePlayerRating(id, rating, ratingDeviation, eventCount) {
|
|
90
|
-
const updateData = {
|
|
91
|
-
rating,
|
|
92
|
-
ratingDeviation,
|
|
93
|
-
lastRatingUpdate: /* @__PURE__ */ new Date(),
|
|
94
|
-
lastEventDate: /* @__PURE__ */ new Date()
|
|
95
|
-
};
|
|
96
|
-
if (eventCount !== void 0) {
|
|
97
|
-
updateData.eventCount = eventCount;
|
|
98
|
-
updateData.isRated = eventCount >= 5;
|
|
99
|
-
}
|
|
100
|
-
return updatePlayer(id, updateData);
|
|
101
|
-
}
|
|
102
102
|
async function deletePlayer(id) {
|
|
103
103
|
return prisma.player.delete({
|
|
104
104
|
where: { id }
|
|
@@ -111,7 +111,7 @@ async function getPlayerWithResults(id) {
|
|
|
111
111
|
const player = await prisma.player.findUnique({
|
|
112
112
|
where: { id },
|
|
113
113
|
include: {
|
|
114
|
-
|
|
114
|
+
standings: {
|
|
115
115
|
include: {
|
|
116
116
|
tournament: true
|
|
117
117
|
},
|
|
@@ -128,7 +128,7 @@ async function getPlayerWithResults(id) {
|
|
|
128
128
|
}
|
|
129
129
|
return {
|
|
130
130
|
...player,
|
|
131
|
-
results: player.
|
|
131
|
+
results: player.standings
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
async function searchPlayers(query, limit = 20) {
|
|
@@ -140,6 +140,212 @@ async function searchPlayers(query, limit = 20) {
|
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
// src/oppr-rankings.ts
|
|
144
|
+
async function getOrCreateOpprPlayerRanking(playerId) {
|
|
145
|
+
const existing = await prisma.opprPlayerRanking.findUnique({
|
|
146
|
+
where: { playerId }
|
|
147
|
+
});
|
|
148
|
+
if (existing) return existing;
|
|
149
|
+
return prisma.opprPlayerRanking.create({
|
|
150
|
+
data: { playerId }
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async function createOpprPlayerRanking(data) {
|
|
154
|
+
return prisma.opprPlayerRanking.create({
|
|
155
|
+
data
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async function findOpprPlayerRankingById(id, include) {
|
|
159
|
+
return prisma.opprPlayerRanking.findUnique({
|
|
160
|
+
where: { id },
|
|
161
|
+
include
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
async function findOpprPlayerRankingByPlayerId(playerId, include) {
|
|
165
|
+
return prisma.opprPlayerRanking.findUnique({
|
|
166
|
+
where: { playerId },
|
|
167
|
+
include
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async function findOpprPlayerRankings(options = {}) {
|
|
171
|
+
return prisma.opprPlayerRanking.findMany({
|
|
172
|
+
take: options.take,
|
|
173
|
+
skip: options.skip,
|
|
174
|
+
where: options.where,
|
|
175
|
+
orderBy: options.orderBy,
|
|
176
|
+
include: options.include
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async function getTopPlayersByOpprRating(limit = 50) {
|
|
180
|
+
return prisma.opprPlayerRanking.findMany({
|
|
181
|
+
take: limit,
|
|
182
|
+
where: { isRated: true },
|
|
183
|
+
orderBy: { rating: "desc" },
|
|
184
|
+
include: { player: true }
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
async function getTopPlayersByOpprRanking(limit = 50) {
|
|
188
|
+
return prisma.opprPlayerRanking.findMany({
|
|
189
|
+
take: limit,
|
|
190
|
+
where: {
|
|
191
|
+
isRated: true,
|
|
192
|
+
ranking: { not: null }
|
|
193
|
+
},
|
|
194
|
+
orderBy: { ranking: "asc" },
|
|
195
|
+
include: { player: true }
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async function getRatedOpprPlayers(options = {}) {
|
|
199
|
+
return prisma.opprPlayerRanking.findMany({
|
|
200
|
+
...options,
|
|
201
|
+
where: { isRated: true },
|
|
202
|
+
include: { player: true, ...options.include }
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
async function updateOpprPlayerRanking(playerId, data) {
|
|
206
|
+
return prisma.opprPlayerRanking.update({
|
|
207
|
+
where: { playerId },
|
|
208
|
+
data: {
|
|
209
|
+
...data,
|
|
210
|
+
lastRatingUpdate: data.lastRatingUpdate ?? /* @__PURE__ */ new Date()
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
async function updateOpprRatingAfterTournament(playerId, newRating, newRD, tournamentId, eventCount) {
|
|
215
|
+
const ranking = await getOrCreateOpprPlayerRanking(playerId);
|
|
216
|
+
const isRated = eventCount !== void 0 ? eventCount >= 5 : ranking.isRated;
|
|
217
|
+
const updated = await prisma.opprPlayerRanking.update({
|
|
218
|
+
where: { playerId },
|
|
219
|
+
data: {
|
|
220
|
+
rating: newRating,
|
|
221
|
+
ratingDeviation: newRD,
|
|
222
|
+
lastRatingUpdate: /* @__PURE__ */ new Date(),
|
|
223
|
+
isRated
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
await createOpprRankingHistory({
|
|
227
|
+
opprPlayerRankingId: ranking.id,
|
|
228
|
+
rating: newRating,
|
|
229
|
+
ratingDeviation: newRD,
|
|
230
|
+
ranking: updated.ranking ?? void 0,
|
|
231
|
+
isRated,
|
|
232
|
+
changeType: "TOURNAMENT_RESULT",
|
|
233
|
+
tournamentId
|
|
234
|
+
});
|
|
235
|
+
return updated;
|
|
236
|
+
}
|
|
237
|
+
async function updateWorldRankings(rankings) {
|
|
238
|
+
await prisma.$transaction(async (tx) => {
|
|
239
|
+
for (const { playerId, ranking } of rankings) {
|
|
240
|
+
const opprRanking = await tx.opprPlayerRanking.findUnique({
|
|
241
|
+
where: { playerId }
|
|
242
|
+
});
|
|
243
|
+
if (opprRanking) {
|
|
244
|
+
await tx.opprPlayerRanking.update({
|
|
245
|
+
where: { playerId },
|
|
246
|
+
data: { ranking }
|
|
247
|
+
});
|
|
248
|
+
await tx.opprRankingHistory.create({
|
|
249
|
+
data: {
|
|
250
|
+
opprPlayerRankingId: opprRanking.id,
|
|
251
|
+
rating: opprRanking.rating,
|
|
252
|
+
ratingDeviation: opprRanking.ratingDeviation,
|
|
253
|
+
ranking,
|
|
254
|
+
isRated: opprRanking.isRated,
|
|
255
|
+
changeType: "RANKING_REFRESH"
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
async function applyRDDecayForInactivePlayers(thresholdDays = 30, decayPerDay = 0.3, maxRD = 200) {
|
|
263
|
+
const cutoffDate = /* @__PURE__ */ new Date();
|
|
264
|
+
cutoffDate.setDate(cutoffDate.getDate() - thresholdDays);
|
|
265
|
+
const inactivePlayers = await prisma.opprPlayerRanking.findMany({
|
|
266
|
+
where: {
|
|
267
|
+
lastRatingUpdate: { lt: cutoffDate },
|
|
268
|
+
ratingDeviation: { lt: maxRD }
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
let updatedCount = 0;
|
|
272
|
+
await prisma.$transaction(async (tx) => {
|
|
273
|
+
for (const ranking of inactivePlayers) {
|
|
274
|
+
const daysSinceUpdate = Math.floor(
|
|
275
|
+
(Date.now() - ranking.lastRatingUpdate.getTime()) / (1e3 * 60 * 60 * 24)
|
|
276
|
+
);
|
|
277
|
+
const newRD = Math.min(ranking.ratingDeviation + daysSinceUpdate * decayPerDay, maxRD);
|
|
278
|
+
await tx.opprPlayerRanking.update({
|
|
279
|
+
where: { id: ranking.id },
|
|
280
|
+
data: { ratingDeviation: newRD }
|
|
281
|
+
});
|
|
282
|
+
await tx.opprRankingHistory.create({
|
|
283
|
+
data: {
|
|
284
|
+
opprPlayerRankingId: ranking.id,
|
|
285
|
+
rating: ranking.rating,
|
|
286
|
+
ratingDeviation: newRD,
|
|
287
|
+
ranking: ranking.ranking,
|
|
288
|
+
isRated: ranking.isRated,
|
|
289
|
+
changeType: "RD_DECAY",
|
|
290
|
+
notes: `RD increased from ${ranking.ratingDeviation.toFixed(1)} to ${newRD.toFixed(1)} due to ${daysSinceUpdate} days of inactivity`
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
updatedCount++;
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
return updatedCount;
|
|
297
|
+
}
|
|
298
|
+
async function deleteOpprPlayerRanking(playerId) {
|
|
299
|
+
return prisma.opprPlayerRanking.delete({
|
|
300
|
+
where: { playerId }
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
async function countOpprPlayerRankings(where) {
|
|
304
|
+
return prisma.opprPlayerRanking.count({ where });
|
|
305
|
+
}
|
|
306
|
+
async function createOpprRankingHistory(data) {
|
|
307
|
+
return prisma.opprRankingHistory.create({
|
|
308
|
+
data
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
async function getOpprRankingHistory(playerId, limit) {
|
|
312
|
+
const ranking = await findOpprPlayerRankingByPlayerId(playerId);
|
|
313
|
+
if (!ranking) return [];
|
|
314
|
+
return prisma.opprRankingHistory.findMany({
|
|
315
|
+
where: { opprPlayerRankingId: ranking.id },
|
|
316
|
+
orderBy: { createdAt: "desc" },
|
|
317
|
+
take: limit,
|
|
318
|
+
include: { tournament: true }
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
async function getOpprRankingHistoryByDateRange(playerId, startDate, endDate) {
|
|
322
|
+
const ranking = await findOpprPlayerRankingByPlayerId(playerId);
|
|
323
|
+
if (!ranking) return [];
|
|
324
|
+
return prisma.opprRankingHistory.findMany({
|
|
325
|
+
where: {
|
|
326
|
+
opprPlayerRankingId: ranking.id,
|
|
327
|
+
createdAt: {
|
|
328
|
+
gte: startDate,
|
|
329
|
+
lte: endDate
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
orderBy: { createdAt: "asc" },
|
|
333
|
+
include: { tournament: true }
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
async function getLatestOpprRankingHistory(playerId) {
|
|
337
|
+
const ranking = await findOpprPlayerRankingByPlayerId(playerId);
|
|
338
|
+
if (!ranking) return null;
|
|
339
|
+
return prisma.opprRankingHistory.findFirst({
|
|
340
|
+
where: { opprPlayerRankingId: ranking.id },
|
|
341
|
+
orderBy: { createdAt: "desc" },
|
|
342
|
+
include: { tournament: true }
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
async function countOpprRankingHistory(where) {
|
|
346
|
+
return prisma.opprRankingHistory.count({ where });
|
|
347
|
+
}
|
|
348
|
+
|
|
143
349
|
// src/tournaments.ts
|
|
144
350
|
async function createTournament(data) {
|
|
145
351
|
return prisma.tournament.create({
|
|
@@ -219,13 +425,33 @@ async function getTournamentWithResults(id) {
|
|
|
219
425
|
return prisma.tournament.findUnique({
|
|
220
426
|
where: { id },
|
|
221
427
|
include: {
|
|
222
|
-
|
|
428
|
+
standings: {
|
|
223
429
|
include: {
|
|
224
430
|
player: true
|
|
225
431
|
},
|
|
226
|
-
orderBy: {
|
|
227
|
-
|
|
228
|
-
|
|
432
|
+
orderBy: [{ isFinals: "desc" }, { position: "asc" }]
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
async function getTournamentWithMatches(id) {
|
|
438
|
+
return prisma.tournament.findUnique({
|
|
439
|
+
where: { id },
|
|
440
|
+
include: {
|
|
441
|
+
rounds: {
|
|
442
|
+
include: {
|
|
443
|
+
matches: {
|
|
444
|
+
include: {
|
|
445
|
+
entries: {
|
|
446
|
+
include: {
|
|
447
|
+
player: true
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
orderBy: { number: "asc" }
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
orderBy: [{ isFinals: "asc" }, { number: "asc" }]
|
|
229
455
|
}
|
|
230
456
|
}
|
|
231
457
|
});
|
|
@@ -236,7 +462,7 @@ async function searchTournaments(query, limit = 20) {
|
|
|
236
462
|
where: {
|
|
237
463
|
OR: [
|
|
238
464
|
{ name: { contains: query, mode: "insensitive" } },
|
|
239
|
-
{ location: { contains: query, mode: "insensitive" } }
|
|
465
|
+
{ location: { name: { contains: query, mode: "insensitive" } } }
|
|
240
466
|
]
|
|
241
467
|
},
|
|
242
468
|
orderBy: { date: "desc" }
|
|
@@ -247,7 +473,7 @@ async function getTournamentStats(id) {
|
|
|
247
473
|
if (!tournament) {
|
|
248
474
|
return null;
|
|
249
475
|
}
|
|
250
|
-
const playerCount = tournament.
|
|
476
|
+
const playerCount = tournament.standings.length;
|
|
251
477
|
if (playerCount === 0) {
|
|
252
478
|
return {
|
|
253
479
|
tournament,
|
|
@@ -258,9 +484,9 @@ async function getTournamentStats(id) {
|
|
|
258
484
|
lowestPoints: 0
|
|
259
485
|
};
|
|
260
486
|
}
|
|
261
|
-
const totalPoints = tournament.
|
|
262
|
-
const totalEfficiency = tournament.
|
|
263
|
-
const allPoints = tournament.
|
|
487
|
+
const totalPoints = tournament.standings.reduce((sum, s) => sum + (s.totalPoints || 0), 0);
|
|
488
|
+
const totalEfficiency = tournament.standings.reduce((sum, s) => sum + (s.efficiency || 0), 0);
|
|
489
|
+
const allPoints = tournament.standings.map((s) => s.totalPoints || 0);
|
|
264
490
|
return {
|
|
265
491
|
tournament,
|
|
266
492
|
playerCount,
|
|
@@ -271,44 +497,364 @@ async function getTournamentStats(id) {
|
|
|
271
497
|
};
|
|
272
498
|
}
|
|
273
499
|
|
|
274
|
-
// src/
|
|
275
|
-
async function
|
|
276
|
-
|
|
500
|
+
// src/rounds.ts
|
|
501
|
+
async function createRound(data) {
|
|
502
|
+
return prisma.round.create({
|
|
503
|
+
data: {
|
|
504
|
+
...data,
|
|
505
|
+
isFinals: data.isFinals ?? false
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
async function createManyRounds(data) {
|
|
510
|
+
const roundsData = data.map((item) => ({
|
|
511
|
+
...item,
|
|
512
|
+
isFinals: item.isFinals ?? false
|
|
513
|
+
}));
|
|
514
|
+
return prisma.round.createMany({
|
|
515
|
+
data: roundsData
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
async function findRoundById(id, include) {
|
|
519
|
+
return prisma.round.findUnique({
|
|
520
|
+
where: { id },
|
|
521
|
+
include
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
async function findRoundByTournamentAndNumber(tournamentId, number, isFinals, include) {
|
|
525
|
+
return prisma.round.findUnique({
|
|
526
|
+
where: {
|
|
527
|
+
tournamentId_number_isFinals: {
|
|
528
|
+
tournamentId,
|
|
529
|
+
number,
|
|
530
|
+
isFinals
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
include
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
async function findRounds(options = {}) {
|
|
537
|
+
return prisma.round.findMany({
|
|
538
|
+
take: options.take,
|
|
539
|
+
skip: options.skip,
|
|
540
|
+
where: options.where,
|
|
541
|
+
orderBy: options.orderBy,
|
|
542
|
+
include: options.include
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
async function getTournamentRounds(tournamentId, options = {}) {
|
|
546
|
+
return findRounds({
|
|
547
|
+
...options,
|
|
548
|
+
where: { tournamentId },
|
|
549
|
+
orderBy: options.orderBy ?? [{ isFinals: "asc" }, { number: "asc" }]
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
async function getQualifyingRounds(tournamentId, options = {}) {
|
|
553
|
+
return findRounds({
|
|
554
|
+
...options,
|
|
555
|
+
where: { tournamentId, isFinals: false },
|
|
556
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
async function getFinalsRounds(tournamentId, options = {}) {
|
|
560
|
+
return findRounds({
|
|
561
|
+
...options,
|
|
562
|
+
where: { tournamentId, isFinals: true },
|
|
563
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
async function updateRound(id, data) {
|
|
567
|
+
return prisma.round.update({
|
|
568
|
+
where: { id },
|
|
569
|
+
data
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
async function deleteRound(id) {
|
|
573
|
+
return prisma.round.delete({
|
|
574
|
+
where: { id }
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
async function deleteRoundsByTournament(tournamentId) {
|
|
578
|
+
return prisma.round.deleteMany({
|
|
579
|
+
where: { tournamentId }
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
async function countRounds(where) {
|
|
583
|
+
return prisma.round.count({ where });
|
|
584
|
+
}
|
|
585
|
+
async function getRoundWithMatches(id) {
|
|
586
|
+
return prisma.round.findUnique({
|
|
587
|
+
where: { id },
|
|
588
|
+
include: {
|
|
589
|
+
matches: {
|
|
590
|
+
include: {
|
|
591
|
+
entries: {
|
|
592
|
+
include: {
|
|
593
|
+
player: true
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
},
|
|
597
|
+
orderBy: {
|
|
598
|
+
number: "asc"
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// src/matches.ts
|
|
606
|
+
async function createMatch(data) {
|
|
607
|
+
return prisma.match.create({
|
|
608
|
+
data
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
async function createManyMatches(data) {
|
|
612
|
+
return prisma.match.createMany({
|
|
613
|
+
data
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
async function findMatchById(id, include) {
|
|
617
|
+
return prisma.match.findUnique({
|
|
618
|
+
where: { id },
|
|
619
|
+
include
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
async function findMatches(options = {}) {
|
|
623
|
+
return prisma.match.findMany({
|
|
624
|
+
take: options.take,
|
|
625
|
+
skip: options.skip,
|
|
626
|
+
where: options.where,
|
|
627
|
+
orderBy: options.orderBy,
|
|
628
|
+
include: options.include
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
async function getTournamentMatches(tournamentId, options = {}) {
|
|
632
|
+
return findMatches({
|
|
633
|
+
...options,
|
|
634
|
+
where: { tournamentId },
|
|
635
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
async function getRoundMatches(roundId, options = {}) {
|
|
639
|
+
return findMatches({
|
|
640
|
+
...options,
|
|
641
|
+
where: { roundId },
|
|
642
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
async function updateMatch(id, data) {
|
|
646
|
+
return prisma.match.update({
|
|
647
|
+
where: { id },
|
|
648
|
+
data
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
async function deleteMatch(id) {
|
|
652
|
+
return prisma.match.delete({
|
|
653
|
+
where: { id }
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
async function deleteMatchesByTournament(tournamentId) {
|
|
657
|
+
return prisma.match.deleteMany({
|
|
658
|
+
where: { tournamentId }
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
async function deleteMatchesByRound(roundId) {
|
|
662
|
+
return prisma.match.deleteMany({
|
|
663
|
+
where: { roundId }
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
async function countMatches(where) {
|
|
667
|
+
return prisma.match.count({ where });
|
|
668
|
+
}
|
|
669
|
+
async function getMatchWithEntries(id) {
|
|
670
|
+
return prisma.match.findUnique({
|
|
671
|
+
where: { id },
|
|
672
|
+
include: {
|
|
673
|
+
entries: {
|
|
674
|
+
include: {
|
|
675
|
+
player: true
|
|
676
|
+
},
|
|
677
|
+
orderBy: {
|
|
678
|
+
position: "asc"
|
|
679
|
+
}
|
|
680
|
+
},
|
|
681
|
+
round: true
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
async function getPlayerTournamentMatches(playerId, tournamentId, include) {
|
|
686
|
+
return findMatches({
|
|
687
|
+
where: {
|
|
688
|
+
tournamentId,
|
|
689
|
+
entries: {
|
|
690
|
+
some: {
|
|
691
|
+
playerId
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
include: include ?? {
|
|
696
|
+
entries: {
|
|
697
|
+
include: {
|
|
698
|
+
player: true
|
|
699
|
+
}
|
|
700
|
+
},
|
|
701
|
+
round: true
|
|
702
|
+
},
|
|
703
|
+
orderBy: [{ round: { number: "asc" } }, { number: "asc" }]
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// src/entries.ts
|
|
708
|
+
async function createEntry(data) {
|
|
709
|
+
return prisma.entry.create({
|
|
710
|
+
data
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
async function createManyEntries(data) {
|
|
714
|
+
return prisma.entry.createMany({
|
|
715
|
+
data
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
async function findEntryById(id, include) {
|
|
719
|
+
return prisma.entry.findUnique({
|
|
720
|
+
where: { id },
|
|
721
|
+
include
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
async function findEntryByMatchAndPlayer(matchId, playerId, include) {
|
|
725
|
+
return prisma.entry.findUnique({
|
|
726
|
+
where: {
|
|
727
|
+
matchId_playerId: {
|
|
728
|
+
matchId,
|
|
729
|
+
playerId
|
|
730
|
+
}
|
|
731
|
+
},
|
|
732
|
+
include
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
async function findEntries(options = {}) {
|
|
736
|
+
return prisma.entry.findMany({
|
|
737
|
+
take: options.take,
|
|
738
|
+
skip: options.skip,
|
|
739
|
+
where: options.where,
|
|
740
|
+
orderBy: options.orderBy,
|
|
741
|
+
include: options.include
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
async function getMatchEntries(matchId, options = {}) {
|
|
745
|
+
return findEntries({
|
|
746
|
+
...options,
|
|
747
|
+
where: { matchId },
|
|
748
|
+
include: options.include ?? { player: true },
|
|
749
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
async function getPlayerEntries(playerId, options = {}) {
|
|
753
|
+
return findEntries({
|
|
754
|
+
...options,
|
|
755
|
+
where: { playerId },
|
|
756
|
+
include: options.include ?? { match: { include: { round: true, tournament: true } } }
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
async function getPlayerTournamentEntries(playerId, tournamentId, include) {
|
|
760
|
+
return findEntries({
|
|
761
|
+
where: {
|
|
762
|
+
playerId,
|
|
763
|
+
match: {
|
|
764
|
+
tournamentId
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
include: include ?? {
|
|
768
|
+
match: {
|
|
769
|
+
include: {
|
|
770
|
+
round: true,
|
|
771
|
+
entries: {
|
|
772
|
+
include: {
|
|
773
|
+
player: true
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
async function updateEntry(id, data) {
|
|
782
|
+
return prisma.entry.update({
|
|
783
|
+
where: { id },
|
|
784
|
+
data
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
async function deleteEntry(id) {
|
|
788
|
+
return prisma.entry.delete({
|
|
789
|
+
where: { id }
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
async function deleteEntriesByMatch(matchId) {
|
|
793
|
+
return prisma.entry.deleteMany({
|
|
794
|
+
where: { matchId }
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
async function countEntries(where) {
|
|
798
|
+
return prisma.entry.count({ where });
|
|
799
|
+
}
|
|
800
|
+
async function getPlayerEntryStats(playerId) {
|
|
801
|
+
const entries = await getPlayerEntries(playerId);
|
|
802
|
+
if (entries.length === 0) {
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
const wins = entries.filter((e) => e.result === "WIN").length;
|
|
806
|
+
const losses = entries.filter((e) => e.result === "LOSS").length;
|
|
807
|
+
const ties = entries.filter((e) => e.result === "TIE").length;
|
|
808
|
+
return {
|
|
809
|
+
totalMatches: entries.length,
|
|
810
|
+
wins,
|
|
811
|
+
losses,
|
|
812
|
+
ties,
|
|
813
|
+
winRate: wins / entries.length
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/standings.ts
|
|
818
|
+
async function createStanding(data) {
|
|
819
|
+
const standingData = {
|
|
277
820
|
...data,
|
|
821
|
+
isFinals: data.isFinals ?? false,
|
|
278
822
|
decayedPoints: data.decayedPoints ?? data.totalPoints ?? 0
|
|
279
823
|
};
|
|
280
|
-
return prisma.
|
|
281
|
-
data:
|
|
824
|
+
return prisma.standing.create({
|
|
825
|
+
data: standingData
|
|
282
826
|
});
|
|
283
827
|
}
|
|
284
|
-
async function
|
|
285
|
-
const
|
|
828
|
+
async function createManyStandings(data) {
|
|
829
|
+
const standingsData = data.map((item) => ({
|
|
286
830
|
...item,
|
|
831
|
+
isFinals: item.isFinals ?? false,
|
|
287
832
|
decayedPoints: item.decayedPoints ?? item.totalPoints ?? 0
|
|
288
833
|
}));
|
|
289
|
-
return prisma.
|
|
290
|
-
data:
|
|
834
|
+
return prisma.standing.createMany({
|
|
835
|
+
data: standingsData
|
|
291
836
|
});
|
|
292
837
|
}
|
|
293
|
-
async function
|
|
294
|
-
return prisma.
|
|
838
|
+
async function findStandingById(id, include) {
|
|
839
|
+
return prisma.standing.findUnique({
|
|
295
840
|
where: { id },
|
|
296
841
|
include
|
|
297
842
|
});
|
|
298
843
|
}
|
|
299
|
-
async function
|
|
300
|
-
return prisma.
|
|
844
|
+
async function findStandingByPlayerAndTournament(playerId, tournamentId, isFinals, include) {
|
|
845
|
+
return prisma.standing.findUnique({
|
|
301
846
|
where: {
|
|
302
|
-
|
|
847
|
+
playerId_tournamentId_isFinals: {
|
|
303
848
|
playerId,
|
|
304
|
-
tournamentId
|
|
849
|
+
tournamentId,
|
|
850
|
+
isFinals
|
|
305
851
|
}
|
|
306
852
|
},
|
|
307
853
|
include
|
|
308
854
|
});
|
|
309
855
|
}
|
|
310
|
-
async function
|
|
311
|
-
return prisma.
|
|
856
|
+
async function findStandings(options = {}) {
|
|
857
|
+
return prisma.standing.findMany({
|
|
312
858
|
take: options.take,
|
|
313
859
|
skip: options.skip,
|
|
314
860
|
where: options.where,
|
|
@@ -316,45 +862,85 @@ async function findResults(options = {}) {
|
|
|
316
862
|
include: options.include
|
|
317
863
|
});
|
|
318
864
|
}
|
|
319
|
-
async function
|
|
320
|
-
return
|
|
865
|
+
async function getPlayerStandings(playerId, options = {}) {
|
|
866
|
+
return findStandings({
|
|
321
867
|
...options,
|
|
322
868
|
where: { playerId },
|
|
323
869
|
include: { tournament: true, ...options.include },
|
|
324
870
|
orderBy: { tournament: { date: "desc" } }
|
|
325
871
|
});
|
|
326
872
|
}
|
|
327
|
-
async function
|
|
328
|
-
return
|
|
873
|
+
async function getTournamentStandings(tournamentId, options = {}) {
|
|
874
|
+
return findStandings({
|
|
329
875
|
...options,
|
|
330
876
|
where: { tournamentId },
|
|
331
877
|
include: { player: true, ...options.include },
|
|
332
|
-
orderBy: { position: "asc" }
|
|
878
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
async function getQualifyingStandings(tournamentId, options = {}) {
|
|
882
|
+
return findStandings({
|
|
883
|
+
...options,
|
|
884
|
+
where: { tournamentId, isFinals: false },
|
|
885
|
+
include: { player: true, ...options.include },
|
|
886
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
333
887
|
});
|
|
334
888
|
}
|
|
889
|
+
async function getFinalsStandings(tournamentId, options = {}) {
|
|
890
|
+
return findStandings({
|
|
891
|
+
...options,
|
|
892
|
+
where: { tournamentId, isFinals: true },
|
|
893
|
+
include: { player: true, ...options.include },
|
|
894
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
async function getMergedStandings(tournamentId) {
|
|
898
|
+
const [finals, qualifying] = await Promise.all([
|
|
899
|
+
findStandings({
|
|
900
|
+
where: { tournamentId, isFinals: true },
|
|
901
|
+
orderBy: { position: "asc" },
|
|
902
|
+
include: { player: true }
|
|
903
|
+
}),
|
|
904
|
+
findStandings({
|
|
905
|
+
where: { tournamentId, isFinals: false },
|
|
906
|
+
orderBy: { position: "asc" },
|
|
907
|
+
include: { player: true }
|
|
908
|
+
})
|
|
909
|
+
]);
|
|
910
|
+
const finalistIds = new Set(finals.map((s) => s.playerId));
|
|
911
|
+
const nonFinalists = qualifying.filter((s) => !finalistIds.has(s.playerId));
|
|
912
|
+
return [
|
|
913
|
+
...finals.map((s) => ({ ...s, mergedPosition: s.position, isFinalist: true })),
|
|
914
|
+
...nonFinalists.map((s, i) => ({
|
|
915
|
+
...s,
|
|
916
|
+
mergedPosition: finals.length + i + 1,
|
|
917
|
+
isFinalist: false
|
|
918
|
+
}))
|
|
919
|
+
];
|
|
920
|
+
}
|
|
335
921
|
async function getPlayerTopFinishes(playerId, limit = 15) {
|
|
336
|
-
return
|
|
922
|
+
return findStandings({
|
|
337
923
|
where: { playerId },
|
|
338
924
|
take: limit,
|
|
339
925
|
include: { tournament: true },
|
|
340
926
|
orderBy: { decayedPoints: "desc" }
|
|
341
927
|
});
|
|
342
928
|
}
|
|
343
|
-
async function
|
|
344
|
-
return prisma.
|
|
929
|
+
async function updateStanding(id, data) {
|
|
930
|
+
return prisma.standing.update({
|
|
345
931
|
where: { id },
|
|
346
932
|
data
|
|
347
933
|
});
|
|
348
934
|
}
|
|
349
|
-
async function
|
|
350
|
-
const
|
|
935
|
+
async function updateStandingPoints(id, linearPoints, dynamicPoints, totalPoints) {
|
|
936
|
+
const standing = await findStandingById(id, {
|
|
351
937
|
tournament: true
|
|
352
938
|
});
|
|
353
|
-
if (!
|
|
354
|
-
throw new Error(`
|
|
939
|
+
if (!standing) {
|
|
940
|
+
throw new Error(`Standing with id ${id} not found`);
|
|
355
941
|
}
|
|
356
942
|
const now = /* @__PURE__ */ new Date();
|
|
357
|
-
const tournamentDate =
|
|
943
|
+
const tournamentDate = standing.tournament.date;
|
|
358
944
|
const ageInDays = Math.floor((now.getTime() - tournamentDate.getTime()) / (1e3 * 60 * 60 * 24));
|
|
359
945
|
const ageInYears = ageInDays / 365;
|
|
360
946
|
let decayMultiplier = 0;
|
|
@@ -368,7 +954,7 @@ async function updateResultPoints(id, linearPoints, dynamicPoints, totalPoints)
|
|
|
368
954
|
decayMultiplier = 0;
|
|
369
955
|
}
|
|
370
956
|
const decayedPoints = totalPoints * decayMultiplier;
|
|
371
|
-
return
|
|
957
|
+
return updateStanding(id, {
|
|
372
958
|
linearPoints,
|
|
373
959
|
dynamicPoints,
|
|
374
960
|
totalPoints,
|
|
@@ -377,50 +963,50 @@ async function updateResultPoints(id, linearPoints, dynamicPoints, totalPoints)
|
|
|
377
963
|
decayedPoints
|
|
378
964
|
});
|
|
379
965
|
}
|
|
380
|
-
async function
|
|
381
|
-
return prisma.
|
|
966
|
+
async function deleteStanding(id) {
|
|
967
|
+
return prisma.standing.delete({
|
|
382
968
|
where: { id }
|
|
383
969
|
});
|
|
384
970
|
}
|
|
385
|
-
async function
|
|
386
|
-
return prisma.
|
|
971
|
+
async function deleteStandingsByTournament(tournamentId) {
|
|
972
|
+
return prisma.standing.deleteMany({
|
|
387
973
|
where: { tournamentId }
|
|
388
974
|
});
|
|
389
975
|
}
|
|
390
|
-
async function
|
|
391
|
-
return prisma.
|
|
976
|
+
async function countStandings(where) {
|
|
977
|
+
return prisma.standing.count({ where });
|
|
392
978
|
}
|
|
393
979
|
async function getPlayerStats(playerId) {
|
|
394
|
-
const
|
|
395
|
-
if (
|
|
980
|
+
const standings = await getPlayerStandings(playerId);
|
|
981
|
+
if (standings.length === 0) {
|
|
396
982
|
return null;
|
|
397
983
|
}
|
|
398
|
-
const totalPoints =
|
|
399
|
-
const totalDecayedPoints =
|
|
400
|
-
const averagePosition =
|
|
401
|
-
const averageEfficiency =
|
|
402
|
-
const firstPlaceFinishes =
|
|
403
|
-
const topThreeFinishes =
|
|
984
|
+
const totalPoints = standings.reduce((sum, s) => sum + (s.totalPoints || 0), 0);
|
|
985
|
+
const totalDecayedPoints = standings.reduce((sum, s) => sum + (s.decayedPoints || 0), 0);
|
|
986
|
+
const averagePosition = standings.reduce((sum, s) => sum + s.position, 0) / standings.length;
|
|
987
|
+
const averageEfficiency = standings.reduce((sum, s) => sum + (s.efficiency || 0), 0) / standings.length;
|
|
988
|
+
const firstPlaceFinishes = standings.filter((s) => s.position === 1).length;
|
|
989
|
+
const topThreeFinishes = standings.filter((s) => s.position <= 3).length;
|
|
404
990
|
return {
|
|
405
|
-
totalEvents:
|
|
991
|
+
totalEvents: standings.length,
|
|
406
992
|
totalPoints,
|
|
407
993
|
totalDecayedPoints,
|
|
408
|
-
averagePoints: totalPoints /
|
|
994
|
+
averagePoints: totalPoints / standings.length,
|
|
409
995
|
averagePosition,
|
|
410
996
|
averageFinish: averagePosition,
|
|
411
997
|
averageEfficiency,
|
|
412
998
|
firstPlaceFinishes,
|
|
413
999
|
topThreeFinishes,
|
|
414
|
-
bestFinish: Math.min(...
|
|
415
|
-
highestPoints: Math.max(...
|
|
1000
|
+
bestFinish: Math.min(...standings.map((s) => s.position)),
|
|
1001
|
+
highestPoints: Math.max(...standings.map((s) => s.totalPoints || 0))
|
|
416
1002
|
};
|
|
417
1003
|
}
|
|
418
1004
|
async function recalculateTimeDecay(referenceDate = /* @__PURE__ */ new Date()) {
|
|
419
|
-
const
|
|
1005
|
+
const standings = await findStandings({
|
|
420
1006
|
include: { tournament: true }
|
|
421
1007
|
});
|
|
422
|
-
const updates =
|
|
423
|
-
const tournamentDate =
|
|
1008
|
+
const updates = standings.map((standing) => {
|
|
1009
|
+
const tournamentDate = standing.tournament.date;
|
|
424
1010
|
const ageInDays = Math.floor(
|
|
425
1011
|
(referenceDate.getTime() - tournamentDate.getTime()) / (1e3 * 60 * 60 * 24)
|
|
426
1012
|
);
|
|
@@ -435,9 +1021,9 @@ async function recalculateTimeDecay(referenceDate = /* @__PURE__ */ new Date())
|
|
|
435
1021
|
} else {
|
|
436
1022
|
decayMultiplier = 0;
|
|
437
1023
|
}
|
|
438
|
-
const decayedPoints = (
|
|
439
|
-
return prisma.
|
|
440
|
-
where: { id:
|
|
1024
|
+
const decayedPoints = (standing.totalPoints || 0) * decayMultiplier;
|
|
1025
|
+
return prisma.standing.update({
|
|
1026
|
+
where: { id: standing.id },
|
|
441
1027
|
data: {
|
|
442
1028
|
ageInDays,
|
|
443
1029
|
decayMultiplier,
|
|
@@ -456,9 +1042,11 @@ async function createUser(data) {
|
|
|
456
1042
|
}
|
|
457
1043
|
async function createUserWithPlayer(userData, playerData) {
|
|
458
1044
|
return prisma.$transaction(async (tx) => {
|
|
1045
|
+
const playerNumber = await generateUniquePlayerNumber();
|
|
459
1046
|
const player = await tx.player.create({
|
|
460
1047
|
data: {
|
|
461
|
-
name: playerData.name
|
|
1048
|
+
name: playerData.name,
|
|
1049
|
+
playerNumber
|
|
462
1050
|
}
|
|
463
1051
|
});
|
|
464
1052
|
const user = await tx.user.create({
|
|
@@ -470,11 +1058,8 @@ async function createUserWithPlayer(userData, playerData) {
|
|
|
470
1058
|
player: {
|
|
471
1059
|
select: {
|
|
472
1060
|
id: true,
|
|
1061
|
+
playerNumber: true,
|
|
473
1062
|
name: true,
|
|
474
|
-
rating: true,
|
|
475
|
-
ratingDeviation: true,
|
|
476
|
-
ranking: true,
|
|
477
|
-
isRated: true,
|
|
478
1063
|
eventCount: true
|
|
479
1064
|
}
|
|
480
1065
|
}
|
|
@@ -502,11 +1087,8 @@ async function getUserWithPlayer(id) {
|
|
|
502
1087
|
player: {
|
|
503
1088
|
select: {
|
|
504
1089
|
id: true,
|
|
1090
|
+
playerNumber: true,
|
|
505
1091
|
name: true,
|
|
506
|
-
rating: true,
|
|
507
|
-
ratingDeviation: true,
|
|
508
|
-
ranking: true,
|
|
509
|
-
isRated: true,
|
|
510
1092
|
eventCount: true
|
|
511
1093
|
}
|
|
512
1094
|
}
|
|
@@ -524,11 +1106,8 @@ async function getUserByEmailWithPlayer(email) {
|
|
|
524
1106
|
player: {
|
|
525
1107
|
select: {
|
|
526
1108
|
id: true,
|
|
1109
|
+
playerNumber: true,
|
|
527
1110
|
name: true,
|
|
528
|
-
rating: true,
|
|
529
|
-
ratingDeviation: true,
|
|
530
|
-
ranking: true,
|
|
531
|
-
isRated: true,
|
|
532
1111
|
eventCount: true
|
|
533
1112
|
}
|
|
534
1113
|
}
|
|
@@ -569,11 +1148,8 @@ async function findUsers(params) {
|
|
|
569
1148
|
player: {
|
|
570
1149
|
select: {
|
|
571
1150
|
id: true,
|
|
1151
|
+
playerNumber: true,
|
|
572
1152
|
name: true,
|
|
573
|
-
rating: true,
|
|
574
|
-
ratingDeviation: true,
|
|
575
|
-
ranking: true,
|
|
576
|
-
isRated: true,
|
|
577
1153
|
eventCount: true
|
|
578
1154
|
}
|
|
579
1155
|
}
|
|
@@ -600,11 +1176,8 @@ async function linkPlayerToUser(userId, playerId) {
|
|
|
600
1176
|
player: {
|
|
601
1177
|
select: {
|
|
602
1178
|
id: true,
|
|
1179
|
+
playerNumber: true,
|
|
603
1180
|
name: true,
|
|
604
|
-
rating: true,
|
|
605
|
-
ratingDeviation: true,
|
|
606
|
-
ranking: true,
|
|
607
|
-
isRated: true,
|
|
608
1181
|
eventCount: true
|
|
609
1182
|
}
|
|
610
1183
|
}
|
|
@@ -613,64 +1186,467 @@ async function linkPlayerToUser(userId, playerId) {
|
|
|
613
1186
|
return user;
|
|
614
1187
|
});
|
|
615
1188
|
}
|
|
1189
|
+
|
|
1190
|
+
// src/api-keys.ts
|
|
1191
|
+
var MAX_API_KEYS_PER_USER = 5;
|
|
1192
|
+
async function createApiKey(data) {
|
|
1193
|
+
return prisma.apiKey.create({ data });
|
|
1194
|
+
}
|
|
1195
|
+
async function findApiKeyById(id) {
|
|
1196
|
+
return prisma.apiKey.findUnique({ where: { id } });
|
|
1197
|
+
}
|
|
1198
|
+
async function findApiKeysByPrefix(keyPrefix) {
|
|
1199
|
+
const keys = await prisma.apiKey.findMany({
|
|
1200
|
+
where: { keyPrefix },
|
|
1201
|
+
include: {
|
|
1202
|
+
user: {
|
|
1203
|
+
select: {
|
|
1204
|
+
id: true,
|
|
1205
|
+
email: true,
|
|
1206
|
+
role: true
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
return keys;
|
|
1212
|
+
}
|
|
1213
|
+
async function getUserApiKeys(userId) {
|
|
1214
|
+
return prisma.apiKey.findMany({
|
|
1215
|
+
where: { userId },
|
|
1216
|
+
select: {
|
|
1217
|
+
id: true,
|
|
1218
|
+
name: true,
|
|
1219
|
+
keyPrefix: true,
|
|
1220
|
+
expiresAt: true,
|
|
1221
|
+
lastUsedAt: true,
|
|
1222
|
+
createdAt: true
|
|
1223
|
+
},
|
|
1224
|
+
orderBy: { createdAt: "desc" }
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
async function countUserApiKeys(userId) {
|
|
1228
|
+
return prisma.apiKey.count({ where: { userId } });
|
|
1229
|
+
}
|
|
1230
|
+
async function updateApiKeyLastUsed(id) {
|
|
1231
|
+
await prisma.apiKey.update({
|
|
1232
|
+
where: { id },
|
|
1233
|
+
data: { lastUsedAt: /* @__PURE__ */ new Date() }
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
async function deleteApiKey(id) {
|
|
1237
|
+
return prisma.apiKey.delete({ where: { id } });
|
|
1238
|
+
}
|
|
1239
|
+
async function deleteUserApiKey(id, userId) {
|
|
1240
|
+
const key = await prisma.apiKey.findFirst({
|
|
1241
|
+
where: { id, userId }
|
|
1242
|
+
});
|
|
1243
|
+
if (!key) {
|
|
1244
|
+
return null;
|
|
1245
|
+
}
|
|
1246
|
+
return prisma.apiKey.delete({ where: { id } });
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/locations.ts
|
|
1250
|
+
async function createLocation(data) {
|
|
1251
|
+
return prisma.location.create({
|
|
1252
|
+
data
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
async function findLocationById(id, include) {
|
|
1256
|
+
return prisma.location.findUnique({
|
|
1257
|
+
where: { id },
|
|
1258
|
+
include
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
async function findLocationByExternalId(externalId, include) {
|
|
1262
|
+
return prisma.location.findUnique({
|
|
1263
|
+
where: { externalId },
|
|
1264
|
+
include
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
async function findLocations(options = {}) {
|
|
1268
|
+
return prisma.location.findMany({
|
|
1269
|
+
take: options.take,
|
|
1270
|
+
skip: options.skip,
|
|
1271
|
+
where: options.where,
|
|
1272
|
+
orderBy: options.orderBy,
|
|
1273
|
+
include: options.include
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
async function searchLocations(query, limit = 20) {
|
|
1277
|
+
return findLocations({
|
|
1278
|
+
take: limit,
|
|
1279
|
+
where: {
|
|
1280
|
+
OR: [
|
|
1281
|
+
{ name: { contains: query, mode: "insensitive" } },
|
|
1282
|
+
{ city: { contains: query, mode: "insensitive" } }
|
|
1283
|
+
]
|
|
1284
|
+
},
|
|
1285
|
+
orderBy: { name: "asc" }
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
async function updateLocation(id, data) {
|
|
1289
|
+
return prisma.location.update({
|
|
1290
|
+
where: { id },
|
|
1291
|
+
data
|
|
1292
|
+
});
|
|
1293
|
+
}
|
|
1294
|
+
async function deleteLocation(id) {
|
|
1295
|
+
return prisma.location.delete({
|
|
1296
|
+
where: { id }
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
async function countLocations(where) {
|
|
1300
|
+
return prisma.location.count({ where });
|
|
1301
|
+
}
|
|
1302
|
+
async function getLocationWithTournaments(id) {
|
|
1303
|
+
return prisma.location.findUnique({
|
|
1304
|
+
where: { id },
|
|
1305
|
+
include: {
|
|
1306
|
+
tournaments: {
|
|
1307
|
+
orderBy: {
|
|
1308
|
+
date: "desc"
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
// src/blog-posts.ts
|
|
1316
|
+
var defaultInclude = {
|
|
1317
|
+
author: {
|
|
1318
|
+
select: { id: true, email: true }
|
|
1319
|
+
},
|
|
1320
|
+
tags: {
|
|
1321
|
+
select: { id: true, name: true, slug: true }
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
async function createBlogPost(data) {
|
|
1325
|
+
const { tagIds, ...postData } = data;
|
|
1326
|
+
return prisma.blogPost.create({
|
|
1327
|
+
data: {
|
|
1328
|
+
...postData,
|
|
1329
|
+
tags: tagIds?.length ? { connect: tagIds.map((id) => ({ id })) } : void 0
|
|
1330
|
+
},
|
|
1331
|
+
include: defaultInclude
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
async function findBlogPostById(id) {
|
|
1335
|
+
return prisma.blogPost.findUnique({
|
|
1336
|
+
where: { id },
|
|
1337
|
+
include: defaultInclude
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
async function findBlogPostBySlug(slug) {
|
|
1341
|
+
return prisma.blogPost.findUnique({
|
|
1342
|
+
where: { slug },
|
|
1343
|
+
include: defaultInclude
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
async function findBlogPosts(options = {}) {
|
|
1347
|
+
return prisma.blogPost.findMany({
|
|
1348
|
+
take: options.take,
|
|
1349
|
+
skip: options.skip,
|
|
1350
|
+
where: options.where,
|
|
1351
|
+
orderBy: options.orderBy ?? { createdAt: "desc" },
|
|
1352
|
+
include: options.include ?? defaultInclude
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
async function findPublishedBlogPosts(options = {}) {
|
|
1356
|
+
const { tagSlug, ...restOptions } = options;
|
|
1357
|
+
const where = {
|
|
1358
|
+
status: "PUBLISHED",
|
|
1359
|
+
publishedAt: { not: null },
|
|
1360
|
+
...tagSlug && {
|
|
1361
|
+
tags: {
|
|
1362
|
+
some: { slug: tagSlug }
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
};
|
|
1366
|
+
return findBlogPosts({
|
|
1367
|
+
...restOptions,
|
|
1368
|
+
where,
|
|
1369
|
+
orderBy: options.orderBy ?? { publishedAt: "desc" }
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
async function searchBlogPosts(query, limit = 20, publishedOnly = true) {
|
|
1373
|
+
const where = {
|
|
1374
|
+
OR: [
|
|
1375
|
+
{ title: { contains: query, mode: "insensitive" } },
|
|
1376
|
+
{ excerpt: { contains: query, mode: "insensitive" } }
|
|
1377
|
+
],
|
|
1378
|
+
...publishedOnly && {
|
|
1379
|
+
status: "PUBLISHED",
|
|
1380
|
+
publishedAt: { not: null }
|
|
1381
|
+
}
|
|
1382
|
+
};
|
|
1383
|
+
return findBlogPosts({
|
|
1384
|
+
take: limit,
|
|
1385
|
+
where,
|
|
1386
|
+
orderBy: { publishedAt: "desc" }
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
async function updateBlogPost(id, data) {
|
|
1390
|
+
const { tagIds, ...postData } = data;
|
|
1391
|
+
return prisma.blogPost.update({
|
|
1392
|
+
where: { id },
|
|
1393
|
+
data: {
|
|
1394
|
+
...postData,
|
|
1395
|
+
// If tagIds is provided, replace all tags
|
|
1396
|
+
...tagIds !== void 0 && {
|
|
1397
|
+
tags: {
|
|
1398
|
+
set: tagIds.map((tagId) => ({ id: tagId }))
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
},
|
|
1402
|
+
include: defaultInclude
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
async function deleteBlogPost(id) {
|
|
1406
|
+
return prisma.blogPost.delete({
|
|
1407
|
+
where: { id }
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
async function countBlogPosts(where) {
|
|
1411
|
+
return prisma.blogPost.count({ where });
|
|
1412
|
+
}
|
|
1413
|
+
async function countPublishedBlogPosts(tagSlug) {
|
|
1414
|
+
return countBlogPosts({
|
|
1415
|
+
status: "PUBLISHED",
|
|
1416
|
+
publishedAt: { not: null },
|
|
1417
|
+
...tagSlug && {
|
|
1418
|
+
tags: {
|
|
1419
|
+
some: { slug: tagSlug }
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// src/blog-tags.ts
|
|
1426
|
+
async function createBlogTag(data) {
|
|
1427
|
+
return prisma.blogTag.create({
|
|
1428
|
+
data
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
async function findBlogTagById(id) {
|
|
1432
|
+
return prisma.blogTag.findUnique({
|
|
1433
|
+
where: { id }
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
async function findBlogTagBySlug(slug) {
|
|
1437
|
+
return prisma.blogTag.findUnique({
|
|
1438
|
+
where: { slug }
|
|
1439
|
+
});
|
|
1440
|
+
}
|
|
1441
|
+
async function findBlogTags(options = {}) {
|
|
1442
|
+
return prisma.blogTag.findMany({
|
|
1443
|
+
take: options.take,
|
|
1444
|
+
skip: options.skip,
|
|
1445
|
+
where: options.where,
|
|
1446
|
+
orderBy: options.orderBy ?? { name: "asc" },
|
|
1447
|
+
include: options.include
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
async function searchBlogTags(query, limit = 20) {
|
|
1451
|
+
return findBlogTags({
|
|
1452
|
+
take: limit,
|
|
1453
|
+
where: {
|
|
1454
|
+
name: { contains: query, mode: "insensitive" }
|
|
1455
|
+
},
|
|
1456
|
+
orderBy: { name: "asc" }
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1459
|
+
async function updateBlogTag(id, data) {
|
|
1460
|
+
return prisma.blogTag.update({
|
|
1461
|
+
where: { id },
|
|
1462
|
+
data
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1465
|
+
async function deleteBlogTag(id) {
|
|
1466
|
+
return prisma.blogTag.delete({
|
|
1467
|
+
where: { id }
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
async function countBlogTags(where) {
|
|
1471
|
+
return prisma.blogTag.count({ where });
|
|
1472
|
+
}
|
|
1473
|
+
async function getBlogTagWithPostCount(id) {
|
|
1474
|
+
return prisma.blogTag.findUnique({
|
|
1475
|
+
where: { id },
|
|
1476
|
+
include: {
|
|
1477
|
+
_count: {
|
|
1478
|
+
select: { posts: true }
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
async function getBlogTagsWithPostCounts() {
|
|
1484
|
+
return prisma.blogTag.findMany({
|
|
1485
|
+
include: {
|
|
1486
|
+
_count: {
|
|
1487
|
+
select: { posts: true }
|
|
1488
|
+
}
|
|
1489
|
+
},
|
|
1490
|
+
orderBy: { name: "asc" }
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
616
1493
|
export {
|
|
1494
|
+
MAX_API_KEYS_PER_USER,
|
|
1495
|
+
applyRDDecayForInactivePlayers,
|
|
617
1496
|
connect,
|
|
1497
|
+
countBlogPosts,
|
|
1498
|
+
countBlogTags,
|
|
1499
|
+
countEntries,
|
|
1500
|
+
countLocations,
|
|
1501
|
+
countMatches,
|
|
1502
|
+
countOpprPlayerRankings,
|
|
1503
|
+
countOpprRankingHistory,
|
|
618
1504
|
countPlayers,
|
|
619
|
-
|
|
1505
|
+
countPublishedBlogPosts,
|
|
1506
|
+
countRounds,
|
|
1507
|
+
countStandings,
|
|
620
1508
|
countTournaments,
|
|
1509
|
+
countUserApiKeys,
|
|
621
1510
|
countUsers,
|
|
622
|
-
|
|
1511
|
+
createApiKey,
|
|
1512
|
+
createBlogPost,
|
|
1513
|
+
createBlogTag,
|
|
1514
|
+
createEntry,
|
|
1515
|
+
createLocation,
|
|
1516
|
+
createManyEntries,
|
|
1517
|
+
createManyMatches,
|
|
1518
|
+
createManyRounds,
|
|
1519
|
+
createManyStandings,
|
|
1520
|
+
createMatch,
|
|
1521
|
+
createOpprPlayerRanking,
|
|
1522
|
+
createOpprRankingHistory,
|
|
623
1523
|
createPlayer,
|
|
624
|
-
|
|
1524
|
+
createRound,
|
|
1525
|
+
createStanding,
|
|
625
1526
|
createTournament,
|
|
626
1527
|
createUser,
|
|
627
1528
|
createUserWithPlayer,
|
|
1529
|
+
deleteApiKey,
|
|
1530
|
+
deleteBlogPost,
|
|
1531
|
+
deleteBlogTag,
|
|
1532
|
+
deleteEntriesByMatch,
|
|
1533
|
+
deleteEntry,
|
|
1534
|
+
deleteLocation,
|
|
1535
|
+
deleteMatch,
|
|
1536
|
+
deleteMatchesByRound,
|
|
1537
|
+
deleteMatchesByTournament,
|
|
1538
|
+
deleteOpprPlayerRanking,
|
|
628
1539
|
deletePlayer,
|
|
629
|
-
|
|
630
|
-
|
|
1540
|
+
deleteRound,
|
|
1541
|
+
deleteRoundsByTournament,
|
|
1542
|
+
deleteStanding,
|
|
1543
|
+
deleteStandingsByTournament,
|
|
631
1544
|
deleteTournament,
|
|
632
1545
|
deleteUser,
|
|
1546
|
+
deleteUserApiKey,
|
|
633
1547
|
disconnect,
|
|
1548
|
+
findApiKeyById,
|
|
1549
|
+
findApiKeysByPrefix,
|
|
1550
|
+
findBlogPostById,
|
|
1551
|
+
findBlogPostBySlug,
|
|
1552
|
+
findBlogPosts,
|
|
1553
|
+
findBlogTagById,
|
|
1554
|
+
findBlogTagBySlug,
|
|
1555
|
+
findBlogTags,
|
|
1556
|
+
findEntries,
|
|
1557
|
+
findEntryById,
|
|
1558
|
+
findEntryByMatchAndPlayer,
|
|
1559
|
+
findLocationByExternalId,
|
|
1560
|
+
findLocationById,
|
|
1561
|
+
findLocations,
|
|
1562
|
+
findMatchById,
|
|
1563
|
+
findMatches,
|
|
1564
|
+
findOpprPlayerRankingById,
|
|
1565
|
+
findOpprPlayerRankingByPlayerId,
|
|
1566
|
+
findOpprPlayerRankings,
|
|
634
1567
|
findPlayerByExternalId,
|
|
635
1568
|
findPlayerById,
|
|
1569
|
+
findPlayerByPlayerNumber,
|
|
636
1570
|
findPlayerByUserEmail,
|
|
637
1571
|
findPlayers,
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
1572
|
+
findPublishedBlogPosts,
|
|
1573
|
+
findRoundById,
|
|
1574
|
+
findRoundByTournamentAndNumber,
|
|
1575
|
+
findRounds,
|
|
1576
|
+
findStandingById,
|
|
1577
|
+
findStandingByPlayerAndTournament,
|
|
1578
|
+
findStandings,
|
|
641
1579
|
findTournamentByExternalId,
|
|
642
1580
|
findTournamentById,
|
|
643
1581
|
findTournaments,
|
|
644
1582
|
findUserByEmail,
|
|
645
1583
|
findUserById,
|
|
646
1584
|
findUsers,
|
|
1585
|
+
generateUniquePlayerNumber,
|
|
1586
|
+
getBlogTagWithPostCount,
|
|
1587
|
+
getBlogTagsWithPostCounts,
|
|
1588
|
+
getFinalsRounds,
|
|
1589
|
+
getFinalsStandings,
|
|
1590
|
+
getLatestOpprRankingHistory,
|
|
1591
|
+
getLocationWithTournaments,
|
|
647
1592
|
getMajorTournaments,
|
|
648
|
-
|
|
1593
|
+
getMatchEntries,
|
|
1594
|
+
getMatchWithEntries,
|
|
1595
|
+
getMergedStandings,
|
|
1596
|
+
getOpprRankingHistory,
|
|
1597
|
+
getOpprRankingHistoryByDateRange,
|
|
1598
|
+
getOrCreateOpprPlayerRanking,
|
|
1599
|
+
getPlayerEntries,
|
|
1600
|
+
getPlayerEntryStats,
|
|
1601
|
+
getPlayerStandings,
|
|
649
1602
|
getPlayerStats,
|
|
650
1603
|
getPlayerTopFinishes,
|
|
1604
|
+
getPlayerTournamentEntries,
|
|
1605
|
+
getPlayerTournamentMatches,
|
|
651
1606
|
getPlayerWithResults,
|
|
652
|
-
|
|
1607
|
+
getQualifyingRounds,
|
|
1608
|
+
getQualifyingStandings,
|
|
1609
|
+
getRatedOpprPlayers,
|
|
653
1610
|
getRecentTournaments,
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
1611
|
+
getRoundMatches,
|
|
1612
|
+
getRoundWithMatches,
|
|
1613
|
+
getTopPlayersByOpprRanking,
|
|
1614
|
+
getTopPlayersByOpprRating,
|
|
1615
|
+
getTournamentMatches,
|
|
1616
|
+
getTournamentRounds,
|
|
1617
|
+
getTournamentStandings,
|
|
657
1618
|
getTournamentStats,
|
|
1619
|
+
getTournamentWithMatches,
|
|
658
1620
|
getTournamentWithResults,
|
|
659
1621
|
getTournamentsByBoosterType,
|
|
660
1622
|
getTournamentsByDateRange,
|
|
1623
|
+
getUserApiKeys,
|
|
661
1624
|
getUserByEmailWithPlayer,
|
|
662
1625
|
getUserWithPlayer,
|
|
1626
|
+
isValidPlayerNumber,
|
|
663
1627
|
linkPlayerToUser,
|
|
664
1628
|
prisma,
|
|
665
1629
|
recalculateTimeDecay,
|
|
1630
|
+
searchBlogPosts,
|
|
1631
|
+
searchBlogTags,
|
|
1632
|
+
searchLocations,
|
|
666
1633
|
searchPlayers,
|
|
667
1634
|
searchTournaments,
|
|
668
1635
|
testConnection,
|
|
1636
|
+
updateApiKeyLastUsed,
|
|
1637
|
+
updateBlogPost,
|
|
1638
|
+
updateBlogTag,
|
|
1639
|
+
updateEntry,
|
|
1640
|
+
updateLocation,
|
|
1641
|
+
updateMatch,
|
|
1642
|
+
updateOpprPlayerRanking,
|
|
1643
|
+
updateOpprRatingAfterTournament,
|
|
669
1644
|
updatePlayer,
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
1645
|
+
updateRound,
|
|
1646
|
+
updateStanding,
|
|
1647
|
+
updateStandingPoints,
|
|
673
1648
|
updateTournament,
|
|
674
1649
|
updateUser,
|
|
675
|
-
updateUserRefreshToken
|
|
1650
|
+
updateUserRefreshToken,
|
|
1651
|
+
updateWorldRankings
|
|
676
1652
|
};
|