From 2dfec9d10575a598201ea83aff3b421bdbfc7e36 Mon Sep 17 00:00:00 2001
From: Renovate Bot <renovate@vylpes.com>
Date: Mon, 11 Sep 2023 02:01:47 +0000
Subject: [PATCH 1/8] Update dependency @types/node to v20.6.0

---
 yarn.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/yarn.lock b/yarn.lock
index e5ab839..47082b0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -888,9 +888,9 @@
     "@types/node" "*"
 
 "@types/node@*", "@types/node@^20.0.0":
-  version "20.5.1"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30"
-  integrity sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==
+  version "20.6.0"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.0.tgz#9d7daa855d33d4efec8aea88cd66db1c2f0ebe16"
+  integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==
 
 "@types/normalize-package-data@^2.4.1":
   version "2.4.1"

From ad505b3ea29b09afd217f4c35a0d3181dd8b8f5c Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 13 Sep 2023 14:37:17 +0100
Subject: [PATCH 2/8] Fix users being able to claim a card twice if the user
 has multiple of it already

---
 .../Up/01-CreateClaim.sql                     |  8 ++++++
 .../Up/02-MoveToClaim.sql                     | 10 +++++++
 .../Up/03-AlterInventory.sql                  |  2 ++
 src/buttonEvents/Claim.ts                     | 16 +++++++++--
 src/database/entities/app/Claim.ts            | 27 +++++++++++++++++++
 src/database/entities/app/Inventory.ts        | 22 +++++++--------
 .../app/0.1.5/1694609771821-CreateClaim.ts    | 17 ++++++++++++
 7 files changed, 87 insertions(+), 15 deletions(-)
 create mode 100644 database/0.1.5/1694609771821-CreateClaim/Up/01-CreateClaim.sql
 create mode 100644 database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql
 create mode 100644 database/0.1.5/1694609771821-CreateClaim/Up/03-AlterInventory.sql
 create mode 100644 src/database/entities/app/Claim.ts
 create mode 100644 src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts

diff --git a/database/0.1.5/1694609771821-CreateClaim/Up/01-CreateClaim.sql b/database/0.1.5/1694609771821-CreateClaim/Up/01-CreateClaim.sql
new file mode 100644
index 0000000..bfd8057
--- /dev/null
+++ b/database/0.1.5/1694609771821-CreateClaim/Up/01-CreateClaim.sql
@@ -0,0 +1,8 @@
+CREATE TABLE `claim` (
+  `Id` varchar(255) NOT NULL,
+  `WhenCreated` datetime NOT NULL,
+  `WhenUpdated` datetime NOT NULL,
+  `ClaimId` varchar(255) NOT NULL,
+  `InventoryId` varchar(255) NOT NULL,
+  PRIMARY KEY (`Id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
\ No newline at end of file
diff --git a/database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql b/database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql
new file mode 100644
index 0000000..b73eb32
--- /dev/null
+++ b/database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql
@@ -0,0 +1,10 @@
+INSERT INTO claim (
+    Id,
+    ClaimId,
+    InventoryId
+)
+SELECT
+    UUID(),
+    ClaimId,
+    Id
+FROM inventory;
\ No newline at end of file
diff --git a/database/0.1.5/1694609771821-CreateClaim/Up/03-AlterInventory.sql b/database/0.1.5/1694609771821-CreateClaim/Up/03-AlterInventory.sql
new file mode 100644
index 0000000..7005ca3
--- /dev/null
+++ b/database/0.1.5/1694609771821-CreateClaim/Up/03-AlterInventory.sql
@@ -0,0 +1,2 @@
+ALTER TABLE inventory
+DROP ClaimId;
\ No newline at end of file
diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts
index 5412db8..ce04803 100644
--- a/src/buttonEvents/Claim.ts
+++ b/src/buttonEvents/Claim.ts
@@ -2,6 +2,7 @@ import { ButtonInteraction } from "discord.js";
 import { ButtonEvent } from "../type/buttonEvent";
 import Inventory from "../database/entities/app/Inventory";
 import { CoreClient } from "../client/client";
+import { default as eClaim } from "../database/entities/app/Claim";
 
 export default class Claim extends ButtonEvent {
     public override async execute(interaction: ButtonInteraction) {
@@ -11,7 +12,7 @@ export default class Claim extends ButtonEvent {
         const claimId = interaction.customId.split(' ')[2];
         const userId = interaction.user.id;
 
-        const claimed = await Inventory.FetchOneByClaimId(claimId);
+        const claimed = await eClaim.FetchOneByClaimId(claimId);
 
         if (claimed) {
             await interaction.reply('This card has already been claimed');
@@ -26,13 +27,24 @@ export default class Claim extends ButtonEvent {
         let inventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber);
 
         if (!inventory) {
-            inventory = new Inventory(userId, cardNumber, 1, claimId);
+            inventory = new Inventory(userId, cardNumber, 1);
         } else {
             inventory.SetQuantity(inventory.Quantity + 1);
         }
 
         await inventory.Save(Inventory, inventory);
 
+        const claim = new eClaim(claimId);
+        await claim.Save(eClaim, claim);
+
+        inventory = await Inventory.FetchOneById(Inventory, inventory.Id, [ "Claims" ]);
+
+        if (inventory) {
+            inventory.AddClaim(claim);
+
+            await inventory.Save(Inventory, inventory);
+        }
+
         await interaction.reply('Card claimed');
     }
 }
\ No newline at end of file
diff --git a/src/database/entities/app/Claim.ts b/src/database/entities/app/Claim.ts
new file mode 100644
index 0000000..7e1c4f9
--- /dev/null
+++ b/src/database/entities/app/Claim.ts
@@ -0,0 +1,27 @@
+import { Column, Entity, ManyToOne } from "typeorm";
+import AppBaseEntity from "../../../contracts/AppBaseEntity";
+import Inventory from "./Inventory";
+import AppDataSource from "../../dataSources/appDataSource";
+
+@Entity()
+export default class Claim extends AppBaseEntity {
+    constructor(claimId: string) {
+        super();
+
+        this.ClaimId = claimId;
+    }
+
+    @Column()
+    ClaimId: string;
+
+    @ManyToOne(() => Inventory, x => x.Claims)
+    Inventory: Inventory;
+
+    public static async FetchOneByClaimId(claimId: string): Promise<Claim | null> {
+        const repository = AppDataSource.getRepository(Claim);
+
+        const single = await repository.findOne({ where: { ClaimId: claimId }});
+
+        return single;
+    }
+}
\ No newline at end of file
diff --git a/src/database/entities/app/Inventory.ts b/src/database/entities/app/Inventory.ts
index c6319a9..adec824 100644
--- a/src/database/entities/app/Inventory.ts
+++ b/src/database/entities/app/Inventory.ts
@@ -1,16 +1,16 @@
-import { Column, Entity } from "typeorm";
+import { Column, Entity, OneToMany } from "typeorm";
 import AppBaseEntity from "../../../contracts/AppBaseEntity";
 import AppDataSource from "../../dataSources/appDataSource";
+import Claim from "./Claim";
 
 @Entity()
 export default class Inventory extends AppBaseEntity {
-    constructor(userId: string, cardNumber: string, quantity: number, claimId: string) {
+    constructor(userId: string, cardNumber: string, quantity: number) {
         super();
 
         this.UserId = userId;
         this.CardNumber = cardNumber;
         this.Quantity = quantity;
-        this.ClaimId = claimId;
     }
 
     @Column()
@@ -22,13 +22,17 @@ export default class Inventory extends AppBaseEntity {
     @Column()
     Quantity: number;
 
-    @Column()
-    ClaimId: string;
+    @OneToMany(() => Claim, x => x.Inventory)
+    Claims: Claim[];
 
     public SetQuantity(quantity: number) {
         this.Quantity = quantity;
     }
 
+    public AddClaim(claim: Claim) {
+        this.Claims.push(claim);
+    }
+
     public static async FetchOneByCardNumberAndUserId(userId: string, cardNumber: string): Promise<Inventory | null> {
         const repository = AppDataSource.getRepository(Inventory);
 
@@ -36,12 +40,4 @@ export default class Inventory extends AppBaseEntity {
 
         return single;
     }
-
-    public static async FetchOneByClaimId(claimId: string): Promise<Inventory | null> {
-        const repository = AppDataSource.getRepository(Inventory);
-
-        const single = await repository.findOne({ where: { ClaimId: claimId }});
-
-        return single;
-    }
 }
\ No newline at end of file
diff --git a/src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts b/src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts
new file mode 100644
index 0000000..22fe74c
--- /dev/null
+++ b/src/database/migrations/app/0.1.5/1694609771821-CreateClaim.ts
@@ -0,0 +1,17 @@
+import { MigrationInterface, QueryRunner } from "typeorm"
+import MigrationHelper from "../../../../helpers/MigrationHelper"
+
+export class CreateClaim1694609771821 implements MigrationInterface {
+
+    public async up(queryRunner: QueryRunner): Promise<void> {
+        MigrationHelper.Up('1694609771821-CreateClaim', '0.1.5', [
+            '01-CreateClaim',
+            '02-MoveToClaim',
+            '03-AlterInventory',
+        ], queryRunner);
+    }
+
+    public async down(queryRunner: QueryRunner): Promise<void> {
+    }
+
+}

From 8ccd7c33d4819f94f0a1066e9e755e496fa1ee1a Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 13 Sep 2023 15:06:53 +0100
Subject: [PATCH 3/8] Prevent users from being able to claim the latest card
 unless you were the one to drop it

---
 src/buttonEvents/Claim.ts          | 15 +++++----------
 src/buttonEvents/Reroll.ts         |  2 +-
 src/commands/drop.ts               |  3 +--
 src/database/entities/app/Claim.ts |  4 ++++
 4 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts
index ce04803..6f9ae58 100644
--- a/src/buttonEvents/Claim.ts
+++ b/src/buttonEvents/Claim.ts
@@ -10,6 +10,7 @@ export default class Claim extends ButtonEvent {
 
         const cardNumber = interaction.customId.split(' ')[1];
         const claimId = interaction.customId.split(' ')[2];
+        const droppedBy = interaction.customId.split(' ')[3];
         const userId = interaction.user.id;
 
         const claimed = await eClaim.FetchOneByClaimId(claimId);
@@ -19,8 +20,8 @@ export default class Claim extends ButtonEvent {
             return;
         }
 
-        if (claimId != CoreClient.ClaimId) {
-            await interaction.reply('This card has expired');
+        if (claimId == CoreClient.ClaimId && userId != droppedBy) {
+            await interaction.reply('The latest dropped card can only be claimed by the user who dropped it');
             return;
         }
 
@@ -35,16 +36,10 @@ export default class Claim extends ButtonEvent {
         await inventory.Save(Inventory, inventory);
 
         const claim = new eClaim(claimId);
+        claim.SetInventory(inventory);
+
         await claim.Save(eClaim, claim);
 
-        inventory = await Inventory.FetchOneById(Inventory, inventory.Id, [ "Claims" ]);
-
-        if (inventory) {
-            inventory.AddClaim(claim);
-
-            await inventory.Save(Inventory, inventory);
-        }
-
         await interaction.reply('Card claimed');
     }
 }
\ No newline at end of file
diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts
index c1a54ea..bc91c90 100644
--- a/src/buttonEvents/Reroll.ts
+++ b/src/buttonEvents/Reroll.ts
@@ -45,7 +45,7 @@ export default class Reroll extends ButtonEvent {
 
         row.addComponents(
             new ButtonBuilder()
-                .setCustomId(`claim ${randomCard.CardNumber} ${claimId}`)
+                .setCustomId(`claim ${randomCard.CardNumber} ${claimId} ${interaction.user.id}`)
                 .setLabel("Claim")
                 .setStyle(ButtonStyle.Primary),
             new ButtonBuilder()
diff --git a/src/commands/drop.ts b/src/commands/drop.ts
index 5770903..7503bf7 100644
--- a/src/commands/drop.ts
+++ b/src/commands/drop.ts
@@ -51,7 +51,7 @@ export default class Drop extends Command {
 
         row.addComponents(
             new ButtonBuilder()
-                .setCustomId(`claim ${randomCard.CardNumber} ${claimId}`)
+                .setCustomId(`claim ${randomCard.CardNumber} ${claimId} ${interaction.user.id}`)
                 .setLabel("Claim")
                 .setStyle(ButtonStyle.Primary),
             new ButtonBuilder()
@@ -76,7 +76,6 @@ export default class Drop extends Command {
             }
         }
 
-
         CoreClient.ClaimId = claimId;
     }
 }
\ No newline at end of file
diff --git a/src/database/entities/app/Claim.ts b/src/database/entities/app/Claim.ts
index 7e1c4f9..b4cde5e 100644
--- a/src/database/entities/app/Claim.ts
+++ b/src/database/entities/app/Claim.ts
@@ -17,6 +17,10 @@ export default class Claim extends AppBaseEntity {
     @ManyToOne(() => Inventory, x => x.Claims)
     Inventory: Inventory;
 
+    public SetInventory(inventory: Inventory) {
+        this.Inventory = inventory;
+    }
+
     public static async FetchOneByClaimId(claimId: string): Promise<Claim | null> {
         const repository = AppDataSource.getRepository(Claim);
 

From 9c408e07b0123d3d43595125ceddba872db62ce4 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 13 Sep 2023 18:51:14 +0100
Subject: [PATCH 4/8] v0.1.5

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 80f753a..505b116 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "card-drop",
-  "version": "0.1.4",
+  "version": "0.1.5",
   "main": "./dist/bot.js",
   "typings": "./dist",
   "scripts": {

From 7f64065589bbe38c64f73375dd91800f163438b6 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 13 Sep 2023 18:57:20 +0100
Subject: [PATCH 5/8] Add dates to migration script

---
 .../0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql     | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql b/database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql
index b73eb32..c95401a 100644
--- a/database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql
+++ b/database/0.1.5/1694609771821-CreateClaim/Up/02-MoveToClaim.sql
@@ -1,10 +1,14 @@
 INSERT INTO claim (
     Id,
+    WhenCreated,
+    WhenUpdated,
     ClaimId,
     InventoryId
 )
 SELECT
     UUID(),
+    NOW(),
+    NOW(),
     ClaimId,
     Id
 FROM inventory;
\ No newline at end of file

From aebc7999664fa9e796c6239cae3f1ee7e1a8ca67 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 13 Sep 2023 18:57:39 +0100
Subject: [PATCH 6/8] Revert to 0.1.4

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 505b116..80f753a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "card-drop",
-  "version": "0.1.5",
+  "version": "0.1.4",
   "main": "./dist/bot.js",
   "typings": "./dist",
   "scripts": {

From 005a366883c4d7ce050904845ab1b97909fb6065 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 13 Sep 2023 18:57:45 +0100
Subject: [PATCH 7/8] v0.1.5

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 80f753a..505b116 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "card-drop",
-  "version": "0.1.4",
+  "version": "0.1.5",
   "main": "./dist/bot.js",
   "typings": "./dist",
   "scripts": {

From 5406c0ce68f351022fa3afb9dee31b18d22f91b6 Mon Sep 17 00:00:00 2001
From: Renovate Bot <renovate@vylpes.com>
Date: Thu, 28 Sep 2023 10:43:05 +0000
Subject: [PATCH 8/8] Update dependency @types/node to v20.7.1

---
 yarn.lock | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/yarn.lock b/yarn.lock
index e5ab839..0f601a5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -888,19 +888,19 @@
     "@types/node" "*"
 
 "@types/node@*", "@types/node@^20.0.0":
-  version "20.5.1"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30"
-  integrity sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==
+  version "20.7.1"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.7.1.tgz#06d732ead0bd5ad978ef0ea9cbdeb24dc8717514"
+  integrity sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==
 
 "@types/normalize-package-data@^2.4.1":
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
-  integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==
+  version "2.4.2"
+  resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz#9b0e3e8533fe5024ad32d6637eb9589988b6fdca"
+  integrity sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==
 
 "@types/responselike@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
-  integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.1.tgz#1dd57e54509b3b95c7958e52709567077019d65d"
+  integrity sha512-TiGnitEDxj2X0j+98Eqk5lv/Cij8oHd32bU4D/Yw6AOq7vvTk0gSD2GPj0G/HkvhMoVsdlhYF4yqqlyPBTM6Sg==
   dependencies:
     "@types/node" "*"