feat: add points persistence foundation
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Tiku.Domain.Catalog;
|
||||
using Tiku.Domain.Commerce;
|
||||
using Tiku.Domain.Identity;
|
||||
|
||||
namespace Tiku.Infrastructure.Persistence.Configurations;
|
||||
|
||||
internal sealed class PointActivityTaskConfiguration : IEntityTypeConfiguration<PointActivityTask>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PointActivityTask> builder)
|
||||
{
|
||||
builder.ConfigureTenantEntity("point_activity_tasks");
|
||||
builder.ConfigureTimestamps();
|
||||
builder.Property(entity => entity.TaskKey).HasColumnType("citext").HasMaxLength(100);
|
||||
builder.Property(entity => entity.Title).HasMaxLength(200);
|
||||
builder.Property(entity => entity.Description).HasMaxLength(1000);
|
||||
builder.Property(entity => entity.TaskType).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.Rules).IsJson("{}");
|
||||
builder.Property(entity => entity.Metadata).IsJson("{}");
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.TaskKey }).IsUnique();
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.Status, entity.SortOrder });
|
||||
builder.ToTable(table =>
|
||||
{
|
||||
table.HasCheckConstraint("ck_point_activity_tasks_points", "points > 0");
|
||||
table.HasCheckConstraint("ck_point_activity_tasks_max_claims", "max_claims_per_user > 0");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class PointActivityClaimConfiguration : IEntityTypeConfiguration<PointActivityClaim>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PointActivityClaim> builder)
|
||||
{
|
||||
builder.ConfigureTenantEntity("point_activity_claims");
|
||||
builder.ConfigureTimestamps();
|
||||
builder.Property(entity => entity.TaskKey).HasColumnType("citext").HasMaxLength(100);
|
||||
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.SourceType).HasMaxLength(100);
|
||||
builder.Property(entity => entity.Metadata).IsJson("{}");
|
||||
builder.Property(entity => entity.ClaimedAt).HasDefaultValueSql("now()");
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.TaskId, entity.SourceType, entity.SourceId })
|
||||
.IsUnique()
|
||||
.HasFilter("source_type is not null and source_id is not null");
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.CreatedAt });
|
||||
builder.HasOne<PointActivityTask>().WithMany()
|
||||
.HasForeignKey(entity => new { entity.TenantId, entity.TaskId })
|
||||
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UserId).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.ToTable(table =>
|
||||
{
|
||||
table.HasCheckConstraint("ck_point_activity_claims_points", "points > 0");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class PointExchangeItemConfiguration : IEntityTypeConfiguration<PointExchangeItem>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PointExchangeItem> builder)
|
||||
{
|
||||
builder.ConfigureTenantEntity("point_exchange_items");
|
||||
builder.ConfigureTimestamps();
|
||||
builder.Property(entity => entity.ItemKey).HasColumnType("citext").HasMaxLength(100);
|
||||
builder.Property(entity => entity.Name).HasMaxLength(200);
|
||||
builder.Property(entity => entity.Description).HasMaxLength(1000);
|
||||
builder.Property(entity => entity.ItemType).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.FulfillmentPayload).IsJson("{}");
|
||||
builder.Property(entity => entity.Metadata).IsJson("{}");
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.ItemKey }).IsUnique();
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.RegionId, entity.Status, entity.SortOrder });
|
||||
builder.HasOne<Region>().WithMany()
|
||||
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
|
||||
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
builder.ToTable(table =>
|
||||
{
|
||||
table.HasCheckConstraint("ck_point_exchange_items_points_cost", "points_cost > 0");
|
||||
table.HasCheckConstraint("ck_point_exchange_items_stock", "stock is null or stock >= 0");
|
||||
table.HasCheckConstraint("ck_point_exchange_items_days", "days is null or days >= 0");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class PointExchangeOrderConfiguration : IEntityTypeConfiguration<PointExchangeOrder>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<PointExchangeOrder> builder)
|
||||
{
|
||||
builder.ConfigureTenantEntity("point_exchange_orders");
|
||||
builder.ConfigureTimestamps();
|
||||
builder.Property(entity => entity.OrderNo).HasMaxLength(100);
|
||||
builder.Property(entity => entity.ItemName).HasMaxLength(200);
|
||||
builder.Property(entity => entity.ItemType).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
||||
builder.Property(entity => entity.FulfillmentSnapshot).IsJson("{}");
|
||||
builder.Property(entity => entity.Metadata).IsJson("{}");
|
||||
builder.Property(entity => entity.OrderedAt).HasDefaultValueSql("now()");
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.OrderNo }).IsUnique();
|
||||
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.CreatedAt });
|
||||
builder.HasOne<PointExchangeItem>().WithMany()
|
||||
.HasForeignKey(entity => new { entity.TenantId, entity.ItemId })
|
||||
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UserId).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.ToTable(table =>
|
||||
{
|
||||
table.HasCheckConstraint("ck_point_exchange_orders_points_cost", "points_cost > 0");
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user