using Microsoft.EntityFrameworkCore; using StellaOps.Integrations.Core; namespace StellaOps.Integrations.Persistence; /// /// EF Core DbContext for Integration persistence. /// SQL migrations remain authoritative; EF models are scaffolded FROM schema. /// public partial class IntegrationDbContext : DbContext { public const string DefaultSchemaName = "integrations"; private readonly string _schemaName; public IntegrationDbContext(DbContextOptions options, string? schemaName = null) : base(options) { _schemaName = string.IsNullOrWhiteSpace(schemaName) ? DefaultSchemaName : schemaName.Trim(); } public DbSet Integrations => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { var schemaName = _schemaName; modelBuilder.Entity(entity => { entity.ToTable("integrations", schemaName); entity.HasKey(e => e.Id); entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.Name).HasColumnName("name").HasMaxLength(256).IsRequired(); entity.Property(e => e.Description).HasColumnName("description").HasMaxLength(1024); entity.Property(e => e.Type).HasConversion().HasColumnType("text").HasColumnName("type").IsRequired(); entity.Property(e => e.Provider).HasConversion().HasColumnType("text").HasColumnName("provider").IsRequired(); entity.Property(e => e.Status).HasConversion().HasColumnType("text").HasColumnName("status").IsRequired(); entity.Property(e => e.Endpoint).HasColumnName("endpoint").HasMaxLength(2048).IsRequired(); entity.Property(e => e.AuthRefUri).HasColumnName("auth_ref_uri").HasMaxLength(1024); entity.Property(e => e.OrganizationId).HasColumnName("organization_id").HasMaxLength(256); entity.Property(e => e.ConfigJson).HasColumnName("config_json").HasColumnType("jsonb"); entity.Property(e => e.LastHealthStatus).HasConversion().HasColumnType("text").HasColumnName("last_health_status"); entity.Property(e => e.LastHealthCheckAt).HasColumnName("last_health_check_at"); entity.Property(e => e.CreatedAt).HasColumnName("created_at").IsRequired(); entity.Property(e => e.UpdatedAt).HasColumnName("updated_at").IsRequired(); entity.Property(e => e.CreatedBy).HasColumnName("created_by").HasMaxLength(256); entity.Property(e => e.UpdatedBy).HasColumnName("updated_by").HasMaxLength(256); entity.Property(e => e.TenantId).HasColumnName("tenant_id").HasMaxLength(128); entity.Property(e => e.TagsJson).HasColumnName("tags").HasColumnType("jsonb"); entity.Property(e => e.IsDeleted).HasColumnName("is_deleted").IsRequired(); entity.HasIndex(e => e.Type); entity.HasIndex(e => e.Provider); entity.HasIndex(e => e.Status); entity.HasIndex(e => e.TenantId); entity.HasIndex(e => new { e.TenantId, e.Name }).IsUnique().HasFilter("is_deleted = false"); }); OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } /// /// EF Core entity for Integration. /// public sealed class IntegrationEntity { public Guid Id { get; set; } public string Name { get; set; } = string.Empty; public string? Description { get; set; } public IntegrationType Type { get; set; } public IntegrationProvider Provider { get; set; } public IntegrationStatus Status { get; set; } public string Endpoint { get; set; } = string.Empty; public string? AuthRefUri { get; set; } public string? OrganizationId { get; set; } public string? ConfigJson { get; set; } public HealthStatus LastHealthStatus { get; set; } public DateTimeOffset? LastHealthCheckAt { get; set; } public DateTimeOffset CreatedAt { get; set; } public DateTimeOffset UpdatedAt { get; set; } public string? CreatedBy { get; set; } public string? UpdatedBy { get; set; } public string? TenantId { get; set; } public string? TagsJson { get; set; } public bool IsDeleted { get; set; } }