using System; using System.Collections.Generic; using System.Text.Json; using FinlyticCore.Database; using FinlyticCore.Dtos.Simulation; using FinlyticCore.Entities.Settings; using FinlyticSimulation.Database.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace FinlyticSimulation.Database; public class SimulationDbContext : DbContext, ISettingsDbContext { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = false }; public SimulationDbContext(DbContextOptions options) : base(options) { } public DbSet DynamicSettings => Set(); public DbSet SimulationRuns => Set(); public DbSet StrategyMatrix => Set(); public DbSet StrategyParameters => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 1. Settings Table modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => e.Key).IsUnique(); }); // 2. Report JSONB Converter var reportConverter = new ValueConverter( v => JsonSerializer.Serialize(v, JsonOptions), v => JsonSerializer.Deserialize(v, JsonOptions) ?? new BacktestReportDto( Guid.Empty, "", "", "", "", DateTime.UtcNow, DateTime.UtcNow, 0, 0, 0, 0m, 0m, 0m, 0m, 0m, 0m, 0m, TimeSpan.Zero, new List(), new List()) ); // 3. Simulation Runs Table modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => new { e.Isin, e.StrategyKey, e.Timeframe }); entity.HasIndex(e => e.CreatedAtUtc); entity.Property(e => e.ReportJson) .HasColumnType("jsonb") .HasConversion(reportConverter); }); // 4. Strategy Matrix Table modelBuilder.Entity(entity => { entity.HasKey(e => new { e.Isin, e.StrategyKey, e.Timeframe }); entity.HasIndex(e => new { e.Isin, e.IsApproved }); entity.HasIndex(e => e.ReliabilityScore); }); // 5. Saved Strategy Parameter Profiles Table var parametersConverter = new ValueConverter, string>( v => JsonSerializer.Serialize(v, JsonOptions), v => JsonSerializer.Deserialize>(v, JsonOptions) ?? new Dictionary() ); modelBuilder.Entity(entity => { entity.HasKey(e => new { e.Isin, e.StrategyKey }); entity.Property(e => e.Parameters) .HasColumnType("jsonb") .HasConversion(parametersConverter); }); } } public class SimulationDbContextFactory : IDesignTimeDbContextFactory { public SimulationDbContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseNpgsql("Host=localhost;Database=finlytic_simulation;Username=postgres;Password=postgres"); return new SimulationDbContext(optionsBuilder.Options); } }