From 06c5db1cd53b3181304cdc4e24d427e469d50de6 Mon Sep 17 00:00:00 2001
From: Stanislav Vysotskyi <66203238+ArdenHide@users.noreply.github.com>
Date: Tue, 24 Dec 2024 13:17:37 +0300
Subject: [PATCH] Many signatures for one dispenser (#47)

* Many signatures for one dispenser

* - add migration
---
 .../DispenserContext.cs                       |   5 +-
 .../Models/DispenserDTO.cs                    |   4 +-
 .../Models/SignatureDTO.cs                    |   2 +
 ...ny-Signatures-To-One-Dispenser.Designer.cs | 240 ++++++++++++++++++
 ...095922_Many-Signatures-To-One-Dispenser.cs |  83 ++++++
 .../DispenserContextModelSnapshot.cs          |  48 ++--
 6 files changed, 352 insertions(+), 30 deletions(-)
 create mode 100644 src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.Designer.cs
 create mode 100644 src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.cs

diff --git a/src/DispenserProvider.DataBase/DispenserContext.cs b/src/DispenserProvider.DataBase/DispenserContext.cs
index 936587d..81bcf43 100644
--- a/src/DispenserProvider.DataBase/DispenserContext.cs
+++ b/src/DispenserProvider.DataBase/DispenserContext.cs
@@ -40,10 +40,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
                     x => new EthereumAddress(x)
                 );
 
-            entity.HasOne(e => e.UserSignature)
+            entity.HasMany(e => e.UserSignatures)
                 .WithOne(e => e.Dispenser)
-                .HasForeignKey<DispenserDTO>(e => e.Signature)
-                .IsRequired(false)
+                .HasForeignKey(e => e.DispenserId)
                 .OnDelete(DeleteBehavior.Restrict);
 
             entity.HasOne(e => e.WithdrawalDetail)
diff --git a/src/DispenserProvider.DataBase/Models/DispenserDTO.cs b/src/DispenserProvider.DataBase/Models/DispenserDTO.cs
index 85cd766..0dd89a6 100644
--- a/src/DispenserProvider.DataBase/Models/DispenserDTO.cs
+++ b/src/DispenserProvider.DataBase/Models/DispenserDTO.cs
@@ -15,9 +15,7 @@ public class DispenserDTO
     [Column(TypeName = "datetime2(0)")]
     public DateTime? RefundFinishTime { get; set; }
 
-    [Column(TypeName = "nvarchar(132)")]
-    public string? Signature { get; set; }
-    public virtual SignatureDTO? UserSignature { get; set; } = null!;
+    public virtual List<SignatureDTO> UserSignatures { get; set; } = [];
 
     public long WithdrawalDetailId { get; set; }
     public virtual TransactionDetailDTO WithdrawalDetail { get; set; } = null!;
diff --git a/src/DispenserProvider.DataBase/Models/SignatureDTO.cs b/src/DispenserProvider.DataBase/Models/SignatureDTO.cs
index 0d7a155..7136991 100644
--- a/src/DispenserProvider.DataBase/Models/SignatureDTO.cs
+++ b/src/DispenserProvider.DataBase/Models/SignatureDTO.cs
@@ -15,5 +15,7 @@ public class SignatureDTO
 
     public bool IsRefund { get; set; }
 
+    [Column(TypeName = "nvarchar(64)")]
+    public string DispenserId { get; set; } = null!;
     public virtual DispenserDTO Dispenser { get; set; } = null!;
 }
\ No newline at end of file
diff --git a/src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.Designer.cs b/src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.Designer.cs
new file mode 100644
index 0000000..f48a855
--- /dev/null
+++ b/src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.Designer.cs
@@ -0,0 +1,240 @@
+// <auto-generated />
+using System;
+using DispenserProvider.DataBase;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace DispenserProvider.DataBase.Migrations
+{
+    [DbContext(typeof(DispenserContext))]
+    [Migration("20241224095922_Many-Signatures-To-One-Dispenser")]
+    partial class ManySignaturesToOneDispenser
+    {
+        /// <inheritdoc />
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "8.0.8")
+                .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.BuilderDTO", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
+
+                    b.Property<DateTime?>("FinishTime")
+                        .HasColumnType("datetime2(0)");
+
+                    b.Property<string>("ProviderAddress")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(42)");
+
+                    b.Property<DateTime?>("StartTime")
+                        .HasColumnType("datetime2(0)");
+
+                    b.Property<long>("TransactionDetailId")
+                        .HasColumnType("bigint");
+
+                    b.Property<string>("WeiAmount")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(78)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TransactionDetailId");
+
+                    b.ToTable("Builders");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.DispenserDTO", b =>
+                {
+                    b.Property<string>("Id")
+                        .HasColumnType("nvarchar(64)");
+
+                    b.Property<string>("CreationLogSignature")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(132)");
+
+                    b.Property<string>("DeletionLogSignature")
+                        .HasColumnType("nvarchar(132)");
+
+                    b.Property<long?>("RefundDetailId")
+                        .HasColumnType("bigint");
+
+                    b.Property<DateTime?>("RefundFinishTime")
+                        .HasColumnType("datetime2(0)");
+
+                    b.Property<string>("UserAddress")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(42)");
+
+                    b.Property<long>("WithdrawalDetailId")
+                        .HasColumnType("bigint");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CreationLogSignature");
+
+                    b.HasIndex("DeletionLogSignature");
+
+                    b.HasIndex("RefundDetailId")
+                        .IsUnique()
+                        .HasFilter("[RefundDetailId] IS NOT NULL");
+
+                    b.HasIndex("WithdrawalDetailId")
+                        .IsUnique();
+
+                    b.ToTable("Dispenser");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.LogDTO", b =>
+                {
+                    b.Property<string>("Signature")
+                        .HasColumnType("nvarchar(132)");
+
+                    b.Property<DateTime>("CreationTime")
+                        .HasColumnType("datetime2(0)");
+
+                    b.Property<string>("Operation")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(32)");
+
+                    b.HasKey("Signature");
+
+                    b.ToTable("Logs");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.SignatureDTO", b =>
+                {
+                    b.Property<string>("Signature")
+                        .HasColumnType("nvarchar(132)");
+
+                    b.Property<string>("DispenserId")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(64)");
+
+                    b.Property<bool>("IsRefund")
+                        .HasColumnType("bit");
+
+                    b.Property<DateTime>("ValidFrom")
+                        .HasColumnType("datetime2(0)");
+
+                    b.Property<DateTime>("ValidUntil")
+                        .HasColumnType("datetime2(0)");
+
+                    b.HasKey("Signature");
+
+                    b.HasIndex("DispenserId");
+
+                    b.ToTable("Signatures");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.TransactionDetailDTO", b =>
+                {
+                    b.Property<long>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("bigint");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
+
+                    b.Property<long>("ChainId")
+                        .HasColumnType("bigint");
+
+                    b.Property<long>("PoolId")
+                        .HasColumnType("bigint");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("TransactionDetails");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.BuilderDTO", b =>
+                {
+                    b.HasOne("DispenserProvider.DataBase.Models.TransactionDetailDTO", "TransactionDetail")
+                        .WithMany("Builders")
+                        .HasForeignKey("TransactionDetailId")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("TransactionDetail");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.DispenserDTO", b =>
+                {
+                    b.HasOne("DispenserProvider.DataBase.Models.LogDTO", "CreationLog")
+                        .WithMany("CreationDispensers")
+                        .HasForeignKey("CreationLogSignature")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("DispenserProvider.DataBase.Models.LogDTO", "DeletionLog")
+                        .WithMany("DeletionDispensers")
+                        .HasForeignKey("DeletionLogSignature")
+                        .OnDelete(DeleteBehavior.Restrict);
+
+                    b.HasOne("DispenserProvider.DataBase.Models.TransactionDetailDTO", "RefundDetail")
+                        .WithOne("RefundDispenser")
+                        .HasForeignKey("DispenserProvider.DataBase.Models.DispenserDTO", "RefundDetailId")
+                        .OnDelete(DeleteBehavior.Restrict);
+
+                    b.HasOne("DispenserProvider.DataBase.Models.TransactionDetailDTO", "WithdrawalDetail")
+                        .WithOne("WithdrawalDispenser")
+                        .HasForeignKey("DispenserProvider.DataBase.Models.DispenserDTO", "WithdrawalDetailId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .IsRequired();
+
+                    b.Navigation("CreationLog");
+
+                    b.Navigation("DeletionLog");
+
+                    b.Navigation("RefundDetail");
+
+                    b.Navigation("WithdrawalDetail");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.SignatureDTO", b =>
+                {
+                    b.HasOne("DispenserProvider.DataBase.Models.DispenserDTO", "Dispenser")
+                        .WithMany("UserSignatures")
+                        .HasForeignKey("DispenserId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .IsRequired();
+
+                    b.Navigation("Dispenser");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.DispenserDTO", b =>
+                {
+                    b.Navigation("UserSignatures");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.LogDTO", b =>
+                {
+                    b.Navigation("CreationDispensers");
+
+                    b.Navigation("DeletionDispensers");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.TransactionDetailDTO", b =>
+                {
+                    b.Navigation("Builders");
+
+                    b.Navigation("RefundDispenser");
+
+                    b.Navigation("WithdrawalDispenser");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}
diff --git a/src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.cs b/src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.cs
new file mode 100644
index 0000000..c3de8dd
--- /dev/null
+++ b/src/DispenserProvider.Migrations/Migrations/20241224095922_Many-Signatures-To-One-Dispenser.cs
@@ -0,0 +1,83 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace DispenserProvider.DataBase.Migrations
+{
+    /// <inheritdoc />
+    public partial class ManySignaturesToOneDispenser : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropForeignKey(
+                name: "FK_Dispenser_Signatures_Signature",
+                table: "Dispenser");
+
+            migrationBuilder.DropIndex(
+                name: "IX_Dispenser_Signature",
+                table: "Dispenser");
+
+            migrationBuilder.DropColumn(
+                name: "Signature",
+                table: "Dispenser");
+
+            migrationBuilder.AddColumn<string>(
+                name: "DispenserId",
+                table: "Signatures",
+                type: "nvarchar(64)",
+                nullable: false,
+                defaultValue: "");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Signatures_DispenserId",
+                table: "Signatures",
+                column: "DispenserId");
+
+            migrationBuilder.AddForeignKey(
+                name: "FK_Signatures_Dispenser_DispenserId",
+                table: "Signatures",
+                column: "DispenserId",
+                principalTable: "Dispenser",
+                principalColumn: "Id",
+                onDelete: ReferentialAction.Restrict);
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropForeignKey(
+                name: "FK_Signatures_Dispenser_DispenserId",
+                table: "Signatures");
+
+            migrationBuilder.DropIndex(
+                name: "IX_Signatures_DispenserId",
+                table: "Signatures");
+
+            migrationBuilder.DropColumn(
+                name: "DispenserId",
+                table: "Signatures");
+
+            migrationBuilder.AddColumn<string>(
+                name: "Signature",
+                table: "Dispenser",
+                type: "nvarchar(132)",
+                nullable: true);
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Dispenser_Signature",
+                table: "Dispenser",
+                column: "Signature",
+                unique: true,
+                filter: "[Signature] IS NOT NULL");
+
+            migrationBuilder.AddForeignKey(
+                name: "FK_Dispenser_Signatures_Signature",
+                table: "Dispenser",
+                column: "Signature",
+                principalTable: "Signatures",
+                principalColumn: "Signature",
+                onDelete: ReferentialAction.Restrict);
+        }
+    }
+}
diff --git a/src/DispenserProvider.Migrations/Migrations/DispenserContextModelSnapshot.cs b/src/DispenserProvider.Migrations/Migrations/DispenserContextModelSnapshot.cs
index ab1c82d..d488261 100644
--- a/src/DispenserProvider.Migrations/Migrations/DispenserContextModelSnapshot.cs
+++ b/src/DispenserProvider.Migrations/Migrations/DispenserContextModelSnapshot.cs
@@ -72,9 +72,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
                     b.Property<DateTime?>("RefundFinishTime")
                         .HasColumnType("datetime2(0)");
 
-                    b.Property<string>("Signature")
-                        .HasColumnType("nvarchar(132)");
-
                     b.Property<string>("UserAddress")
                         .IsRequired()
                         .HasColumnType("nvarchar(42)");
@@ -92,10 +89,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
                         .IsUnique()
                         .HasFilter("[RefundDetailId] IS NOT NULL");
 
-                    b.HasIndex("Signature")
-                        .IsUnique()
-                        .HasFilter("[Signature] IS NOT NULL");
-
                     b.HasIndex("WithdrawalDetailId")
                         .IsUnique();
 
@@ -124,6 +117,10 @@ protected override void BuildModel(ModelBuilder modelBuilder)
                     b.Property<string>("Signature")
                         .HasColumnType("nvarchar(132)");
 
+                    b.Property<string>("DispenserId")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(64)");
+
                     b.Property<bool>("IsRefund")
                         .HasColumnType("bit");
 
@@ -135,6 +132,8 @@ protected override void BuildModel(ModelBuilder modelBuilder)
 
                     b.HasKey("Signature");
 
+                    b.HasIndex("DispenserId");
+
                     b.ToTable("Signatures");
                 });
 
@@ -186,11 +185,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
                         .HasForeignKey("DispenserProvider.DataBase.Models.DispenserDTO", "RefundDetailId")
                         .OnDelete(DeleteBehavior.Restrict);
 
-                    b.HasOne("DispenserProvider.DataBase.Models.SignatureDTO", "UserSignature")
-                        .WithOne("Dispenser")
-                        .HasForeignKey("DispenserProvider.DataBase.Models.DispenserDTO", "Signature")
-                        .OnDelete(DeleteBehavior.Restrict);
-
                     b.HasOne("DispenserProvider.DataBase.Models.TransactionDetailDTO", "WithdrawalDetail")
                         .WithOne("WithdrawalDispenser")
                         .HasForeignKey("DispenserProvider.DataBase.Models.DispenserDTO", "WithdrawalDetailId")
@@ -203,33 +197,39 @@ protected override void BuildModel(ModelBuilder modelBuilder)
 
                     b.Navigation("RefundDetail");
 
-                    b.Navigation("UserSignature");
-
                     b.Navigation("WithdrawalDetail");
                 });
 
-            modelBuilder.Entity("DispenserProvider.DataBase.Models.LogDTO", b =>
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.SignatureDTO", b =>
                 {
-                    b.Navigation("CreationDispensers");
+                    b.HasOne("DispenserProvider.DataBase.Models.DispenserDTO", "Dispenser")
+                        .WithMany("UserSignatures")
+                        .HasForeignKey("DispenserId")
+                        .OnDelete(DeleteBehavior.Restrict)
+                        .IsRequired();
 
-                    b.Navigation("DeletionDispensers");
+                    b.Navigation("Dispenser");
                 });
 
-            modelBuilder.Entity("DispenserProvider.DataBase.Models.SignatureDTO", b =>
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.DispenserDTO", b =>
                 {
-                    b.Navigation("Dispenser")
-                        .IsRequired();
+                    b.Navigation("UserSignatures");
+                });
+
+            modelBuilder.Entity("DispenserProvider.DataBase.Models.LogDTO", b =>
+                {
+                    b.Navigation("CreationDispensers");
+
+                    b.Navigation("DeletionDispensers");
                 });
 
             modelBuilder.Entity("DispenserProvider.DataBase.Models.TransactionDetailDTO", b =>
                 {
                     b.Navigation("Builders");
 
-                    b.Navigation("RefundDispenser")
-                        .IsRequired();
+                    b.Navigation("RefundDispenser");
 
-                    b.Navigation("WithdrawalDispenser")
-                        .IsRequired();
+                    b.Navigation("WithdrawalDispenser");
                 });
 #pragma warning restore 612, 618
         }