using MealPlan.Api.Models;
using Microsoft.EntityFrameworkCore;
namespace MealPlan.Api.Data;
///
/// Database-first context for the existing PostgreSQL database.
/// Tables are mapped explicitly; this context never creates or alters schema.
///
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions options) : base(options)
{
}
public DbSet Recipes => Set();
public DbSet Ingredients => Set();
public DbSet RecipeSteps => Set();
public DbSet Users => Set();
public DbSet UserDailyGoals => Set();
public DbSet DrinkCatalog => Set();
public DbSet MealConsumptions => Set();
public DbSet DrinkConsumptions => Set();
public DbSet DietReminders => Set();
public DbSet IngredientCategories => Set();
public DbSet IngredientNutritionCatalog => Set();
public DbSet RefreshTokens => Set();
public DbSet MealPlanEntries => Set();
public DbSet UserFavoriteRecipes => Set();
public DbSet UserFavoriteCatalogItems => Set();
public DbSet DietUserProfiles => Set();
public DbSet DietGeneratorSessions => Set();
public DbSet DietGeneratorDraftMeals => Set();
public DbSet DietGeneratorDraftMealIngredients =>
Set();
public DbSet RecipeGeneratorSessions => Set();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("diet");
modelBuilder.Entity(e =>
{
e.HasKey(r => r.Id);
e.Property(r => r.Id).UseIdentityByDefaultColumn();
e.Property(r => r.Protein).HasColumnType("numeric(6,2)");
e.Property(r => r.Fat).HasColumnType("numeric(6,2)");
e.Property(r => r.Carbs).HasColumnType("numeric(6,2)");
e.HasMany(r => r.Ingredients)
.WithOne(i => i.Recipe!)
.HasForeignKey(i => i.RecipeId)
.OnDelete(DeleteBehavior.Cascade);
e.HasMany(r => r.Steps)
.WithOne(s => s.Recipe!)
.HasForeignKey(s => s.RecipeId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(i => i.Id);
e.Property(i => i.Id).UseIdentityByDefaultColumn();
e.Property(i => i.AmountGrams).HasColumnType("numeric(8,2)");
e.HasOne(i => i.CatalogItem)
.WithMany()
.HasForeignKey(i => i.CatalogItemId)
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity(e =>
{
e.HasKey(s => s.Id);
e.Property(s => s.Id).UseIdentityByDefaultColumn();
});
modelBuilder.Entity(e =>
{
e.HasKey(u => u.Id);
e.Property(u => u.Id).HasColumnType("uuid");
});
modelBuilder.Entity(e =>
{
e.HasKey(g => g.UserId);
e.Property(g => g.UserId).HasColumnType("uuid");
e.Property(g => g.ProteinGoalG).HasColumnType("numeric(6,2)");
e.Property(g => g.FatGoalG).HasColumnType("numeric(6,2)");
e.Property(g => g.CarbsGoalG).HasColumnType("numeric(6,2)");
e.HasOne(g => g.User)
.WithMany()
.HasForeignKey(g => g.UserId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(d => d.Id);
e.Property(d => d.Id).UseIdentityByDefaultColumn();
e.Property(d => d.CaloriesPer100Ml).HasColumnType("numeric(6,2)");
});
modelBuilder.Entity(e =>
{
e.HasKey(m => m.Id);
e.Property(m => m.Id).UseIdentityByDefaultColumn();
e.Property(m => m.UserId).HasColumnType("uuid");
e.Property(m => m.Portions).HasColumnType("numeric(4,2)");
e.Property(m => m.ProteinG).HasColumnType("numeric(6,2)");
e.Property(m => m.FatG).HasColumnType("numeric(6,2)");
e.Property(m => m.CarbsG).HasColumnType("numeric(6,2)");
e.HasOne(m => m.User)
.WithMany()
.HasForeignKey(m => m.UserId)
.OnDelete(DeleteBehavior.Cascade);
e.HasOne(m => m.Recipe)
.WithMany()
.HasForeignKey(m => m.RecipeId)
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity(e =>
{
e.HasKey(d => d.Id);
e.Property(d => d.Id).UseIdentityByDefaultColumn();
e.Property(d => d.UserId).HasColumnType("uuid");
e.HasOne(d => d.User)
.WithMany()
.HasForeignKey(d => d.UserId)
.OnDelete(DeleteBehavior.Cascade);
e.HasOne(d => d.DrinkCatalog)
.WithMany()
.HasForeignKey(d => d.DrinkCatalogId)
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity(e =>
{
e.HasKey(r => r.Id);
e.Property(r => r.Id).UseIdentityByDefaultColumn();
e.Property(r => r.UserId).HasColumnType("uuid");
e.HasOne(r => r.User)
.WithMany()
.HasForeignKey(r => r.UserId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(c => c.Id);
e.Property(c => c.Id).UseIdentityByDefaultColumn();
});
modelBuilder.Entity(e =>
{
e.HasKey(i => i.Id);
e.Property(i => i.Id).UseIdentityByDefaultColumn();
e.Property(i => i.ProteinGPer100G).HasColumnType("numeric(6,2)");
e.Property(i => i.FatGPer100G).HasColumnType("numeric(6,2)");
e.Property(i => i.CarbsGPer100G).HasColumnType("numeric(6,2)");
e.Property(i => i.FiberGPer100G).HasColumnType("numeric(6,2)");
e.HasOne(i => i.Category)
.WithMany(c => c.Items)
.HasForeignKey(i => i.CategoryId)
.OnDelete(DeleteBehavior.Restrict);
});
modelBuilder.Entity(e =>
{
e.HasKey(t => t.Token);
e.Property(t => t.UserId).HasColumnType("uuid");
e.HasOne(t => t.User)
.WithMany()
.HasForeignKey(t => t.UserId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(m => m.Id);
e.Property(m => m.Id).UseIdentityByDefaultColumn();
e.Property(m => m.UserId).HasColumnType("uuid");
e.Property(m => m.Portions).HasColumnType("numeric(4,2)");
e.HasOne(m => m.User).WithMany().HasForeignKey(m => m.UserId).OnDelete(DeleteBehavior.Cascade);
e.HasOne(m => m.Recipe).WithMany().HasForeignKey(m => m.RecipeId).OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(f => new { f.UserId, f.RecipeId });
e.Property(f => f.UserId).HasColumnType("uuid");
e.HasOne(f => f.Recipe).WithMany().HasForeignKey(f => f.RecipeId).OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(f => new { f.UserId, f.CatalogItemId });
e.Property(f => f.UserId).HasColumnType("uuid");
e.HasOne(f => f.CatalogItem).WithMany().HasForeignKey(f => f.CatalogItemId).OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(p => p.UserId);
e.Property(p => p.UserId).HasColumnType("uuid");
e.Property(p => p.HeightCm).HasColumnType("numeric(5,2)");
e.Property(p => p.WeightKg).HasColumnType("numeric(5,2)");
e.HasOne(p => p.User)
.WithMany()
.HasForeignKey(p => p.UserId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(s => s.Id);
e.Property(s => s.Id).UseIdentityByDefaultColumn();
e.Property(s => s.UserId).HasColumnType("uuid");
e.Property(s => s.ProposedProteinG).HasColumnType("numeric(6,2)");
e.Property(s => s.ProposedFatG).HasColumnType("numeric(6,2)");
e.Property(s => s.ProposedCarbsG).HasColumnType("numeric(6,2)");
e.Property(s => s.PreferencesJson).HasColumnType("jsonb");
e.HasMany(s => s.DraftMeals).WithOne(m => m.Session!).HasForeignKey(m => m.SessionId).OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(m => m.Id);
e.Property(m => m.Id).UseIdentityByDefaultColumn();
e.Property(m => m.Portions).HasColumnType("numeric(4,2)");
e.Property(m => m.ProteinG).HasColumnType("numeric(6,2)");
e.Property(m => m.FatG).HasColumnType("numeric(6,2)");
e.Property(m => m.CarbsG).HasColumnType("numeric(6,2)");
e.HasOne(m => m.Recipe).WithMany().HasForeignKey(m => m.RecipeId).OnDelete(DeleteBehavior.Cascade);
e.HasMany(m => m.PlannedIngredients).WithOne(i => i.DraftMeal!).HasForeignKey(i => i.DraftMealId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity(e =>
{
e.HasKey(i => i.Id);
e.Property(i => i.Id).UseIdentityByDefaultColumn();
e.Property(i => i.AmountGrams).HasColumnType("numeric(8,2)");
e.HasOne(i => i.SourceIngredient).WithMany().HasForeignKey(i => i.SourceIngredientId)
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity(e =>
{
e.HasKey(s => s.Id);
e.Property(s => s.Id).UseIdentityByDefaultColumn();
e.Property(s => s.UserId).HasColumnType("uuid");
e.Property(s => s.ConstraintsJson).HasColumnType("jsonb");
e.Property(s => s.DraftJson).HasColumnType("jsonb");
e.HasOne(s => s.SavedRecipe).WithMany().HasForeignKey(s => s.SavedRecipeId).OnDelete(DeleteBehavior.SetNull);
});
}
}