using Microsoft.EntityFrameworkCore; using Serilog; using TriliumMind.Data.Entities; using TriliumMind.Models; namespace TriliumMind.Data; public class PostgresDbContext : DbContext, IAppDbContext { private readonly Serilog.ILogger _log; private readonly string _connectionString; public DbSet Configs { get; set; } public DbSet JiraIssues { get; set; } public PostgresDbContext(AppConfigs configs) { _log = Log.ForContext(); var pgConfig = configs.AppSettings.Database.Postgres; var connectionStringBuilder = new Npgsql.NpgsqlConnectionStringBuilder { Host = pgConfig.Host, Port = pgConfig.Port, Database = pgConfig.Database, Username = pgConfig.Username, Password = pgConfig.Password }; // Set SSL/TLS if (!string.IsNullOrEmpty(pgConfig.SslCertificatePath)) { var certPath = Path.IsPathRooted(pgConfig.SslCertificatePath) ? pgConfig.SslCertificatePath : Path.Combine(AppContext.BaseDirectory, pgConfig.SslCertificatePath); if (File.Exists(certPath)) { _log.Information("Configuring PostgreSQL with SSL certificate: {CertPath}", certPath); connectionStringBuilder.SslMode = Npgsql.SslMode.VerifyFull; connectionStringBuilder.RootCertificate = certPath; } else { _log.Warning("SSL certificate not found at {CertPath}, connecting without SSL", certPath); connectionStringBuilder.SslMode = Npgsql.SslMode.Prefer; } } else { _log.Information("No SSL certificate configured, connecting without SSL"); connectionStringBuilder.SslMode = Npgsql.SslMode.Prefer; } _connectionString = connectionStringBuilder.ConnectionString; _log.Debug("PostgreSQL connection string configured (password hidden)"); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql(_connectionString); protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity(entity => { entity.HasKey(e => e.Key); entity.Property(e => e.Key).IsRequired(); entity.Property(e => e.Value).IsRequired(); }); modelBuilder.Entity(entity => { entity.HasKey(e => e.Key); entity.Property(e => e.Key).IsRequired(); entity.Property(e => e.Summary).IsRequired(); entity.Property(e => e.Type).IsRequired(); entity.Property(e => e.Status).IsRequired(); entity.Property(e => e.Assignee).IsRequired(); entity.Property(e => e.Manager).IsRequired(); entity.Property(e => e.Due).IsRequired(); entity.Property(e => e.Updated).IsRequired(); entity.Property(e => e.Published).IsRequired(); entity.Property(e => e.NeedNotify).IsRequired(); }); } }