using Lutra.Application.Interfaces; using Lutra.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace Lutra.Infrastructure.Sql; public class LutraDbContext : DbContext, ILutraDbContext { public LutraDbContext(DbContextOptions options) : base(options) { } public DbSet Supermarkten => Set(); public DbSet Beoordelingen => Set(); public DbSet VerspakketFotos => Set(); public DbSet Verspaketten => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Global soft-delete filter: exclude logically deleted entities from all queries. modelBuilder.Entity().HasQueryFilter(b => !b.IsDeleted); modelBuilder.Entity().HasQueryFilter(f => !f.IsDeleted); modelBuilder.Entity().HasQueryFilter(s => !s.IsDeleted); modelBuilder.Entity(b => { b.HasQueryFilter(v => !v.IsDeleted); b.HasMany(v => v.Beoordelingen) .WithOne() .HasForeignKey(beo => beo.VerspakketId) .IsRequired(); b.HasMany(v => v.Fotos) .WithOne() .HasForeignKey(foto => foto.VerspakketId) .IsRequired(); b.ToTable(t => { t.HasCheckConstraint("CK_Verspaketten_AantalPersonen", "\"AantalPersonen\" BETWEEN 1 AND 10"); t.HasCheckConstraint("CK_Verspaketten_PrijsInCenten", "\"PrijsInCenten\" IS NULL OR \"PrijsInCenten\" >= 0"); }); }); } /// /// Populates audit fields on tracked entities before persisting. /// public override Task SaveChangesAsync(CancellationToken cancellationToken = default) { var now = DateTime.UtcNow; foreach (var entry in ChangeTracker.Entries()) { switch (entry.State) { case EntityState.Added: entry.Entity.CreatedAt = now; entry.Entity.ModifiedAt = now; break; case EntityState.Modified: entry.Entity.ModifiedAt = now; break; } } return base.SaveChangesAsync(cancellationToken); } }