using System.Text.Json; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Tiku.Domain.Common; using Tiku.Domain.Tenancy; namespace Tiku.Infrastructure.Persistence.Configurations; internal static class ConfigurationSupport { public static void ConfigureEntity( this EntityTypeBuilder builder, string tableName) where TEntity : Entity { builder.ToTable(tableName); builder.HasKey(entity => entity.Id); builder.Property(entity => entity.Id).HasDefaultValueSql("gen_random_uuid()"); } public static void ConfigureTenantEntity( this EntityTypeBuilder builder, string tableName) where TEntity : TenantEntity { builder.ConfigureEntity(tableName); builder.HasAlternateKey(entity => new { entity.TenantId, entity.Id }); builder.HasOne() .WithMany() .HasForeignKey(entity => entity.TenantId) .OnDelete(DeleteBehavior.Cascade); } public static void ConfigureTimestamps(this EntityTypeBuilder builder) where TEntity : class, IHasTimestamps { builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()"); builder.Property(entity => entity.UpdatedAt).HasDefaultValueSql("now()"); } public static PropertyBuilder IsJson( this PropertyBuilder property, string defaultJson) { return property .HasColumnType("jsonb") .HasDefaultValueSql($"'{defaultJson}'::jsonb"); } public static PropertyBuilder HasSnakeCaseEnum( this PropertyBuilder property, int maxLength = 32) where TEnum : struct, Enum { return property .HasConversion(new SnakeCaseEnumConverter()) .HasMaxLength(maxLength); } public static PropertyBuilder HasNullableSnakeCaseEnum( this PropertyBuilder property, int maxLength = 32) where TEnum : struct, Enum { return property .HasConversion( value => value.HasValue ? ModelBuilderExtensions.ToSnakeCase(value.Value.ToString()) : null, value => string.IsNullOrWhiteSpace(value) ? null : Enum.Parse(value.Replace("_", string.Empty), true)) .HasMaxLength(maxLength); } }