From 73269bd42a5a2950b1309e1671dd204c02582838 Mon Sep 17 00:00:00 2001 From: lumijiez <59575049+lumijiez@users.noreply.github.com> Date: Tue, 27 May 2025 12:28:12 +0300 Subject: [PATCH] Repositories + some models --- .../Common/Models/PagedResult.cs | 12 + .../Common/Models/ProductFilterParameters.cs | 15 + src/Printbase.Domain/Entities/EntityBase.cs | 4 +- src/Printbase.Domain/Entities/Orders/Order.cs | 12 +- .../Entities/Orders/OrderAddress.cs | 12 +- .../Entities/Orders/OrderItem.cs | 10 +- .../Entities/Orders/OrderStatus.cs | 2 +- .../Entities/Orders/ShippingStatus.cs | 2 +- .../Entities/Product/Category.cs | 8 +- .../Entities/Product/Product.cs | 14 +- .../Entities/Product/ProductVariant.cs | 14 +- .../Entities/Users/Address.cs | 18 +- .../Entities/Users/ApplicationRole.cs | 10 +- .../Entities/Users/ApplicationUser.cs | 6 +- src/Printbase.Domain/Printbase.Domain.csproj | 1 + .../Repositories/ICategoryRepository.cs | 20 + .../Repositories/IProductRepository.cs | 20 + .../Repositories/IProductVariantRepository.cs | 19 + .../Products/ProductVariantConfiguration.cs | 4 +- .../Database/ApplicationDbContext.cs | 2 + .../20250526100748_InitialSetup.Designer.cs | 1150 ----------------- .../Migrations/20250526100748_InitialSetup.cs | 777 ----------- .../ApplicationDbContextModelSnapshot.cs | 1147 ---------------- .../Printbase.Infrastructure.csproj | 4 + .../Repositories/CategoryRepository.cs | 111 ++ .../Repositories/ProductRepository.cs | 155 +++ 26 files changed, 416 insertions(+), 3133 deletions(-) create mode 100644 src/Printbase.Domain/Common/Models/PagedResult.cs create mode 100644 src/Printbase.Domain/Common/Models/ProductFilterParameters.cs create mode 100644 src/Printbase.Domain/Repositories/ICategoryRepository.cs create mode 100644 src/Printbase.Domain/Repositories/IProductRepository.cs create mode 100644 src/Printbase.Domain/Repositories/IProductVariantRepository.cs delete mode 100644 src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.Designer.cs delete mode 100644 src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.cs delete mode 100644 src/Printbase.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs create mode 100644 src/Printbase.Infrastructure/Repositories/CategoryRepository.cs create mode 100644 src/Printbase.Infrastructure/Repositories/ProductRepository.cs diff --git a/src/Printbase.Domain/Common/Models/PagedResult.cs b/src/Printbase.Domain/Common/Models/PagedResult.cs new file mode 100644 index 0000000..33eed62 --- /dev/null +++ b/src/Printbase.Domain/Common/Models/PagedResult.cs @@ -0,0 +1,12 @@ +namespace Printbase.Domain.Common.Models; + +public class PagedResult +{ + public IEnumerable Items { get; set; } = new List(); + public int TotalCount { get; set; } + public int PageNumber { get; set; } + public int PageSize { get; set; } + public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize); + public bool HasPreviousPage => PageNumber > 1; + public bool HasNextPage => PageNumber < TotalPages; +} \ No newline at end of file diff --git a/src/Printbase.Domain/Common/Models/ProductFilterParameters.cs b/src/Printbase.Domain/Common/Models/ProductFilterParameters.cs new file mode 100644 index 0000000..d9cac2b --- /dev/null +++ b/src/Printbase.Domain/Common/Models/ProductFilterParameters.cs @@ -0,0 +1,15 @@ +namespace Printbase.Domain.Common.Models; + +public class ProductFilterParameters +{ + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 10; + public string? SearchTerm { get; set; } + public Guid? CategoryId { get; set; } + public decimal? MinPrice { get; set; } + public decimal? MaxPrice { get; set; } + public bool? IsActive { get; set; } = true; + public bool? IsCustomizable { get; set; } + public string SortBy { get; set; } = "Name"; + public string SortDirection { get; set; } = "ASC"; +} \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/EntityBase.cs b/src/Printbase.Domain/Entities/EntityBase.cs index 6da79c0..bcaf92c 100644 --- a/src/Printbase.Domain/Entities/EntityBase.cs +++ b/src/Printbase.Domain/Entities/EntityBase.cs @@ -5,6 +5,6 @@ public abstract class EntityBase public Guid Id { get; set; } public DateTime CreatedAt { get; set; } public DateTime ModifiedAt { get; set; } - public string CreatedBy { get; set; } - public string ModifiedBy { get; set; } + public string? CreatedBy { get; set; } + public string? ModifiedBy { get; set; } } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Orders/Order.cs b/src/Printbase.Domain/Entities/Orders/Order.cs index b78be59..59d6b7c 100644 --- a/src/Printbase.Domain/Entities/Orders/Order.cs +++ b/src/Printbase.Domain/Entities/Orders/Order.cs @@ -2,16 +2,16 @@ namespace Printbase.Domain.Entities.Orders; public class Order : EntityBase { - public string UserId { get; set; } + public string UserId { get; set; } = null!; public DateTime OrderDate { get; set; } public decimal TotalPrice { get; set; } public int OrderStatusId { get; set; } public int ShippingStatusId { get; set; } - public string OrderNumber { get; set; } - public string Notes { get; set; } + public string OrderNumber { get; set; } = null!; + public string Notes { get; set; } = null!; - public virtual OrderStatus OrderStatus { get; set; } - public virtual ShippingStatus ShippingStatus { get; set; } - public virtual OrderAddress OrderAddress { get; set; } + public OrderStatus OrderStatus { get; set; } = null!; + public ShippingStatus ShippingStatus { get; set; } = null!; + public OrderAddress OrderAddress { get; set; } = null!; public virtual ICollection OrderItems { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Orders/OrderAddress.cs b/src/Printbase.Domain/Entities/Orders/OrderAddress.cs index ef873d2..41d2047 100644 --- a/src/Printbase.Domain/Entities/Orders/OrderAddress.cs +++ b/src/Printbase.Domain/Entities/Orders/OrderAddress.cs @@ -3,11 +3,11 @@ namespace Printbase.Domain.Entities.Orders; public class OrderAddress : EntityBase { public Guid OrderId { get; set; } - public string Street { get; set; } - public string City { get; set; } - public string State { get; set; } - public string PostalCode { get; set; } - public string Country { get; set; } + public required string Street { get; set; } + public required string City { get; set; } + public required string State { get; set; } + public required string PostalCode { get; set; } + public required string Country { get; set; } - public virtual Order Order { get; set; } + public virtual required Order Order { get; set; } } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Orders/OrderItem.cs b/src/Printbase.Domain/Entities/Orders/OrderItem.cs index 8c5db9d..1ecd67b 100644 --- a/src/Printbase.Domain/Entities/Orders/OrderItem.cs +++ b/src/Printbase.Domain/Entities/Orders/OrderItem.cs @@ -10,10 +10,10 @@ public class OrderItem : EntityBase public int Quantity { get; set; } public decimal UnitPrice { get; set; } public decimal TotalPrice { get; set; } - public string CustomizationImageUrl { get; set; } = default!; - public string CustomizationDescription { get; set; } = default!; + public string CustomizationImageUrl { get; set; } = null!; + public string CustomizationDescription { get; set; } = null!; - public virtual Order Order { get; set; } = default!; - public virtual Product.Product Product { get; set; } = default!; - public virtual ProductVariant ProductVariant { get; set; } = default!; + public Order Order { get; set; } = null!; + public Product.Product Product { get; set; } = null!; + public ProductVariant ProductVariant { get; set; } = null!; } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Orders/OrderStatus.cs b/src/Printbase.Domain/Entities/Orders/OrderStatus.cs index 5fadb33..4af946e 100644 --- a/src/Printbase.Domain/Entities/Orders/OrderStatus.cs +++ b/src/Printbase.Domain/Entities/Orders/OrderStatus.cs @@ -3,7 +3,7 @@ namespace Printbase.Domain.Entities.Orders; public class OrderStatus { public int Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } = null!; public virtual ICollection Orders { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Orders/ShippingStatus.cs b/src/Printbase.Domain/Entities/Orders/ShippingStatus.cs index d94c61a..18b4444 100644 --- a/src/Printbase.Domain/Entities/Orders/ShippingStatus.cs +++ b/src/Printbase.Domain/Entities/Orders/ShippingStatus.cs @@ -3,7 +3,7 @@ namespace Printbase.Domain.Entities.Orders; public class ShippingStatus { public int Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } = null!; public virtual ICollection Orders { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Product/Category.cs b/src/Printbase.Domain/Entities/Product/Category.cs index c0019f8..90493d8 100644 --- a/src/Printbase.Domain/Entities/Product/Category.cs +++ b/src/Printbase.Domain/Entities/Product/Category.cs @@ -2,14 +2,14 @@ namespace Printbase.Domain.Entities.Product; public class Category : EntityBase { - public string Name { get; set; } - public string Description { get; set; } - public string ImageUrl { get; set; } + public string Name { get; set; } = null!; + public string Description { get; set; } = null!; + public string? ImageUrl { get; set; } public int SortOrder { get; set; } public bool IsActive { get; set; } public Guid? ParentCategoryId { get; set; } - public virtual Category ParentCategory { get; set; } + public virtual Category? ParentCategory { get; set; } public virtual ICollection SubCategories { get; set; } = new List(); public virtual ICollection Products { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Product/Product.cs b/src/Printbase.Domain/Entities/Product/Product.cs index 11caaaa..1031ad0 100644 --- a/src/Printbase.Domain/Entities/Product/Product.cs +++ b/src/Printbase.Domain/Entities/Product/Product.cs @@ -4,15 +4,15 @@ namespace Printbase.Domain.Entities.Product; public class Product : EntityBase { - public string Name { get; set; } - public string Description { get; set; } - public decimal BasePrice { get; set; } - public bool IsCustomizable { get; set; } - public bool IsActive { get; set; } - public string ImageUrl { get; set; } + public required string Name { get; set; } + public string? Description { get; set; } + public required decimal BasePrice { get; set; } + public required bool IsCustomizable { get; set; } + public required bool IsActive { get; set; } + public string? ImageUrl { get; set; } public Guid? CategoryId { get; set; } - public virtual Category Category { get; set; } + public virtual required Category Category { get; set; } public virtual ICollection ProductVariants { get; set; } = new List(); public virtual ICollection OrderItems { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Product/ProductVariant.cs b/src/Printbase.Domain/Entities/Product/ProductVariant.cs index 38e52c2..aeeda8a 100644 --- a/src/Printbase.Domain/Entities/Product/ProductVariant.cs +++ b/src/Printbase.Domain/Entities/Product/ProductVariant.cs @@ -4,15 +4,15 @@ namespace Printbase.Domain.Entities.Product; public class ProductVariant : EntityBase { - public Guid ProductId { get; set; } - public string Size { get; set; } - public string Color { get; set; } - public decimal Price { get; set; } - public string ImageUrl { get; set; } - public string SKU { get; set; } + public required Guid ProductId { get; set; } + public required string Size { get; set; } + public string? Color { get; set; } + public required decimal Price { get; set; } + public string? ImageUrl { get; set; } + public required string Sku { get; set; } public int StockQuantity { get; set; } public bool IsActive { get; set; } - public virtual Product Product { get; set; } + public virtual required Product Product { get; set; } public virtual ICollection OrderItems { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Users/Address.cs b/src/Printbase.Domain/Entities/Users/Address.cs index 67ae370..436d9cb 100644 --- a/src/Printbase.Domain/Entities/Users/Address.cs +++ b/src/Printbase.Domain/Entities/Users/Address.cs @@ -2,13 +2,13 @@ namespace Printbase.Domain.Entities.Users; public class Address : EntityBase { - public string UserId { get; set; } - public string AddressType { get; set; } - public string Street { get; set; } - public string City { get; set; } - public string State { get; set; } - public string PostalCode { get; set; } - public string Country { get; set; } - public bool IsDefault { get; set; } - public bool IsActive { get; set; } + public required string UserId { get; set; } + public required string AddressType { get; set; } + public required string Street { get; set; } + public required string City { get; set; } + public required string State { get; set; } + public required string PostalCode { get; set; } + public required string Country { get; set; } + public required bool IsDefault { get; set; } + public required bool IsActive { get; set; } } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Users/ApplicationRole.cs b/src/Printbase.Domain/Entities/Users/ApplicationRole.cs index 9cb1efb..8049ebe 100644 --- a/src/Printbase.Domain/Entities/Users/ApplicationRole.cs +++ b/src/Printbase.Domain/Entities/Users/ApplicationRole.cs @@ -4,15 +4,13 @@ namespace Printbase.Domain.Entities.Users; public class ApplicationRole : IdentityRole { - public string Description { get; set; } + public string Description { get; set; } = null!; public DateTime CreatedAt { get; set; } public bool IsActive { get; set; } - public ApplicationRole() : base() - { - } + public ApplicationRole() + {} public ApplicationRole(string roleName) : base(roleName) - { - } + {} } \ No newline at end of file diff --git a/src/Printbase.Domain/Entities/Users/ApplicationUser.cs b/src/Printbase.Domain/Entities/Users/ApplicationUser.cs index 2449c82..0890bf0 100644 --- a/src/Printbase.Domain/Entities/Users/ApplicationUser.cs +++ b/src/Printbase.Domain/Entities/Users/ApplicationUser.cs @@ -5,13 +5,13 @@ namespace Printbase.Domain.Entities.Users; public sealed class ApplicationUser : IdentityUser { - public string FirstName { get; set; } - public string LastName { get; set; } + public required string FirstName { get; set; } + public required string LastName { get; set; } public DateTime? DateOfBirth { get; set; } public DateTime CreatedAt { get; set; } public DateTime LastLoginAt { get; set; } public bool IsActive { get; set; } - public string ProfileImageUrl { get; set; } + public string? ProfileImageUrl { get; set; } public ICollection
Addresses { get; set; } = new List
(); public ICollection Orders { get; set; } = new List(); diff --git a/src/Printbase.Domain/Printbase.Domain.csproj b/src/Printbase.Domain/Printbase.Domain.csproj index 17f66ee..da1134f 100644 --- a/src/Printbase.Domain/Printbase.Domain.csproj +++ b/src/Printbase.Domain/Printbase.Domain.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Printbase.Domain/Repositories/ICategoryRepository.cs b/src/Printbase.Domain/Repositories/ICategoryRepository.cs new file mode 100644 index 0000000..b71995f --- /dev/null +++ b/src/Printbase.Domain/Repositories/ICategoryRepository.cs @@ -0,0 +1,20 @@ +using Printbase.Domain.Entities.Product; + +namespace Printbase.Domain.Repositories; + +public interface ICategoryRepository +{ + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + Task GetByIdWithSubCategoriesAsync(Guid id, CancellationToken cancellationToken = default); + Task GetByIdWithProductsAsync(Guid id, CancellationToken cancellationToken = default); + Task> GetAllAsync(CancellationToken cancellationToken = default); + Task> GetActiveAsync(CancellationToken cancellationToken = default); + Task> GetRootCategoriesAsync(CancellationToken cancellationToken = default); + Task> GetSubCategoriesAsync(Guid parentCategoryId, CancellationToken cancellationToken = default); + Task AddAsync(Category category, CancellationToken cancellationToken = default); + Task UpdateAsync(Category category, CancellationToken cancellationToken = default); + Task DeleteAsync(Guid id, CancellationToken cancellationToken = default); + Task ExistsAsync(Guid id, CancellationToken cancellationToken = default); + Task HasSubCategoriesAsync(Guid categoryId, CancellationToken cancellationToken = default); + Task HasProductsAsync(Guid categoryId, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/Printbase.Domain/Repositories/IProductRepository.cs b/src/Printbase.Domain/Repositories/IProductRepository.cs new file mode 100644 index 0000000..4a51b85 --- /dev/null +++ b/src/Printbase.Domain/Repositories/IProductRepository.cs @@ -0,0 +1,20 @@ +using Printbase.Domain.Common; +using Printbase.Domain.Common.Models; +using Printbase.Domain.Entities.Product; + +namespace Printbase.Domain.Repositories; + +public interface IProductRepository +{ + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + Task GetByIdWithVariantsAsync(Guid id, CancellationToken cancellationToken = default); + Task GetByIdWithCategoryAsync(Guid id, CancellationToken cancellationToken = default); + Task GetByIdFullAsync(Guid id, CancellationToken cancellationToken = default); + Task> GetPagedAsync(ProductFilterParameters filterParameters, CancellationToken cancellationToken = default); + Task> GetByCategoryAsync(Guid categoryId, CancellationToken cancellationToken = default); + Task> GetCustomizableAsync(CancellationToken cancellationToken = default); + Task AddAsync(Product product, CancellationToken cancellationToken = default); + Task UpdateAsync(Product product, CancellationToken cancellationToken = default); + Task DeleteAsync(Guid id, CancellationToken cancellationToken = default); + Task ExistsAsync(Guid id, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/Printbase.Domain/Repositories/IProductVariantRepository.cs b/src/Printbase.Domain/Repositories/IProductVariantRepository.cs new file mode 100644 index 0000000..20592d9 --- /dev/null +++ b/src/Printbase.Domain/Repositories/IProductVariantRepository.cs @@ -0,0 +1,19 @@ +using Printbase.Domain.Entities.Product; + +namespace Printbase.Domain.Repositories; + +public interface IProductVariantRepository +{ + Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default); + Task GetByIdWithProductAsync(Guid id, CancellationToken cancellationToken = default); + Task GetBySkuAsync(string sku, CancellationToken cancellationToken = default); + Task> GetByProductIdAsync(Guid productId, CancellationToken cancellationToken = default); + Task> GetActiveByProductIdAsync(Guid productId, CancellationToken cancellationToken = default); + Task> GetInStockByProductIdAsync(Guid productId, CancellationToken cancellationToken = default); + Task AddAsync(ProductVariant productVariant, CancellationToken cancellationToken = default); + Task UpdateAsync(ProductVariant productVariant, CancellationToken cancellationToken = default); + Task DeleteAsync(Guid id, CancellationToken cancellationToken = default); + Task ExistsAsync(Guid id, CancellationToken cancellationToken = default); + Task SkuExistsAsync(string sku, Guid? excludeId = null, CancellationToken cancellationToken = default); + Task UpdateStockQuantityAsync(Guid id, int quantity, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/Printbase.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs b/src/Printbase.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs index 2d764d8..a9ecc46 100644 --- a/src/Printbase.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs +++ b/src/Printbase.Infrastructure/Configuration/Products/ProductVariantConfiguration.cs @@ -26,7 +26,7 @@ public class ProductVariantConfiguration : EntityBaseConfiguration pv.ImageUrl) .HasMaxLength(500); - builder.Property(pv => pv.SKU) + builder.Property(pv => pv.Sku) .IsRequired() .HasMaxLength(100); @@ -46,7 +46,7 @@ public class ProductVariantConfiguration : EntityBaseConfiguration pv.ProductId) .HasDatabaseName("IX_ProductVariant_ProductId"); - builder.HasIndex(pv => pv.SKU) + builder.HasIndex(pv => pv.Sku) .IsUnique() .HasDatabaseName("IX_ProductVariant_SKU"); diff --git a/src/Printbase.Infrastructure/Database/ApplicationDbContext.cs b/src/Printbase.Infrastructure/Database/ApplicationDbContext.cs index 3175bf5..c1a02ad 100644 --- a/src/Printbase.Infrastructure/Database/ApplicationDbContext.cs +++ b/src/Printbase.Infrastructure/Database/ApplicationDbContext.cs @@ -22,6 +22,7 @@ public class ApplicationDbContext(DbContextOptions options public DbSet
Addresses { get; set; } public DbSet OrderStatuses { get; set; } public DbSet ShippingStatuses { get; set; } + public DbSet Categories { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -38,5 +39,6 @@ public class ApplicationDbContext(DbContextOptions options modelBuilder.ApplyConfiguration(new AddressConfiguration()); modelBuilder.ApplyConfiguration(new OrderStatusConfiguration()); modelBuilder.ApplyConfiguration(new ShippingStatusConfiguration()); + modelBuilder.ApplyConfiguration(new CategoryConfiguration()); } } \ No newline at end of file diff --git a/src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.Designer.cs b/src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.Designer.cs deleted file mode 100644 index 632d4c0..0000000 --- a/src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.Designer.cs +++ /dev/null @@ -1,1150 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Printbase.Infrastructure.Database; - -#nullable disable - -namespace Printbase.Infrastructure.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20250526100748_InitialSetup")] - partial class InitialSetup - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.5") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ApplicationRole", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("IsActive") - .HasDatabaseName("IX_ApplicationRole_IsActive"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - - b.HasData( - new - { - Id = "1", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Full system access", - IsActive = true, - Name = "Administrator", - NormalizedName = "ADMINISTRATOR" - }, - new - { - Id = "2", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Standard customer access", - IsActive = true, - Name = "Customer", - NormalizedName = "CUSTOMER" - }, - new - { - Id = "3", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Manage orders and fulfillment", - IsActive = true, - Name = "OrderManager", - NormalizedName = "ORDERMANAGER" - }, - new - { - Id = "4", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Manage products and inventory", - IsActive = true, - Name = "ProductManager", - NormalizedName = "PRODUCTMANAGER" - }); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("RoleId") - .HasColumnType("nvarchar(450)"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("AddressType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("City") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Country") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("IsDefault") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("PostalCode") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("State") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Street") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("UserId") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_Address_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_Address_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_Address_ModifiedAt"); - - b.HasIndex("UserId") - .HasDatabaseName("IX_Address_UserId"); - - b.HasIndex("UserId", "AddressType") - .HasDatabaseName("IX_Address_User_Type"); - - b.HasIndex("UserId", "IsDefault") - .HasDatabaseName("IX_Address_User_Default"); - - b.ToTable("Addresses"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Category", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Description") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ImageUrl") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("IsActive") - .HasColumnType("bit"); - - b.Property("ModifiedAt") - .HasColumnType("datetime2"); - - b.Property("ModifiedBy") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ParentCategoryId") - .HasColumnType("uniqueidentifier"); - - b.Property("SortOrder") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("ParentCategoryId"); - - b.ToTable("Category"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Notes") - .IsRequired() - .HasMaxLength(1000) - .HasColumnType("nvarchar(1000)"); - - b.Property("OrderDate") - .HasColumnType("datetime2"); - - b.Property("OrderNumber") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("OrderStatusId") - .HasColumnType("int"); - - b.Property("ShippingStatusId") - .HasColumnType("int"); - - b.Property("TotalPrice") - .HasColumnType("decimal(18,2)"); - - b.Property("UserId") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_Order_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_Order_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_Order_ModifiedAt"); - - b.HasIndex("OrderDate") - .HasDatabaseName("IX_Order_OrderDate"); - - b.HasIndex("OrderNumber") - .IsUnique() - .HasDatabaseName("IX_Order_OrderNumber"); - - b.HasIndex("OrderStatusId") - .HasDatabaseName("IX_Order_OrderStatusId"); - - b.HasIndex("ShippingStatusId") - .HasDatabaseName("IX_Order_ShippingStatusId"); - - b.HasIndex("UserId") - .HasDatabaseName("IX_Order_UserId"); - - b.HasIndex("UserId", "OrderDate") - .HasDatabaseName("IX_Order_User_Date"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderAddress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("City") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Country") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("OrderId") - .HasColumnType("uniqueidentifier"); - - b.Property("PostalCode") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("State") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Street") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_OrderAddress_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_OrderAddress_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_OrderAddress_ModifiedAt"); - - b.HasIndex("OrderId") - .IsUnique() - .HasDatabaseName("IX_OrderAddress_OrderId"); - - b.ToTable("OrderAddresses"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("CustomizationDescription") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("CustomizationImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("OrderId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProductId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProductVariantId") - .HasColumnType("uniqueidentifier"); - - b.Property("Quantity") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasDefaultValue(1); - - b.Property("TotalPrice") - .HasColumnType("decimal(18,2)"); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_OrderItem_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_OrderItem_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_OrderItem_ModifiedAt"); - - b.HasIndex("OrderId") - .HasDatabaseName("IX_OrderItem_OrderId"); - - b.HasIndex("ProductId") - .HasDatabaseName("IX_OrderItem_ProductId"); - - b.HasIndex("ProductVariantId") - .HasDatabaseName("IX_OrderItem_ProductVariantId"); - - b.HasIndex("OrderId", "ProductId") - .HasDatabaseName("IX_OrderItem_Order_Product"); - - b.ToTable("OrderItems"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderStatus", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique() - .HasDatabaseName("IX_OrderStatus_Name"); - - b.ToTable("OrderStatuses"); - - b.HasData( - new - { - Id = 0, - Name = "Pending" - }, - new - { - Id = 1, - Name = "Processing" - }, - new - { - Id = 2, - Name = "Completed" - }, - new - { - Id = 3, - Name = "Cancelled" - }); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("BasePrice") - .HasColumnType("decimal(18,2)"); - - b.Property("CategoryId") - .HasColumnType("uniqueidentifier"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("ImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("IsCustomizable") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId") - .HasDatabaseName("IX_Product_CategoryId"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_Product_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_Product_CreatedBy"); - - b.HasIndex("IsActive") - .HasDatabaseName("IX_Product_IsActive"); - - b.HasIndex("IsCustomizable") - .HasDatabaseName("IX_Product_IsCustomizable"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_Product_ModifiedAt"); - - b.HasIndex("Name") - .HasDatabaseName("IX_Product_Name"); - - b.HasIndex("CategoryId", "IsActive") - .HasDatabaseName("IX_Product_Category_Active"); - - b.HasIndex("IsActive", "IsCustomizable") - .HasDatabaseName("IX_Product_Active_Customizable"); - - b.ToTable("Products"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ProductVariant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("Color") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("ImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Price") - .HasColumnType("decimal(18,2)"); - - b.Property("ProductId") - .HasColumnType("uniqueidentifier"); - - b.Property("SKU") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Size") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("StockQuantity") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasDefaultValue(0); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_ProductVariant_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_ProductVariant_CreatedBy"); - - b.HasIndex("IsActive") - .HasDatabaseName("IX_ProductVariant_IsActive"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_ProductVariant_ModifiedAt"); - - b.HasIndex("ProductId") - .HasDatabaseName("IX_ProductVariant_ProductId"); - - b.HasIndex("SKU") - .IsUnique() - .HasDatabaseName("IX_ProductVariant_SKU"); - - b.HasIndex("ProductId", "Size", "Color") - .IsUnique() - .HasDatabaseName("IX_ProductVariant_Product_Size_Color"); - - b.ToTable("ProductVariants"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ShippingStatus", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique() - .HasDatabaseName("IX_ShippingStatus_Name"); - - b.ToTable("ShippingStatuses"); - - b.HasData( - new - { - Id = 0, - Name = "Prepping" - }, - new - { - Id = 1, - Name = "Packaging" - }, - new - { - Id = 2, - Name = "Shipped" - }, - new - { - Id = 3, - Name = "Delivered" - }); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Users.ApplicationUser", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("DateOfBirth") - .HasColumnType("datetime2"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("FirstName") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("LastLoginAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("LastName") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("ProfileImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Address", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany("Addresses") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Category", b => - { - b.HasOne("Printbase.Domain.Entities.Category", "ParentCategory") - .WithMany("SubCategories") - .HasForeignKey("ParentCategoryId"); - - b.Navigation("ParentCategory"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Order", b => - { - b.HasOne("Printbase.Domain.Entities.OrderStatus", "OrderStatus") - .WithMany("Orders") - .HasForeignKey("OrderStatusId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.ShippingStatus", "ShippingStatus") - .WithMany("Orders") - .HasForeignKey("ShippingStatusId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany("Orders") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("OrderStatus"); - - b.Navigation("ShippingStatus"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderAddress", b => - { - b.HasOne("Printbase.Domain.Entities.Order", "Order") - .WithOne("OrderAddress") - .HasForeignKey("Printbase.Domain.Entities.OrderAddress", "OrderId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Order"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderItem", b => - { - b.HasOne("Printbase.Domain.Entities.Order", "Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.Product", "Product") - .WithMany("OrderItems") - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.ProductVariant", "ProductVariant") - .WithMany("OrderItems") - .HasForeignKey("ProductVariantId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Order"); - - b.Navigation("Product"); - - b.Navigation("ProductVariant"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Product", b => - { - b.HasOne("Printbase.Domain.Entities.Category", "Category") - .WithMany("Products") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.SetNull); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ProductVariant", b => - { - b.HasOne("Printbase.Domain.Entities.Product", "Product") - .WithMany("ProductVariants") - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Category", b => - { - b.Navigation("Products"); - - b.Navigation("SubCategories"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Order", b => - { - b.Navigation("OrderAddress") - .IsRequired(); - - b.Navigation("OrderItems"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderStatus", b => - { - b.Navigation("Orders"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Product", b => - { - b.Navigation("OrderItems"); - - b.Navigation("ProductVariants"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ProductVariant", b => - { - b.Navigation("OrderItems"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ShippingStatus", b => - { - b.Navigation("Orders"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Users.ApplicationUser", b => - { - b.Navigation("Addresses"); - - b.Navigation("Orders"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.cs b/src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.cs deleted file mode 100644 index ab38160..0000000 --- a/src/Printbase.Infrastructure/Migrations/20250526100748_InitialSetup.cs +++ /dev/null @@ -1,777 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional - -namespace Printbase.Infrastructure.Migrations -{ - /// - public partial class InitialSetup : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AspNetRoles", - columns: table => new - { - Id = table.Column(type: "nvarchar(450)", nullable: false), - Description = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), - CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - IsActive = table.Column(type: "bit", nullable: false, defaultValue: true), - Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetUsers", - columns: table => new - { - Id = table.Column(type: "nvarchar(450)", nullable: false), - FirstName = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - LastName = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - DateOfBirth = table.Column(type: "datetime2", nullable: true), - CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - LastLoginAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - IsActive = table.Column(type: "bit", nullable: false, defaultValue: true), - ProfileImageUrl = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), - UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - EmailConfirmed = table.Column(type: "bit", nullable: false), - PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), - SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), - PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), - PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), - TwoFactorEnabled = table.Column(type: "bit", nullable: false), - LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), - LockoutEnabled = table.Column(type: "bit", nullable: false), - AccessFailedCount = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUsers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Category", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Name = table.Column(type: "nvarchar(max)", nullable: false), - Description = table.Column(type: "nvarchar(max)", nullable: false), - ImageUrl = table.Column(type: "nvarchar(max)", nullable: false), - SortOrder = table.Column(type: "int", nullable: false), - IsActive = table.Column(type: "bit", nullable: false), - ParentCategoryId = table.Column(type: "uniqueidentifier", nullable: true), - CreatedAt = table.Column(type: "datetime2", nullable: false), - ModifiedAt = table.Column(type: "datetime2", nullable: false), - CreatedBy = table.Column(type: "nvarchar(max)", nullable: false), - ModifiedBy = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Category", x => x.Id); - table.ForeignKey( - name: "FK_Category_Category_ParentCategoryId", - column: x => x.ParentCategoryId, - principalTable: "Category", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "OrderStatuses", - columns: table => new - { - Id = table.Column(type: "int", nullable: false), - Name = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_OrderStatuses", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "ShippingStatuses", - columns: table => new - { - Id = table.Column(type: "int", nullable: false), - Name = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ShippingStatuses", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetRoleClaims", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - RoleId = table.Column(type: "nvarchar(450)", nullable: false), - ClaimType = table.Column(type: "nvarchar(max)", nullable: true), - ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Addresses", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWID()"), - UserId = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - AddressType = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), - Street = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - City = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - State = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - PostalCode = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false), - Country = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - IsDefault = table.Column(type: "bit", nullable: false, defaultValue: false), - IsActive = table.Column(type: "bit", nullable: false, defaultValue: true), - CreatedAt = table.Column(type: "datetime2", nullable: false), - ModifiedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - CreatedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - ModifiedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Addresses", x => x.Id); - table.ForeignKey( - name: "FK_Addresses_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserClaims", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - UserId = table.Column(type: "nvarchar(450)", nullable: false), - ClaimType = table.Column(type: "nvarchar(max)", nullable: true), - ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetUserClaims_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserLogins", - columns: table => new - { - LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), - ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), - ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), - UserId = table.Column(type: "nvarchar(450)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); - table.ForeignKey( - name: "FK_AspNetUserLogins_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserRoles", - columns: table => new - { - UserId = table.Column(type: "nvarchar(450)", nullable: false), - RoleId = table.Column(type: "nvarchar(450)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserTokens", - columns: table => new - { - UserId = table.Column(type: "nvarchar(450)", nullable: false), - LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), - Name = table.Column(type: "nvarchar(450)", nullable: false), - Value = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); - table.ForeignKey( - name: "FK_AspNetUserTokens_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Products", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWID()"), - Name = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - Description = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: false), - BasePrice = table.Column(type: "decimal(18,2)", nullable: false), - IsCustomizable = table.Column(type: "bit", nullable: false, defaultValue: false), - IsActive = table.Column(type: "bit", nullable: false, defaultValue: true), - ImageUrl = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), - CategoryId = table.Column(type: "uniqueidentifier", nullable: true), - CreatedAt = table.Column(type: "datetime2", nullable: false), - ModifiedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - CreatedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - ModifiedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Products", x => x.Id); - table.ForeignKey( - name: "FK_Products_Category_CategoryId", - column: x => x.CategoryId, - principalTable: "Category", - principalColumn: "Id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "Orders", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWID()"), - UserId = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - OrderDate = table.Column(type: "datetime2", nullable: false), - TotalPrice = table.Column(type: "decimal(18,2)", nullable: false), - OrderStatusId = table.Column(type: "int", nullable: false), - ShippingStatusId = table.Column(type: "int", nullable: false), - OrderNumber = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), - Notes = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: false), - CreatedAt = table.Column(type: "datetime2", nullable: false), - ModifiedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - CreatedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - ModifiedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Orders", x => x.Id); - table.ForeignKey( - name: "FK_Orders_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_Orders_OrderStatuses_OrderStatusId", - column: x => x.OrderStatusId, - principalTable: "OrderStatuses", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_Orders_ShippingStatuses_ShippingStatusId", - column: x => x.ShippingStatusId, - principalTable: "ShippingStatuses", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "ProductVariants", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWID()"), - ProductId = table.Column(type: "uniqueidentifier", nullable: false), - Size = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), - Color = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), - Price = table.Column(type: "decimal(18,2)", nullable: false), - ImageUrl = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), - SKU = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - StockQuantity = table.Column(type: "int", nullable: false, defaultValue: 0), - IsActive = table.Column(type: "bit", nullable: false, defaultValue: true), - CreatedAt = table.Column(type: "datetime2", nullable: false), - ModifiedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - CreatedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - ModifiedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ProductVariants", x => x.Id); - table.ForeignKey( - name: "FK_ProductVariants_Products_ProductId", - column: x => x.ProductId, - principalTable: "Products", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "OrderAddresses", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWID()"), - OrderId = table.Column(type: "uniqueidentifier", nullable: false), - Street = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - City = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - State = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - PostalCode = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false), - Country = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - CreatedAt = table.Column(type: "datetime2", nullable: false), - ModifiedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - CreatedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - ModifiedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_OrderAddresses", x => x.Id); - table.ForeignKey( - name: "FK_OrderAddresses_Orders_OrderId", - column: x => x.OrderId, - principalTable: "Orders", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "OrderItems", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWID()"), - OrderId = table.Column(type: "uniqueidentifier", nullable: false), - ProductId = table.Column(type: "uniqueidentifier", nullable: false), - ProductVariantId = table.Column(type: "uniqueidentifier", nullable: true), - Quantity = table.Column(type: "int", nullable: false, defaultValue: 1), - UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), - TotalPrice = table.Column(type: "decimal(18,2)", nullable: false), - CustomizationImageUrl = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), - CustomizationDescription = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: false), - CreatedAt = table.Column(type: "datetime2", nullable: false), - ModifiedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - CreatedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), - ModifiedBy = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_OrderItems", x => x.Id); - table.ForeignKey( - name: "FK_OrderItems_Orders_OrderId", - column: x => x.OrderId, - principalTable: "Orders", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_OrderItems_ProductVariants_ProductVariantId", - column: x => x.ProductVariantId, - principalTable: "ProductVariants", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_OrderItems_Products_ProductId", - column: x => x.ProductId, - principalTable: "Products", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.InsertData( - table: "AspNetRoles", - columns: new[] { "Id", "ConcurrencyStamp", "CreatedAt", "Description", "IsActive", "Name", "NormalizedName" }, - values: new object[,] - { - { "1", null, new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), "Full system access", true, "Administrator", "ADMINISTRATOR" }, - { "2", null, new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), "Standard customer access", true, "Customer", "CUSTOMER" }, - { "3", null, new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), "Manage orders and fulfillment", true, "OrderManager", "ORDERMANAGER" }, - { "4", null, new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), "Manage products and inventory", true, "ProductManager", "PRODUCTMANAGER" } - }); - - migrationBuilder.InsertData( - table: "OrderStatuses", - columns: new[] { "Id", "Name" }, - values: new object[,] - { - { 0, "Pending" }, - { 1, "Processing" }, - { 2, "Completed" }, - { 3, "Cancelled" } - }); - - migrationBuilder.InsertData( - table: "ShippingStatuses", - columns: new[] { "Id", "Name" }, - values: new object[,] - { - { 0, "Prepping" }, - { 1, "Packaging" }, - { 2, "Shipped" }, - { 3, "Delivered" } - }); - - migrationBuilder.CreateIndex( - name: "IX_Address_CreatedAt", - table: "Addresses", - column: "CreatedAt"); - - migrationBuilder.CreateIndex( - name: "IX_Address_CreatedBy", - table: "Addresses", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_Address_ModifiedAt", - table: "Addresses", - column: "ModifiedAt"); - - migrationBuilder.CreateIndex( - name: "IX_Address_User_Default", - table: "Addresses", - columns: new[] { "UserId", "IsDefault" }); - - migrationBuilder.CreateIndex( - name: "IX_Address_User_Type", - table: "Addresses", - columns: new[] { "UserId", "AddressType" }); - - migrationBuilder.CreateIndex( - name: "IX_Address_UserId", - table: "Addresses", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetRoleClaims_RoleId", - table: "AspNetRoleClaims", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "IX_ApplicationRole_IsActive", - table: "AspNetRoles", - column: "IsActive"); - - migrationBuilder.CreateIndex( - name: "RoleNameIndex", - table: "AspNetRoles", - column: "NormalizedName", - unique: true, - filter: "[NormalizedName] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserClaims_UserId", - table: "AspNetUserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserLogins_UserId", - table: "AspNetUserLogins", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserRoles_RoleId", - table: "AspNetUserRoles", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "EmailIndex", - table: "AspNetUsers", - column: "NormalizedEmail"); - - migrationBuilder.CreateIndex( - name: "UserNameIndex", - table: "AspNetUsers", - column: "NormalizedUserName", - unique: true, - filter: "[NormalizedUserName] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Category_ParentCategoryId", - table: "Category", - column: "ParentCategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_OrderAddress_CreatedAt", - table: "OrderAddresses", - column: "CreatedAt"); - - migrationBuilder.CreateIndex( - name: "IX_OrderAddress_CreatedBy", - table: "OrderAddresses", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_OrderAddress_ModifiedAt", - table: "OrderAddresses", - column: "ModifiedAt"); - - migrationBuilder.CreateIndex( - name: "IX_OrderAddress_OrderId", - table: "OrderAddresses", - column: "OrderId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_CreatedAt", - table: "OrderItems", - column: "CreatedAt"); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_CreatedBy", - table: "OrderItems", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_ModifiedAt", - table: "OrderItems", - column: "ModifiedAt"); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_Order_Product", - table: "OrderItems", - columns: new[] { "OrderId", "ProductId" }); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_OrderId", - table: "OrderItems", - column: "OrderId"); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_ProductId", - table: "OrderItems", - column: "ProductId"); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_ProductVariantId", - table: "OrderItems", - column: "ProductVariantId"); - - migrationBuilder.CreateIndex( - name: "IX_Order_CreatedAt", - table: "Orders", - column: "CreatedAt"); - - migrationBuilder.CreateIndex( - name: "IX_Order_CreatedBy", - table: "Orders", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_Order_ModifiedAt", - table: "Orders", - column: "ModifiedAt"); - - migrationBuilder.CreateIndex( - name: "IX_Order_OrderDate", - table: "Orders", - column: "OrderDate"); - - migrationBuilder.CreateIndex( - name: "IX_Order_OrderNumber", - table: "Orders", - column: "OrderNumber", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Order_OrderStatusId", - table: "Orders", - column: "OrderStatusId"); - - migrationBuilder.CreateIndex( - name: "IX_Order_ShippingStatusId", - table: "Orders", - column: "ShippingStatusId"); - - migrationBuilder.CreateIndex( - name: "IX_Order_User_Date", - table: "Orders", - columns: new[] { "UserId", "OrderDate" }); - - migrationBuilder.CreateIndex( - name: "IX_Order_UserId", - table: "Orders", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_OrderStatus_Name", - table: "OrderStatuses", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Product_Active_Customizable", - table: "Products", - columns: new[] { "IsActive", "IsCustomizable" }); - - migrationBuilder.CreateIndex( - name: "IX_Product_Category_Active", - table: "Products", - columns: new[] { "CategoryId", "IsActive" }); - - migrationBuilder.CreateIndex( - name: "IX_Product_CategoryId", - table: "Products", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_Product_CreatedAt", - table: "Products", - column: "CreatedAt"); - - migrationBuilder.CreateIndex( - name: "IX_Product_CreatedBy", - table: "Products", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_Product_IsActive", - table: "Products", - column: "IsActive"); - - migrationBuilder.CreateIndex( - name: "IX_Product_IsCustomizable", - table: "Products", - column: "IsCustomizable"); - - migrationBuilder.CreateIndex( - name: "IX_Product_ModifiedAt", - table: "Products", - column: "ModifiedAt"); - - migrationBuilder.CreateIndex( - name: "IX_Product_Name", - table: "Products", - column: "Name"); - - migrationBuilder.CreateIndex( - name: "IX_ProductVariant_CreatedAt", - table: "ProductVariants", - column: "CreatedAt"); - - migrationBuilder.CreateIndex( - name: "IX_ProductVariant_CreatedBy", - table: "ProductVariants", - column: "CreatedBy"); - - migrationBuilder.CreateIndex( - name: "IX_ProductVariant_IsActive", - table: "ProductVariants", - column: "IsActive"); - - migrationBuilder.CreateIndex( - name: "IX_ProductVariant_ModifiedAt", - table: "ProductVariants", - column: "ModifiedAt"); - - migrationBuilder.CreateIndex( - name: "IX_ProductVariant_Product_Size_Color", - table: "ProductVariants", - columns: new[] { "ProductId", "Size", "Color" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_ProductVariant_ProductId", - table: "ProductVariants", - column: "ProductId"); - - migrationBuilder.CreateIndex( - name: "IX_ProductVariant_SKU", - table: "ProductVariants", - column: "SKU", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_ShippingStatus_Name", - table: "ShippingStatuses", - column: "Name", - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Addresses"); - - migrationBuilder.DropTable( - name: "AspNetRoleClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserLogins"); - - migrationBuilder.DropTable( - name: "AspNetUserRoles"); - - migrationBuilder.DropTable( - name: "AspNetUserTokens"); - - migrationBuilder.DropTable( - name: "OrderAddresses"); - - migrationBuilder.DropTable( - name: "OrderItems"); - - migrationBuilder.DropTable( - name: "AspNetRoles"); - - migrationBuilder.DropTable( - name: "Orders"); - - migrationBuilder.DropTable( - name: "ProductVariants"); - - migrationBuilder.DropTable( - name: "AspNetUsers"); - - migrationBuilder.DropTable( - name: "OrderStatuses"); - - migrationBuilder.DropTable( - name: "ShippingStatuses"); - - migrationBuilder.DropTable( - name: "Products"); - - migrationBuilder.DropTable( - name: "Category"); - } - } -} diff --git a/src/Printbase.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Printbase.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs deleted file mode 100644 index 95a5181..0000000 --- a/src/Printbase.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs +++ /dev/null @@ -1,1147 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Printbase.Infrastructure.Database; - -#nullable disable - -namespace Printbase.Infrastructure.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - partial class ApplicationDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.5") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ApplicationRole", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("IsActive") - .HasDatabaseName("IX_ApplicationRole_IsActive"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - - b.HasData( - new - { - Id = "1", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Full system access", - IsActive = true, - Name = "Administrator", - NormalizedName = "ADMINISTRATOR" - }, - new - { - Id = "2", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Standard customer access", - IsActive = true, - Name = "Customer", - NormalizedName = "CUSTOMER" - }, - new - { - Id = "3", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Manage orders and fulfillment", - IsActive = true, - Name = "OrderManager", - NormalizedName = "ORDERMANAGER" - }, - new - { - Id = "4", - CreatedAt = new DateTime(2025, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), - Description = "Manage products and inventory", - IsActive = true, - Name = "ProductManager", - NormalizedName = "PRODUCTMANAGER" - }); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("RoleId") - .HasColumnType("nvarchar(450)"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("AddressType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("City") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Country") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("IsDefault") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("PostalCode") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("State") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Street") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("UserId") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_Address_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_Address_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_Address_ModifiedAt"); - - b.HasIndex("UserId") - .HasDatabaseName("IX_Address_UserId"); - - b.HasIndex("UserId", "AddressType") - .HasDatabaseName("IX_Address_User_Type"); - - b.HasIndex("UserId", "IsDefault") - .HasDatabaseName("IX_Address_User_Default"); - - b.ToTable("Addresses"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Category", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Description") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ImageUrl") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("IsActive") - .HasColumnType("bit"); - - b.Property("ModifiedAt") - .HasColumnType("datetime2"); - - b.Property("ModifiedBy") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ParentCategoryId") - .HasColumnType("uniqueidentifier"); - - b.Property("SortOrder") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("ParentCategoryId"); - - b.ToTable("Category"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Notes") - .IsRequired() - .HasMaxLength(1000) - .HasColumnType("nvarchar(1000)"); - - b.Property("OrderDate") - .HasColumnType("datetime2"); - - b.Property("OrderNumber") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("OrderStatusId") - .HasColumnType("int"); - - b.Property("ShippingStatusId") - .HasColumnType("int"); - - b.Property("TotalPrice") - .HasColumnType("decimal(18,2)"); - - b.Property("UserId") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_Order_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_Order_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_Order_ModifiedAt"); - - b.HasIndex("OrderDate") - .HasDatabaseName("IX_Order_OrderDate"); - - b.HasIndex("OrderNumber") - .IsUnique() - .HasDatabaseName("IX_Order_OrderNumber"); - - b.HasIndex("OrderStatusId") - .HasDatabaseName("IX_Order_OrderStatusId"); - - b.HasIndex("ShippingStatusId") - .HasDatabaseName("IX_Order_ShippingStatusId"); - - b.HasIndex("UserId") - .HasDatabaseName("IX_Order_UserId"); - - b.HasIndex("UserId", "OrderDate") - .HasDatabaseName("IX_Order_User_Date"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderAddress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("City") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Country") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("OrderId") - .HasColumnType("uniqueidentifier"); - - b.Property("PostalCode") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("State") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Street") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_OrderAddress_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_OrderAddress_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_OrderAddress_ModifiedAt"); - - b.HasIndex("OrderId") - .IsUnique() - .HasDatabaseName("IX_OrderAddress_OrderId"); - - b.ToTable("OrderAddresses"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("CustomizationDescription") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("CustomizationImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("OrderId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProductId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProductVariantId") - .HasColumnType("uniqueidentifier"); - - b.Property("Quantity") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasDefaultValue(1); - - b.Property("TotalPrice") - .HasColumnType("decimal(18,2)"); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_OrderItem_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_OrderItem_CreatedBy"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_OrderItem_ModifiedAt"); - - b.HasIndex("OrderId") - .HasDatabaseName("IX_OrderItem_OrderId"); - - b.HasIndex("ProductId") - .HasDatabaseName("IX_OrderItem_ProductId"); - - b.HasIndex("ProductVariantId") - .HasDatabaseName("IX_OrderItem_ProductVariantId"); - - b.HasIndex("OrderId", "ProductId") - .HasDatabaseName("IX_OrderItem_Order_Product"); - - b.ToTable("OrderItems"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderStatus", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique() - .HasDatabaseName("IX_OrderStatus_Name"); - - b.ToTable("OrderStatuses"); - - b.HasData( - new - { - Id = 0, - Name = "Pending" - }, - new - { - Id = 1, - Name = "Processing" - }, - new - { - Id = 2, - Name = "Completed" - }, - new - { - Id = 3, - Name = "Cancelled" - }); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("BasePrice") - .HasColumnType("decimal(18,2)"); - - b.Property("CategoryId") - .HasColumnType("uniqueidentifier"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("ImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("IsCustomizable") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId") - .HasDatabaseName("IX_Product_CategoryId"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_Product_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_Product_CreatedBy"); - - b.HasIndex("IsActive") - .HasDatabaseName("IX_Product_IsActive"); - - b.HasIndex("IsCustomizable") - .HasDatabaseName("IX_Product_IsCustomizable"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_Product_ModifiedAt"); - - b.HasIndex("Name") - .HasDatabaseName("IX_Product_Name"); - - b.HasIndex("CategoryId", "IsActive") - .HasDatabaseName("IX_Product_Category_Active"); - - b.HasIndex("IsActive", "IsCustomizable") - .HasDatabaseName("IX_Product_Active_Customizable"); - - b.ToTable("Products"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ProductVariant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWID()"); - - b.Property("Color") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("ImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("ModifiedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("ModifiedBy") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)"); - - b.Property("Price") - .HasColumnType("decimal(18,2)"); - - b.Property("ProductId") - .HasColumnType("uniqueidentifier"); - - b.Property("SKU") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Size") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("StockQuantity") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasDefaultValue(0); - - b.HasKey("Id"); - - b.HasIndex("CreatedAt") - .HasDatabaseName("IX_ProductVariant_CreatedAt"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("IX_ProductVariant_CreatedBy"); - - b.HasIndex("IsActive") - .HasDatabaseName("IX_ProductVariant_IsActive"); - - b.HasIndex("ModifiedAt") - .HasDatabaseName("IX_ProductVariant_ModifiedAt"); - - b.HasIndex("ProductId") - .HasDatabaseName("IX_ProductVariant_ProductId"); - - b.HasIndex("SKU") - .IsUnique() - .HasDatabaseName("IX_ProductVariant_SKU"); - - b.HasIndex("ProductId", "Size", "Color") - .IsUnique() - .HasDatabaseName("IX_ProductVariant_Product_Size_Color"); - - b.ToTable("ProductVariants"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ShippingStatus", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique() - .HasDatabaseName("IX_ShippingStatus_Name"); - - b.ToTable("ShippingStatuses"); - - b.HasData( - new - { - Id = 0, - Name = "Prepping" - }, - new - { - Id = 1, - Name = "Packaging" - }, - new - { - Id = 2, - Name = "Shipped" - }, - new - { - Id = 3, - Name = "Delivered" - }); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Users.ApplicationUser", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("DateOfBirth") - .HasColumnType("datetime2"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("FirstName") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("IsActive") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(true); - - b.Property("LastLoginAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2") - .HasDefaultValueSql("GETUTCDATE()"); - - b.Property("LastName") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("ProfileImageUrl") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Address", b => - { - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany("Addresses") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Category", b => - { - b.HasOne("Printbase.Domain.Entities.Category", "ParentCategory") - .WithMany("SubCategories") - .HasForeignKey("ParentCategoryId"); - - b.Navigation("ParentCategory"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Order", b => - { - b.HasOne("Printbase.Domain.Entities.OrderStatus", "OrderStatus") - .WithMany("Orders") - .HasForeignKey("OrderStatusId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.ShippingStatus", "ShippingStatus") - .WithMany("Orders") - .HasForeignKey("ShippingStatusId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.Users.ApplicationUser", null) - .WithMany("Orders") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("OrderStatus"); - - b.Navigation("ShippingStatus"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderAddress", b => - { - b.HasOne("Printbase.Domain.Entities.Order", "Order") - .WithOne("OrderAddress") - .HasForeignKey("Printbase.Domain.Entities.OrderAddress", "OrderId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Order"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderItem", b => - { - b.HasOne("Printbase.Domain.Entities.Order", "Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.Product", "Product") - .WithMany("OrderItems") - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("Printbase.Domain.Entities.ProductVariant", "ProductVariant") - .WithMany("OrderItems") - .HasForeignKey("ProductVariantId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Order"); - - b.Navigation("Product"); - - b.Navigation("ProductVariant"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Product", b => - { - b.HasOne("Printbase.Domain.Entities.Category", "Category") - .WithMany("Products") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.SetNull); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ProductVariant", b => - { - b.HasOne("Printbase.Domain.Entities.Product", "Product") - .WithMany("ProductVariants") - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Category", b => - { - b.Navigation("Products"); - - b.Navigation("SubCategories"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Order", b => - { - b.Navigation("OrderAddress") - .IsRequired(); - - b.Navigation("OrderItems"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.OrderStatus", b => - { - b.Navigation("Orders"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Product", b => - { - b.Navigation("OrderItems"); - - b.Navigation("ProductVariants"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ProductVariant", b => - { - b.Navigation("OrderItems"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.ShippingStatus", b => - { - b.Navigation("Orders"); - }); - - modelBuilder.Entity("Printbase.Domain.Entities.Users.ApplicationUser", b => - { - b.Navigation("Addresses"); - - b.Navigation("Orders"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Printbase.Infrastructure/Printbase.Infrastructure.csproj b/src/Printbase.Infrastructure/Printbase.Infrastructure.csproj index 7e22d89..2221b51 100644 --- a/src/Printbase.Infrastructure/Printbase.Infrastructure.csproj +++ b/src/Printbase.Infrastructure/Printbase.Infrastructure.csproj @@ -22,4 +22,8 @@ + + + + diff --git a/src/Printbase.Infrastructure/Repositories/CategoryRepository.cs b/src/Printbase.Infrastructure/Repositories/CategoryRepository.cs new file mode 100644 index 0000000..c791eeb --- /dev/null +++ b/src/Printbase.Infrastructure/Repositories/CategoryRepository.cs @@ -0,0 +1,111 @@ +using Microsoft.EntityFrameworkCore; +using Printbase.Domain.Entities.Product; +using Printbase.Domain.Repositories; +using Printbase.Infrastructure.Database; + +namespace Printbase.Infrastructure.Repositories; + +public class CategoryRepository(ApplicationDbContext context) : ICategoryRepository +{ + public async Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Categories + .FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + } + + public async Task GetByIdWithSubCategoriesAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Categories + .Include(c => c.SubCategories.Where(sc => sc.IsActive)) + .FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + } + + public async Task GetByIdWithProductsAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Categories + .Include(c => c.Products.Where(p => p.IsActive)) + .FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + } + + public async Task> GetAllAsync(CancellationToken cancellationToken = default) + { + return await context.Categories + .OrderBy(c => c.SortOrder) + .ThenBy(c => c.Name) + .ToListAsync(cancellationToken); + } + + public async Task> GetActiveAsync(CancellationToken cancellationToken = default) + { + return await context.Categories + .Where(c => c.IsActive) + .OrderBy(c => c.SortOrder) + .ThenBy(c => c.Name) + .ToListAsync(cancellationToken); + } + + public async Task> GetRootCategoriesAsync(CancellationToken cancellationToken = default) + { + return await context.Categories + .Where(c => c.ParentCategoryId == null && c.IsActive) + .OrderBy(c => c.SortOrder) + .ThenBy(c => c.Name) + .ToListAsync(cancellationToken); + } + + public async Task> GetSubCategoriesAsync(Guid parentCategoryId, CancellationToken cancellationToken = default) + { + return await context.Categories + .Where(c => c.ParentCategoryId == parentCategoryId && c.IsActive) + .OrderBy(c => c.SortOrder) + .ThenBy(c => c.Name) + .ToListAsync(cancellationToken); + } + + public async Task AddAsync(Category category, CancellationToken cancellationToken = default) + { + category.Id = Guid.NewGuid(); + category.CreatedAt = DateTime.UtcNow; + category.ModifiedAt = DateTime.UtcNow; + + context.Categories.Add(category); + await context.SaveChangesAsync(cancellationToken); + return category; + } + + public async Task UpdateAsync(Category category, CancellationToken cancellationToken = default) + { + category.ModifiedAt = DateTime.UtcNow; + context.Categories.Update(category); + await context.SaveChangesAsync(cancellationToken); + return category; + } + + public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) + { + var category = await GetByIdAsync(id, cancellationToken); + if (category != null) + { + context.Categories.Remove(category); + await context.SaveChangesAsync(cancellationToken); + } + } + + public async Task ExistsAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Categories + .AnyAsync(c => c.Id == id, cancellationToken); + } + + public async Task HasSubCategoriesAsync(Guid categoryId, CancellationToken cancellationToken = default) + { + return await context.Categories + .AnyAsync(c => c.ParentCategoryId == categoryId, cancellationToken); + } + + public async Task HasProductsAsync(Guid categoryId, CancellationToken cancellationToken = default) + { + return await context.Products + .AnyAsync(p => p.CategoryId == categoryId, cancellationToken); + } +} \ No newline at end of file diff --git a/src/Printbase.Infrastructure/Repositories/ProductRepository.cs b/src/Printbase.Infrastructure/Repositories/ProductRepository.cs new file mode 100644 index 0000000..a35ec42 --- /dev/null +++ b/src/Printbase.Infrastructure/Repositories/ProductRepository.cs @@ -0,0 +1,155 @@ +using Microsoft.EntityFrameworkCore; +using Printbase.Domain.Common.Models; +using Printbase.Domain.Entities.Product; +using Printbase.Domain.Repositories; +using Printbase.Infrastructure.Database; + +namespace Printbase.Infrastructure.Repositories; + +public class ProductRepository(ApplicationDbContext context) : IProductRepository +{ + public async Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Products + .FirstOrDefaultAsync(p => p.Id == id, cancellationToken); + } + + public async Task GetByIdWithVariantsAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Products + .Include(p => p.ProductVariants.Where(pv => pv.IsActive)) + .FirstOrDefaultAsync(p => p.Id == id, cancellationToken); + } + + public async Task GetByIdWithCategoryAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Products + .Include(p => p.Category) + .FirstOrDefaultAsync(p => p.Id == id, cancellationToken); + } + + public async Task GetByIdFullAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Products + .Include(p => p.Category) + .Include(p => p.ProductVariants.Where(pv => pv.IsActive)) + .FirstOrDefaultAsync(p => p.Id == id, cancellationToken); + } + + public async Task> GetPagedAsync(ProductFilterParameters filterParameters, CancellationToken cancellationToken = default) + { + var query = context.Products + .Include(p => p.Category) + .AsQueryable(); + + if (filterParameters.IsActive.HasValue) + { + query = query.Where(p => p.IsActive == filterParameters.IsActive.Value); + } + + if (!string.IsNullOrEmpty(filterParameters.SearchTerm)) + { + query = query.Where(p => p.Name.Contains(filterParameters.SearchTerm) || + (p.Description != null && p.Description.Contains(filterParameters.SearchTerm))); + } + + if (filterParameters.CategoryId.HasValue) + { + query = query.Where(p => p.CategoryId == filterParameters.CategoryId.Value); + } + + if (filterParameters.MinPrice.HasValue) + { + query = query.Where(p => p.BasePrice >= filterParameters.MinPrice.Value); + } + + if (filterParameters.MaxPrice.HasValue) + { + query = query.Where(p => p.BasePrice <= filterParameters.MaxPrice.Value); + } + + if (filterParameters.IsCustomizable.HasValue) + { + query = query.Where(p => p.IsCustomizable == filterParameters.IsCustomizable.Value); + } + + query = filterParameters.SortBy.ToLower() switch + { + "price" => filterParameters.SortDirection.ToUpper() == "DESC" + ? query.OrderByDescending(p => p.BasePrice) + : query.OrderBy(p => p.BasePrice), + "name" => filterParameters.SortDirection.ToUpper() == "DESC" + ? query.OrderByDescending(p => p.Name) + : query.OrderBy(p => p.Name), + _ => query.OrderBy(p => p.Name) + }; + + var totalCount = await query.CountAsync(cancellationToken); + + var items = await query + .Skip((filterParameters.PageNumber - 1) * filterParameters.PageSize) + .Take(filterParameters.PageSize) + .ToListAsync(cancellationToken); + + return new PagedResult + { + Items = items, + TotalCount = totalCount, + PageNumber = filterParameters.PageNumber, + PageSize = filterParameters.PageSize + }; + } + + public async Task> GetByCategoryAsync(Guid categoryId, CancellationToken cancellationToken = default) + { + return await context.Products + .Include(p => p.Category) + .Where(p => p.CategoryId == categoryId && p.IsActive) + .OrderBy(p => p.Name) + .ToListAsync(cancellationToken); + } + + public async Task> GetCustomizableAsync(CancellationToken cancellationToken = default) + { + return await context.Products + .Include(p => p.Category) + .Where(p => p.IsCustomizable && p.IsActive) + .OrderBy(p => p.Name) + .ToListAsync(cancellationToken); + } + + public async Task AddAsync(Product product, CancellationToken cancellationToken = default) + { + product.Id = Guid.NewGuid(); + product.CreatedAt = DateTime.UtcNow; + product.ModifiedAt = DateTime.UtcNow; + + context.Products.Add(product); + await context.SaveChangesAsync(cancellationToken); + return product; + } + + public async Task UpdateAsync(Product product, CancellationToken cancellationToken = default) + { + product.ModifiedAt = DateTime.UtcNow; + context.Products.Update(product); + await context.SaveChangesAsync(cancellationToken); + return product; + } + + public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) + { + var product = await GetByIdAsync(id, cancellationToken); + if (product != null) + { + context.Products.Remove(product); + await context.SaveChangesAsync(cancellationToken); + } + } + + public async Task ExistsAsync(Guid id, CancellationToken cancellationToken = default) + { + return await context.Products + .AnyAsync(p => p.Id == id, cancellationToken); + } +} \ No newline at end of file