using FinlyticCore.Database; using FinlyticCore.Entities.Settings; using FinlyticSentiment.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; namespace FinlyticSentiment.Database; /// /// EF Core DbContext for managing FinlyticSentiment persistent entities and dynamic settings. /// public class SentimentDbContext : DbContext, ISettingsDbContext { public SentimentDbContext(DbContextOptions options) : base(options) { } public DbSet DynamicSettings => Set(); public DbSet ArticleSentiments => Set(); public DbSet CompanySentiments => Set(); public DbSet SectorSentiments => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Dynamic Settings modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => e.Key).IsUnique(); }); // Individual Article Sentiments modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); // Prevent duplicate analysis of the same article for the same asset entity.HasIndex(e => new { e.ArticleId, e.Isin }).IsUnique(); // High-performance time-series index for timeline charts & time-decay scans entity.HasIndex(e => new { e.Isin, e.PublishedAtUtc }); entity.HasIndex(e => e.AnalyzedAtUtc); entity.HasIndex(e => e.Sector); }); // Pre-Aggregated Company Sentiment Summaries modelBuilder.Entity(entity => { entity.HasKey(e => e.Isin); entity.HasIndex(e => e.Sector); entity.HasIndex(e => e.WeightedScore); entity.HasIndex(e => e.LastUpdatedUtc); }); // Pre-Aggregated Sector Sentiment Summaries modelBuilder.Entity(entity => { entity.HasKey(e => e.Sector); entity.HasIndex(e => e.LastUpdatedUtc); }); } } public class SentimentDbContextFactory : IDesignTimeDbContextFactory { public SentimentDbContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseNpgsql("Host=localhost;Database=sentiment;Username=postgres;Password=postgres"); return new SentimentDbContext(optionsBuilder.Options); } }