@opprs/db-prisma 2.6.0 → 3.0.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.js CHANGED
@@ -434,28 +434,6 @@ async function getTournamentWithResults(id) {
434
434
  }
435
435
  });
436
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" }]
455
- }
456
- }
457
- });
458
- }
459
437
  async function searchTournaments(query, limit = 20) {
460
438
  return findTournaments({
461
439
  take: limit,
@@ -497,323 +475,6 @@ async function getTournamentStats(id) {
497
475
  };
498
476
  }
499
477
 
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
478
  // src/standings.ts
818
479
  async function createStanding(data) {
819
480
  const standingData = {
@@ -1496,14 +1157,11 @@ export {
1496
1157
  connect,
1497
1158
  countBlogPosts,
1498
1159
  countBlogTags,
1499
- countEntries,
1500
1160
  countLocations,
1501
- countMatches,
1502
1161
  countOpprPlayerRankings,
1503
1162
  countOpprRankingHistory,
1504
1163
  countPlayers,
1505
1164
  countPublishedBlogPosts,
1506
- countRounds,
1507
1165
  countStandings,
1508
1166
  countTournaments,
1509
1167
  countUserApiKeys,
@@ -1511,17 +1169,11 @@ export {
1511
1169
  createApiKey,
1512
1170
  createBlogPost,
1513
1171
  createBlogTag,
1514
- createEntry,
1515
1172
  createLocation,
1516
- createManyEntries,
1517
- createManyMatches,
1518
- createManyRounds,
1519
1173
  createManyStandings,
1520
- createMatch,
1521
1174
  createOpprPlayerRanking,
1522
1175
  createOpprRankingHistory,
1523
1176
  createPlayer,
1524
- createRound,
1525
1177
  createStanding,
1526
1178
  createTournament,
1527
1179
  createUser,
@@ -1529,16 +1181,9 @@ export {
1529
1181
  deleteApiKey,
1530
1182
  deleteBlogPost,
1531
1183
  deleteBlogTag,
1532
- deleteEntriesByMatch,
1533
- deleteEntry,
1534
1184
  deleteLocation,
1535
- deleteMatch,
1536
- deleteMatchesByRound,
1537
- deleteMatchesByTournament,
1538
1185
  deleteOpprPlayerRanking,
1539
1186
  deletePlayer,
1540
- deleteRound,
1541
- deleteRoundsByTournament,
1542
1187
  deleteStanding,
1543
1188
  deleteStandingsByTournament,
1544
1189
  deleteTournament,
@@ -1553,14 +1198,9 @@ export {
1553
1198
  findBlogTagById,
1554
1199
  findBlogTagBySlug,
1555
1200
  findBlogTags,
1556
- findEntries,
1557
- findEntryById,
1558
- findEntryByMatchAndPlayer,
1559
1201
  findLocationByExternalId,
1560
1202
  findLocationById,
1561
1203
  findLocations,
1562
- findMatchById,
1563
- findMatches,
1564
1204
  findOpprPlayerRankingById,
1565
1205
  findOpprPlayerRankingByPlayerId,
1566
1206
  findOpprPlayerRankings,
@@ -1570,9 +1210,6 @@ export {
1570
1210
  findPlayerByUserEmail,
1571
1211
  findPlayers,
1572
1212
  findPublishedBlogPosts,
1573
- findRoundById,
1574
- findRoundByTournamentAndNumber,
1575
- findRounds,
1576
1213
  findStandingById,
1577
1214
  findStandingByPlayerAndTournament,
1578
1215
  findStandings,
@@ -1585,38 +1222,25 @@ export {
1585
1222
  generateUniquePlayerNumber,
1586
1223
  getBlogTagWithPostCount,
1587
1224
  getBlogTagsWithPostCounts,
1588
- getFinalsRounds,
1589
1225
  getFinalsStandings,
1590
1226
  getLatestOpprRankingHistory,
1591
1227
  getLocationWithTournaments,
1592
1228
  getMajorTournaments,
1593
- getMatchEntries,
1594
- getMatchWithEntries,
1595
1229
  getMergedStandings,
1596
1230
  getOpprRankingHistory,
1597
1231
  getOpprRankingHistoryByDateRange,
1598
1232
  getOrCreateOpprPlayerRanking,
1599
- getPlayerEntries,
1600
- getPlayerEntryStats,
1601
1233
  getPlayerStandings,
1602
1234
  getPlayerStats,
1603
1235
  getPlayerTopFinishes,
1604
- getPlayerTournamentEntries,
1605
- getPlayerTournamentMatches,
1606
1236
  getPlayerWithResults,
1607
- getQualifyingRounds,
1608
1237
  getQualifyingStandings,
1609
1238
  getRatedOpprPlayers,
1610
1239
  getRecentTournaments,
1611
- getRoundMatches,
1612
- getRoundWithMatches,
1613
1240
  getTopPlayersByOpprRanking,
1614
1241
  getTopPlayersByOpprRating,
1615
- getTournamentMatches,
1616
- getTournamentRounds,
1617
1242
  getTournamentStandings,
1618
1243
  getTournamentStats,
1619
- getTournamentWithMatches,
1620
1244
  getTournamentWithResults,
1621
1245
  getTournamentsByBoosterType,
1622
1246
  getTournamentsByDateRange,
@@ -1636,13 +1260,10 @@ export {
1636
1260
  updateApiKeyLastUsed,
1637
1261
  updateBlogPost,
1638
1262
  updateBlogTag,
1639
- updateEntry,
1640
1263
  updateLocation,
1641
- updateMatch,
1642
1264
  updateOpprPlayerRanking,
1643
1265
  updateOpprRatingAfterTournament,
1644
1266
  updatePlayer,
1645
- updateRound,
1646
1267
  updateStanding,
1647
1268
  updateStandingPoints,
1648
1269
  updateTournament,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opprs/db-prisma",
3
- "version": "2.6.0",
3
+ "version": "3.0.0",
4
4
  "description": "Database backend for OPPR (Open Pinball Player Ranking System) using Prisma and PostgreSQL",
5
5
  "keywords": [
6
6
  "oppr",
@@ -12,7 +12,7 @@
12
12
  "tournament"
13
13
  ],
14
14
  "author": "Mitch McAffee",
15
- "license": "MIT",
15
+ "license": "AGPL-3.0-or-later",
16
16
  "repository": {
17
17
  "type": "git",
18
18
  "url": "https://github.com/themcaffee/OPPR",
@@ -56,7 +56,7 @@
56
56
  "vitest": "^4.0.16"
57
57
  },
58
58
  "peerDependencies": {
59
- "@opprs/core": "^2.2.1"
59
+ "@opprs/core": "^3.0.0"
60
60
  },
61
61
  "engines": {
62
62
  "node": ">=20.9.0"
@@ -66,6 +66,7 @@
66
66
  },
67
67
  "scripts": {
68
68
  "build": "tsup src/index.ts --format cjs,esm --dts --clean",
69
+ "postbuild": "cp ../../LICENSE .",
69
70
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
70
71
  "typecheck": "tsc --noEmit",
71
72
  "lint": "eslint src --ext .ts",
@@ -0,0 +1,81 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "PostStatus" AS ENUM ('DRAFT', 'PUBLISHED');
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "BlogPost" (
6
+ "id" TEXT NOT NULL,
7
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
+ "updatedAt" TIMESTAMP(3) NOT NULL,
9
+ "title" TEXT NOT NULL,
10
+ "slug" TEXT NOT NULL,
11
+ "content" TEXT NOT NULL,
12
+ "excerpt" VARCHAR(500),
13
+ "status" "PostStatus" NOT NULL DEFAULT 'DRAFT',
14
+ "publishedAt" TIMESTAMP(3),
15
+ "featuredImageUrl" TEXT,
16
+ "featuredImageAlt" TEXT,
17
+ "metaTitle" VARCHAR(60),
18
+ "metaDescription" VARCHAR(160),
19
+ "ogTitle" TEXT,
20
+ "ogDescription" TEXT,
21
+ "ogImageUrl" TEXT,
22
+ "authorId" TEXT NOT NULL,
23
+
24
+ CONSTRAINT "BlogPost_pkey" PRIMARY KEY ("id")
25
+ );
26
+
27
+ -- CreateTable
28
+ CREATE TABLE "BlogTag" (
29
+ "id" TEXT NOT NULL,
30
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
31
+ "updatedAt" TIMESTAMP(3) NOT NULL,
32
+ "name" TEXT NOT NULL,
33
+ "slug" TEXT NOT NULL,
34
+ "description" TEXT,
35
+
36
+ CONSTRAINT "BlogTag_pkey" PRIMARY KEY ("id")
37
+ );
38
+
39
+ -- CreateTable (implicit many-to-many join table)
40
+ CREATE TABLE "_BlogPostToTag" (
41
+ "A" TEXT NOT NULL,
42
+ "B" TEXT NOT NULL,
43
+
44
+ CONSTRAINT "_BlogPostToTag_AB_pkey" PRIMARY KEY ("A","B")
45
+ );
46
+
47
+ -- CreateIndex
48
+ CREATE UNIQUE INDEX "BlogPost_slug_key" ON "BlogPost"("slug");
49
+
50
+ -- CreateIndex
51
+ CREATE INDEX "BlogPost_slug_idx" ON "BlogPost"("slug");
52
+
53
+ -- CreateIndex
54
+ CREATE INDEX "BlogPost_status_idx" ON "BlogPost"("status");
55
+
56
+ -- CreateIndex
57
+ CREATE INDEX "BlogPost_publishedAt_idx" ON "BlogPost"("publishedAt");
58
+
59
+ -- CreateIndex
60
+ CREATE INDEX "BlogPost_authorId_idx" ON "BlogPost"("authorId");
61
+
62
+ -- CreateIndex
63
+ CREATE UNIQUE INDEX "BlogTag_name_key" ON "BlogTag"("name");
64
+
65
+ -- CreateIndex
66
+ CREATE UNIQUE INDEX "BlogTag_slug_key" ON "BlogTag"("slug");
67
+
68
+ -- CreateIndex
69
+ CREATE INDEX "BlogTag_slug_idx" ON "BlogTag"("slug");
70
+
71
+ -- CreateIndex
72
+ CREATE INDEX "_BlogPostToTag_B_index" ON "_BlogPostToTag"("B");
73
+
74
+ -- AddForeignKey
75
+ ALTER TABLE "BlogPost" ADD CONSTRAINT "BlogPost_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
76
+
77
+ -- AddForeignKey
78
+ ALTER TABLE "_BlogPostToTag" ADD CONSTRAINT "_BlogPostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "BlogPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
79
+
80
+ -- AddForeignKey
81
+ ALTER TABLE "_BlogPostToTag" ADD CONSTRAINT "_BlogPostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "BlogTag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,26 @@
1
+ -- DropForeignKey
2
+ ALTER TABLE "Entry" DROP CONSTRAINT "Entry_matchId_fkey";
3
+
4
+ -- DropForeignKey
5
+ ALTER TABLE "Entry" DROP CONSTRAINT "Entry_playerId_fkey";
6
+
7
+ -- DropForeignKey
8
+ ALTER TABLE "Match" DROP CONSTRAINT "Match_roundId_fkey";
9
+
10
+ -- DropForeignKey
11
+ ALTER TABLE "Match" DROP CONSTRAINT "Match_tournamentId_fkey";
12
+
13
+ -- DropForeignKey
14
+ ALTER TABLE "Round" DROP CONSTRAINT "Round_tournamentId_fkey";
15
+
16
+ -- DropTable
17
+ DROP TABLE "Entry";
18
+
19
+ -- DropTable
20
+ DROP TABLE "Match";
21
+
22
+ -- DropTable
23
+ DROP TABLE "Round";
24
+
25
+ -- DropEnum
26
+ DROP TYPE "MatchResult";
@@ -27,7 +27,6 @@ model Player {
27
27
 
28
28
  // Relations
29
29
  standings Standing[]
30
- entries Entry[]
31
30
  user User?
32
31
  organizedTournaments Tournament[] @relation("OrganizedTournaments")
33
32
  opprRanking OpprPlayerRanking?
@@ -76,8 +75,6 @@ model Tournament {
76
75
  firstPlaceValue Float?
77
76
 
78
77
  // Relations
79
- rounds Round[]
80
- matches Match[]
81
78
  standings Standing[]
82
79
  rankingHistoryRecords OpprRankingHistory[]
83
80
 
@@ -88,67 +85,6 @@ model Tournament {
88
85
  @@index([organizerId])
89
86
  }
90
87
 
91
- // Round model - groups matches within a tournament stage
92
- model Round {
93
- id String @id @default(cuid())
94
- createdAt DateTime @default(now())
95
- updatedAt DateTime @updatedAt
96
-
97
- tournamentId String
98
- tournament Tournament @relation(fields: [tournamentId], references: [id], onDelete: Cascade)
99
-
100
- number Int // Round number within the stage (1, 2, 3...)
101
- name String? // Optional name (e.g., "Quarterfinals", "Semifinal")
102
- isFinals Boolean @default(false)
103
-
104
- // Relations
105
- matches Match[]
106
-
107
- @@unique([tournamentId, number, isFinals])
108
- @@index([tournamentId])
109
- @@index([tournamentId, isFinals])
110
- }
111
-
112
- // Match model - a single game with 1-4 players
113
- model Match {
114
- id String @id @default(cuid())
115
- createdAt DateTime @default(now())
116
- updatedAt DateTime @updatedAt
117
-
118
- tournamentId String
119
- tournament Tournament @relation(fields: [tournamentId], references: [id], onDelete: Cascade)
120
- roundId String?
121
- round Round? @relation(fields: [roundId], references: [id], onDelete: SetNull)
122
-
123
- number Int? // Match number within the round
124
- machineName String? // Machine played on
125
-
126
- // Relations
127
- entries Entry[]
128
-
129
- @@index([tournamentId])
130
- @@index([roundId])
131
- }
132
-
133
- // Entry model - a player's participation in a match
134
- model Entry {
135
- id String @id @default(cuid())
136
- createdAt DateTime @default(now())
137
- updatedAt DateTime @updatedAt
138
-
139
- matchId String
140
- match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
141
- playerId String
142
- player Player @relation(fields: [playerId], references: [id], onDelete: Cascade)
143
-
144
- result MatchResult // WIN, LOSS, TIE
145
- position Int? // Position within the match (1st, 2nd, 3rd, 4th for group games)
146
-
147
- @@unique([matchId, playerId])
148
- @@index([matchId])
149
- @@index([playerId])
150
- }
151
-
152
88
  // Standing model - final position for qualifying or finals
153
89
  model Standing {
154
90
  id String @id @default(cuid())
@@ -180,13 +116,6 @@ model Standing {
180
116
  @@index([position])
181
117
  }
182
118
 
183
- // Enum for match results
184
- enum MatchResult {
185
- WIN
186
- LOSS
187
- TIE
188
- }
189
-
190
119
  // Enum for event booster types
191
120
  enum EventBoosterType {
192
121
  NONE