@opprs/db-prisma 2.3.0 → 2.6.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 +1182 -156
- package/dist/index.d.cts +1006 -105
- package/dist/index.d.ts +1006 -105
- package/dist/index.js +1069 -139
- package/package.json +1 -1
- 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/schema.prisma +307 -37
- package/prisma/seed.ts +107 -35
package/dist/index.cjs
CHANGED
|
@@ -20,31 +20,91 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
MAX_API_KEYS_PER_USER: () => MAX_API_KEYS_PER_USER,
|
|
24
|
+
applyRDDecayForInactivePlayers: () => applyRDDecayForInactivePlayers,
|
|
23
25
|
connect: () => connect,
|
|
26
|
+
countBlogPosts: () => countBlogPosts,
|
|
27
|
+
countBlogTags: () => countBlogTags,
|
|
28
|
+
countEntries: () => countEntries,
|
|
29
|
+
countLocations: () => countLocations,
|
|
30
|
+
countMatches: () => countMatches,
|
|
31
|
+
countOpprPlayerRankings: () => countOpprPlayerRankings,
|
|
32
|
+
countOpprRankingHistory: () => countOpprRankingHistory,
|
|
24
33
|
countPlayers: () => countPlayers,
|
|
25
|
-
|
|
34
|
+
countPublishedBlogPosts: () => countPublishedBlogPosts,
|
|
35
|
+
countRounds: () => countRounds,
|
|
36
|
+
countStandings: () => countStandings,
|
|
26
37
|
countTournaments: () => countTournaments,
|
|
38
|
+
countUserApiKeys: () => countUserApiKeys,
|
|
27
39
|
countUsers: () => countUsers,
|
|
28
|
-
|
|
40
|
+
createApiKey: () => createApiKey,
|
|
41
|
+
createBlogPost: () => createBlogPost,
|
|
42
|
+
createBlogTag: () => createBlogTag,
|
|
43
|
+
createEntry: () => createEntry,
|
|
44
|
+
createLocation: () => createLocation,
|
|
45
|
+
createManyEntries: () => createManyEntries,
|
|
46
|
+
createManyMatches: () => createManyMatches,
|
|
47
|
+
createManyRounds: () => createManyRounds,
|
|
48
|
+
createManyStandings: () => createManyStandings,
|
|
49
|
+
createMatch: () => createMatch,
|
|
50
|
+
createOpprPlayerRanking: () => createOpprPlayerRanking,
|
|
51
|
+
createOpprRankingHistory: () => createOpprRankingHistory,
|
|
29
52
|
createPlayer: () => createPlayer,
|
|
30
|
-
|
|
53
|
+
createRound: () => createRound,
|
|
54
|
+
createStanding: () => createStanding,
|
|
31
55
|
createTournament: () => createTournament,
|
|
32
56
|
createUser: () => createUser,
|
|
33
57
|
createUserWithPlayer: () => createUserWithPlayer,
|
|
58
|
+
deleteApiKey: () => deleteApiKey,
|
|
59
|
+
deleteBlogPost: () => deleteBlogPost,
|
|
60
|
+
deleteBlogTag: () => deleteBlogTag,
|
|
61
|
+
deleteEntriesByMatch: () => deleteEntriesByMatch,
|
|
62
|
+
deleteEntry: () => deleteEntry,
|
|
63
|
+
deleteLocation: () => deleteLocation,
|
|
64
|
+
deleteMatch: () => deleteMatch,
|
|
65
|
+
deleteMatchesByRound: () => deleteMatchesByRound,
|
|
66
|
+
deleteMatchesByTournament: () => deleteMatchesByTournament,
|
|
67
|
+
deleteOpprPlayerRanking: () => deleteOpprPlayerRanking,
|
|
34
68
|
deletePlayer: () => deletePlayer,
|
|
35
|
-
|
|
36
|
-
|
|
69
|
+
deleteRound: () => deleteRound,
|
|
70
|
+
deleteRoundsByTournament: () => deleteRoundsByTournament,
|
|
71
|
+
deleteStanding: () => deleteStanding,
|
|
72
|
+
deleteStandingsByTournament: () => deleteStandingsByTournament,
|
|
37
73
|
deleteTournament: () => deleteTournament,
|
|
38
74
|
deleteUser: () => deleteUser,
|
|
75
|
+
deleteUserApiKey: () => deleteUserApiKey,
|
|
39
76
|
disconnect: () => disconnect,
|
|
77
|
+
findApiKeyById: () => findApiKeyById,
|
|
78
|
+
findApiKeysByPrefix: () => findApiKeysByPrefix,
|
|
79
|
+
findBlogPostById: () => findBlogPostById,
|
|
80
|
+
findBlogPostBySlug: () => findBlogPostBySlug,
|
|
81
|
+
findBlogPosts: () => findBlogPosts,
|
|
82
|
+
findBlogTagById: () => findBlogTagById,
|
|
83
|
+
findBlogTagBySlug: () => findBlogTagBySlug,
|
|
84
|
+
findBlogTags: () => findBlogTags,
|
|
85
|
+
findEntries: () => findEntries,
|
|
86
|
+
findEntryById: () => findEntryById,
|
|
87
|
+
findEntryByMatchAndPlayer: () => findEntryByMatchAndPlayer,
|
|
88
|
+
findLocationByExternalId: () => findLocationByExternalId,
|
|
89
|
+
findLocationById: () => findLocationById,
|
|
90
|
+
findLocations: () => findLocations,
|
|
91
|
+
findMatchById: () => findMatchById,
|
|
92
|
+
findMatches: () => findMatches,
|
|
93
|
+
findOpprPlayerRankingById: () => findOpprPlayerRankingById,
|
|
94
|
+
findOpprPlayerRankingByPlayerId: () => findOpprPlayerRankingByPlayerId,
|
|
95
|
+
findOpprPlayerRankings: () => findOpprPlayerRankings,
|
|
40
96
|
findPlayerByExternalId: () => findPlayerByExternalId,
|
|
41
97
|
findPlayerById: () => findPlayerById,
|
|
42
98
|
findPlayerByPlayerNumber: () => findPlayerByPlayerNumber,
|
|
43
99
|
findPlayerByUserEmail: () => findPlayerByUserEmail,
|
|
44
100
|
findPlayers: () => findPlayers,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
101
|
+
findPublishedBlogPosts: () => findPublishedBlogPosts,
|
|
102
|
+
findRoundById: () => findRoundById,
|
|
103
|
+
findRoundByTournamentAndNumber: () => findRoundByTournamentAndNumber,
|
|
104
|
+
findRounds: () => findRounds,
|
|
105
|
+
findStandingById: () => findStandingById,
|
|
106
|
+
findStandingByPlayerAndTournament: () => findStandingByPlayerAndTournament,
|
|
107
|
+
findStandings: () => findStandings,
|
|
48
108
|
findTournamentByExternalId: () => findTournamentByExternalId,
|
|
49
109
|
findTournamentById: () => findTournamentById,
|
|
50
110
|
findTournaments: () => findTournaments,
|
|
@@ -52,36 +112,72 @@ __export(index_exports, {
|
|
|
52
112
|
findUserById: () => findUserById,
|
|
53
113
|
findUsers: () => findUsers,
|
|
54
114
|
generateUniquePlayerNumber: () => generateUniquePlayerNumber,
|
|
115
|
+
getBlogTagWithPostCount: () => getBlogTagWithPostCount,
|
|
116
|
+
getBlogTagsWithPostCounts: () => getBlogTagsWithPostCounts,
|
|
117
|
+
getFinalsRounds: () => getFinalsRounds,
|
|
118
|
+
getFinalsStandings: () => getFinalsStandings,
|
|
119
|
+
getLatestOpprRankingHistory: () => getLatestOpprRankingHistory,
|
|
120
|
+
getLocationWithTournaments: () => getLocationWithTournaments,
|
|
55
121
|
getMajorTournaments: () => getMajorTournaments,
|
|
56
|
-
|
|
122
|
+
getMatchEntries: () => getMatchEntries,
|
|
123
|
+
getMatchWithEntries: () => getMatchWithEntries,
|
|
124
|
+
getMergedStandings: () => getMergedStandings,
|
|
125
|
+
getOpprRankingHistory: () => getOpprRankingHistory,
|
|
126
|
+
getOpprRankingHistoryByDateRange: () => getOpprRankingHistoryByDateRange,
|
|
127
|
+
getOrCreateOpprPlayerRanking: () => getOrCreateOpprPlayerRanking,
|
|
128
|
+
getPlayerEntries: () => getPlayerEntries,
|
|
129
|
+
getPlayerEntryStats: () => getPlayerEntryStats,
|
|
130
|
+
getPlayerStandings: () => getPlayerStandings,
|
|
57
131
|
getPlayerStats: () => getPlayerStats,
|
|
58
132
|
getPlayerTopFinishes: () => getPlayerTopFinishes,
|
|
133
|
+
getPlayerTournamentEntries: () => getPlayerTournamentEntries,
|
|
134
|
+
getPlayerTournamentMatches: () => getPlayerTournamentMatches,
|
|
59
135
|
getPlayerWithResults: () => getPlayerWithResults,
|
|
60
|
-
|
|
136
|
+
getQualifyingRounds: () => getQualifyingRounds,
|
|
137
|
+
getQualifyingStandings: () => getQualifyingStandings,
|
|
138
|
+
getRatedOpprPlayers: () => getRatedOpprPlayers,
|
|
61
139
|
getRecentTournaments: () => getRecentTournaments,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
140
|
+
getRoundMatches: () => getRoundMatches,
|
|
141
|
+
getRoundWithMatches: () => getRoundWithMatches,
|
|
142
|
+
getTopPlayersByOpprRanking: () => getTopPlayersByOpprRanking,
|
|
143
|
+
getTopPlayersByOpprRating: () => getTopPlayersByOpprRating,
|
|
144
|
+
getTournamentMatches: () => getTournamentMatches,
|
|
145
|
+
getTournamentRounds: () => getTournamentRounds,
|
|
146
|
+
getTournamentStandings: () => getTournamentStandings,
|
|
65
147
|
getTournamentStats: () => getTournamentStats,
|
|
148
|
+
getTournamentWithMatches: () => getTournamentWithMatches,
|
|
66
149
|
getTournamentWithResults: () => getTournamentWithResults,
|
|
67
150
|
getTournamentsByBoosterType: () => getTournamentsByBoosterType,
|
|
68
151
|
getTournamentsByDateRange: () => getTournamentsByDateRange,
|
|
152
|
+
getUserApiKeys: () => getUserApiKeys,
|
|
69
153
|
getUserByEmailWithPlayer: () => getUserByEmailWithPlayer,
|
|
70
154
|
getUserWithPlayer: () => getUserWithPlayer,
|
|
71
155
|
isValidPlayerNumber: () => isValidPlayerNumber,
|
|
72
156
|
linkPlayerToUser: () => linkPlayerToUser,
|
|
73
157
|
prisma: () => prisma,
|
|
74
158
|
recalculateTimeDecay: () => recalculateTimeDecay,
|
|
159
|
+
searchBlogPosts: () => searchBlogPosts,
|
|
160
|
+
searchBlogTags: () => searchBlogTags,
|
|
161
|
+
searchLocations: () => searchLocations,
|
|
75
162
|
searchPlayers: () => searchPlayers,
|
|
76
163
|
searchTournaments: () => searchTournaments,
|
|
77
164
|
testConnection: () => testConnection,
|
|
165
|
+
updateApiKeyLastUsed: () => updateApiKeyLastUsed,
|
|
166
|
+
updateBlogPost: () => updateBlogPost,
|
|
167
|
+
updateBlogTag: () => updateBlogTag,
|
|
168
|
+
updateEntry: () => updateEntry,
|
|
169
|
+
updateLocation: () => updateLocation,
|
|
170
|
+
updateMatch: () => updateMatch,
|
|
171
|
+
updateOpprPlayerRanking: () => updateOpprPlayerRanking,
|
|
172
|
+
updateOpprRatingAfterTournament: () => updateOpprRatingAfterTournament,
|
|
78
173
|
updatePlayer: () => updatePlayer,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
174
|
+
updateRound: () => updateRound,
|
|
175
|
+
updateStanding: () => updateStanding,
|
|
176
|
+
updateStandingPoints: () => updateStandingPoints,
|
|
82
177
|
updateTournament: () => updateTournament,
|
|
83
178
|
updateUser: () => updateUser,
|
|
84
|
-
updateUserRefreshToken: () => updateUserRefreshToken
|
|
179
|
+
updateUserRefreshToken: () => updateUserRefreshToken,
|
|
180
|
+
updateWorldRankings: () => updateWorldRankings
|
|
85
181
|
});
|
|
86
182
|
module.exports = __toCommonJS(index_exports);
|
|
87
183
|
|
|
@@ -180,48 +276,12 @@ async function findPlayers(options = {}) {
|
|
|
180
276
|
include: options.include
|
|
181
277
|
});
|
|
182
278
|
}
|
|
183
|
-
async function getRatedPlayers(options = {}) {
|
|
184
|
-
return findPlayers({
|
|
185
|
-
...options,
|
|
186
|
-
where: { isRated: true }
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
async function getTopPlayersByRating(limit = 50) {
|
|
190
|
-
return findPlayers({
|
|
191
|
-
take: limit,
|
|
192
|
-
orderBy: { rating: "desc" },
|
|
193
|
-
where: { isRated: true }
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
async function getTopPlayersByRanking(limit = 50) {
|
|
197
|
-
return findPlayers({
|
|
198
|
-
take: limit,
|
|
199
|
-
orderBy: { ranking: "asc" },
|
|
200
|
-
where: {
|
|
201
|
-
isRated: true,
|
|
202
|
-
ranking: { not: null }
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
279
|
async function updatePlayer(id, data) {
|
|
207
280
|
return prisma.player.update({
|
|
208
281
|
where: { id },
|
|
209
282
|
data
|
|
210
283
|
});
|
|
211
284
|
}
|
|
212
|
-
async function updatePlayerRating(id, rating, ratingDeviation, eventCount) {
|
|
213
|
-
const updateData = {
|
|
214
|
-
rating,
|
|
215
|
-
ratingDeviation,
|
|
216
|
-
lastRatingUpdate: /* @__PURE__ */ new Date(),
|
|
217
|
-
lastEventDate: /* @__PURE__ */ new Date()
|
|
218
|
-
};
|
|
219
|
-
if (eventCount !== void 0) {
|
|
220
|
-
updateData.eventCount = eventCount;
|
|
221
|
-
updateData.isRated = eventCount >= 5;
|
|
222
|
-
}
|
|
223
|
-
return updatePlayer(id, updateData);
|
|
224
|
-
}
|
|
225
285
|
async function deletePlayer(id) {
|
|
226
286
|
return prisma.player.delete({
|
|
227
287
|
where: { id }
|
|
@@ -234,7 +294,7 @@ async function getPlayerWithResults(id) {
|
|
|
234
294
|
const player = await prisma.player.findUnique({
|
|
235
295
|
where: { id },
|
|
236
296
|
include: {
|
|
237
|
-
|
|
297
|
+
standings: {
|
|
238
298
|
include: {
|
|
239
299
|
tournament: true
|
|
240
300
|
},
|
|
@@ -251,7 +311,7 @@ async function getPlayerWithResults(id) {
|
|
|
251
311
|
}
|
|
252
312
|
return {
|
|
253
313
|
...player,
|
|
254
|
-
results: player.
|
|
314
|
+
results: player.standings
|
|
255
315
|
};
|
|
256
316
|
}
|
|
257
317
|
async function searchPlayers(query, limit = 20) {
|
|
@@ -263,6 +323,212 @@ async function searchPlayers(query, limit = 20) {
|
|
|
263
323
|
});
|
|
264
324
|
}
|
|
265
325
|
|
|
326
|
+
// src/oppr-rankings.ts
|
|
327
|
+
async function getOrCreateOpprPlayerRanking(playerId) {
|
|
328
|
+
const existing = await prisma.opprPlayerRanking.findUnique({
|
|
329
|
+
where: { playerId }
|
|
330
|
+
});
|
|
331
|
+
if (existing) return existing;
|
|
332
|
+
return prisma.opprPlayerRanking.create({
|
|
333
|
+
data: { playerId }
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
async function createOpprPlayerRanking(data) {
|
|
337
|
+
return prisma.opprPlayerRanking.create({
|
|
338
|
+
data
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
async function findOpprPlayerRankingById(id, include) {
|
|
342
|
+
return prisma.opprPlayerRanking.findUnique({
|
|
343
|
+
where: { id },
|
|
344
|
+
include
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
async function findOpprPlayerRankingByPlayerId(playerId, include) {
|
|
348
|
+
return prisma.opprPlayerRanking.findUnique({
|
|
349
|
+
where: { playerId },
|
|
350
|
+
include
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async function findOpprPlayerRankings(options = {}) {
|
|
354
|
+
return prisma.opprPlayerRanking.findMany({
|
|
355
|
+
take: options.take,
|
|
356
|
+
skip: options.skip,
|
|
357
|
+
where: options.where,
|
|
358
|
+
orderBy: options.orderBy,
|
|
359
|
+
include: options.include
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async function getTopPlayersByOpprRating(limit = 50) {
|
|
363
|
+
return prisma.opprPlayerRanking.findMany({
|
|
364
|
+
take: limit,
|
|
365
|
+
where: { isRated: true },
|
|
366
|
+
orderBy: { rating: "desc" },
|
|
367
|
+
include: { player: true }
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
async function getTopPlayersByOpprRanking(limit = 50) {
|
|
371
|
+
return prisma.opprPlayerRanking.findMany({
|
|
372
|
+
take: limit,
|
|
373
|
+
where: {
|
|
374
|
+
isRated: true,
|
|
375
|
+
ranking: { not: null }
|
|
376
|
+
},
|
|
377
|
+
orderBy: { ranking: "asc" },
|
|
378
|
+
include: { player: true }
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
async function getRatedOpprPlayers(options = {}) {
|
|
382
|
+
return prisma.opprPlayerRanking.findMany({
|
|
383
|
+
...options,
|
|
384
|
+
where: { isRated: true },
|
|
385
|
+
include: { player: true, ...options.include }
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
async function updateOpprPlayerRanking(playerId, data) {
|
|
389
|
+
return prisma.opprPlayerRanking.update({
|
|
390
|
+
where: { playerId },
|
|
391
|
+
data: {
|
|
392
|
+
...data,
|
|
393
|
+
lastRatingUpdate: data.lastRatingUpdate ?? /* @__PURE__ */ new Date()
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
async function updateOpprRatingAfterTournament(playerId, newRating, newRD, tournamentId, eventCount) {
|
|
398
|
+
const ranking = await getOrCreateOpprPlayerRanking(playerId);
|
|
399
|
+
const isRated = eventCount !== void 0 ? eventCount >= 5 : ranking.isRated;
|
|
400
|
+
const updated = await prisma.opprPlayerRanking.update({
|
|
401
|
+
where: { playerId },
|
|
402
|
+
data: {
|
|
403
|
+
rating: newRating,
|
|
404
|
+
ratingDeviation: newRD,
|
|
405
|
+
lastRatingUpdate: /* @__PURE__ */ new Date(),
|
|
406
|
+
isRated
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
await createOpprRankingHistory({
|
|
410
|
+
opprPlayerRankingId: ranking.id,
|
|
411
|
+
rating: newRating,
|
|
412
|
+
ratingDeviation: newRD,
|
|
413
|
+
ranking: updated.ranking ?? void 0,
|
|
414
|
+
isRated,
|
|
415
|
+
changeType: "TOURNAMENT_RESULT",
|
|
416
|
+
tournamentId
|
|
417
|
+
});
|
|
418
|
+
return updated;
|
|
419
|
+
}
|
|
420
|
+
async function updateWorldRankings(rankings) {
|
|
421
|
+
await prisma.$transaction(async (tx) => {
|
|
422
|
+
for (const { playerId, ranking } of rankings) {
|
|
423
|
+
const opprRanking = await tx.opprPlayerRanking.findUnique({
|
|
424
|
+
where: { playerId }
|
|
425
|
+
});
|
|
426
|
+
if (opprRanking) {
|
|
427
|
+
await tx.opprPlayerRanking.update({
|
|
428
|
+
where: { playerId },
|
|
429
|
+
data: { ranking }
|
|
430
|
+
});
|
|
431
|
+
await tx.opprRankingHistory.create({
|
|
432
|
+
data: {
|
|
433
|
+
opprPlayerRankingId: opprRanking.id,
|
|
434
|
+
rating: opprRanking.rating,
|
|
435
|
+
ratingDeviation: opprRanking.ratingDeviation,
|
|
436
|
+
ranking,
|
|
437
|
+
isRated: opprRanking.isRated,
|
|
438
|
+
changeType: "RANKING_REFRESH"
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
async function applyRDDecayForInactivePlayers(thresholdDays = 30, decayPerDay = 0.3, maxRD = 200) {
|
|
446
|
+
const cutoffDate = /* @__PURE__ */ new Date();
|
|
447
|
+
cutoffDate.setDate(cutoffDate.getDate() - thresholdDays);
|
|
448
|
+
const inactivePlayers = await prisma.opprPlayerRanking.findMany({
|
|
449
|
+
where: {
|
|
450
|
+
lastRatingUpdate: { lt: cutoffDate },
|
|
451
|
+
ratingDeviation: { lt: maxRD }
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
let updatedCount = 0;
|
|
455
|
+
await prisma.$transaction(async (tx) => {
|
|
456
|
+
for (const ranking of inactivePlayers) {
|
|
457
|
+
const daysSinceUpdate = Math.floor(
|
|
458
|
+
(Date.now() - ranking.lastRatingUpdate.getTime()) / (1e3 * 60 * 60 * 24)
|
|
459
|
+
);
|
|
460
|
+
const newRD = Math.min(ranking.ratingDeviation + daysSinceUpdate * decayPerDay, maxRD);
|
|
461
|
+
await tx.opprPlayerRanking.update({
|
|
462
|
+
where: { id: ranking.id },
|
|
463
|
+
data: { ratingDeviation: newRD }
|
|
464
|
+
});
|
|
465
|
+
await tx.opprRankingHistory.create({
|
|
466
|
+
data: {
|
|
467
|
+
opprPlayerRankingId: ranking.id,
|
|
468
|
+
rating: ranking.rating,
|
|
469
|
+
ratingDeviation: newRD,
|
|
470
|
+
ranking: ranking.ranking,
|
|
471
|
+
isRated: ranking.isRated,
|
|
472
|
+
changeType: "RD_DECAY",
|
|
473
|
+
notes: `RD increased from ${ranking.ratingDeviation.toFixed(1)} to ${newRD.toFixed(1)} due to ${daysSinceUpdate} days of inactivity`
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
updatedCount++;
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
return updatedCount;
|
|
480
|
+
}
|
|
481
|
+
async function deleteOpprPlayerRanking(playerId) {
|
|
482
|
+
return prisma.opprPlayerRanking.delete({
|
|
483
|
+
where: { playerId }
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
async function countOpprPlayerRankings(where) {
|
|
487
|
+
return prisma.opprPlayerRanking.count({ where });
|
|
488
|
+
}
|
|
489
|
+
async function createOpprRankingHistory(data) {
|
|
490
|
+
return prisma.opprRankingHistory.create({
|
|
491
|
+
data
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
async function getOpprRankingHistory(playerId, limit) {
|
|
495
|
+
const ranking = await findOpprPlayerRankingByPlayerId(playerId);
|
|
496
|
+
if (!ranking) return [];
|
|
497
|
+
return prisma.opprRankingHistory.findMany({
|
|
498
|
+
where: { opprPlayerRankingId: ranking.id },
|
|
499
|
+
orderBy: { createdAt: "desc" },
|
|
500
|
+
take: limit,
|
|
501
|
+
include: { tournament: true }
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
async function getOpprRankingHistoryByDateRange(playerId, startDate, endDate) {
|
|
505
|
+
const ranking = await findOpprPlayerRankingByPlayerId(playerId);
|
|
506
|
+
if (!ranking) return [];
|
|
507
|
+
return prisma.opprRankingHistory.findMany({
|
|
508
|
+
where: {
|
|
509
|
+
opprPlayerRankingId: ranking.id,
|
|
510
|
+
createdAt: {
|
|
511
|
+
gte: startDate,
|
|
512
|
+
lte: endDate
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
orderBy: { createdAt: "asc" },
|
|
516
|
+
include: { tournament: true }
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
async function getLatestOpprRankingHistory(playerId) {
|
|
520
|
+
const ranking = await findOpprPlayerRankingByPlayerId(playerId);
|
|
521
|
+
if (!ranking) return null;
|
|
522
|
+
return prisma.opprRankingHistory.findFirst({
|
|
523
|
+
where: { opprPlayerRankingId: ranking.id },
|
|
524
|
+
orderBy: { createdAt: "desc" },
|
|
525
|
+
include: { tournament: true }
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
async function countOpprRankingHistory(where) {
|
|
529
|
+
return prisma.opprRankingHistory.count({ where });
|
|
530
|
+
}
|
|
531
|
+
|
|
266
532
|
// src/tournaments.ts
|
|
267
533
|
async function createTournament(data) {
|
|
268
534
|
return prisma.tournament.create({
|
|
@@ -342,13 +608,33 @@ async function getTournamentWithResults(id) {
|
|
|
342
608
|
return prisma.tournament.findUnique({
|
|
343
609
|
where: { id },
|
|
344
610
|
include: {
|
|
345
|
-
|
|
611
|
+
standings: {
|
|
346
612
|
include: {
|
|
347
613
|
player: true
|
|
348
614
|
},
|
|
349
|
-
orderBy: {
|
|
350
|
-
|
|
351
|
-
|
|
615
|
+
orderBy: [{ isFinals: "desc" }, { position: "asc" }]
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
async function getTournamentWithMatches(id) {
|
|
621
|
+
return prisma.tournament.findUnique({
|
|
622
|
+
where: { id },
|
|
623
|
+
include: {
|
|
624
|
+
rounds: {
|
|
625
|
+
include: {
|
|
626
|
+
matches: {
|
|
627
|
+
include: {
|
|
628
|
+
entries: {
|
|
629
|
+
include: {
|
|
630
|
+
player: true
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
orderBy: { number: "asc" }
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
orderBy: [{ isFinals: "asc" }, { number: "asc" }]
|
|
352
638
|
}
|
|
353
639
|
}
|
|
354
640
|
});
|
|
@@ -359,7 +645,7 @@ async function searchTournaments(query, limit = 20) {
|
|
|
359
645
|
where: {
|
|
360
646
|
OR: [
|
|
361
647
|
{ name: { contains: query, mode: "insensitive" } },
|
|
362
|
-
{ location: { contains: query, mode: "insensitive" } }
|
|
648
|
+
{ location: { name: { contains: query, mode: "insensitive" } } }
|
|
363
649
|
]
|
|
364
650
|
},
|
|
365
651
|
orderBy: { date: "desc" }
|
|
@@ -370,7 +656,7 @@ async function getTournamentStats(id) {
|
|
|
370
656
|
if (!tournament) {
|
|
371
657
|
return null;
|
|
372
658
|
}
|
|
373
|
-
const playerCount = tournament.
|
|
659
|
+
const playerCount = tournament.standings.length;
|
|
374
660
|
if (playerCount === 0) {
|
|
375
661
|
return {
|
|
376
662
|
tournament,
|
|
@@ -381,9 +667,9 @@ async function getTournamentStats(id) {
|
|
|
381
667
|
lowestPoints: 0
|
|
382
668
|
};
|
|
383
669
|
}
|
|
384
|
-
const totalPoints = tournament.
|
|
385
|
-
const totalEfficiency = tournament.
|
|
386
|
-
const allPoints = tournament.
|
|
670
|
+
const totalPoints = tournament.standings.reduce((sum, s) => sum + (s.totalPoints || 0), 0);
|
|
671
|
+
const totalEfficiency = tournament.standings.reduce((sum, s) => sum + (s.efficiency || 0), 0);
|
|
672
|
+
const allPoints = tournament.standings.map((s) => s.totalPoints || 0);
|
|
387
673
|
return {
|
|
388
674
|
tournament,
|
|
389
675
|
playerCount,
|
|
@@ -394,44 +680,364 @@ async function getTournamentStats(id) {
|
|
|
394
680
|
};
|
|
395
681
|
}
|
|
396
682
|
|
|
397
|
-
// src/
|
|
398
|
-
async function
|
|
399
|
-
|
|
683
|
+
// src/rounds.ts
|
|
684
|
+
async function createRound(data) {
|
|
685
|
+
return prisma.round.create({
|
|
686
|
+
data: {
|
|
687
|
+
...data,
|
|
688
|
+
isFinals: data.isFinals ?? false
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
async function createManyRounds(data) {
|
|
693
|
+
const roundsData = data.map((item) => ({
|
|
694
|
+
...item,
|
|
695
|
+
isFinals: item.isFinals ?? false
|
|
696
|
+
}));
|
|
697
|
+
return prisma.round.createMany({
|
|
698
|
+
data: roundsData
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
async function findRoundById(id, include) {
|
|
702
|
+
return prisma.round.findUnique({
|
|
703
|
+
where: { id },
|
|
704
|
+
include
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
async function findRoundByTournamentAndNumber(tournamentId, number, isFinals, include) {
|
|
708
|
+
return prisma.round.findUnique({
|
|
709
|
+
where: {
|
|
710
|
+
tournamentId_number_isFinals: {
|
|
711
|
+
tournamentId,
|
|
712
|
+
number,
|
|
713
|
+
isFinals
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
include
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
async function findRounds(options = {}) {
|
|
720
|
+
return prisma.round.findMany({
|
|
721
|
+
take: options.take,
|
|
722
|
+
skip: options.skip,
|
|
723
|
+
where: options.where,
|
|
724
|
+
orderBy: options.orderBy,
|
|
725
|
+
include: options.include
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
async function getTournamentRounds(tournamentId, options = {}) {
|
|
729
|
+
return findRounds({
|
|
730
|
+
...options,
|
|
731
|
+
where: { tournamentId },
|
|
732
|
+
orderBy: options.orderBy ?? [{ isFinals: "asc" }, { number: "asc" }]
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
async function getQualifyingRounds(tournamentId, options = {}) {
|
|
736
|
+
return findRounds({
|
|
737
|
+
...options,
|
|
738
|
+
where: { tournamentId, isFinals: false },
|
|
739
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
async function getFinalsRounds(tournamentId, options = {}) {
|
|
743
|
+
return findRounds({
|
|
744
|
+
...options,
|
|
745
|
+
where: { tournamentId, isFinals: true },
|
|
746
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
async function updateRound(id, data) {
|
|
750
|
+
return prisma.round.update({
|
|
751
|
+
where: { id },
|
|
752
|
+
data
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
async function deleteRound(id) {
|
|
756
|
+
return prisma.round.delete({
|
|
757
|
+
where: { id }
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
async function deleteRoundsByTournament(tournamentId) {
|
|
761
|
+
return prisma.round.deleteMany({
|
|
762
|
+
where: { tournamentId }
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
async function countRounds(where) {
|
|
766
|
+
return prisma.round.count({ where });
|
|
767
|
+
}
|
|
768
|
+
async function getRoundWithMatches(id) {
|
|
769
|
+
return prisma.round.findUnique({
|
|
770
|
+
where: { id },
|
|
771
|
+
include: {
|
|
772
|
+
matches: {
|
|
773
|
+
include: {
|
|
774
|
+
entries: {
|
|
775
|
+
include: {
|
|
776
|
+
player: true
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
},
|
|
780
|
+
orderBy: {
|
|
781
|
+
number: "asc"
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// src/matches.ts
|
|
789
|
+
async function createMatch(data) {
|
|
790
|
+
return prisma.match.create({
|
|
791
|
+
data
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
async function createManyMatches(data) {
|
|
795
|
+
return prisma.match.createMany({
|
|
796
|
+
data
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
async function findMatchById(id, include) {
|
|
800
|
+
return prisma.match.findUnique({
|
|
801
|
+
where: { id },
|
|
802
|
+
include
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
async function findMatches(options = {}) {
|
|
806
|
+
return prisma.match.findMany({
|
|
807
|
+
take: options.take,
|
|
808
|
+
skip: options.skip,
|
|
809
|
+
where: options.where,
|
|
810
|
+
orderBy: options.orderBy,
|
|
811
|
+
include: options.include
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
async function getTournamentMatches(tournamentId, options = {}) {
|
|
815
|
+
return findMatches({
|
|
816
|
+
...options,
|
|
817
|
+
where: { tournamentId },
|
|
818
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
async function getRoundMatches(roundId, options = {}) {
|
|
822
|
+
return findMatches({
|
|
823
|
+
...options,
|
|
824
|
+
where: { roundId },
|
|
825
|
+
orderBy: options.orderBy ?? { number: "asc" }
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
async function updateMatch(id, data) {
|
|
829
|
+
return prisma.match.update({
|
|
830
|
+
where: { id },
|
|
831
|
+
data
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
async function deleteMatch(id) {
|
|
835
|
+
return prisma.match.delete({
|
|
836
|
+
where: { id }
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
async function deleteMatchesByTournament(tournamentId) {
|
|
840
|
+
return prisma.match.deleteMany({
|
|
841
|
+
where: { tournamentId }
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
async function deleteMatchesByRound(roundId) {
|
|
845
|
+
return prisma.match.deleteMany({
|
|
846
|
+
where: { roundId }
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
async function countMatches(where) {
|
|
850
|
+
return prisma.match.count({ where });
|
|
851
|
+
}
|
|
852
|
+
async function getMatchWithEntries(id) {
|
|
853
|
+
return prisma.match.findUnique({
|
|
854
|
+
where: { id },
|
|
855
|
+
include: {
|
|
856
|
+
entries: {
|
|
857
|
+
include: {
|
|
858
|
+
player: true
|
|
859
|
+
},
|
|
860
|
+
orderBy: {
|
|
861
|
+
position: "asc"
|
|
862
|
+
}
|
|
863
|
+
},
|
|
864
|
+
round: true
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
async function getPlayerTournamentMatches(playerId, tournamentId, include) {
|
|
869
|
+
return findMatches({
|
|
870
|
+
where: {
|
|
871
|
+
tournamentId,
|
|
872
|
+
entries: {
|
|
873
|
+
some: {
|
|
874
|
+
playerId
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
include: include ?? {
|
|
879
|
+
entries: {
|
|
880
|
+
include: {
|
|
881
|
+
player: true
|
|
882
|
+
}
|
|
883
|
+
},
|
|
884
|
+
round: true
|
|
885
|
+
},
|
|
886
|
+
orderBy: [{ round: { number: "asc" } }, { number: "asc" }]
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// src/entries.ts
|
|
891
|
+
async function createEntry(data) {
|
|
892
|
+
return prisma.entry.create({
|
|
893
|
+
data
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
async function createManyEntries(data) {
|
|
897
|
+
return prisma.entry.createMany({
|
|
898
|
+
data
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
async function findEntryById(id, include) {
|
|
902
|
+
return prisma.entry.findUnique({
|
|
903
|
+
where: { id },
|
|
904
|
+
include
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
async function findEntryByMatchAndPlayer(matchId, playerId, include) {
|
|
908
|
+
return prisma.entry.findUnique({
|
|
909
|
+
where: {
|
|
910
|
+
matchId_playerId: {
|
|
911
|
+
matchId,
|
|
912
|
+
playerId
|
|
913
|
+
}
|
|
914
|
+
},
|
|
915
|
+
include
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
async function findEntries(options = {}) {
|
|
919
|
+
return prisma.entry.findMany({
|
|
920
|
+
take: options.take,
|
|
921
|
+
skip: options.skip,
|
|
922
|
+
where: options.where,
|
|
923
|
+
orderBy: options.orderBy,
|
|
924
|
+
include: options.include
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
async function getMatchEntries(matchId, options = {}) {
|
|
928
|
+
return findEntries({
|
|
929
|
+
...options,
|
|
930
|
+
where: { matchId },
|
|
931
|
+
include: options.include ?? { player: true },
|
|
932
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
async function getPlayerEntries(playerId, options = {}) {
|
|
936
|
+
return findEntries({
|
|
937
|
+
...options,
|
|
938
|
+
where: { playerId },
|
|
939
|
+
include: options.include ?? { match: { include: { round: true, tournament: true } } }
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
async function getPlayerTournamentEntries(playerId, tournamentId, include) {
|
|
943
|
+
return findEntries({
|
|
944
|
+
where: {
|
|
945
|
+
playerId,
|
|
946
|
+
match: {
|
|
947
|
+
tournamentId
|
|
948
|
+
}
|
|
949
|
+
},
|
|
950
|
+
include: include ?? {
|
|
951
|
+
match: {
|
|
952
|
+
include: {
|
|
953
|
+
round: true,
|
|
954
|
+
entries: {
|
|
955
|
+
include: {
|
|
956
|
+
player: true
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
async function updateEntry(id, data) {
|
|
965
|
+
return prisma.entry.update({
|
|
966
|
+
where: { id },
|
|
967
|
+
data
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
async function deleteEntry(id) {
|
|
971
|
+
return prisma.entry.delete({
|
|
972
|
+
where: { id }
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
async function deleteEntriesByMatch(matchId) {
|
|
976
|
+
return prisma.entry.deleteMany({
|
|
977
|
+
where: { matchId }
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
async function countEntries(where) {
|
|
981
|
+
return prisma.entry.count({ where });
|
|
982
|
+
}
|
|
983
|
+
async function getPlayerEntryStats(playerId) {
|
|
984
|
+
const entries = await getPlayerEntries(playerId);
|
|
985
|
+
if (entries.length === 0) {
|
|
986
|
+
return null;
|
|
987
|
+
}
|
|
988
|
+
const wins = entries.filter((e) => e.result === "WIN").length;
|
|
989
|
+
const losses = entries.filter((e) => e.result === "LOSS").length;
|
|
990
|
+
const ties = entries.filter((e) => e.result === "TIE").length;
|
|
991
|
+
return {
|
|
992
|
+
totalMatches: entries.length,
|
|
993
|
+
wins,
|
|
994
|
+
losses,
|
|
995
|
+
ties,
|
|
996
|
+
winRate: wins / entries.length
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// src/standings.ts
|
|
1001
|
+
async function createStanding(data) {
|
|
1002
|
+
const standingData = {
|
|
400
1003
|
...data,
|
|
1004
|
+
isFinals: data.isFinals ?? false,
|
|
401
1005
|
decayedPoints: data.decayedPoints ?? data.totalPoints ?? 0
|
|
402
1006
|
};
|
|
403
|
-
return prisma.
|
|
404
|
-
data:
|
|
1007
|
+
return prisma.standing.create({
|
|
1008
|
+
data: standingData
|
|
405
1009
|
});
|
|
406
1010
|
}
|
|
407
|
-
async function
|
|
408
|
-
const
|
|
1011
|
+
async function createManyStandings(data) {
|
|
1012
|
+
const standingsData = data.map((item) => ({
|
|
409
1013
|
...item,
|
|
1014
|
+
isFinals: item.isFinals ?? false,
|
|
410
1015
|
decayedPoints: item.decayedPoints ?? item.totalPoints ?? 0
|
|
411
1016
|
}));
|
|
412
|
-
return prisma.
|
|
413
|
-
data:
|
|
1017
|
+
return prisma.standing.createMany({
|
|
1018
|
+
data: standingsData
|
|
414
1019
|
});
|
|
415
1020
|
}
|
|
416
|
-
async function
|
|
417
|
-
return prisma.
|
|
1021
|
+
async function findStandingById(id, include) {
|
|
1022
|
+
return prisma.standing.findUnique({
|
|
418
1023
|
where: { id },
|
|
419
1024
|
include
|
|
420
1025
|
});
|
|
421
1026
|
}
|
|
422
|
-
async function
|
|
423
|
-
return prisma.
|
|
1027
|
+
async function findStandingByPlayerAndTournament(playerId, tournamentId, isFinals, include) {
|
|
1028
|
+
return prisma.standing.findUnique({
|
|
424
1029
|
where: {
|
|
425
|
-
|
|
1030
|
+
playerId_tournamentId_isFinals: {
|
|
426
1031
|
playerId,
|
|
427
|
-
tournamentId
|
|
1032
|
+
tournamentId,
|
|
1033
|
+
isFinals
|
|
428
1034
|
}
|
|
429
1035
|
},
|
|
430
1036
|
include
|
|
431
1037
|
});
|
|
432
1038
|
}
|
|
433
|
-
async function
|
|
434
|
-
return prisma.
|
|
1039
|
+
async function findStandings(options = {}) {
|
|
1040
|
+
return prisma.standing.findMany({
|
|
435
1041
|
take: options.take,
|
|
436
1042
|
skip: options.skip,
|
|
437
1043
|
where: options.where,
|
|
@@ -439,45 +1045,85 @@ async function findResults(options = {}) {
|
|
|
439
1045
|
include: options.include
|
|
440
1046
|
});
|
|
441
1047
|
}
|
|
442
|
-
async function
|
|
443
|
-
return
|
|
1048
|
+
async function getPlayerStandings(playerId, options = {}) {
|
|
1049
|
+
return findStandings({
|
|
444
1050
|
...options,
|
|
445
1051
|
where: { playerId },
|
|
446
1052
|
include: { tournament: true, ...options.include },
|
|
447
1053
|
orderBy: { tournament: { date: "desc" } }
|
|
448
1054
|
});
|
|
449
1055
|
}
|
|
450
|
-
async function
|
|
451
|
-
return
|
|
1056
|
+
async function getTournamentStandings(tournamentId, options = {}) {
|
|
1057
|
+
return findStandings({
|
|
452
1058
|
...options,
|
|
453
1059
|
where: { tournamentId },
|
|
454
1060
|
include: { player: true, ...options.include },
|
|
455
|
-
orderBy: { position: "asc" }
|
|
1061
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
456
1062
|
});
|
|
457
1063
|
}
|
|
1064
|
+
async function getQualifyingStandings(tournamentId, options = {}) {
|
|
1065
|
+
return findStandings({
|
|
1066
|
+
...options,
|
|
1067
|
+
where: { tournamentId, isFinals: false },
|
|
1068
|
+
include: { player: true, ...options.include },
|
|
1069
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
async function getFinalsStandings(tournamentId, options = {}) {
|
|
1073
|
+
return findStandings({
|
|
1074
|
+
...options,
|
|
1075
|
+
where: { tournamentId, isFinals: true },
|
|
1076
|
+
include: { player: true, ...options.include },
|
|
1077
|
+
orderBy: options.orderBy ?? { position: "asc" }
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
async function getMergedStandings(tournamentId) {
|
|
1081
|
+
const [finals, qualifying] = await Promise.all([
|
|
1082
|
+
findStandings({
|
|
1083
|
+
where: { tournamentId, isFinals: true },
|
|
1084
|
+
orderBy: { position: "asc" },
|
|
1085
|
+
include: { player: true }
|
|
1086
|
+
}),
|
|
1087
|
+
findStandings({
|
|
1088
|
+
where: { tournamentId, isFinals: false },
|
|
1089
|
+
orderBy: { position: "asc" },
|
|
1090
|
+
include: { player: true }
|
|
1091
|
+
})
|
|
1092
|
+
]);
|
|
1093
|
+
const finalistIds = new Set(finals.map((s) => s.playerId));
|
|
1094
|
+
const nonFinalists = qualifying.filter((s) => !finalistIds.has(s.playerId));
|
|
1095
|
+
return [
|
|
1096
|
+
...finals.map((s) => ({ ...s, mergedPosition: s.position, isFinalist: true })),
|
|
1097
|
+
...nonFinalists.map((s, i) => ({
|
|
1098
|
+
...s,
|
|
1099
|
+
mergedPosition: finals.length + i + 1,
|
|
1100
|
+
isFinalist: false
|
|
1101
|
+
}))
|
|
1102
|
+
];
|
|
1103
|
+
}
|
|
458
1104
|
async function getPlayerTopFinishes(playerId, limit = 15) {
|
|
459
|
-
return
|
|
1105
|
+
return findStandings({
|
|
460
1106
|
where: { playerId },
|
|
461
1107
|
take: limit,
|
|
462
1108
|
include: { tournament: true },
|
|
463
1109
|
orderBy: { decayedPoints: "desc" }
|
|
464
1110
|
});
|
|
465
1111
|
}
|
|
466
|
-
async function
|
|
467
|
-
return prisma.
|
|
1112
|
+
async function updateStanding(id, data) {
|
|
1113
|
+
return prisma.standing.update({
|
|
468
1114
|
where: { id },
|
|
469
1115
|
data
|
|
470
1116
|
});
|
|
471
1117
|
}
|
|
472
|
-
async function
|
|
473
|
-
const
|
|
1118
|
+
async function updateStandingPoints(id, linearPoints, dynamicPoints, totalPoints) {
|
|
1119
|
+
const standing = await findStandingById(id, {
|
|
474
1120
|
tournament: true
|
|
475
1121
|
});
|
|
476
|
-
if (!
|
|
477
|
-
throw new Error(`
|
|
1122
|
+
if (!standing) {
|
|
1123
|
+
throw new Error(`Standing with id ${id} not found`);
|
|
478
1124
|
}
|
|
479
1125
|
const now = /* @__PURE__ */ new Date();
|
|
480
|
-
const tournamentDate =
|
|
1126
|
+
const tournamentDate = standing.tournament.date;
|
|
481
1127
|
const ageInDays = Math.floor((now.getTime() - tournamentDate.getTime()) / (1e3 * 60 * 60 * 24));
|
|
482
1128
|
const ageInYears = ageInDays / 365;
|
|
483
1129
|
let decayMultiplier = 0;
|
|
@@ -491,7 +1137,7 @@ async function updateResultPoints(id, linearPoints, dynamicPoints, totalPoints)
|
|
|
491
1137
|
decayMultiplier = 0;
|
|
492
1138
|
}
|
|
493
1139
|
const decayedPoints = totalPoints * decayMultiplier;
|
|
494
|
-
return
|
|
1140
|
+
return updateStanding(id, {
|
|
495
1141
|
linearPoints,
|
|
496
1142
|
dynamicPoints,
|
|
497
1143
|
totalPoints,
|
|
@@ -500,50 +1146,50 @@ async function updateResultPoints(id, linearPoints, dynamicPoints, totalPoints)
|
|
|
500
1146
|
decayedPoints
|
|
501
1147
|
});
|
|
502
1148
|
}
|
|
503
|
-
async function
|
|
504
|
-
return prisma.
|
|
1149
|
+
async function deleteStanding(id) {
|
|
1150
|
+
return prisma.standing.delete({
|
|
505
1151
|
where: { id }
|
|
506
1152
|
});
|
|
507
1153
|
}
|
|
508
|
-
async function
|
|
509
|
-
return prisma.
|
|
1154
|
+
async function deleteStandingsByTournament(tournamentId) {
|
|
1155
|
+
return prisma.standing.deleteMany({
|
|
510
1156
|
where: { tournamentId }
|
|
511
1157
|
});
|
|
512
1158
|
}
|
|
513
|
-
async function
|
|
514
|
-
return prisma.
|
|
1159
|
+
async function countStandings(where) {
|
|
1160
|
+
return prisma.standing.count({ where });
|
|
515
1161
|
}
|
|
516
1162
|
async function getPlayerStats(playerId) {
|
|
517
|
-
const
|
|
518
|
-
if (
|
|
1163
|
+
const standings = await getPlayerStandings(playerId);
|
|
1164
|
+
if (standings.length === 0) {
|
|
519
1165
|
return null;
|
|
520
1166
|
}
|
|
521
|
-
const totalPoints =
|
|
522
|
-
const totalDecayedPoints =
|
|
523
|
-
const averagePosition =
|
|
524
|
-
const averageEfficiency =
|
|
525
|
-
const firstPlaceFinishes =
|
|
526
|
-
const topThreeFinishes =
|
|
1167
|
+
const totalPoints = standings.reduce((sum, s) => sum + (s.totalPoints || 0), 0);
|
|
1168
|
+
const totalDecayedPoints = standings.reduce((sum, s) => sum + (s.decayedPoints || 0), 0);
|
|
1169
|
+
const averagePosition = standings.reduce((sum, s) => sum + s.position, 0) / standings.length;
|
|
1170
|
+
const averageEfficiency = standings.reduce((sum, s) => sum + (s.efficiency || 0), 0) / standings.length;
|
|
1171
|
+
const firstPlaceFinishes = standings.filter((s) => s.position === 1).length;
|
|
1172
|
+
const topThreeFinishes = standings.filter((s) => s.position <= 3).length;
|
|
527
1173
|
return {
|
|
528
|
-
totalEvents:
|
|
1174
|
+
totalEvents: standings.length,
|
|
529
1175
|
totalPoints,
|
|
530
1176
|
totalDecayedPoints,
|
|
531
|
-
averagePoints: totalPoints /
|
|
1177
|
+
averagePoints: totalPoints / standings.length,
|
|
532
1178
|
averagePosition,
|
|
533
1179
|
averageFinish: averagePosition,
|
|
534
1180
|
averageEfficiency,
|
|
535
1181
|
firstPlaceFinishes,
|
|
536
1182
|
topThreeFinishes,
|
|
537
|
-
bestFinish: Math.min(...
|
|
538
|
-
highestPoints: Math.max(...
|
|
1183
|
+
bestFinish: Math.min(...standings.map((s) => s.position)),
|
|
1184
|
+
highestPoints: Math.max(...standings.map((s) => s.totalPoints || 0))
|
|
539
1185
|
};
|
|
540
1186
|
}
|
|
541
1187
|
async function recalculateTimeDecay(referenceDate = /* @__PURE__ */ new Date()) {
|
|
542
|
-
const
|
|
1188
|
+
const standings = await findStandings({
|
|
543
1189
|
include: { tournament: true }
|
|
544
1190
|
});
|
|
545
|
-
const updates =
|
|
546
|
-
const tournamentDate =
|
|
1191
|
+
const updates = standings.map((standing) => {
|
|
1192
|
+
const tournamentDate = standing.tournament.date;
|
|
547
1193
|
const ageInDays = Math.floor(
|
|
548
1194
|
(referenceDate.getTime() - tournamentDate.getTime()) / (1e3 * 60 * 60 * 24)
|
|
549
1195
|
);
|
|
@@ -558,9 +1204,9 @@ async function recalculateTimeDecay(referenceDate = /* @__PURE__ */ new Date())
|
|
|
558
1204
|
} else {
|
|
559
1205
|
decayMultiplier = 0;
|
|
560
1206
|
}
|
|
561
|
-
const decayedPoints = (
|
|
562
|
-
return prisma.
|
|
563
|
-
where: { id:
|
|
1207
|
+
const decayedPoints = (standing.totalPoints || 0) * decayMultiplier;
|
|
1208
|
+
return prisma.standing.update({
|
|
1209
|
+
where: { id: standing.id },
|
|
564
1210
|
data: {
|
|
565
1211
|
ageInDays,
|
|
566
1212
|
decayMultiplier,
|
|
@@ -597,10 +1243,6 @@ async function createUserWithPlayer(userData, playerData) {
|
|
|
597
1243
|
id: true,
|
|
598
1244
|
playerNumber: true,
|
|
599
1245
|
name: true,
|
|
600
|
-
rating: true,
|
|
601
|
-
ratingDeviation: true,
|
|
602
|
-
ranking: true,
|
|
603
|
-
isRated: true,
|
|
604
1246
|
eventCount: true
|
|
605
1247
|
}
|
|
606
1248
|
}
|
|
@@ -630,10 +1272,6 @@ async function getUserWithPlayer(id) {
|
|
|
630
1272
|
id: true,
|
|
631
1273
|
playerNumber: true,
|
|
632
1274
|
name: true,
|
|
633
|
-
rating: true,
|
|
634
|
-
ratingDeviation: true,
|
|
635
|
-
ranking: true,
|
|
636
|
-
isRated: true,
|
|
637
1275
|
eventCount: true
|
|
638
1276
|
}
|
|
639
1277
|
}
|
|
@@ -653,10 +1291,6 @@ async function getUserByEmailWithPlayer(email) {
|
|
|
653
1291
|
id: true,
|
|
654
1292
|
playerNumber: true,
|
|
655
1293
|
name: true,
|
|
656
|
-
rating: true,
|
|
657
|
-
ratingDeviation: true,
|
|
658
|
-
ranking: true,
|
|
659
|
-
isRated: true,
|
|
660
1294
|
eventCount: true
|
|
661
1295
|
}
|
|
662
1296
|
}
|
|
@@ -699,10 +1333,6 @@ async function findUsers(params) {
|
|
|
699
1333
|
id: true,
|
|
700
1334
|
playerNumber: true,
|
|
701
1335
|
name: true,
|
|
702
|
-
rating: true,
|
|
703
|
-
ratingDeviation: true,
|
|
704
|
-
ranking: true,
|
|
705
|
-
isRated: true,
|
|
706
1336
|
eventCount: true
|
|
707
1337
|
}
|
|
708
1338
|
}
|
|
@@ -731,10 +1361,6 @@ async function linkPlayerToUser(userId, playerId) {
|
|
|
731
1361
|
id: true,
|
|
732
1362
|
playerNumber: true,
|
|
733
1363
|
name: true,
|
|
734
|
-
rating: true,
|
|
735
|
-
ratingDeviation: true,
|
|
736
|
-
ranking: true,
|
|
737
|
-
isRated: true,
|
|
738
1364
|
eventCount: true
|
|
739
1365
|
}
|
|
740
1366
|
}
|
|
@@ -743,33 +1369,397 @@ async function linkPlayerToUser(userId, playerId) {
|
|
|
743
1369
|
return user;
|
|
744
1370
|
});
|
|
745
1371
|
}
|
|
1372
|
+
|
|
1373
|
+
// src/api-keys.ts
|
|
1374
|
+
var MAX_API_KEYS_PER_USER = 5;
|
|
1375
|
+
async function createApiKey(data) {
|
|
1376
|
+
return prisma.apiKey.create({ data });
|
|
1377
|
+
}
|
|
1378
|
+
async function findApiKeyById(id) {
|
|
1379
|
+
return prisma.apiKey.findUnique({ where: { id } });
|
|
1380
|
+
}
|
|
1381
|
+
async function findApiKeysByPrefix(keyPrefix) {
|
|
1382
|
+
const keys = await prisma.apiKey.findMany({
|
|
1383
|
+
where: { keyPrefix },
|
|
1384
|
+
include: {
|
|
1385
|
+
user: {
|
|
1386
|
+
select: {
|
|
1387
|
+
id: true,
|
|
1388
|
+
email: true,
|
|
1389
|
+
role: true
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
return keys;
|
|
1395
|
+
}
|
|
1396
|
+
async function getUserApiKeys(userId) {
|
|
1397
|
+
return prisma.apiKey.findMany({
|
|
1398
|
+
where: { userId },
|
|
1399
|
+
select: {
|
|
1400
|
+
id: true,
|
|
1401
|
+
name: true,
|
|
1402
|
+
keyPrefix: true,
|
|
1403
|
+
expiresAt: true,
|
|
1404
|
+
lastUsedAt: true,
|
|
1405
|
+
createdAt: true
|
|
1406
|
+
},
|
|
1407
|
+
orderBy: { createdAt: "desc" }
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
async function countUserApiKeys(userId) {
|
|
1411
|
+
return prisma.apiKey.count({ where: { userId } });
|
|
1412
|
+
}
|
|
1413
|
+
async function updateApiKeyLastUsed(id) {
|
|
1414
|
+
await prisma.apiKey.update({
|
|
1415
|
+
where: { id },
|
|
1416
|
+
data: { lastUsedAt: /* @__PURE__ */ new Date() }
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
async function deleteApiKey(id) {
|
|
1420
|
+
return prisma.apiKey.delete({ where: { id } });
|
|
1421
|
+
}
|
|
1422
|
+
async function deleteUserApiKey(id, userId) {
|
|
1423
|
+
const key = await prisma.apiKey.findFirst({
|
|
1424
|
+
where: { id, userId }
|
|
1425
|
+
});
|
|
1426
|
+
if (!key) {
|
|
1427
|
+
return null;
|
|
1428
|
+
}
|
|
1429
|
+
return prisma.apiKey.delete({ where: { id } });
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
// src/locations.ts
|
|
1433
|
+
async function createLocation(data) {
|
|
1434
|
+
return prisma.location.create({
|
|
1435
|
+
data
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
async function findLocationById(id, include) {
|
|
1439
|
+
return prisma.location.findUnique({
|
|
1440
|
+
where: { id },
|
|
1441
|
+
include
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
async function findLocationByExternalId(externalId, include) {
|
|
1445
|
+
return prisma.location.findUnique({
|
|
1446
|
+
where: { externalId },
|
|
1447
|
+
include
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
async function findLocations(options = {}) {
|
|
1451
|
+
return prisma.location.findMany({
|
|
1452
|
+
take: options.take,
|
|
1453
|
+
skip: options.skip,
|
|
1454
|
+
where: options.where,
|
|
1455
|
+
orderBy: options.orderBy,
|
|
1456
|
+
include: options.include
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1459
|
+
async function searchLocations(query, limit = 20) {
|
|
1460
|
+
return findLocations({
|
|
1461
|
+
take: limit,
|
|
1462
|
+
where: {
|
|
1463
|
+
OR: [
|
|
1464
|
+
{ name: { contains: query, mode: "insensitive" } },
|
|
1465
|
+
{ city: { contains: query, mode: "insensitive" } }
|
|
1466
|
+
]
|
|
1467
|
+
},
|
|
1468
|
+
orderBy: { name: "asc" }
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1471
|
+
async function updateLocation(id, data) {
|
|
1472
|
+
return prisma.location.update({
|
|
1473
|
+
where: { id },
|
|
1474
|
+
data
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
async function deleteLocation(id) {
|
|
1478
|
+
return prisma.location.delete({
|
|
1479
|
+
where: { id }
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
async function countLocations(where) {
|
|
1483
|
+
return prisma.location.count({ where });
|
|
1484
|
+
}
|
|
1485
|
+
async function getLocationWithTournaments(id) {
|
|
1486
|
+
return prisma.location.findUnique({
|
|
1487
|
+
where: { id },
|
|
1488
|
+
include: {
|
|
1489
|
+
tournaments: {
|
|
1490
|
+
orderBy: {
|
|
1491
|
+
date: "desc"
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
});
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
// src/blog-posts.ts
|
|
1499
|
+
var defaultInclude = {
|
|
1500
|
+
author: {
|
|
1501
|
+
select: { id: true, email: true }
|
|
1502
|
+
},
|
|
1503
|
+
tags: {
|
|
1504
|
+
select: { id: true, name: true, slug: true }
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
async function createBlogPost(data) {
|
|
1508
|
+
const { tagIds, ...postData } = data;
|
|
1509
|
+
return prisma.blogPost.create({
|
|
1510
|
+
data: {
|
|
1511
|
+
...postData,
|
|
1512
|
+
tags: tagIds?.length ? { connect: tagIds.map((id) => ({ id })) } : void 0
|
|
1513
|
+
},
|
|
1514
|
+
include: defaultInclude
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
async function findBlogPostById(id) {
|
|
1518
|
+
return prisma.blogPost.findUnique({
|
|
1519
|
+
where: { id },
|
|
1520
|
+
include: defaultInclude
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
async function findBlogPostBySlug(slug) {
|
|
1524
|
+
return prisma.blogPost.findUnique({
|
|
1525
|
+
where: { slug },
|
|
1526
|
+
include: defaultInclude
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1529
|
+
async function findBlogPosts(options = {}) {
|
|
1530
|
+
return prisma.blogPost.findMany({
|
|
1531
|
+
take: options.take,
|
|
1532
|
+
skip: options.skip,
|
|
1533
|
+
where: options.where,
|
|
1534
|
+
orderBy: options.orderBy ?? { createdAt: "desc" },
|
|
1535
|
+
include: options.include ?? defaultInclude
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
async function findPublishedBlogPosts(options = {}) {
|
|
1539
|
+
const { tagSlug, ...restOptions } = options;
|
|
1540
|
+
const where = {
|
|
1541
|
+
status: "PUBLISHED",
|
|
1542
|
+
publishedAt: { not: null },
|
|
1543
|
+
...tagSlug && {
|
|
1544
|
+
tags: {
|
|
1545
|
+
some: { slug: tagSlug }
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
return findBlogPosts({
|
|
1550
|
+
...restOptions,
|
|
1551
|
+
where,
|
|
1552
|
+
orderBy: options.orderBy ?? { publishedAt: "desc" }
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
async function searchBlogPosts(query, limit = 20, publishedOnly = true) {
|
|
1556
|
+
const where = {
|
|
1557
|
+
OR: [
|
|
1558
|
+
{ title: { contains: query, mode: "insensitive" } },
|
|
1559
|
+
{ excerpt: { contains: query, mode: "insensitive" } }
|
|
1560
|
+
],
|
|
1561
|
+
...publishedOnly && {
|
|
1562
|
+
status: "PUBLISHED",
|
|
1563
|
+
publishedAt: { not: null }
|
|
1564
|
+
}
|
|
1565
|
+
};
|
|
1566
|
+
return findBlogPosts({
|
|
1567
|
+
take: limit,
|
|
1568
|
+
where,
|
|
1569
|
+
orderBy: { publishedAt: "desc" }
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
async function updateBlogPost(id, data) {
|
|
1573
|
+
const { tagIds, ...postData } = data;
|
|
1574
|
+
return prisma.blogPost.update({
|
|
1575
|
+
where: { id },
|
|
1576
|
+
data: {
|
|
1577
|
+
...postData,
|
|
1578
|
+
// If tagIds is provided, replace all tags
|
|
1579
|
+
...tagIds !== void 0 && {
|
|
1580
|
+
tags: {
|
|
1581
|
+
set: tagIds.map((tagId) => ({ id: tagId }))
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
},
|
|
1585
|
+
include: defaultInclude
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
async function deleteBlogPost(id) {
|
|
1589
|
+
return prisma.blogPost.delete({
|
|
1590
|
+
where: { id }
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
async function countBlogPosts(where) {
|
|
1594
|
+
return prisma.blogPost.count({ where });
|
|
1595
|
+
}
|
|
1596
|
+
async function countPublishedBlogPosts(tagSlug) {
|
|
1597
|
+
return countBlogPosts({
|
|
1598
|
+
status: "PUBLISHED",
|
|
1599
|
+
publishedAt: { not: null },
|
|
1600
|
+
...tagSlug && {
|
|
1601
|
+
tags: {
|
|
1602
|
+
some: { slug: tagSlug }
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
// src/blog-tags.ts
|
|
1609
|
+
async function createBlogTag(data) {
|
|
1610
|
+
return prisma.blogTag.create({
|
|
1611
|
+
data
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
async function findBlogTagById(id) {
|
|
1615
|
+
return prisma.blogTag.findUnique({
|
|
1616
|
+
where: { id }
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
async function findBlogTagBySlug(slug) {
|
|
1620
|
+
return prisma.blogTag.findUnique({
|
|
1621
|
+
where: { slug }
|
|
1622
|
+
});
|
|
1623
|
+
}
|
|
1624
|
+
async function findBlogTags(options = {}) {
|
|
1625
|
+
return prisma.blogTag.findMany({
|
|
1626
|
+
take: options.take,
|
|
1627
|
+
skip: options.skip,
|
|
1628
|
+
where: options.where,
|
|
1629
|
+
orderBy: options.orderBy ?? { name: "asc" },
|
|
1630
|
+
include: options.include
|
|
1631
|
+
});
|
|
1632
|
+
}
|
|
1633
|
+
async function searchBlogTags(query, limit = 20) {
|
|
1634
|
+
return findBlogTags({
|
|
1635
|
+
take: limit,
|
|
1636
|
+
where: {
|
|
1637
|
+
name: { contains: query, mode: "insensitive" }
|
|
1638
|
+
},
|
|
1639
|
+
orderBy: { name: "asc" }
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
async function updateBlogTag(id, data) {
|
|
1643
|
+
return prisma.blogTag.update({
|
|
1644
|
+
where: { id },
|
|
1645
|
+
data
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
async function deleteBlogTag(id) {
|
|
1649
|
+
return prisma.blogTag.delete({
|
|
1650
|
+
where: { id }
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
async function countBlogTags(where) {
|
|
1654
|
+
return prisma.blogTag.count({ where });
|
|
1655
|
+
}
|
|
1656
|
+
async function getBlogTagWithPostCount(id) {
|
|
1657
|
+
return prisma.blogTag.findUnique({
|
|
1658
|
+
where: { id },
|
|
1659
|
+
include: {
|
|
1660
|
+
_count: {
|
|
1661
|
+
select: { posts: true }
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
});
|
|
1665
|
+
}
|
|
1666
|
+
async function getBlogTagsWithPostCounts() {
|
|
1667
|
+
return prisma.blogTag.findMany({
|
|
1668
|
+
include: {
|
|
1669
|
+
_count: {
|
|
1670
|
+
select: { posts: true }
|
|
1671
|
+
}
|
|
1672
|
+
},
|
|
1673
|
+
orderBy: { name: "asc" }
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
746
1676
|
// Annotate the CommonJS export names for ESM import in node:
|
|
747
1677
|
0 && (module.exports = {
|
|
1678
|
+
MAX_API_KEYS_PER_USER,
|
|
1679
|
+
applyRDDecayForInactivePlayers,
|
|
748
1680
|
connect,
|
|
1681
|
+
countBlogPosts,
|
|
1682
|
+
countBlogTags,
|
|
1683
|
+
countEntries,
|
|
1684
|
+
countLocations,
|
|
1685
|
+
countMatches,
|
|
1686
|
+
countOpprPlayerRankings,
|
|
1687
|
+
countOpprRankingHistory,
|
|
749
1688
|
countPlayers,
|
|
750
|
-
|
|
1689
|
+
countPublishedBlogPosts,
|
|
1690
|
+
countRounds,
|
|
1691
|
+
countStandings,
|
|
751
1692
|
countTournaments,
|
|
1693
|
+
countUserApiKeys,
|
|
752
1694
|
countUsers,
|
|
753
|
-
|
|
1695
|
+
createApiKey,
|
|
1696
|
+
createBlogPost,
|
|
1697
|
+
createBlogTag,
|
|
1698
|
+
createEntry,
|
|
1699
|
+
createLocation,
|
|
1700
|
+
createManyEntries,
|
|
1701
|
+
createManyMatches,
|
|
1702
|
+
createManyRounds,
|
|
1703
|
+
createManyStandings,
|
|
1704
|
+
createMatch,
|
|
1705
|
+
createOpprPlayerRanking,
|
|
1706
|
+
createOpprRankingHistory,
|
|
754
1707
|
createPlayer,
|
|
755
|
-
|
|
1708
|
+
createRound,
|
|
1709
|
+
createStanding,
|
|
756
1710
|
createTournament,
|
|
757
1711
|
createUser,
|
|
758
1712
|
createUserWithPlayer,
|
|
1713
|
+
deleteApiKey,
|
|
1714
|
+
deleteBlogPost,
|
|
1715
|
+
deleteBlogTag,
|
|
1716
|
+
deleteEntriesByMatch,
|
|
1717
|
+
deleteEntry,
|
|
1718
|
+
deleteLocation,
|
|
1719
|
+
deleteMatch,
|
|
1720
|
+
deleteMatchesByRound,
|
|
1721
|
+
deleteMatchesByTournament,
|
|
1722
|
+
deleteOpprPlayerRanking,
|
|
759
1723
|
deletePlayer,
|
|
760
|
-
|
|
761
|
-
|
|
1724
|
+
deleteRound,
|
|
1725
|
+
deleteRoundsByTournament,
|
|
1726
|
+
deleteStanding,
|
|
1727
|
+
deleteStandingsByTournament,
|
|
762
1728
|
deleteTournament,
|
|
763
1729
|
deleteUser,
|
|
1730
|
+
deleteUserApiKey,
|
|
764
1731
|
disconnect,
|
|
1732
|
+
findApiKeyById,
|
|
1733
|
+
findApiKeysByPrefix,
|
|
1734
|
+
findBlogPostById,
|
|
1735
|
+
findBlogPostBySlug,
|
|
1736
|
+
findBlogPosts,
|
|
1737
|
+
findBlogTagById,
|
|
1738
|
+
findBlogTagBySlug,
|
|
1739
|
+
findBlogTags,
|
|
1740
|
+
findEntries,
|
|
1741
|
+
findEntryById,
|
|
1742
|
+
findEntryByMatchAndPlayer,
|
|
1743
|
+
findLocationByExternalId,
|
|
1744
|
+
findLocationById,
|
|
1745
|
+
findLocations,
|
|
1746
|
+
findMatchById,
|
|
1747
|
+
findMatches,
|
|
1748
|
+
findOpprPlayerRankingById,
|
|
1749
|
+
findOpprPlayerRankingByPlayerId,
|
|
1750
|
+
findOpprPlayerRankings,
|
|
765
1751
|
findPlayerByExternalId,
|
|
766
1752
|
findPlayerById,
|
|
767
1753
|
findPlayerByPlayerNumber,
|
|
768
1754
|
findPlayerByUserEmail,
|
|
769
1755
|
findPlayers,
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
1756
|
+
findPublishedBlogPosts,
|
|
1757
|
+
findRoundById,
|
|
1758
|
+
findRoundByTournamentAndNumber,
|
|
1759
|
+
findRounds,
|
|
1760
|
+
findStandingById,
|
|
1761
|
+
findStandingByPlayerAndTournament,
|
|
1762
|
+
findStandings,
|
|
773
1763
|
findTournamentByExternalId,
|
|
774
1764
|
findTournamentById,
|
|
775
1765
|
findTournaments,
|
|
@@ -777,34 +1767,70 @@ async function linkPlayerToUser(userId, playerId) {
|
|
|
777
1767
|
findUserById,
|
|
778
1768
|
findUsers,
|
|
779
1769
|
generateUniquePlayerNumber,
|
|
1770
|
+
getBlogTagWithPostCount,
|
|
1771
|
+
getBlogTagsWithPostCounts,
|
|
1772
|
+
getFinalsRounds,
|
|
1773
|
+
getFinalsStandings,
|
|
1774
|
+
getLatestOpprRankingHistory,
|
|
1775
|
+
getLocationWithTournaments,
|
|
780
1776
|
getMajorTournaments,
|
|
781
|
-
|
|
1777
|
+
getMatchEntries,
|
|
1778
|
+
getMatchWithEntries,
|
|
1779
|
+
getMergedStandings,
|
|
1780
|
+
getOpprRankingHistory,
|
|
1781
|
+
getOpprRankingHistoryByDateRange,
|
|
1782
|
+
getOrCreateOpprPlayerRanking,
|
|
1783
|
+
getPlayerEntries,
|
|
1784
|
+
getPlayerEntryStats,
|
|
1785
|
+
getPlayerStandings,
|
|
782
1786
|
getPlayerStats,
|
|
783
1787
|
getPlayerTopFinishes,
|
|
1788
|
+
getPlayerTournamentEntries,
|
|
1789
|
+
getPlayerTournamentMatches,
|
|
784
1790
|
getPlayerWithResults,
|
|
785
|
-
|
|
1791
|
+
getQualifyingRounds,
|
|
1792
|
+
getQualifyingStandings,
|
|
1793
|
+
getRatedOpprPlayers,
|
|
786
1794
|
getRecentTournaments,
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1795
|
+
getRoundMatches,
|
|
1796
|
+
getRoundWithMatches,
|
|
1797
|
+
getTopPlayersByOpprRanking,
|
|
1798
|
+
getTopPlayersByOpprRating,
|
|
1799
|
+
getTournamentMatches,
|
|
1800
|
+
getTournamentRounds,
|
|
1801
|
+
getTournamentStandings,
|
|
790
1802
|
getTournamentStats,
|
|
1803
|
+
getTournamentWithMatches,
|
|
791
1804
|
getTournamentWithResults,
|
|
792
1805
|
getTournamentsByBoosterType,
|
|
793
1806
|
getTournamentsByDateRange,
|
|
1807
|
+
getUserApiKeys,
|
|
794
1808
|
getUserByEmailWithPlayer,
|
|
795
1809
|
getUserWithPlayer,
|
|
796
1810
|
isValidPlayerNumber,
|
|
797
1811
|
linkPlayerToUser,
|
|
798
1812
|
prisma,
|
|
799
1813
|
recalculateTimeDecay,
|
|
1814
|
+
searchBlogPosts,
|
|
1815
|
+
searchBlogTags,
|
|
1816
|
+
searchLocations,
|
|
800
1817
|
searchPlayers,
|
|
801
1818
|
searchTournaments,
|
|
802
1819
|
testConnection,
|
|
1820
|
+
updateApiKeyLastUsed,
|
|
1821
|
+
updateBlogPost,
|
|
1822
|
+
updateBlogTag,
|
|
1823
|
+
updateEntry,
|
|
1824
|
+
updateLocation,
|
|
1825
|
+
updateMatch,
|
|
1826
|
+
updateOpprPlayerRanking,
|
|
1827
|
+
updateOpprRatingAfterTournament,
|
|
803
1828
|
updatePlayer,
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
1829
|
+
updateRound,
|
|
1830
|
+
updateStanding,
|
|
1831
|
+
updateStandingPoints,
|
|
807
1832
|
updateTournament,
|
|
808
1833
|
updateUser,
|
|
809
|
-
updateUserRefreshToken
|
|
1834
|
+
updateUserRefreshToken,
|
|
1835
|
+
updateWorldRankings
|
|
810
1836
|
});
|