using FlowAPI.Domain.Entities; using FlowAPI.Domain.Enums; using Microsoft.EntityFrameworkCore; namespace FlowAPI.Infrastructure.Data { public class AppDbContext : DbContext { public AppDbContext(DbContextOptions options) : base(options) { } public DbSet Users => Set(); public DbSet Graphs => Set(); public DbSet TaskNodes => Set(); public DbSet Edges => Set(); public DbSet HabitRecords => Set(); public DbSet Achievements => Set(); public DbSet UserAchievements => Set(); public DbSet SharedGraphs => Set(); public DbSet CustomTemplates => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // User modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasIndex(e => e.Email).IsUnique(); entity.Property(e => e.Email).IsRequired().HasMaxLength(256); entity.Property(e => e.PasswordHash).IsRequired(); entity.Property(e => e.DisplayName).HasMaxLength(100); entity.Property(e => e.SubscriptionTier).HasDefaultValue("Free").HasMaxLength(50); }); // Graph modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.Property(e => e.Title).IsRequired().HasMaxLength(200); entity.Property(e => e.Description).HasMaxLength(1000); entity.HasOne(e => e.User) .WithMany(u => u.Graphs) .HasForeignKey(e => e.UserId) .OnDelete(DeleteBehavior.Cascade); }); // TaskNode modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.Property(e => e.Label).IsRequired().HasMaxLength(1000); entity.Property(e => e.State) .HasConversion() .HasDefaultValue(NodeState.Pending); entity.Property(e => e.Type).HasMaxLength(100).HasDefaultValue("sketch"); entity.Property(e => e.Decision).HasMaxLength(1000000); entity.Property(e => e.Data).HasMaxLength(10000000); // Support up to ~10MB images entity.Property(e => e.Description).HasMaxLength(10000); entity.Property(e => e.Color).HasMaxLength(100); entity.HasOne(e => e.Graph) .WithMany(g => g.Nodes) .HasForeignKey(e => e.GraphId) .OnDelete(DeleteBehavior.Cascade); }); // Edge modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.Property(e => e.Condition).HasMaxLength(500); entity.HasOne(e => e.Graph) .WithMany(g => g.Edges) .HasForeignKey(e => e.GraphId) .OnDelete(DeleteBehavior.Cascade); entity.HasOne(e => e.FromNode) .WithMany(n => n.OutgoingEdges) .HasForeignKey(e => e.FromNodeId) .OnDelete(DeleteBehavior.Cascade); entity.HasOne(e => e.ToNode) .WithMany(n => n.IncomingEdges) .HasForeignKey(e => e.ToNodeId) .OnDelete(DeleteBehavior.Cascade); }); // HabitRecord modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.Property(e => e.HabitName).IsRequired().HasMaxLength(100); entity.HasOne(e => e.User) .WithMany(u => u.HabitRecords) .HasForeignKey(e => e.UserId) .OnDelete(DeleteBehavior.Cascade); }); // Achievement modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.Property(e => e.Title).IsRequired().HasMaxLength(200); entity.Property(e => e.Category).HasMaxLength(100); entity.Property(e => e.TriggerEventName).HasMaxLength(100); }); // UserAchievement modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasOne(e => e.User) .WithMany(u => u.UserAchievements) .HasForeignKey(e => e.UserId) .OnDelete(DeleteBehavior.Cascade); entity.HasOne(e => e.Achievement) .WithMany() .HasForeignKey(e => e.AchievementId) .OnDelete(DeleteBehavior.Cascade); }); // SharedGraph modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.Property(e => e.Permission).IsRequired().HasMaxLength(50).HasDefaultValue("Read"); entity.HasOne(e => e.Graph) .WithMany(g => g.SharedGraphs) .HasForeignKey(e => e.GraphId) .OnDelete(DeleteBehavior.Cascade); entity.HasOne(e => e.SharedWithUser) .WithMany(u => u.SharedGraphs) .HasForeignKey(e => e.SharedWithUserId) .OnDelete(DeleteBehavior.Cascade); entity.HasIndex(e => new { e.GraphId, e.SharedWithUserId }).IsUnique(); }); // CustomTemplate modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.Property(e => e.Title).IsRequired().HasMaxLength(200); entity.Property(e => e.Description).HasMaxLength(1000); entity.Property(e => e.Category).HasMaxLength(100); entity.Property(e => e.Icon).HasMaxLength(100); entity.Property(e => e.ContentJson).IsRequired().HasMaxLength(10000000); entity.HasOne(e => e.User) .WithMany() .HasForeignKey(e => e.UserId) .OnDelete(DeleteBehavior.Cascade); }); } } }