Files
tiku-backend.net/Tiku.Infrastructure/Persistence/Configurations/OperationsConfigurations.cs

497 lines
26 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Tiku.Domain.Catalog;
using Tiku.Domain.Content;
using Tiku.Domain.Identity;
using Tiku.Domain.Operations;
using Tiku.Domain.Platform;
using Tiku.Domain.QuestionBanks;
using Tiku.Domain.Tenancy;
namespace Tiku.Infrastructure.Persistence.Configurations;
internal sealed class BannerConfiguration : IEntityTypeConfiguration<Banner>
{
public void Configure(EntityTypeBuilder<Banner> builder)
{
builder.ConfigureTenantEntity("banners");
builder.ConfigureTimestamps();
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
builder.Property(entity => entity.Title).HasMaxLength(300);
builder.Property(entity => entity.Subtitle).HasMaxLength(500);
builder.Property(entity => entity.ButtonText).HasMaxLength(100);
builder.Property(entity => entity.ButtonLink).HasMaxLength(2048);
builder.Property(entity => entity.BackgroundColor).HasMaxLength(50);
builder.Property(entity => entity.BorderColor).HasMaxLength(50);
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.RegionId, entity.IsActive, entity.SortOrder });
builder.HasOne<Region>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class FaqConfiguration : IEntityTypeConfiguration<Faq>
{
public void Configure(EntityTypeBuilder<Faq> builder)
{
builder.ConfigureTenantEntity("faqs");
builder.ConfigureTimestamps();
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.RegionId, entity.IsActive, entity.SortOrder });
builder.HasOne<Region>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class AnnouncementConfiguration : IEntityTypeConfiguration<Announcement>
{
public void Configure(EntityTypeBuilder<Announcement> builder)
{
builder.ConfigureTenantEntity("announcements");
builder.ConfigureTimestamps();
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
builder.Property(entity => entity.Link).HasMaxLength(2048);
builder.Property(entity => entity.BackgroundColor).HasMaxLength(50);
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.IsActive, entity.SortOrder });
}
}
internal sealed class AuditLogConfiguration : IEntityTypeConfiguration<AuditLog>
{
public void Configure(EntityTypeBuilder<AuditLog> builder)
{
builder.ConfigureEntity("audit_logs");
builder.Property(entity => entity.Action).HasMaxLength(200);
builder.Property(entity => entity.TargetType).HasMaxLength(200);
builder.Property(entity => entity.TargetId).HasMaxLength(200);
builder.Property(entity => entity.Details).IsJson("{}");
builder.Property(entity => entity.IpAddress).HasMaxLength(100);
builder.Property(entity => entity.UserAgent).HasMaxLength(1024);
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasIndex(entity => new { entity.TenantId, entity.CreatedAt });
builder.HasIndex(entity => new { entity.TenantId, entity.TargetType, entity.TargetId, entity.CreatedAt });
builder.HasOne<Tenant>().WithMany().HasForeignKey(entity => entity.TenantId).OnDelete(DeleteBehavior.Cascade);
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.ActorUserId).OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class BackendPermissionConfiguration : IEntityTypeConfiguration<BackendPermission>
{
public void Configure(EntityTypeBuilder<BackendPermission> builder)
{
builder.ConfigureEntity("backend_permissions");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Code).HasMaxLength(160);
builder.Property(entity => entity.Name).HasMaxLength(200);
builder.Property(entity => entity.Area).HasSnakeCaseEnum();
builder.Property(entity => entity.PermissionModuleCode).HasMaxLength(120);
builder.Property(entity => entity.Description).HasMaxLength(1000);
builder.HasIndex(entity => entity.Code).IsUnique();
builder.HasIndex(entity => new { entity.Area, entity.PermissionModuleCode, entity.SortOrder });
builder.HasOne<PermissionModule>().WithMany()
.HasPrincipalKey(entity => entity.Code)
.HasForeignKey(entity => entity.PermissionModuleCode)
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class BackendMenuConfiguration : IEntityTypeConfiguration<BackendMenu>
{
public void Configure(EntityTypeBuilder<BackendMenu> builder)
{
builder.ConfigureEntity("backend_menus");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Code).HasMaxLength(160);
builder.Property(entity => entity.ParentCode).HasMaxLength(160);
builder.Property(entity => entity.Title).HasMaxLength(200);
builder.Property(entity => entity.Area).HasSnakeCaseEnum();
builder.Property(entity => entity.Path).HasMaxLength(1024);
builder.Property(entity => entity.Icon).HasMaxLength(100);
builder.Property(entity => entity.PermissionCode).HasMaxLength(160);
builder.HasIndex(entity => entity.Code).IsUnique();
builder.HasIndex(entity => new { entity.Area, entity.ParentCode, entity.SortOrder });
builder.HasOne<BackendPermission>().WithMany()
.HasPrincipalKey(entity => entity.Code)
.HasForeignKey(entity => entity.PermissionCode)
.OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class TenantBackendRoleConfiguration : IEntityTypeConfiguration<TenantBackendRole>
{
public void Configure(EntityTypeBuilder<TenantBackendRole> builder)
{
builder.ConfigureTenantEntity("tenant_backend_roles");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Code).HasMaxLength(100);
builder.Property(entity => entity.Name).HasMaxLength(200);
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.Description).HasMaxLength(1000);
builder.Property(entity => entity.DataScope).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.Code }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.Status, entity.Code });
}
}
internal sealed class TenantBackendRolePermissionConfiguration : IEntityTypeConfiguration<TenantBackendRolePermission>
{
public void Configure(EntityTypeBuilder<TenantBackendRolePermission> builder)
{
builder.ConfigureEntity("tenant_backend_role_permissions");
builder.Property(entity => entity.PermissionCode).HasMaxLength(160);
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasAlternateKey(entity => new { entity.TenantId, entity.Id });
builder.HasIndex(entity => new { entity.TenantId, entity.RoleId, entity.PermissionCode }).IsUnique();
builder.HasOne<TenantBackendRole>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.RoleId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<BackendPermission>().WithMany()
.HasPrincipalKey(entity => entity.Code)
.HasForeignKey(entity => entity.PermissionCode)
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class TenantBackendRoleMenuConfiguration : IEntityTypeConfiguration<TenantBackendRoleMenu>
{
public void Configure(EntityTypeBuilder<TenantBackendRoleMenu> builder)
{
builder.ConfigureEntity("tenant_backend_role_menus");
builder.Property(entity => entity.MenuCode).HasMaxLength(160);
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasAlternateKey(entity => new { entity.TenantId, entity.Id });
builder.HasIndex(entity => new { entity.TenantId, entity.RoleId, entity.MenuCode }).IsUnique();
builder.HasOne<TenantBackendRole>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.RoleId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<BackendMenu>().WithMany()
.HasPrincipalKey(entity => entity.Code)
.HasForeignKey(entity => entity.MenuCode)
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class TenantBackendUserRoleConfiguration : IEntityTypeConfiguration<TenantBackendUserRole>
{
public void Configure(EntityTypeBuilder<TenantBackendUserRole> builder)
{
builder.ConfigureEntity("tenant_backend_user_roles");
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasAlternateKey(entity => new { entity.TenantId, entity.Id });
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.RoleId }).IsUnique();
builder.HasOne<TenantBackendRole>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.RoleId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<User>().WithMany()
.HasForeignKey(entity => entity.UserId)
.OnDelete(DeleteBehavior.Cascade);
}
}
internal sealed class PlatformBackendRoleConfiguration : IEntityTypeConfiguration<PlatformBackendRole>
{
public void Configure(EntityTypeBuilder<PlatformBackendRole> builder)
{
builder.ConfigureEntity("platform_backend_roles");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Code).HasMaxLength(100);
builder.Property(entity => entity.Name).HasMaxLength(200);
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.Description).HasMaxLength(1000);
builder.HasIndex(entity => entity.Code).IsUnique();
builder.HasIndex(entity => new { entity.Status, entity.Code });
}
}
internal sealed class PlatformBackendRolePermissionConfiguration : IEntityTypeConfiguration<PlatformBackendRolePermission>
{
public void Configure(EntityTypeBuilder<PlatformBackendRolePermission> builder)
{
builder.ConfigureEntity("platform_backend_role_permissions");
builder.Property(entity => entity.PermissionCode).HasMaxLength(160);
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasIndex(entity => new { entity.RoleId, entity.PermissionCode }).IsUnique();
builder.HasOne<PlatformBackendRole>().WithMany()
.HasForeignKey(entity => entity.RoleId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<BackendPermission>().WithMany()
.HasPrincipalKey(entity => entity.Code)
.HasForeignKey(entity => entity.PermissionCode)
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class PlatformBackendRoleMenuConfiguration : IEntityTypeConfiguration<PlatformBackendRoleMenu>
{
public void Configure(EntityTypeBuilder<PlatformBackendRoleMenu> builder)
{
builder.ConfigureEntity("platform_backend_role_menus");
builder.Property(entity => entity.MenuCode).HasMaxLength(160);
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasIndex(entity => new { entity.RoleId, entity.MenuCode }).IsUnique();
builder.HasOne<PlatformBackendRole>().WithMany()
.HasForeignKey(entity => entity.RoleId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<BackendMenu>().WithMany()
.HasPrincipalKey(entity => entity.Code)
.HasForeignKey(entity => entity.MenuCode)
.OnDelete(DeleteBehavior.Restrict);
}
}
internal sealed class PlatformBackendUserRoleConfiguration : IEntityTypeConfiguration<PlatformBackendUserRole>
{
public void Configure(EntityTypeBuilder<PlatformBackendUserRole> builder)
{
builder.ConfigureEntity("platform_backend_user_roles");
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.HasIndex(entity => new { entity.UserId, entity.RoleId }).IsUnique();
builder.HasOne<PlatformBackendRole>().WithMany()
.HasForeignKey(entity => entity.RoleId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<User>().WithMany()
.HasForeignKey(entity => entity.UserId)
.OnDelete(DeleteBehavior.Cascade);
}
}
internal sealed class AuthorizationScopeVersionConfiguration : IEntityTypeConfiguration<AuthorizationScopeVersion>
{
public void Configure(EntityTypeBuilder<AuthorizationScopeVersion> builder)
{
builder.ConfigureEntity("authorization_scope_versions");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Realm).HasSnakeCaseEnum();
builder.Property(entity => entity.Version).HasDefaultValue(1L).IsConcurrencyToken();
builder.ToTable("authorization_scope_versions", table => table.HasCheckConstraint(
"ck_authorization_scope_versions_realm_tenant",
"(realm = 'tenant' and tenant_id is not null) or (realm = 'platform' and tenant_id is null)"));
builder.HasIndex(entity => entity.TenantId)
.IsUnique()
.HasFilter("tenant_id is not null");
builder.HasIndex(entity => entity.Realm)
.IsUnique()
.HasFilter("realm = 'platform'");
builder.HasOne<Tenant>().WithMany().HasForeignKey(entity => entity.TenantId).OnDelete(DeleteBehavior.Cascade);
}
}
internal sealed class AuthorizationCacheInvalidationConfiguration : IEntityTypeConfiguration<AuthorizationCacheInvalidation>
{
public void Configure(EntityTypeBuilder<AuthorizationCacheInvalidation> builder)
{
builder.ConfigureEntity("authorization_cache_invalidations");
builder.ConfigureTimestamps();
builder.Property(entity => entity.TargetType).HasMaxLength(40);
builder.Property(entity => entity.Realm).HasConversion(
value => value.HasValue ? value.Value.ToString().ToLowerInvariant() : null,
value => value == null ? null : Enum.Parse<AuthRealm>(value, true));
builder.Property(entity => entity.LastError).HasMaxLength(2000);
builder.HasIndex(entity => new { entity.ProcessedAt, entity.CreatedAt });
builder.HasIndex(entity => new { entity.TargetType, entity.TenantId, entity.UserId, entity.SessionId, entity.Version });
}
}
internal sealed class BackgroundJobConfiguration : IEntityTypeConfiguration<BackgroundJob>
{
public void Configure(EntityTypeBuilder<BackgroundJob> builder)
{
builder.ConfigureTenantEntity("background_jobs");
builder.ConfigureTimestamps();
builder.Property(entity => entity.JobType).HasMaxLength(100);
builder.Property(entity => entity.IdempotencyKey).HasMaxLength(200);
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.Payload).IsJson("{}");
builder.Property(entity => entity.LockedBy).HasMaxLength(200);
builder.Property(entity => entity.LastError).HasMaxLength(4000);
builder.Property(entity => entity.CancellationReason).HasMaxLength(1000);
builder.Property(entity => entity.Result).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.Status, entity.RunAfter, entity.CreatedAt });
builder.HasIndex(entity => new { entity.TenantId, entity.JobType, entity.Status, entity.CreatedAt });
builder.HasIndex(entity => new { entity.TenantId, entity.JobType, entity.IdempotencyKey })
.IsUnique()
.HasFilter("idempotency_key is not null");
builder.HasOne<ContentAsset>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.OutputAssetId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class TenantLifecycleOperationConfiguration : IEntityTypeConfiguration<TenantLifecycleOperation>
{
public void Configure(EntityTypeBuilder<TenantLifecycleOperation> builder)
{
builder.ConfigureTenantEntity("tenant_lifecycle_operations");
builder.ConfigureTimestamps();
builder.Property(entity => entity.OperationType).HasSnakeCaseEnum();
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.Reason).HasMaxLength(1000);
builder.Property(entity => entity.LastError).HasMaxLength(4000);
builder.Property(entity => entity.Result).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.OperationType, entity.Status, entity.CreatedAt });
builder.HasOne<ContentAsset>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.ExportAssetId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class WorkerHeartbeatConfiguration : IEntityTypeConfiguration<WorkerHeartbeat>
{
public void Configure(EntityTypeBuilder<WorkerHeartbeat> builder)
{
builder.ConfigureEntity("worker_heartbeats");
builder.Property(entity => entity.WorkerId).HasMaxLength(200);
builder.Property(entity => entity.Processor).HasMaxLength(100);
builder.Property(entity => entity.LastError).HasMaxLength(4000);
builder.HasIndex(entity => new { entity.WorkerId, entity.Processor }).IsUnique();
builder.HasIndex(entity => new { entity.Processor, entity.LastHeartbeatAt });
}
}
internal sealed class UserNotificationConfiguration : IEntityTypeConfiguration<UserNotification>
{
public void Configure(EntityTypeBuilder<UserNotification> builder)
{
builder.ConfigureTenantEntity("user_notifications");
builder.ConfigureTimestamps();
builder.Property(entity => entity.NotificationType).HasMaxLength(100);
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.Severity).HasSnakeCaseEnum();
builder.Property(entity => entity.Title).HasMaxLength(300);
builder.Property(entity => entity.ActionLabel).HasMaxLength(100);
builder.Property(entity => entity.ActionPath).HasMaxLength(2048);
builder.Property(entity => entity.SourceType).HasMaxLength(100);
builder.Property(entity => entity.DedupeKey).HasMaxLength(200);
builder.Property(entity => entity.Metadata).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.NotificationType, entity.DedupeKey })
.IsUnique()
.HasFilter("dedupe_key is not null");
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.Status, entity.CreatedAt });
builder.HasIndex(entity => new { entity.TenantId, entity.SourceType, entity.SourceId });
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UserId).OnDelete(DeleteBehavior.Cascade);
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.CreatedBy).OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class BadgeConfiguration : IEntityTypeConfiguration<Badge>
{
public void Configure(EntityTypeBuilder<Badge> builder)
{
builder.ConfigureTenantEntity("badges");
builder.ConfigureTimestamps();
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
builder.Property(entity => entity.Name).HasMaxLength(200);
builder.Property(entity => entity.Category).HasMaxLength(100);
builder.Property(entity => entity.IconUrl).HasMaxLength(2048);
builder.Property(entity => entity.UnlockType).HasMaxLength(100);
builder.Property(entity => entity.ConditionField).HasMaxLength(100);
builder.Property(entity => entity.ConditionOperator).HasMaxLength(50);
builder.Property(entity => entity.ConditionValue).HasPrecision(18, 4);
builder.Property(entity => entity.ConditionExtra).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.Category, entity.IsActive, entity.SortOrder });
}
}
internal sealed class UserBadgeConfiguration : IEntityTypeConfiguration<UserBadge>
{
public void Configure(EntityTypeBuilder<UserBadge> builder)
{
builder.ConfigureTenantEntity("user_badges");
builder.ConfigureTimestamps();
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
builder.HasIndex(entity => new { entity.TenantId, entity.UserId, entity.BadgeId }).IsUnique();
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.UserId).OnDelete(DeleteBehavior.Cascade);
builder.HasOne<Badge>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.BadgeId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.GrantedBy).OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class TenantContentNotificationConfiguration : IEntityTypeConfiguration<TenantContentNotification>
{
public void Configure(EntityTypeBuilder<TenantContentNotification> builder)
{
builder.ConfigureTenantEntity("tenant_content_notifications");
builder.ConfigureTimestamps();
builder.Property(entity => entity.NotificationType).HasSnakeCaseEnum();
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.Property(entity => entity.Severity).HasSnakeCaseEnum();
builder.Property(entity => entity.Title).HasMaxLength(300);
builder.Property(entity => entity.ActionLabel).HasMaxLength(100);
builder.Property(entity => entity.ActionPath).HasMaxLength(2048);
builder.Property(entity => entity.DedupeKey).HasMaxLength(200);
builder.Property(entity => entity.Metadata).IsJson("{}");
builder.HasIndex(entity => new { entity.TenantId, entity.NotificationType, entity.DedupeKey })
.IsUnique()
.HasFilter("dedupe_key is not null");
builder.HasIndex(entity => new { entity.TenantId, entity.Status, entity.CreatedAt });
builder.HasIndex(entity => new { entity.TenantId, entity.AdoptionId, entity.NotificationType, entity.Status });
builder.HasOne<QuestionBank>().WithMany()
.HasForeignKey(entity => new { entity.TenantId, entity.SourceQuestionBankId })
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
.OnDelete(DeleteBehavior.Cascade);
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.CreatedBy).OnDelete(DeleteBehavior.SetNull);
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.ReadBy).OnDelete(DeleteBehavior.SetNull);
}
}
internal sealed class TenantThemeTemplateConfiguration : IEntityTypeConfiguration<TenantThemeTemplate>
{
public void Configure(EntityTypeBuilder<TenantThemeTemplate> builder)
{
builder.ConfigureEntity("tenant_theme_templates");
builder.ConfigureTimestamps();
builder.Property(entity => entity.Code).HasMaxLength(100);
builder.Property(entity => entity.Name).HasMaxLength(200);
builder.Property(entity => entity.PreviewImageUrl).HasMaxLength(2048);
builder.Property(entity => entity.Theme).IsJson("{}");
builder.Property(entity => entity.PublicAssets).IsJson("{}");
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.HasAlternateKey(entity => entity.Code);
builder.HasIndex(entity => entity.Code).IsUnique();
builder.HasIndex(entity => new { entity.Status, entity.SortOrder, entity.Code });
}
}
internal sealed class TenantThemeConfigConfiguration : IEntityTypeConfiguration<TenantThemeConfig>
{
public void Configure(EntityTypeBuilder<TenantThemeConfig> builder)
{
builder.ConfigureTenantEntity("tenant_theme_configs");
builder.ConfigureTimestamps();
builder.Property(entity => entity.ActiveTemplateCode).HasMaxLength(100);
builder.Property(entity => entity.ActiveTheme).IsJson("{}");
builder.Property(entity => entity.ActivePublicAssets).IsJson("{}");
builder.Property(entity => entity.DraftTemplateCode).HasMaxLength(100);
builder.Property(entity => entity.DraftTheme).IsJson("{}");
builder.Property(entity => entity.DraftPublicAssets).IsJson("{}");
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
builder.HasIndex(entity => entity.TenantId).IsUnique();
builder.HasOne<TenantThemeTemplate>().WithMany()
.HasForeignKey(entity => entity.ActiveTemplateCode)
.HasPrincipalKey(entity => entity.Code)
.OnDelete(DeleteBehavior.SetNull);
builder.HasOne<TenantThemeTemplate>().WithMany()
.HasForeignKey(entity => entity.DraftTemplateCode)
.HasPrincipalKey(entity => entity.Code)
.OnDelete(DeleteBehavior.SetNull);
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.PublishedBy).OnDelete(DeleteBehavior.SetNull);
builder.HasOne<User>().WithMany().HasForeignKey(entity => entity.DraftUpdatedBy).OnDelete(DeleteBehavior.SetNull);
}
}