using Bimix.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace Bimix.Infrastructure.Data; public class BimixDbContext(DbContextOptions options) : DbContext(options) { public DbSet Products { get; set; } public DbSet SyncStates { get; set; } public DbSet Users { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Product properties modelBuilder.Entity().HasKey(x => x.Id); modelBuilder.Entity().Property(x => x.Name).IsRequired().HasMaxLength(512); modelBuilder.Entity().Property(x => x.Code).IsRequired().HasMaxLength(40); modelBuilder.Entity().Property(x => x.Ean).IsRequired().HasMaxLength(50); modelBuilder.Entity().Property(x => x.StockAddresses).IsRequired().HasMaxLength(512); // SyncState properties modelBuilder.Entity().HasKey((x => x.Entity)); // User properties modelBuilder.Entity().HasKey(x => x.Id); modelBuilder.Entity().Property(x => x.GoogleId).IsRequired().HasMaxLength(100); modelBuilder.Entity().Property(x => x.Email).IsRequired().HasMaxLength(255); modelBuilder.Entity().Property(x => x.FullName).IsRequired().HasMaxLength(255); modelBuilder.Entity().Property(x => x.IsActive).IsRequired().HasDefaultValue(false); modelBuilder.Entity().Property(x => x.LastLoginAt).IsRequired(false); // User indexes modelBuilder.Entity().HasIndex(x => x.GoogleId).IsUnique().HasDatabaseName("IX_Users_GoogleId"); modelBuilder.Entity().HasIndex(x => x.Email).IsUnique().HasDatabaseName("IX_Users_Email"); // Configure defaults for all CreatedAt and UpdatedAt in entities ConfigureBaseEntity(modelBuilder); } private void ConfigureBaseEntity(ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { if (typeof(BaseEntity).IsAssignableFrom(entityType.ClrType)) { modelBuilder.Entity(entityType.ClrType) .Property(nameof(BaseEntity.CreatedAt)) .HasDefaultValueSql("GETUTCDATE()"); modelBuilder.Entity(entityType.ClrType) .Property(nameof(BaseEntity.UpdatedAt)) .HasDefaultValueSql("GETUTCDATE()"); } } } public override int SaveChanges() { UpdateTimestamps(); return base.SaveChanges(); } public override Task SaveChangesAsync(CancellationToken cancellationToken = default) { UpdateTimestamps(); return base.SaveChangesAsync(cancellationToken); } private void UpdateTimestamps() { var entities = ChangeTracker.Entries(); foreach (var entity in entities) { if (entity.State == EntityState.Added) { entity.Entity.CreatedAt = DateTime.UtcNow; entity.Entity.UpdatedAt = DateTime.UtcNow; break; } else if (entity.State == EntityState.Modified) { entity.Entity.UpdatedAt = DateTime.UtcNow; break; } } } }