diff --git a/CleanArchitecture.Application/viewmodels/Users/CreateUserViewModel.cs b/CleanArchitecture.Application/viewmodels/Users/CreateUserViewModel.cs index 2197419..2be45ca 100644 --- a/CleanArchitecture.Application/viewmodels/Users/CreateUserViewModel.cs +++ b/CleanArchitecture.Application/viewmodels/Users/CreateUserViewModel.cs @@ -1,7 +1,10 @@ +using System; + namespace CleanArchitecture.Application.ViewModels.Users; public sealed record CreateUserViewModel( string Email, string FirstName, string LastName, - string Password); \ No newline at end of file + string Password, + Guid TenantId); \ No newline at end of file diff --git a/CleanArchitecture.Domain/Entities/Tenant.cs b/CleanArchitecture.Domain/Entities/Tenant.cs index 897738c..555b095 100644 --- a/CleanArchitecture.Domain/Entities/Tenant.cs +++ b/CleanArchitecture.Domain/Entities/Tenant.cs @@ -7,8 +7,8 @@ public class Tenant : Entity { public string Name { get; private set; } - public ICollection Users { get; private set; } = new HashSet(); - + public virtual ICollection Users { get; private set; } = new HashSet(); + public Tenant( Guid id, string name) : base(id) diff --git a/CleanArchitecture.Domain/Entities/User.cs b/CleanArchitecture.Domain/Entities/User.cs index 916269c..5c50209 100644 --- a/CleanArchitecture.Domain/Entities/User.cs +++ b/CleanArchitecture.Domain/Entities/User.cs @@ -15,8 +15,8 @@ public class User : Entity public string FullName => $"{FirstName}, {LastName}"; public Guid TenantId { get; private set; } - public Tenant Tenant { get; private set; } = null!; - + public virtual Tenant Tenant { get; private set; } = null!; + public User( Guid id, Guid tenantId, diff --git a/CleanArchitecture.Infrastructure/Migrations/20230827171448_AddTenants.Designer.cs b/CleanArchitecture.Infrastructure/Migrations/20230827171448_AddTenants.Designer.cs new file mode 100644 index 0000000..dfb2c12 --- /dev/null +++ b/CleanArchitecture.Infrastructure/Migrations/20230827171448_AddTenants.Designer.cs @@ -0,0 +1,131 @@ +// +using System; +using CleanArchitecture.Infrastructure.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace CleanArchitecture.Infrastructure.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20230827171448_AddTenants")] + partial class AddTenants + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.10") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("CleanArchitecture.Domain.Entities.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Deleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.HasKey("Id"); + + b.ToTable("Tenants"); + + b.HasData( + new + { + Id = new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a"), + Deleted = false, + Name = "Admin Tenant" + }); + }); + + modelBuilder.Entity("CleanArchitecture.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Deleted") + .HasColumnType("bit"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("nvarchar(320)"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Role") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("Users"); + + b.HasData( + new + { + Id = new Guid("7e3892c0-9374-49fa-a3fd-53db637a40ae"), + Deleted = false, + Email = "admin@email.com", + FirstName = "Admin", + LastName = "User", + Password = "$2a$12$Blal/uiFIJdYsCLTMUik/egLbfg3XhbnxBC6Sb5IKz2ZYhiU/MzL2", + Role = 0, + TenantId = new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a") + }); + }); + + modelBuilder.Entity("CleanArchitecture.Domain.Entities.User", b => + { + b.HasOne("CleanArchitecture.Domain.Entities.Tenant", "Tenant") + .WithMany("Users") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("CleanArchitecture.Domain.Entities.Tenant", b => + { + b.Navigation("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/CleanArchitecture.Infrastructure/Migrations/20230827171448_AddTenants.cs b/CleanArchitecture.Infrastructure/Migrations/20230827171448_AddTenants.cs new file mode 100644 index 0000000..7af855e --- /dev/null +++ b/CleanArchitecture.Infrastructure/Migrations/20230827171448_AddTenants.cs @@ -0,0 +1,92 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace CleanArchitecture.Infrastructure.Migrations +{ + /// + public partial class AddTenants : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + table: "Users", + keyColumn: "Id", + keyValue: new Guid("28fc3d91-6a15-448e-b0b5-0c91a3948961")); + + migrationBuilder.AddColumn( + name: "TenantId", + table: "Users", + type: "uniqueidentifier", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); + + migrationBuilder.CreateTable( + name: "Tenants", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false), + Deleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Tenants", x => x.Id); + }); + + migrationBuilder.InsertData( + table: "Tenants", + columns: new[] { "Id", "Deleted", "Name" }, + values: new object[] { new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a"), false, "Admin Tenant" }); + + migrationBuilder.InsertData( + table: "Users", + columns: new[] { "Id", "Deleted", "Email", "FirstName", "LastName", "Password", "Role", "TenantId" }, + values: new object[] { new Guid("7e3892c0-9374-49fa-a3fd-53db637a40ae"), false, "admin@email.com", "Admin", "User", "$2a$12$Blal/uiFIJdYsCLTMUik/egLbfg3XhbnxBC6Sb5IKz2ZYhiU/MzL2", 0, new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a") }); + + migrationBuilder.CreateIndex( + name: "IX_Users_TenantId", + table: "Users", + column: "TenantId"); + + migrationBuilder.AddForeignKey( + name: "FK_Users_Tenants_TenantId", + table: "Users", + column: "TenantId", + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Users_Tenants_TenantId", + table: "Users"); + + migrationBuilder.DropTable( + name: "Tenants"); + + migrationBuilder.DropIndex( + name: "IX_Users_TenantId", + table: "Users"); + + migrationBuilder.DeleteData( + table: "Users", + keyColumn: "Id", + keyValue: new Guid("7e3892c0-9374-49fa-a3fd-53db637a40ae")); + + migrationBuilder.DropColumn( + name: "TenantId", + table: "Users"); + + migrationBuilder.InsertData( + table: "Users", + columns: new[] { "Id", "Deleted", "Email", "FirstName", "LastName", "Password", "Role" }, + values: new object[] { new Guid("28fc3d91-6a15-448e-b0b5-0c91a3948961"), false, "admin@email.com", "Admin", "User", "$2a$12$Blal/uiFIJdYsCLTMUik/egLbfg3XhbnxBC6Sb5IKz2ZYhiU/MzL2", 0 }); + } + } +} diff --git a/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs b/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs index 6a2eca6..2c15819 100644 --- a/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs @@ -17,7 +17,7 @@ namespace CleanArchitecture.Infrastructure.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("ProductVersion", "7.0.10") .HasAnnotation("Proxies:ChangeTracking", false) .HasAnnotation("Proxies:CheckEquality", false) .HasAnnotation("Proxies:LazyLoading", true) @@ -25,6 +25,33 @@ namespace CleanArchitecture.Infrastructure.Migrations SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + modelBuilder.Entity("CleanArchitecture.Domain.Entities.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Deleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.HasKey("Id"); + + b.ToTable("Tenants"); + + b.HasData( + new + { + Id = new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a"), + Deleted = false, + Name = "Admin Tenant" + }); + }); + modelBuilder.Entity("CleanArchitecture.Domain.Entities.User", b => { b.Property("Id") @@ -57,22 +84,44 @@ namespace CleanArchitecture.Infrastructure.Migrations b.Property("Role") .HasColumnType("int"); + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + b.HasKey("Id"); + b.HasIndex("TenantId"); + b.ToTable("Users"); b.HasData( new { - Id = new Guid("28fc3d91-6a15-448e-b0b5-0c91a3948961"), + Id = new Guid("7e3892c0-9374-49fa-a3fd-53db637a40ae"), Deleted = false, Email = "admin@email.com", FirstName = "Admin", LastName = "User", Password = "$2a$12$Blal/uiFIJdYsCLTMUik/egLbfg3XhbnxBC6Sb5IKz2ZYhiU/MzL2", - Role = 0 + Role = 0, + TenantId = new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a") }); }); + + modelBuilder.Entity("CleanArchitecture.Domain.Entities.User", b => + { + b.HasOne("CleanArchitecture.Domain.Entities.Tenant", "Tenant") + .WithMany("Users") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("CleanArchitecture.Domain.Entities.Tenant", b => + { + b.Navigation("Users"); + }); #pragma warning restore 612, 618 } }