using Microsoft.EntityFrameworkCore; using Tiku.Domain.Catalog; using Tiku.Domain.Common; using Tiku.Domain.Content; using Tiku.Domain.Identity; using Tiku.Domain.Learning; using Tiku.Domain.QuestionBanks; using Tiku.Domain.Tenancy; namespace Tiku.Infrastructure.Persistence; public sealed class TikuDbContext(DbContextOptions options) : DbContext(options) { public DbSet Tenants => Set(); public DbSet Users => Set(); public DbSet UserIdentities => Set(); public DbSet TenantMemberships => Set(); public DbSet TenantDomains => Set(); public DbSet TenantBrandings => Set(); public DbSet TenantSettings => Set(); public DbSet StudentProfiles => Set(); public DbSet Regions => Set(); public DbSet RegionModules => Set(); public DbSet ModuleNodes => Set(); public DbSet Schools => Set(); public DbSet Majors => Set(); public DbSet Subjects => Set(); public DbSet Categories => Set(); public DbSet QuestionBanks => Set(); public DbSet Questions => Set(); public DbSet QuestionVersions => Set(); public DbSet ContentEntries => Set(); public DbSet ContentNodes => Set(); public DbSet QuestionCollections => Set(); public DbSet QuestionCollectionItems => Set(); public DbSet PracticeBlueprints => Set(); public DbSet VocabularyUnits => Set(); public DbSet VocabularyWords => Set(); public DbSet UserWordProgress => Set(); public DbSet UserWordFavorites => Set(); public DbSet HandbookSubjects => Set(); public DbSet HandbookChapters => Set(); public DbSet HandbookEntries => Set(); public DbSet QuestionTypeGroups => Set(); public DbSet SubjectShares => Set(); public DbSet ContentAssets => Set(); public DbSet ContentImportJobs => Set(); public DbSet ContentImportItems => Set(); public DbSet ContentImportIssues => Set(); public DbSet Images => Set(); public DbSet AppAssets => Set(); public DbSet VideoExplanations => Set(); public DbSet QuestionVideos => Set(); public DbSet PracticeSessions => Set(); public DbSet AnswerRecords => Set(); public DbSet FavoriteQuestions => Set(); public DbSet WrongQuestions => Set(); public DbSet RecentPractices => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasPostgresExtension("citext"); modelBuilder.HasPostgresExtension("ltree"); modelBuilder.ApplyConfigurationsFromAssembly(typeof(TikuDbContext).Assembly); modelBuilder.UseSnakeCaseIdentifiers(); } public override int SaveChanges(bool acceptAllChangesOnSuccess) { UpdateTimestamps(); return base.SaveChanges(acceptAllChangesOnSuccess); } public override Task SaveChangesAsync( bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) { UpdateTimestamps(); return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); } private void UpdateTimestamps() { var now = DateTimeOffset.UtcNow; foreach (var entry in ChangeTracker.Entries()) { if (entry.State == EntityState.Added) { entry.Entity.CreatedAt = now; } if (entry.State is EntityState.Added or EntityState.Modified) { entry.Entity.UpdatedAt = now; } } } }