feat:Initial commit
This commit is contained in:
127
StoreService/Database/ApplicationContext.cs
Normal file
127
StoreService/Database/ApplicationContext.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using StoreService.Database.Entities;
|
||||
|
||||
namespace StoreService.Database;
|
||||
|
||||
/// <summary>
|
||||
/// Entity Framework Core database context for the Store microservice.
|
||||
/// Defines DbSets and configures entity relationships & constraints.
|
||||
/// </summary>
|
||||
public class ApplicationContext : DbContext
|
||||
{
|
||||
#region Ctor
|
||||
public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DbSets
|
||||
public DbSet<StoreCategory> StoreCategories => Set<StoreCategory>();
|
||||
public DbSet<StoreItem> StoreItems => Set<StoreItem>();
|
||||
public DbSet<StoreDiscount> StoreDiscounts => Set<StoreDiscount>();
|
||||
public DbSet<StoreDiscountItem> StoreDiscountItems => Set<StoreDiscountItem>();
|
||||
public DbSet<StoreOrder> StoreOrders => Set<StoreOrder>();
|
||||
public DbSet<StoreOrderItem> StoreOrderItems => Set<StoreOrderItem>();
|
||||
public DbSet<StoreOrderItemDiscount> StoreOrderItemDiscounts => Set<StoreOrderItemDiscount>();
|
||||
#endregion
|
||||
|
||||
#region ModelCreating
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// store_category
|
||||
modelBuilder.Entity<StoreCategory>(b =>
|
||||
{
|
||||
b.ToTable("store_category");
|
||||
b.HasKey(x => x.Id);
|
||||
b.Property(x => x.Title).HasMaxLength(256).IsRequired();
|
||||
});
|
||||
|
||||
// store_item
|
||||
modelBuilder.Entity<StoreItem>(b =>
|
||||
{
|
||||
b.ToTable("store_item");
|
||||
b.HasKey(x => x.Id);
|
||||
b.Property(x => x.ManaBuyPrice).IsRequired();
|
||||
b.Property(x => x.ManaSellPrice).IsRequired();
|
||||
b.Property(x => x.InventoryLimit).IsRequired();
|
||||
b.Property(x => x.UnlimitedPurchase).HasDefaultValue(false);
|
||||
b.HasOne(x => x.Category)
|
||||
.WithMany(c => c.Items)
|
||||
.HasForeignKey(x => x.StoreCategoryId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
// store_discount
|
||||
modelBuilder.Entity<StoreDiscount>(b =>
|
||||
{
|
||||
b.ToTable("store_discount");
|
||||
b.HasKey(x => x.Id);
|
||||
b.Property(x => x.Percentage).HasPrecision(5, 2); // up to 100.00
|
||||
b.Property(x => x.FromDate).IsRequired();
|
||||
b.Property(x => x.UntilDate).IsRequired();
|
||||
b.Property(x => x.IsCanceled).HasDefaultValue(false);
|
||||
});
|
||||
|
||||
// store_discount_item (many-to-many manual mapping)
|
||||
modelBuilder.Entity<StoreDiscountItem>(b =>
|
||||
{
|
||||
b.ToTable("store_discount_item");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasOne(x => x.Discount)
|
||||
.WithMany(d => d.DiscountItems)
|
||||
.HasForeignKey(x => x.StoreDiscountId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasOne(x => x.StoreItem)
|
||||
.WithMany(i => i.DiscountItems)
|
||||
.HasForeignKey(x => x.StoreItemId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasIndex(x => new { x.StoreDiscountId, x.StoreItemId }).IsUnique();
|
||||
});
|
||||
|
||||
// store_order
|
||||
modelBuilder.Entity<StoreOrder>(b =>
|
||||
{
|
||||
b.ToTable("store_order");
|
||||
b.HasKey(x => x.Id);
|
||||
b.Property(x => x.UserId).IsRequired();
|
||||
b.Property(x => x.CostUpdateDate).IsRequired();
|
||||
b.Property(x => x.ItemsRedeemed).HasDefaultValue(false);
|
||||
});
|
||||
|
||||
// store_order_item
|
||||
modelBuilder.Entity<StoreOrderItem>(b =>
|
||||
{
|
||||
b.ToTable("store_order_item");
|
||||
b.HasKey(x => x.Id);
|
||||
b.Property(x => x.CalculatedPrice).IsRequired();
|
||||
b.HasOne(x => x.Order)
|
||||
.WithMany(o => o.OrderItems)
|
||||
.HasForeignKey(x => x.StoreOrderId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasOne(x => x.StoreItem)
|
||||
.WithMany(i => i.OrderItems)
|
||||
.HasForeignKey(x => x.StoreItemId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
// store_order_item_discount
|
||||
modelBuilder.Entity<StoreOrderItemDiscount>(b =>
|
||||
{
|
||||
b.ToTable("store_order_item_discount");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasOne(x => x.OrderItem)
|
||||
.WithMany(oi => oi.AppliedDiscounts)
|
||||
.HasForeignKey(x => x.StoreOrderItemId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
b.HasOne(x => x.Discount)
|
||||
.WithMany(d => d.OrderItemDiscounts)
|
||||
.HasForeignKey(x => x.StoreDiscountId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
b.HasIndex(x => new { x.StoreOrderItemId, x.StoreDiscountId }).IsUnique();
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
17
StoreService/Database/Entities/StoreCategory.cs
Normal file
17
StoreService/Database/Entities/StoreCategory.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace StoreService.Database.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Category grouping store items.
|
||||
/// </summary>
|
||||
public class StoreCategory
|
||||
{
|
||||
#region Properties
|
||||
public long Id { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
#endregion
|
||||
|
||||
#region Navigation
|
||||
public ICollection<StoreItem> Items { get; set; } = new List<StoreItem>();
|
||||
#endregion
|
||||
}
|
||||
|
||||
36
StoreService/Database/Entities/StoreDiscount.cs
Normal file
36
StoreService/Database/Entities/StoreDiscount.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace StoreService.Database.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Percentage discount that can apply to one or more store items within a time window.
|
||||
/// </summary>
|
||||
public class StoreDiscount
|
||||
{
|
||||
#region Properties
|
||||
public long Id { get; set; }
|
||||
public decimal Percentage { get; set; } // 0 - 100 (%)
|
||||
public string? Description { get; set; }
|
||||
public DateTime FromDate { get; set; }
|
||||
public DateTime UntilDate { get; set; }
|
||||
public bool IsCanceled { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Navigation
|
||||
public ICollection<StoreDiscountItem> DiscountItems { get; set; } = new List<StoreDiscountItem>();
|
||||
public ICollection<StoreOrderItemDiscount> OrderItemDiscounts { get; set; } = new List<StoreOrderItemDiscount>();
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
/// <summary>
|
||||
/// Checks whether discount is active at provided moment (default: now) ignoring cancellation flag (if canceled returns false).
|
||||
/// </summary>
|
||||
public bool IsActive(DateTime? at = null)
|
||||
{
|
||||
if (IsCanceled) return false;
|
||||
var moment = at ?? DateTime.UtcNow;
|
||||
return moment >= FromDate && moment <= UntilDate;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
19
StoreService/Database/Entities/StoreDiscountItem.cs
Normal file
19
StoreService/Database/Entities/StoreDiscountItem.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace StoreService.Database.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Join entity linking discounts to store items.
|
||||
/// </summary>
|
||||
public class StoreDiscountItem
|
||||
{
|
||||
#region Properties
|
||||
public long Id { get; set; }
|
||||
public long StoreDiscountId { get; set; }
|
||||
public long StoreItemId { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Navigation
|
||||
public StoreDiscount? Discount { get; set; }
|
||||
public StoreItem? StoreItem { get; set; }
|
||||
#endregion
|
||||
}
|
||||
|
||||
25
StoreService/Database/Entities/StoreItem.cs
Normal file
25
StoreService/Database/Entities/StoreItem.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace StoreService.Database.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Store item with pricing and purchase rules.
|
||||
/// </summary>
|
||||
public class StoreItem
|
||||
{
|
||||
#region Properties
|
||||
public long Id { get; set; }
|
||||
public long ItemId { get; set; } // FK to external Item service (not modeled here)
|
||||
public long StoreCategoryId { get; set; } // FK to StoreCategory
|
||||
public long? RankId { get; set; } // Minimum rank required to buy (external system)
|
||||
public int ManaBuyPrice { get; set; }
|
||||
public int ManaSellPrice { get; set; }
|
||||
public bool UnlimitedPurchase { get; set; }
|
||||
public int InventoryLimit { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Navigation
|
||||
public StoreCategory? Category { get; set; }
|
||||
public ICollection<StoreDiscountItem> DiscountItems { get; set; } = new List<StoreDiscountItem>();
|
||||
public ICollection<StoreOrderItem> OrderItems { get; set; } = new List<StoreOrderItem>();
|
||||
#endregion
|
||||
}
|
||||
|
||||
20
StoreService/Database/Entities/StoreOrder.cs
Normal file
20
StoreService/Database/Entities/StoreOrder.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace StoreService.Database.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a purchase order created by a user.
|
||||
/// </summary>
|
||||
public class StoreOrder
|
||||
{
|
||||
#region Properties
|
||||
public long Id { get; set; }
|
||||
public long UserId { get; set; }
|
||||
public DateTime CostUpdateDate { get; set; } = DateTime.UtcNow; // updated when prices recalculated
|
||||
public DateTime? PaidDate { get; set; } // when payment succeeded
|
||||
public bool ItemsRedeemed { get; set; } // becomes true once items granted to inventory
|
||||
#endregion
|
||||
|
||||
#region Navigation
|
||||
public ICollection<StoreOrderItem> OrderItems { get; set; } = new List<StoreOrderItem>();
|
||||
#endregion
|
||||
}
|
||||
|
||||
21
StoreService/Database/Entities/StoreOrderItem.cs
Normal file
21
StoreService/Database/Entities/StoreOrderItem.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace StoreService.Database.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Item line inside an order with captured calculated price for history.
|
||||
/// </summary>
|
||||
public class StoreOrderItem
|
||||
{
|
||||
#region Properties
|
||||
public long Id { get; set; }
|
||||
public long StoreOrderId { get; set; }
|
||||
public long StoreItemId { get; set; }
|
||||
public int CalculatedPrice { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Navigation
|
||||
public StoreOrder? Order { get; set; }
|
||||
public StoreItem? StoreItem { get; set; }
|
||||
public ICollection<StoreOrderItemDiscount> AppliedDiscounts { get; set; } = new List<StoreOrderItemDiscount>();
|
||||
#endregion
|
||||
}
|
||||
|
||||
19
StoreService/Database/Entities/StoreOrderItemDiscount.cs
Normal file
19
StoreService/Database/Entities/StoreOrderItemDiscount.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace StoreService.Database.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Captures which discounts were applied to order items at purchase time.
|
||||
/// </summary>
|
||||
public class StoreOrderItemDiscount
|
||||
{
|
||||
#region Properties
|
||||
public long Id { get; set; }
|
||||
public long StoreOrderItemId { get; set; }
|
||||
public long? StoreDiscountId { get; set; } // can be null if discount later removed but kept for history
|
||||
#endregion
|
||||
|
||||
#region Navigation
|
||||
public StoreOrderItem? OrderItem { get; set; }
|
||||
public StoreDiscount? Discount { get; set; }
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user