@opprs/db-prisma 2.2.1-canary.b943669 → 2.2.1-canary.c3d513e

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 CHANGED
@@ -20,15 +20,26 @@ 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,
24
28
  countEntries: () => countEntries,
25
29
  countLocations: () => countLocations,
26
30
  countMatches: () => countMatches,
31
+ countOpprPlayerRankings: () => countOpprPlayerRankings,
32
+ countOpprRankingHistory: () => countOpprRankingHistory,
27
33
  countPlayers: () => countPlayers,
34
+ countPublishedBlogPosts: () => countPublishedBlogPosts,
28
35
  countRounds: () => countRounds,
29
36
  countStandings: () => countStandings,
30
37
  countTournaments: () => countTournaments,
38
+ countUserApiKeys: () => countUserApiKeys,
31
39
  countUsers: () => countUsers,
40
+ createApiKey: () => createApiKey,
41
+ createBlogPost: () => createBlogPost,
42
+ createBlogTag: () => createBlogTag,
32
43
  createEntry: () => createEntry,
33
44
  createLocation: () => createLocation,
34
45
  createManyEntries: () => createManyEntries,
@@ -36,18 +47,24 @@ __export(index_exports, {
36
47
  createManyRounds: () => createManyRounds,
37
48
  createManyStandings: () => createManyStandings,
38
49
  createMatch: () => createMatch,
50
+ createOpprPlayerRanking: () => createOpprPlayerRanking,
51
+ createOpprRankingHistory: () => createOpprRankingHistory,
39
52
  createPlayer: () => createPlayer,
40
53
  createRound: () => createRound,
41
54
  createStanding: () => createStanding,
42
55
  createTournament: () => createTournament,
43
56
  createUser: () => createUser,
44
57
  createUserWithPlayer: () => createUserWithPlayer,
58
+ deleteApiKey: () => deleteApiKey,
59
+ deleteBlogPost: () => deleteBlogPost,
60
+ deleteBlogTag: () => deleteBlogTag,
45
61
  deleteEntriesByMatch: () => deleteEntriesByMatch,
46
62
  deleteEntry: () => deleteEntry,
47
63
  deleteLocation: () => deleteLocation,
48
64
  deleteMatch: () => deleteMatch,
49
65
  deleteMatchesByRound: () => deleteMatchesByRound,
50
66
  deleteMatchesByTournament: () => deleteMatchesByTournament,
67
+ deleteOpprPlayerRanking: () => deleteOpprPlayerRanking,
51
68
  deletePlayer: () => deletePlayer,
52
69
  deleteRound: () => deleteRound,
53
70
  deleteRoundsByTournament: () => deleteRoundsByTournament,
@@ -55,7 +72,16 @@ __export(index_exports, {
55
72
  deleteStandingsByTournament: () => deleteStandingsByTournament,
56
73
  deleteTournament: () => deleteTournament,
57
74
  deleteUser: () => deleteUser,
75
+ deleteUserApiKey: () => deleteUserApiKey,
58
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,
59
85
  findEntries: () => findEntries,
60
86
  findEntryById: () => findEntryById,
61
87
  findEntryByMatchAndPlayer: () => findEntryByMatchAndPlayer,
@@ -64,11 +90,15 @@ __export(index_exports, {
64
90
  findLocations: () => findLocations,
65
91
  findMatchById: () => findMatchById,
66
92
  findMatches: () => findMatches,
93
+ findOpprPlayerRankingById: () => findOpprPlayerRankingById,
94
+ findOpprPlayerRankingByPlayerId: () => findOpprPlayerRankingByPlayerId,
95
+ findOpprPlayerRankings: () => findOpprPlayerRankings,
67
96
  findPlayerByExternalId: () => findPlayerByExternalId,
68
97
  findPlayerById: () => findPlayerById,
69
98
  findPlayerByPlayerNumber: () => findPlayerByPlayerNumber,
70
99
  findPlayerByUserEmail: () => findPlayerByUserEmail,
71
100
  findPlayers: () => findPlayers,
101
+ findPublishedBlogPosts: () => findPublishedBlogPosts,
72
102
  findRoundById: () => findRoundById,
73
103
  findRoundByTournamentAndNumber: () => findRoundByTournamentAndNumber,
74
104
  findRounds: () => findRounds,
@@ -82,13 +112,19 @@ __export(index_exports, {
82
112
  findUserById: () => findUserById,
83
113
  findUsers: () => findUsers,
84
114
  generateUniquePlayerNumber: () => generateUniquePlayerNumber,
115
+ getBlogTagWithPostCount: () => getBlogTagWithPostCount,
116
+ getBlogTagsWithPostCounts: () => getBlogTagsWithPostCounts,
85
117
  getFinalsRounds: () => getFinalsRounds,
86
118
  getFinalsStandings: () => getFinalsStandings,
119
+ getLatestOpprRankingHistory: () => getLatestOpprRankingHistory,
87
120
  getLocationWithTournaments: () => getLocationWithTournaments,
88
121
  getMajorTournaments: () => getMajorTournaments,
89
122
  getMatchEntries: () => getMatchEntries,
90
123
  getMatchWithEntries: () => getMatchWithEntries,
91
124
  getMergedStandings: () => getMergedStandings,
125
+ getOpprRankingHistory: () => getOpprRankingHistory,
126
+ getOpprRankingHistoryByDateRange: () => getOpprRankingHistoryByDateRange,
127
+ getOrCreateOpprPlayerRanking: () => getOrCreateOpprPlayerRanking,
92
128
  getPlayerEntries: () => getPlayerEntries,
93
129
  getPlayerEntryStats: () => getPlayerEntryStats,
94
130
  getPlayerStandings: () => getPlayerStandings,
@@ -99,12 +135,12 @@ __export(index_exports, {
99
135
  getPlayerWithResults: () => getPlayerWithResults,
100
136
  getQualifyingRounds: () => getQualifyingRounds,
101
137
  getQualifyingStandings: () => getQualifyingStandings,
102
- getRatedPlayers: () => getRatedPlayers,
138
+ getRatedOpprPlayers: () => getRatedOpprPlayers,
103
139
  getRecentTournaments: () => getRecentTournaments,
104
140
  getRoundMatches: () => getRoundMatches,
105
141
  getRoundWithMatches: () => getRoundWithMatches,
106
- getTopPlayersByRanking: () => getTopPlayersByRanking,
107
- getTopPlayersByRating: () => getTopPlayersByRating,
142
+ getTopPlayersByOpprRanking: () => getTopPlayersByOpprRanking,
143
+ getTopPlayersByOpprRating: () => getTopPlayersByOpprRating,
108
144
  getTournamentMatches: () => getTournamentMatches,
109
145
  getTournamentRounds: () => getTournamentRounds,
110
146
  getTournamentStandings: () => getTournamentStandings,
@@ -113,27 +149,35 @@ __export(index_exports, {
113
149
  getTournamentWithResults: () => getTournamentWithResults,
114
150
  getTournamentsByBoosterType: () => getTournamentsByBoosterType,
115
151
  getTournamentsByDateRange: () => getTournamentsByDateRange,
152
+ getUserApiKeys: () => getUserApiKeys,
116
153
  getUserByEmailWithPlayer: () => getUserByEmailWithPlayer,
117
154
  getUserWithPlayer: () => getUserWithPlayer,
118
155
  isValidPlayerNumber: () => isValidPlayerNumber,
119
156
  linkPlayerToUser: () => linkPlayerToUser,
120
157
  prisma: () => prisma,
121
158
  recalculateTimeDecay: () => recalculateTimeDecay,
159
+ searchBlogPosts: () => searchBlogPosts,
160
+ searchBlogTags: () => searchBlogTags,
122
161
  searchLocations: () => searchLocations,
123
162
  searchPlayers: () => searchPlayers,
124
163
  searchTournaments: () => searchTournaments,
125
164
  testConnection: () => testConnection,
165
+ updateApiKeyLastUsed: () => updateApiKeyLastUsed,
166
+ updateBlogPost: () => updateBlogPost,
167
+ updateBlogTag: () => updateBlogTag,
126
168
  updateEntry: () => updateEntry,
127
169
  updateLocation: () => updateLocation,
128
170
  updateMatch: () => updateMatch,
171
+ updateOpprPlayerRanking: () => updateOpprPlayerRanking,
172
+ updateOpprRatingAfterTournament: () => updateOpprRatingAfterTournament,
129
173
  updatePlayer: () => updatePlayer,
130
- updatePlayerRating: () => updatePlayerRating,
131
174
  updateRound: () => updateRound,
132
175
  updateStanding: () => updateStanding,
133
176
  updateStandingPoints: () => updateStandingPoints,
134
177
  updateTournament: () => updateTournament,
135
178
  updateUser: () => updateUser,
136
- updateUserRefreshToken: () => updateUserRefreshToken
179
+ updateUserRefreshToken: () => updateUserRefreshToken,
180
+ updateWorldRankings: () => updateWorldRankings
137
181
  });
138
182
  module.exports = __toCommonJS(index_exports);
139
183
 
@@ -232,48 +276,12 @@ async function findPlayers(options = {}) {
232
276
  include: options.include
233
277
  });
234
278
  }
235
- async function getRatedPlayers(options = {}) {
236
- return findPlayers({
237
- ...options,
238
- where: { isRated: true }
239
- });
240
- }
241
- async function getTopPlayersByRating(limit = 50) {
242
- return findPlayers({
243
- take: limit,
244
- orderBy: { rating: "desc" },
245
- where: { isRated: true }
246
- });
247
- }
248
- async function getTopPlayersByRanking(limit = 50) {
249
- return findPlayers({
250
- take: limit,
251
- orderBy: { ranking: "asc" },
252
- where: {
253
- isRated: true,
254
- ranking: { not: null }
255
- }
256
- });
257
- }
258
279
  async function updatePlayer(id, data) {
259
280
  return prisma.player.update({
260
281
  where: { id },
261
282
  data
262
283
  });
263
284
  }
264
- async function updatePlayerRating(id, rating, ratingDeviation, eventCount) {
265
- const updateData = {
266
- rating,
267
- ratingDeviation,
268
- lastRatingUpdate: /* @__PURE__ */ new Date(),
269
- lastEventDate: /* @__PURE__ */ new Date()
270
- };
271
- if (eventCount !== void 0) {
272
- updateData.eventCount = eventCount;
273
- updateData.isRated = eventCount >= 5;
274
- }
275
- return updatePlayer(id, updateData);
276
- }
277
285
  async function deletePlayer(id) {
278
286
  return prisma.player.delete({
279
287
  where: { id }
@@ -315,6 +323,212 @@ async function searchPlayers(query, limit = 20) {
315
323
  });
316
324
  }
317
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
+
318
532
  // src/tournaments.ts
319
533
  async function createTournament(data) {
320
534
  return prisma.tournament.create({
@@ -1029,10 +1243,6 @@ async function createUserWithPlayer(userData, playerData) {
1029
1243
  id: true,
1030
1244
  playerNumber: true,
1031
1245
  name: true,
1032
- rating: true,
1033
- ratingDeviation: true,
1034
- ranking: true,
1035
- isRated: true,
1036
1246
  eventCount: true
1037
1247
  }
1038
1248
  }
@@ -1062,10 +1272,6 @@ async function getUserWithPlayer(id) {
1062
1272
  id: true,
1063
1273
  playerNumber: true,
1064
1274
  name: true,
1065
- rating: true,
1066
- ratingDeviation: true,
1067
- ranking: true,
1068
- isRated: true,
1069
1275
  eventCount: true
1070
1276
  }
1071
1277
  }
@@ -1085,10 +1291,6 @@ async function getUserByEmailWithPlayer(email) {
1085
1291
  id: true,
1086
1292
  playerNumber: true,
1087
1293
  name: true,
1088
- rating: true,
1089
- ratingDeviation: true,
1090
- ranking: true,
1091
- isRated: true,
1092
1294
  eventCount: true
1093
1295
  }
1094
1296
  }
@@ -1131,10 +1333,6 @@ async function findUsers(params) {
1131
1333
  id: true,
1132
1334
  playerNumber: true,
1133
1335
  name: true,
1134
- rating: true,
1135
- ratingDeviation: true,
1136
- ranking: true,
1137
- isRated: true,
1138
1336
  eventCount: true
1139
1337
  }
1140
1338
  }
@@ -1163,10 +1361,6 @@ async function linkPlayerToUser(userId, playerId) {
1163
1361
  id: true,
1164
1362
  playerNumber: true,
1165
1363
  name: true,
1166
- rating: true,
1167
- ratingDeviation: true,
1168
- ranking: true,
1169
- isRated: true,
1170
1364
  eventCount: true
1171
1365
  }
1172
1366
  }
@@ -1176,6 +1370,65 @@ async function linkPlayerToUser(userId, playerId) {
1176
1370
  });
1177
1371
  }
1178
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
+
1179
1432
  // src/locations.ts
1180
1433
  async function createLocation(data) {
1181
1434
  return prisma.location.create({
@@ -1241,17 +1494,207 @@ async function getLocationWithTournaments(id) {
1241
1494
  }
1242
1495
  });
1243
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
+ }
1244
1676
  // Annotate the CommonJS export names for ESM import in node:
1245
1677
  0 && (module.exports = {
1678
+ MAX_API_KEYS_PER_USER,
1679
+ applyRDDecayForInactivePlayers,
1246
1680
  connect,
1681
+ countBlogPosts,
1682
+ countBlogTags,
1247
1683
  countEntries,
1248
1684
  countLocations,
1249
1685
  countMatches,
1686
+ countOpprPlayerRankings,
1687
+ countOpprRankingHistory,
1250
1688
  countPlayers,
1689
+ countPublishedBlogPosts,
1251
1690
  countRounds,
1252
1691
  countStandings,
1253
1692
  countTournaments,
1693
+ countUserApiKeys,
1254
1694
  countUsers,
1695
+ createApiKey,
1696
+ createBlogPost,
1697
+ createBlogTag,
1255
1698
  createEntry,
1256
1699
  createLocation,
1257
1700
  createManyEntries,
@@ -1259,18 +1702,24 @@ async function getLocationWithTournaments(id) {
1259
1702
  createManyRounds,
1260
1703
  createManyStandings,
1261
1704
  createMatch,
1705
+ createOpprPlayerRanking,
1706
+ createOpprRankingHistory,
1262
1707
  createPlayer,
1263
1708
  createRound,
1264
1709
  createStanding,
1265
1710
  createTournament,
1266
1711
  createUser,
1267
1712
  createUserWithPlayer,
1713
+ deleteApiKey,
1714
+ deleteBlogPost,
1715
+ deleteBlogTag,
1268
1716
  deleteEntriesByMatch,
1269
1717
  deleteEntry,
1270
1718
  deleteLocation,
1271
1719
  deleteMatch,
1272
1720
  deleteMatchesByRound,
1273
1721
  deleteMatchesByTournament,
1722
+ deleteOpprPlayerRanking,
1274
1723
  deletePlayer,
1275
1724
  deleteRound,
1276
1725
  deleteRoundsByTournament,
@@ -1278,7 +1727,16 @@ async function getLocationWithTournaments(id) {
1278
1727
  deleteStandingsByTournament,
1279
1728
  deleteTournament,
1280
1729
  deleteUser,
1730
+ deleteUserApiKey,
1281
1731
  disconnect,
1732
+ findApiKeyById,
1733
+ findApiKeysByPrefix,
1734
+ findBlogPostById,
1735
+ findBlogPostBySlug,
1736
+ findBlogPosts,
1737
+ findBlogTagById,
1738
+ findBlogTagBySlug,
1739
+ findBlogTags,
1282
1740
  findEntries,
1283
1741
  findEntryById,
1284
1742
  findEntryByMatchAndPlayer,
@@ -1287,11 +1745,15 @@ async function getLocationWithTournaments(id) {
1287
1745
  findLocations,
1288
1746
  findMatchById,
1289
1747
  findMatches,
1748
+ findOpprPlayerRankingById,
1749
+ findOpprPlayerRankingByPlayerId,
1750
+ findOpprPlayerRankings,
1290
1751
  findPlayerByExternalId,
1291
1752
  findPlayerById,
1292
1753
  findPlayerByPlayerNumber,
1293
1754
  findPlayerByUserEmail,
1294
1755
  findPlayers,
1756
+ findPublishedBlogPosts,
1295
1757
  findRoundById,
1296
1758
  findRoundByTournamentAndNumber,
1297
1759
  findRounds,
@@ -1305,13 +1767,19 @@ async function getLocationWithTournaments(id) {
1305
1767
  findUserById,
1306
1768
  findUsers,
1307
1769
  generateUniquePlayerNumber,
1770
+ getBlogTagWithPostCount,
1771
+ getBlogTagsWithPostCounts,
1308
1772
  getFinalsRounds,
1309
1773
  getFinalsStandings,
1774
+ getLatestOpprRankingHistory,
1310
1775
  getLocationWithTournaments,
1311
1776
  getMajorTournaments,
1312
1777
  getMatchEntries,
1313
1778
  getMatchWithEntries,
1314
1779
  getMergedStandings,
1780
+ getOpprRankingHistory,
1781
+ getOpprRankingHistoryByDateRange,
1782
+ getOrCreateOpprPlayerRanking,
1315
1783
  getPlayerEntries,
1316
1784
  getPlayerEntryStats,
1317
1785
  getPlayerStandings,
@@ -1322,12 +1790,12 @@ async function getLocationWithTournaments(id) {
1322
1790
  getPlayerWithResults,
1323
1791
  getQualifyingRounds,
1324
1792
  getQualifyingStandings,
1325
- getRatedPlayers,
1793
+ getRatedOpprPlayers,
1326
1794
  getRecentTournaments,
1327
1795
  getRoundMatches,
1328
1796
  getRoundWithMatches,
1329
- getTopPlayersByRanking,
1330
- getTopPlayersByRating,
1797
+ getTopPlayersByOpprRanking,
1798
+ getTopPlayersByOpprRating,
1331
1799
  getTournamentMatches,
1332
1800
  getTournamentRounds,
1333
1801
  getTournamentStandings,
@@ -1336,25 +1804,33 @@ async function getLocationWithTournaments(id) {
1336
1804
  getTournamentWithResults,
1337
1805
  getTournamentsByBoosterType,
1338
1806
  getTournamentsByDateRange,
1807
+ getUserApiKeys,
1339
1808
  getUserByEmailWithPlayer,
1340
1809
  getUserWithPlayer,
1341
1810
  isValidPlayerNumber,
1342
1811
  linkPlayerToUser,
1343
1812
  prisma,
1344
1813
  recalculateTimeDecay,
1814
+ searchBlogPosts,
1815
+ searchBlogTags,
1345
1816
  searchLocations,
1346
1817
  searchPlayers,
1347
1818
  searchTournaments,
1348
1819
  testConnection,
1820
+ updateApiKeyLastUsed,
1821
+ updateBlogPost,
1822
+ updateBlogTag,
1349
1823
  updateEntry,
1350
1824
  updateLocation,
1351
1825
  updateMatch,
1826
+ updateOpprPlayerRanking,
1827
+ updateOpprRatingAfterTournament,
1352
1828
  updatePlayer,
1353
- updatePlayerRating,
1354
1829
  updateRound,
1355
1830
  updateStanding,
1356
1831
  updateStandingPoints,
1357
1832
  updateTournament,
1358
1833
  updateUser,
1359
- updateUserRefreshToken
1834
+ updateUserRefreshToken,
1835
+ updateWorldRankings
1360
1836
  });