diff --git a/.idea/.idea.Fin-Backend/.idea/data_source_mapping.xml b/.idea/.idea.Fin-Backend/.idea/data_source_mapping.xml deleted file mode 100644 index c970994..0000000 --- a/.idea/.idea.Fin-Backend/.idea/data_source_mapping.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Fin.Api/CardBrands/CardBrandController.cs b/Fin.Api/CardBrands/CardBrandController.cs new file mode 100644 index 0000000..3ae78bb --- /dev/null +++ b/Fin.Api/CardBrands/CardBrandController.cs @@ -0,0 +1,52 @@ +using Fin.Application.CardBrands; +using Fin.Domain.Global.Classes; +using Fin.Domain.CardBrands.Dtos; +using Fin.Infrastructure.Authentications.Constants; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Fin.Api.CardBrands; + +[Route("card-brand")] +[Authorize] +public class CardBrandController(ICardBrandService service): ControllerBase +{ + [HttpGet] + public async Task> GetList([FromQuery] PagedFilteredAndSortedInput input) + { + return await service.GetList(input); + } + + + [HttpGet("{id:guid}")] + [Authorize(Roles = AuthenticationRoles.Admin)] + public async Task> Get([FromRoute] Guid id) + { + var menu = await service.Get(id); + return menu != null ? Ok(menu) : NotFound(); + } + + [HttpPost] + [Authorize(Roles = AuthenticationRoles.Admin)] + public async Task> Create([FromBody] CardBrandInput input) + { + var menu = await service.Create(input, autoSave: true); + return menu != null ? Created($"card-brand/{menu.Id}", menu) : UnprocessableEntity(); + } + + [HttpPut("{id:guid}")] + [Authorize(Roles = AuthenticationRoles.Admin)] + public async Task Update([FromRoute] Guid id, [FromBody] CardBrandInput input) + { + var updated = await service.Update(id, input, autoSave: true); + return updated ? Ok() : UnprocessableEntity(); + } + + [HttpDelete("{id:guid}")] + [Authorize(Roles = AuthenticationRoles.Admin)] + public async Task Delete([FromRoute] Guid id) + { + var deleted = await service.Delete(id, autoSave: true); + return deleted ? Ok() : UnprocessableEntity(); + } +} \ No newline at end of file diff --git a/Fin.Application/CardBrands/CardBrandService.cs b/Fin.Application/CardBrands/CardBrandService.cs new file mode 100644 index 0000000..fdf84a6 --- /dev/null +++ b/Fin.Application/CardBrands/CardBrandService.cs @@ -0,0 +1,91 @@ +using Fin.Application.CardBrands; +using Fin.Domain.Global.Classes; +using Fin.Domain.CardBrands.Dtos; +using Fin.Domain.CardBrands.Entities; +using Fin.Infrastructure.AmbientDatas; +using Fin.Infrastructure.AutoServices.Interfaces; +using Fin.Infrastructure.Database.Extensions; +using Fin.Infrastructure.Database.Repositories; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; + +namespace Fin.Application.CardBrands; + +public interface ICardBrandService +{ + public Task Get(Guid id); + public Task> GetList(PagedFilteredAndSortedInput input); + public Task Create(CardBrandInput input, bool autoSave = false); + public Task Update(Guid id, CardBrandInput input, bool autoSave = false); + public Task Delete(Guid id, bool autoSave = false); + public Task> GetListForSideNav(); +} + +public class CardBrandService( + IRepository repository, + IAmbientData ambientData + ) : ICardBrandService, IAutoTransient +{ + public async Task Get(Guid id) + { + var entity = await repository.Query() + .FirstOrDefaultAsync(n => n.Id == id); + return entity != null ? new CardBrandOutput(entity) : null; + } + + public async Task> GetList(PagedFilteredAndSortedInput input) + { + return await repository.Query(false) + .OrderBy(m => m.Name) + .ApplyFilterAndSorter(input) + .Select(n => new CardBrandOutput(n)) + .ToPagedResult(input); + } + + public async Task> GetListForSideNav() + { + return await repository.Query(false) + .OrderBy(m => m.Name) + .Select(m => new CardBrandOutput(m)) + .ToListAsync(); + } + + public async Task Create(CardBrandInput input, bool autoSave = false) + { + ValidarInput(input); + var cardBrand = new CardBrand(input); + await repository.AddAsync(cardBrand, autoSave); + return new CardBrandOutput(cardBrand); + } + + public async Task Update(Guid id, CardBrandInput input, bool autoSave = false) + { + ValidarInput(input); + var cardBrand = await repository.Query() + .FirstOrDefaultAsync(u => u.Id == id); + if (cardBrand == null) return false; + + cardBrand.Update(input); + await repository.UpdateAsync(cardBrand, autoSave); + + return true; + } + + public async Task Delete(Guid id, bool autoSave = false) + { + var cardBrand = await repository.Query() + .FirstOrDefaultAsync(u => u.Id == id); + if (cardBrand == null) return false; + + await repository.DeleteAsync(cardBrand, autoSave); + return true; + } + + private static void ValidarInput(CardBrandInput input) + { + if (string.IsNullOrWhiteSpace(input.Name)) + throw new BadHttpRequestException("Name is required"); + if (string.IsNullOrWhiteSpace(input.Icon)) + throw new BadHttpRequestException("Icon is required"); + } +} \ No newline at end of file diff --git a/Fin.Domain/CardBrands/Dtos/CardBrandInput.cs b/Fin.Domain/CardBrands/Dtos/CardBrandInput.cs new file mode 100644 index 0000000..e0855e4 --- /dev/null +++ b/Fin.Domain/CardBrands/Dtos/CardBrandInput.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; +using Fin.Domain.Menus.Enums; + +namespace Fin.Domain.CardBrands.Dtos; + +public class CardBrandInput +{ + [Required] + public string Name { get; set; } + + [Required] + public string Icon { get; set; } + public string Color { get; set; } + +} \ No newline at end of file diff --git a/Fin.Domain/CardBrands/Dtos/CardBrandOutput.cs b/Fin.Domain/CardBrands/Dtos/CardBrandOutput.cs new file mode 100644 index 0000000..beb7243 --- /dev/null +++ b/Fin.Domain/CardBrands/Dtos/CardBrandOutput.cs @@ -0,0 +1,23 @@ + +using Fin.Domain.CardBrands.Entities; + +public class CardBrandOutput +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Icon { get; set; } + public string Color { get; set; } + + + public CardBrandOutput() + { + } + + public CardBrandOutput(CardBrand input) + { + Id = input.Id; + Name = input.Name; + Icon = input.Icon; + Color = input.Color; + } +} \ No newline at end of file diff --git a/Fin.Domain/CardBrands/Entities/CardBrand.cs b/Fin.Domain/CardBrands/Entities/CardBrand.cs new file mode 100644 index 0000000..64e951d --- /dev/null +++ b/Fin.Domain/CardBrands/Entities/CardBrand.cs @@ -0,0 +1,36 @@ +using Fin.Domain.CardBrands.Dtos; +using Fin.Domain.Global.Interfaces; + +namespace Fin.Domain.CardBrands.Entities; + +public class CardBrand: IAuditedEntity +{ + public string Name { get; set; } + public string Icon { get; set; } + public string Color { get; set; } + + public Guid Id { get; set; } + public Guid CreatedBy { get; set; } + public Guid UpdatedBy { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } + + public CardBrand() + { + } + + public CardBrand(CardBrandInput input) + { + Name = input.Name; + Icon = input.Icon; + Color = input.Color; + } + + public void Update(CardBrandInput input) + { + Name = input.Name; + Icon = input.Icon; + Color = input.Color; + + } +} diff --git a/Fin.Domain/Fin.Domain.csproj b/Fin.Domain/Fin.Domain.csproj index 7b8dbdc..6005f43 100644 --- a/Fin.Domain/Fin.Domain.csproj +++ b/Fin.Domain/Fin.Domain.csproj @@ -5,4 +5,8 @@ enable + + + + diff --git a/Fin.Infrastructure/Database/Configurations/CardBrands/CardBrandConfiguration.cs b/Fin.Infrastructure/Database/Configurations/CardBrands/CardBrandConfiguration.cs new file mode 100644 index 0000000..0735b7e --- /dev/null +++ b/Fin.Infrastructure/Database/Configurations/CardBrands/CardBrandConfiguration.cs @@ -0,0 +1,16 @@ +using Fin.Domain.CardBrands.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Fin.Infrastructure.Database.Configurations.CardBrands; + +public class CardBrandConfiguration: IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x => x.Id); + builder.Property(x => x.Name).HasMaxLength(100).IsRequired(); + builder.Property(x => x.Icon).HasMaxLength(20).IsRequired(); + builder.Property(x => x.Color).HasMaxLength(20); + } +} \ No newline at end of file diff --git a/Fin.Infrastructure/Database/FinDbContext.cs b/Fin.Infrastructure/Database/FinDbContext.cs index eb8edbf..9b268d0 100644 --- a/Fin.Infrastructure/Database/FinDbContext.cs +++ b/Fin.Infrastructure/Database/FinDbContext.cs @@ -1,4 +1,5 @@ using System.Reflection; +using Fin.Domain.CardBrands.Entities; using Fin.Domain.Global.Interfaces; using Fin.Domain.Menus.Entities; using Fin.Domain.Notifications; @@ -30,8 +31,8 @@ public class FinDbContext : DbContext public DbSet Menus { get; set; } + public DbSet CardBrands { get; set; } public DbSet TitleCategories { get; set; } - public DbSet Wallets { get; set; } private readonly IAmbientData _ambientData; diff --git a/Fin.Infrastructure/Migrations/20251011173326_adding_cardbrand.Designer.cs b/Fin.Infrastructure/Migrations/20251011173326_adding_cardbrand.Designer.cs new file mode 100644 index 0000000..07b3c2f --- /dev/null +++ b/Fin.Infrastructure/Migrations/20251011173326_adding_cardbrand.Designer.cs @@ -0,0 +1,723 @@ +// +using System; +using Fin.Infrastructure.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Fin.Infrastructure.Migrations +{ + [DbContext(typeof(FinDbContext))] + [Migration("20251011173326_adding_cardbrand")] + partial class adding_cardbrand + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("public") + .HasAnnotation("ProductVersion", "9.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Fin.Domain.CardBrands.Entities.CardBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("CardBrands", "public"); + }); + + modelBuilder.Entity("Fin.Domain.FinancialInstitutions.Entities.FinancialInstitution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .HasMaxLength(15) + .HasColumnType("character varying(15)"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Inactive") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .IsUnicode(true) + .HasColumnType("character varying(100)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("FinancialInstitution", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Menus.Entities.Menu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("FrontRoute") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("KeyWords") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OnlyForAdmin") + .HasColumnType("boolean"); + + b.Property("Position") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("Menus", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Continuous") + .HasColumnType("boolean"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("HtmlBody") + .HasColumnType("text"); + + b.Property("Link") + .HasColumnType("text"); + + b.Property("NormalizedTextBody") + .HasColumnType("text"); + + b.Property("NormalizedTitle") + .HasColumnType("text"); + + b.Property("Severity") + .HasColumnType("integer"); + + b.Property("StartToDelivery") + .HasColumnType("timestamp with time zone"); + + b.Property("StopToDelivery") + .HasColumnType("timestamp with time zone"); + + b.Property("TextBody") + .HasColumnType("text"); + + b.Property("Title") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.Property("Ways") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Notifications", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.NotificationUserDelivery", b => + { + b.Property("NotificationId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("BackgroundJobId") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Delivery") + .HasColumnType("boolean"); + + b.Property("Visualized") + .HasColumnType("boolean"); + + b.HasKey("NotificationId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserDeliveries", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.UserNotificationSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowedWays") + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("FirebaseTokens") + .HasColumnType("text"); + + b.Property("TenantId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationSettings", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.UserRememberUseSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("NotifyOn") + .HasColumnType("interval"); + + b.Property("TenantId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Ways") + .HasColumnType("text"); + + b.Property("WeekDays") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserRememberUseSettings", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Tenants.Entities.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Locale") + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Timezone") + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Tenants", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Tenants.Entities.TenantUser", b => + { + b.Property("TenantId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("TenantId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("TenantUsers", "public"); + }); + + modelBuilder.Entity("Fin.Domain.TitleCategories.Entities.TitleCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Inactivated") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("TenantId") + .HasColumnType("uuid"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("Name", "TenantId") + .IsUnique(); + + b.ToTable("TitleCategories", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Users.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BirthDate") + .HasColumnType("date"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayName") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("FirstName") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Gender") + .HasColumnType("integer"); + + b.Property("ImagePublicUrl") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsActivity") + .HasColumnType("boolean"); + + b.Property("IsAdmin") + .HasColumnType("boolean"); + + b.Property("LastName") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Users", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Users.Entities.UserCredential", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("EncryptedEmail") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("EncryptedPassword") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("FailLoginAttempts") + .HasColumnType("integer"); + + b.Property("GoogleId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("ResetToken") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("EncryptedEmail") + .IsUnique(); + + b.HasIndex("GoogleId") + .IsUnique(); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Credentials", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Users.Entities.UserDeleteRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Aborted") + .HasColumnType("boolean"); + + b.Property("AbortedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("DeleteEffectivatedAt") + .HasColumnType("date"); + + b.Property("DeleteRequestedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.Property("UserAbortedId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserAbortedId"); + + b.HasIndex("UserId"); + + b.ToTable("UserDeleteRequests", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Wallets.Entities.Wallet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CurrentBalance") + .HasColumnType("numeric"); + + b.Property("FinancialInstitutionId") + .HasColumnType("uuid"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Inactivated") + .HasColumnType("boolean"); + + b.Property("InitialBalance") + .HasPrecision(19, 4) + .HasColumnType("numeric(19,4)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("TenantId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("FinancialInstitutionId"); + + b.HasIndex("Name", "TenantId") + .IsUnique(); + + b.ToTable("Wallets", "public"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.NotificationUserDelivery", b => + { + b.HasOne("Fin.Domain.Notifications.Entities.Notification", "Notification") + .WithMany("UserDeliveries") + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Fin.Domain.Users.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.UserNotificationSettings", b => + { + b.HasOne("Fin.Domain.Users.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.UserRememberUseSetting", b => + { + b.HasOne("Fin.Domain.Users.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Fin.Domain.Tenants.Entities.TenantUser", b => + { + b.HasOne("Fin.Domain.Tenants.Entities.Tenant", null) + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Fin.Domain.Users.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Fin.Domain.Users.Entities.UserCredential", b => + { + b.HasOne("Fin.Domain.Users.Entities.User", "User") + .WithOne("Credential") + .HasForeignKey("Fin.Domain.Users.Entities.UserCredential", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Fin.Domain.Users.Entities.UserDeleteRequest", b => + { + b.HasOne("Fin.Domain.Users.Entities.User", "UserAborted") + .WithMany() + .HasForeignKey("UserAbortedId"); + + b.HasOne("Fin.Domain.Users.Entities.User", "User") + .WithMany("DeleteRequests") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("UserAborted"); + }); + + modelBuilder.Entity("Fin.Domain.Wallets.Entities.Wallet", b => + { + b.HasOne("Fin.Domain.FinancialInstitutions.Entities.FinancialInstitution", "FinancialInstitution") + .WithMany("Wallets") + .HasForeignKey("FinancialInstitutionId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("FinancialInstitution"); + }); + + modelBuilder.Entity("Fin.Domain.FinancialInstitutions.Entities.FinancialInstitution", b => + { + b.Navigation("Wallets"); + }); + + modelBuilder.Entity("Fin.Domain.Notifications.Entities.Notification", b => + { + b.Navigation("UserDeliveries"); + }); + + modelBuilder.Entity("Fin.Domain.Users.Entities.User", b => + { + b.Navigation("Credential"); + + b.Navigation("DeleteRequests"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Fin.Infrastructure/Migrations/20251011173326_adding_cardbrand.cs b/Fin.Infrastructure/Migrations/20251011173326_adding_cardbrand.cs new file mode 100644 index 0000000..c68881d --- /dev/null +++ b/Fin.Infrastructure/Migrations/20251011173326_adding_cardbrand.cs @@ -0,0 +1,42 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Fin.Infrastructure.Migrations +{ + /// + public partial class adding_cardbrand : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CardBrands", + schema: "public", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + Icon = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), + Color = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), + CreatedBy = table.Column(type: "uuid", nullable: false), + UpdatedBy = table.Column(type: "uuid", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CardBrands", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CardBrands", + schema: "public"); + } + } +} diff --git a/Fin.Infrastructure/Migrations/FinDbContextModelSnapshot.cs b/Fin.Infrastructure/Migrations/FinDbContextModelSnapshot.cs index e121eb3..7c5b1ef 100644 --- a/Fin.Infrastructure/Migrations/FinDbContextModelSnapshot.cs +++ b/Fin.Infrastructure/Migrations/FinDbContextModelSnapshot.cs @@ -23,6 +23,43 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("Fin.Domain.CardBrands.Entities.CardBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedBy") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("CardBrands", "public"); + }); + modelBuilder.Entity("Fin.Domain.FinancialInstitutions.Entities.FinancialInstitution", b => { b.Property("Id")