From 703d4751e2e9313287d6f4039ec18c4f832f2c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Vrabec?= Date: Sat, 9 Aug 2025 19:05:02 +0200 Subject: [PATCH] Add EF object history --- DrinkRateAPI/Contexts/ApplicationDbContext.cs | 11 +- DrinkRateAPI/DbEntities/DbCompany.cs | 2 +- DrinkRateAPI/DbEntities/DbCompanyRating.cs | 2 +- DrinkRateAPI/DbEntities/DbCompanyTableView.cs | 2 +- .../DbEntities/DbEntityWithHistory.cs | 6 + DrinkRateAPI/DbEntities/DbProduct.cs | 2 +- DrinkRateAPI/DbEntities/DbProductRating.cs | 2 +- DrinkRateAPI/DbEntities/DbProductTableView.cs | 2 +- DrinkRateAPI/DbEntities/DbUpdateRecord.cs | 18 + DrinkRateAPI/DbEntities/DbUserProfile.cs | 6 +- .../20250809170131_ObjectHistory.Designer.cs | 951 ++++++++++++++++++ .../20250809170131_ObjectHistory.cs | 142 +++ .../ApplicationDbContextModelSnapshot.cs | 156 +++ 13 files changed, 1288 insertions(+), 14 deletions(-) create mode 100644 DrinkRateAPI/DbEntities/DbEntityWithHistory.cs create mode 100644 DrinkRateAPI/DbEntities/DbUpdateRecord.cs create mode 100644 DrinkRateAPI/Migrations/20250809170131_ObjectHistory.Designer.cs create mode 100644 DrinkRateAPI/Migrations/20250809170131_ObjectHistory.cs diff --git a/DrinkRateAPI/Contexts/ApplicationDbContext.cs b/DrinkRateAPI/Contexts/ApplicationDbContext.cs index f59b044..14cfccb 100644 --- a/DrinkRateAPI/Contexts/ApplicationDbContext.cs +++ b/DrinkRateAPI/Contexts/ApplicationDbContext.cs @@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore; namespace DrinkRateAPI.Contexts; -public class ApplicationDbContext : IdentityDbContext, Guid> +public class ApplicationDbContext : IdentityDbContext, Guid> { public DbSet Companies { get; set; } public DbSet CompanyRatings { get; set; } @@ -21,6 +21,9 @@ public class ApplicationDbContext : IdentityDbContext UserProfileCompanyTableStats { get; set; } public DbSet UserProfileProductTableStats { get; set; } + public DbSet UpdateRecords { get; set; } + public DbSet UpdateRecordFieldChanges { get; set; } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); @@ -35,7 +38,7 @@ public class ApplicationDbContext : IdentityDbContext(entity => { @@ -189,7 +192,7 @@ public class ApplicationDbContext : IdentityDbContext up.UserName) .IsUnique(); - + entity.HasOne(up => up.ApplicationUser) .WithOne(au => au.UserProfile) .HasForeignKey(up => up.ApplicationUserId); @@ -218,6 +221,6 @@ public class ApplicationDbContext : IdentityDbContext uppts.ProductTable) .WithMany(); }); - + } } \ No newline at end of file diff --git a/DrinkRateAPI/DbEntities/DbCompany.cs b/DrinkRateAPI/DbEntities/DbCompany.cs index fad6670..83862f5 100644 --- a/DrinkRateAPI/DbEntities/DbCompany.cs +++ b/DrinkRateAPI/DbEntities/DbCompany.cs @@ -1,6 +1,6 @@ namespace DrinkRateAPI.DbEntities; -public class DbCompany +public class DbCompany : DbEntityWithHistory { public Guid Id { get; set; } diff --git a/DrinkRateAPI/DbEntities/DbCompanyRating.cs b/DrinkRateAPI/DbEntities/DbCompanyRating.cs index 2d51cb8..3d6126d 100644 --- a/DrinkRateAPI/DbEntities/DbCompanyRating.cs +++ b/DrinkRateAPI/DbEntities/DbCompanyRating.cs @@ -1,6 +1,6 @@ namespace DrinkRateAPI.DbEntities; -public class DbCompanyRating +public class DbCompanyRating : DbEntityWithHistory { public Guid UserProfileId { get; set; } public DbUserProfile UserProfile { get; set; } diff --git a/DrinkRateAPI/DbEntities/DbCompanyTableView.cs b/DrinkRateAPI/DbEntities/DbCompanyTableView.cs index ad85b1c..8e63ed6 100644 --- a/DrinkRateAPI/DbEntities/DbCompanyTableView.cs +++ b/DrinkRateAPI/DbEntities/DbCompanyTableView.cs @@ -1,6 +1,6 @@ namespace DrinkRateAPI.DbEntities; -public class DbCompanyTableView +public class DbCompanyTableView : DbEntityWithHistory { public Guid Id { get; set; } diff --git a/DrinkRateAPI/DbEntities/DbEntityWithHistory.cs b/DrinkRateAPI/DbEntities/DbEntityWithHistory.cs new file mode 100644 index 0000000..c4ccdf8 --- /dev/null +++ b/DrinkRateAPI/DbEntities/DbEntityWithHistory.cs @@ -0,0 +1,6 @@ +namespace DrinkRateAPI.DbEntities; + +public abstract class DbEntityWithHistory +{ + public ICollection History { get; set; } +} \ No newline at end of file diff --git a/DrinkRateAPI/DbEntities/DbProduct.cs b/DrinkRateAPI/DbEntities/DbProduct.cs index 970b609..a48190b 100644 --- a/DrinkRateAPI/DbEntities/DbProduct.cs +++ b/DrinkRateAPI/DbEntities/DbProduct.cs @@ -1,6 +1,6 @@ namespace DrinkRateAPI.DbEntities; -public class DbProduct +public class DbProduct : DbEntityWithHistory { public Guid Id { get; set; } diff --git a/DrinkRateAPI/DbEntities/DbProductRating.cs b/DrinkRateAPI/DbEntities/DbProductRating.cs index 5b0162a..8e0a3ab 100644 --- a/DrinkRateAPI/DbEntities/DbProductRating.cs +++ b/DrinkRateAPI/DbEntities/DbProductRating.cs @@ -1,6 +1,6 @@ namespace DrinkRateAPI.DbEntities; -public class DbProductRating +public class DbProductRating : DbEntityWithHistory { public Guid UserProfileId { get; set; } public DbUserProfile UserProfile { get; set; } diff --git a/DrinkRateAPI/DbEntities/DbProductTableView.cs b/DrinkRateAPI/DbEntities/DbProductTableView.cs index 5a0bcf1..56d2740 100644 --- a/DrinkRateAPI/DbEntities/DbProductTableView.cs +++ b/DrinkRateAPI/DbEntities/DbProductTableView.cs @@ -1,6 +1,6 @@ namespace DrinkRateAPI.DbEntities; -public class DbProductTableView +public class DbProductTableView : DbEntityWithHistory { public Guid Id { get; set; } diff --git a/DrinkRateAPI/DbEntities/DbUpdateRecord.cs b/DrinkRateAPI/DbEntities/DbUpdateRecord.cs new file mode 100644 index 0000000..795d126 --- /dev/null +++ b/DrinkRateAPI/DbEntities/DbUpdateRecord.cs @@ -0,0 +1,18 @@ +namespace DrinkRateAPI.DbEntities; + +public class DbUpdateRecord +{ + public Guid Id { get; set; } + public Guid UserProfileId { get; set; } + public DbUserProfile UserProfile { get; set; } + public DateTime UpdateTime { get; set; } + public ICollection UpdateRecordFieldChanges { get; set; } +} + +public class DbUpdateRecordFieldChange +{ + public Guid Id { get; set; } + public string Field { get; set; } + public string OldValue { get; set; } + public string NewValue { get; set; } +} \ No newline at end of file diff --git a/DrinkRateAPI/DbEntities/DbUserProfile.cs b/DrinkRateAPI/DbEntities/DbUserProfile.cs index d53d20c..bde7fa5 100644 --- a/DrinkRateAPI/DbEntities/DbUserProfile.cs +++ b/DrinkRateAPI/DbEntities/DbUserProfile.cs @@ -1,8 +1,6 @@ -using Microsoft.AspNetCore.Identity; - namespace DrinkRateAPI.DbEntities; -public class DbUserProfile +public class DbUserProfile : DbEntityWithHistory { public Guid Id { get; set; } @@ -20,7 +18,7 @@ public class DbUserProfile public bool IsAdmin { get; set; } public bool IsDeleted { get; set; } - + public Guid ApplicationUserId { get; set; } public virtual DbApplicationUser ApplicationUser { get; set; } diff --git a/DrinkRateAPI/Migrations/20250809170131_ObjectHistory.Designer.cs b/DrinkRateAPI/Migrations/20250809170131_ObjectHistory.Designer.cs new file mode 100644 index 0000000..ac7be05 --- /dev/null +++ b/DrinkRateAPI/Migrations/20250809170131_ObjectHistory.Designer.cs @@ -0,0 +1,951 @@ +// +using System; +using DrinkRateAPI.Contexts; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DrinkRateAPI.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20250809170131_ObjectHistory")] + partial class ObjectHistory + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("DbCompanyTableDbCompanyTableView", b => + { + b.Property("CompanyTablesId") + .HasColumnType("uuid"); + + b.Property("DbCompanyTableViewId") + .HasColumnType("uuid"); + + b.HasKey("CompanyTablesId", "DbCompanyTableViewId"); + + b.HasIndex("DbCompanyTableViewId"); + + b.ToTable("DbCompanyTableDbCompanyTableView"); + }); + + modelBuilder.Entity("DbCompanyTableViewDbUserProfile", b => + { + b.Property("CompanyTableViewsId") + .HasColumnType("uuid"); + + b.Property("UserProfilesId") + .HasColumnType("uuid"); + + b.HasKey("CompanyTableViewsId", "UserProfilesId"); + + b.HasIndex("UserProfilesId"); + + b.ToTable("DbCompanyTableViewDbUserProfile"); + }); + + modelBuilder.Entity("DbProductTableDbProductTableView", b => + { + b.Property("DbProductTableViewId") + .HasColumnType("uuid"); + + b.Property("ProductTablesId") + .HasColumnType("uuid"); + + b.HasKey("DbProductTableViewId", "ProductTablesId"); + + b.HasIndex("ProductTablesId"); + + b.ToTable("DbProductTableDbProductTableView"); + }); + + modelBuilder.Entity("DbProductTableViewDbUserProfile", b => + { + b.Property("ProductTableViewsId") + .HasColumnType("uuid"); + + b.Property("UserProfilesId") + .HasColumnType("uuid"); + + b.HasKey("ProductTableViewsId", "UserProfilesId"); + + b.HasIndex("UserProfilesId"); + + b.ToTable("DbProductTableViewDbUserProfile"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompanyName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CompanyTableId") + .HasColumnType("uuid"); + + b.Property("RatingCount") + .HasColumnType("bigint"); + + b.Property("RatingSum") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("CompanyName") + .IsUnique(); + + b.HasIndex("CompanyTableId"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyRating", b => + { + b.Property("UserProfileId") + .HasColumnType("uuid"); + + b.Property("CompanyId") + .HasColumnType("uuid"); + + b.Property("Comment") + .HasColumnType("text"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("UserProfileId", "CompanyId"); + + b.HasIndex("CompanyId"); + + b.ToTable("CompanyRatings"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyTable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompanyTableName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CompanyTableName") + .IsUnique(); + + b.ToTable("CompanyTables"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyTableView", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("CompanyTableViews"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProduct", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompanyId") + .HasColumnType("uuid"); + + b.Property("ProductName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ProductTableId") + .HasColumnType("uuid"); + + b.Property("RatingCount") + .HasColumnType("bigint"); + + b.Property("RatingSum") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("ProductName") + .IsUnique(); + + b.HasIndex("ProductTableId"); + + b.ToTable("Product"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductRating", b => + { + b.Property("UserProfileId") + .HasColumnType("uuid"); + + b.Property("ProductId") + .HasColumnType("uuid"); + + b.Property("Comment") + .HasColumnType("text"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("UserProfileId", "ProductId"); + + b.HasIndex("ProductId"); + + b.ToTable("ProductRating"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductTable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ProductTableName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ProductTableName") + .IsUnique(); + + b.ToTable("ProductTable"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductTableView", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("ProductTableView"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DbCompanyId") + .HasColumnType("uuid"); + + b.Property("DbCompanyRatingCompanyId") + .HasColumnType("uuid"); + + b.Property("DbCompanyRatingUserProfileId") + .HasColumnType("uuid"); + + b.Property("DbCompanyTableViewId") + .HasColumnType("uuid"); + + b.Property("DbProductId") + .HasColumnType("uuid"); + + b.Property("DbProductRatingProductId") + .HasColumnType("uuid"); + + b.Property("DbProductRatingUserProfileId") + .HasColumnType("uuid"); + + b.Property("DbProductTableViewId") + .HasColumnType("uuid"); + + b.Property("UpdateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserProfileId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("DbCompanyId"); + + b.HasIndex("DbCompanyTableViewId"); + + b.HasIndex("DbProductId"); + + b.HasIndex("DbProductTableViewId"); + + b.HasIndex("UserProfileId"); + + b.HasIndex("DbCompanyRatingUserProfileId", "DbCompanyRatingCompanyId"); + + b.HasIndex("DbProductRatingUserProfileId", "DbProductRatingProductId"); + + b.ToTable("UpdateRecords"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecordFieldChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DbUpdateRecordId") + .HasColumnType("uuid"); + + b.Property("Field") + .IsRequired() + .HasColumnType("text"); + + b.Property("NewValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("OldValue") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("DbUpdateRecordId"); + + b.ToTable("UpdateRecordFieldChanges"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b.Property("IsAdmin") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId") + .IsUnique(); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("UserProfiles"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfileCompanyTableStat", b => + { + b.Property("UserProfileId") + .HasColumnType("uuid"); + + b.Property("CompanyTableId") + .HasColumnType("uuid"); + + b.Property("Credits") + .HasColumnType("integer"); + + b.Property("HighestRatingCount") + .HasColumnType("integer"); + + b.Property("RatingCount") + .HasColumnType("integer"); + + b.HasKey("UserProfileId", "CompanyTableId"); + + b.HasIndex("CompanyTableId"); + + b.ToTable("UserProfileCompanyTableStats"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfileProductTableStat", b => + { + b.Property("UserProfileId") + .HasColumnType("uuid"); + + b.Property("ProductTableId") + .HasColumnType("uuid"); + + b.Property("Credits") + .HasColumnType("integer"); + + b.Property("HighestRatingCount") + .HasColumnType("integer"); + + b.Property("RatingCount") + .HasColumnType("integer"); + + b.HasKey("UserProfileId", "ProductTableId"); + + b.HasIndex("ProductTableId"); + + b.ToTable("UserProfileProductTableStats"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("DbCompanyTableDbCompanyTableView", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyTable", null) + .WithMany() + .HasForeignKey("CompanyTablesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyTableView", null) + .WithMany() + .HasForeignKey("DbCompanyTableViewId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DbCompanyTableViewDbUserProfile", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyTableView", null) + .WithMany() + .HasForeignKey("CompanyTableViewsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", null) + .WithMany() + .HasForeignKey("UserProfilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DbProductTableDbProductTableView", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbProductTableView", null) + .WithMany() + .HasForeignKey("DbProductTableViewId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbProductTable", null) + .WithMany() + .HasForeignKey("ProductTablesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DbProductTableViewDbUserProfile", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbProductTableView", null) + .WithMany() + .HasForeignKey("ProductTableViewsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", null) + .WithMany() + .HasForeignKey("UserProfilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompany", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyTable", "CompanyTable") + .WithMany("Companies") + .HasForeignKey("CompanyTableId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyTable"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyRating", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompany", "Company") + .WithMany("CompanyRatings") + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", "UserProfile") + .WithMany("CompanyRatings") + .HasForeignKey("UserProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("UserProfile"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProduct", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompany", "Company") + .WithMany("Products") + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbProductTable", "ProductTable") + .WithMany("Products") + .HasForeignKey("ProductTableId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("ProductTable"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductRating", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbProduct", "Product") + .WithMany("ProductRatings") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", "UserProfile") + .WithMany("ProductRatings") + .HasForeignKey("UserProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("UserProfile"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecord", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompany", null) + .WithMany("History") + .HasForeignKey("DbCompanyId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyTableView", null) + .WithMany("History") + .HasForeignKey("DbCompanyTableViewId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbProduct", null) + .WithMany("History") + .HasForeignKey("DbProductId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbProductTableView", null) + .WithMany("History") + .HasForeignKey("DbProductTableViewId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", "UserProfile") + .WithMany("History") + .HasForeignKey("UserProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyRating", null) + .WithMany("History") + .HasForeignKey("DbCompanyRatingUserProfileId", "DbCompanyRatingCompanyId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbProductRating", null) + .WithMany("History") + .HasForeignKey("DbProductRatingUserProfileId", "DbProductRatingProductId"); + + b.Navigation("UserProfile"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecordFieldChange", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbUpdateRecord", null) + .WithMany("UpdateRecordFieldChanges") + .HasForeignKey("DbUpdateRecordId"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfile", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbApplicationUser", "ApplicationUser") + .WithOne("UserProfile") + .HasForeignKey("DrinkRateAPI.DbEntities.DbUserProfile", "ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfileCompanyTableStat", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyTable", "CompanyTable") + .WithMany() + .HasForeignKey("CompanyTableId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", "UserProfile") + .WithMany("UserProfileCompanyTableStats") + .HasForeignKey("UserProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyTable"); + + b.Navigation("UserProfile"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfileProductTableStat", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbProductTable", "ProductTable") + .WithMany() + .HasForeignKey("ProductTableId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", "UserProfile") + .WithMany("UserProfileProductTableStats") + .HasForeignKey("UserProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProductTable"); + + b.Navigation("UserProfile"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbApplicationUser", b => + { + b.Navigation("UserProfile") + .IsRequired(); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompany", b => + { + b.Navigation("CompanyRatings"); + + b.Navigation("History"); + + b.Navigation("Products"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyRating", b => + { + b.Navigation("History"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyTable", b => + { + b.Navigation("Companies"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyTableView", b => + { + b.Navigation("History"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProduct", b => + { + b.Navigation("History"); + + b.Navigation("ProductRatings"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductRating", b => + { + b.Navigation("History"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductTable", b => + { + b.Navigation("Products"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductTableView", b => + { + b.Navigation("History"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecord", b => + { + b.Navigation("UpdateRecordFieldChanges"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfile", b => + { + b.Navigation("CompanyRatings"); + + b.Navigation("History"); + + b.Navigation("ProductRatings"); + + b.Navigation("UserProfileCompanyTableStats"); + + b.Navigation("UserProfileProductTableStats"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DrinkRateAPI/Migrations/20250809170131_ObjectHistory.cs b/DrinkRateAPI/Migrations/20250809170131_ObjectHistory.cs new file mode 100644 index 0000000..07cd585 --- /dev/null +++ b/DrinkRateAPI/Migrations/20250809170131_ObjectHistory.cs @@ -0,0 +1,142 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DrinkRateAPI.Migrations +{ + /// + public partial class ObjectHistory : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "UpdateRecords", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + UserProfileId = table.Column(type: "uuid", nullable: false), + UpdateTime = table.Column(type: "timestamp with time zone", nullable: false), + DbCompanyId = table.Column(type: "uuid", nullable: true), + DbCompanyRatingCompanyId = table.Column(type: "uuid", nullable: true), + DbCompanyRatingUserProfileId = table.Column(type: "uuid", nullable: true), + DbCompanyTableViewId = table.Column(type: "uuid", nullable: true), + DbProductId = table.Column(type: "uuid", nullable: true), + DbProductRatingProductId = table.Column(type: "uuid", nullable: true), + DbProductRatingUserProfileId = table.Column(type: "uuid", nullable: true), + DbProductTableViewId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UpdateRecords", x => x.Id); + table.ForeignKey( + name: "FK_UpdateRecords_Companies_DbCompanyId", + column: x => x.DbCompanyId, + principalTable: "Companies", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_UpdateRecords_CompanyRatings_DbCompanyRatingUserProfileId_D~", + columns: x => new { x.DbCompanyRatingUserProfileId, x.DbCompanyRatingCompanyId }, + principalTable: "CompanyRatings", + principalColumns: new[] { "UserProfileId", "CompanyId" }); + table.ForeignKey( + name: "FK_UpdateRecords_CompanyTableViews_DbCompanyTableViewId", + column: x => x.DbCompanyTableViewId, + principalTable: "CompanyTableViews", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_UpdateRecords_ProductRating_DbProductRatingUserProfileId_Db~", + columns: x => new { x.DbProductRatingUserProfileId, x.DbProductRatingProductId }, + principalTable: "ProductRating", + principalColumns: new[] { "UserProfileId", "ProductId" }); + table.ForeignKey( + name: "FK_UpdateRecords_ProductTableView_DbProductTableViewId", + column: x => x.DbProductTableViewId, + principalTable: "ProductTableView", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_UpdateRecords_Product_DbProductId", + column: x => x.DbProductId, + principalTable: "Product", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_UpdateRecords_UserProfiles_UserProfileId", + column: x => x.UserProfileId, + principalTable: "UserProfiles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UpdateRecordFieldChanges", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Field = table.Column(type: "text", nullable: false), + OldValue = table.Column(type: "text", nullable: false), + NewValue = table.Column(type: "text", nullable: false), + DbUpdateRecordId = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UpdateRecordFieldChanges", x => x.Id); + table.ForeignKey( + name: "FK_UpdateRecordFieldChanges_UpdateRecords_DbUpdateRecordId", + column: x => x.DbUpdateRecordId, + principalTable: "UpdateRecords", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecordFieldChanges_DbUpdateRecordId", + table: "UpdateRecordFieldChanges", + column: "DbUpdateRecordId"); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecords_DbCompanyId", + table: "UpdateRecords", + column: "DbCompanyId"); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecords_DbCompanyRatingUserProfileId_DbCompanyRatingC~", + table: "UpdateRecords", + columns: new[] { "DbCompanyRatingUserProfileId", "DbCompanyRatingCompanyId" }); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecords_DbCompanyTableViewId", + table: "UpdateRecords", + column: "DbCompanyTableViewId"); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecords_DbProductId", + table: "UpdateRecords", + column: "DbProductId"); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecords_DbProductRatingUserProfileId_DbProductRatingP~", + table: "UpdateRecords", + columns: new[] { "DbProductRatingUserProfileId", "DbProductRatingProductId" }); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecords_DbProductTableViewId", + table: "UpdateRecords", + column: "DbProductTableViewId"); + + migrationBuilder.CreateIndex( + name: "IX_UpdateRecords_UserProfileId", + table: "UpdateRecords", + column: "UserProfileId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UpdateRecordFieldChanges"); + + migrationBuilder.DropTable( + name: "UpdateRecords"); + } + } +} diff --git a/DrinkRateAPI/Migrations/ApplicationDbContextModelSnapshot.cs b/DrinkRateAPI/Migrations/ApplicationDbContextModelSnapshot.cs index c25953b..67d58bf 100644 --- a/DrinkRateAPI/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/DrinkRateAPI/Migrations/ApplicationDbContextModelSnapshot.cs @@ -312,6 +312,89 @@ namespace DrinkRateAPI.Migrations b.ToTable("ProductTableView"); }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DbCompanyId") + .HasColumnType("uuid"); + + b.Property("DbCompanyRatingCompanyId") + .HasColumnType("uuid"); + + b.Property("DbCompanyRatingUserProfileId") + .HasColumnType("uuid"); + + b.Property("DbCompanyTableViewId") + .HasColumnType("uuid"); + + b.Property("DbProductId") + .HasColumnType("uuid"); + + b.Property("DbProductRatingProductId") + .HasColumnType("uuid"); + + b.Property("DbProductRatingUserProfileId") + .HasColumnType("uuid"); + + b.Property("DbProductTableViewId") + .HasColumnType("uuid"); + + b.Property("UpdateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserProfileId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("DbCompanyId"); + + b.HasIndex("DbCompanyTableViewId"); + + b.HasIndex("DbProductId"); + + b.HasIndex("DbProductTableViewId"); + + b.HasIndex("UserProfileId"); + + b.HasIndex("DbCompanyRatingUserProfileId", "DbCompanyRatingCompanyId"); + + b.HasIndex("DbProductRatingUserProfileId", "DbProductRatingProductId"); + + b.ToTable("UpdateRecords"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecordFieldChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DbUpdateRecordId") + .HasColumnType("uuid"); + + b.Property("Field") + .IsRequired() + .HasColumnType("text"); + + b.Property("NewValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("OldValue") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("DbUpdateRecordId"); + + b.ToTable("UpdateRecordFieldChanges"); + }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfile", b => { b.Property("Id") @@ -648,6 +731,48 @@ namespace DrinkRateAPI.Migrations b.Navigation("UserProfile"); }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecord", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbCompany", null) + .WithMany("History") + .HasForeignKey("DbCompanyId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyTableView", null) + .WithMany("History") + .HasForeignKey("DbCompanyTableViewId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbProduct", null) + .WithMany("History") + .HasForeignKey("DbProductId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbProductTableView", null) + .WithMany("History") + .HasForeignKey("DbProductTableViewId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbUserProfile", "UserProfile") + .WithMany("History") + .HasForeignKey("UserProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DrinkRateAPI.DbEntities.DbCompanyRating", null) + .WithMany("History") + .HasForeignKey("DbCompanyRatingUserProfileId", "DbCompanyRatingCompanyId"); + + b.HasOne("DrinkRateAPI.DbEntities.DbProductRating", null) + .WithMany("History") + .HasForeignKey("DbProductRatingUserProfileId", "DbProductRatingProductId"); + + b.Navigation("UserProfile"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecordFieldChange", b => + { + b.HasOne("DrinkRateAPI.DbEntities.DbUpdateRecord", null) + .WithMany("UpdateRecordFieldChanges") + .HasForeignKey("DbUpdateRecordId"); + }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfile", b => { b.HasOne("DrinkRateAPI.DbEntities.DbApplicationUser", "ApplicationUser") @@ -758,28 +883,59 @@ namespace DrinkRateAPI.Migrations { b.Navigation("CompanyRatings"); + b.Navigation("History"); + b.Navigation("Products"); }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyRating", b => + { + b.Navigation("History"); + }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyTable", b => { b.Navigation("Companies"); }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbCompanyTableView", b => + { + b.Navigation("History"); + }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProduct", b => { + b.Navigation("History"); + b.Navigation("ProductRatings"); }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductRating", b => + { + b.Navigation("History"); + }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductTable", b => { b.Navigation("Products"); }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbProductTableView", b => + { + b.Navigation("History"); + }); + + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUpdateRecord", b => + { + b.Navigation("UpdateRecordFieldChanges"); + }); + modelBuilder.Entity("DrinkRateAPI.DbEntities.DbUserProfile", b => { b.Navigation("CompanyRatings"); + b.Navigation("History"); + b.Navigation("ProductRatings"); b.Navigation("UserProfileCompanyTableStats");