.NET 8 backend with Zitadel JWT auth, TheMealDB integration, weekly meal plan generation, shopping list aggregation. Vue 3 + Tailwind 4 frontend with dark emerald theme, manual OIDC PKCE auth, all views implemented. Multi-stage Dockerfile with nginx reverse proxy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
72 lines
2.2 KiB
C#
72 lines
2.2 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using MealPlanner.Models;
|
|
|
|
namespace MealPlanner.Data;
|
|
|
|
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
|
|
{
|
|
public DbSet<Recipe> Recipes => Set<Recipe>();
|
|
public DbSet<RecipeIngredient> RecipeIngredients => Set<RecipeIngredient>();
|
|
public DbSet<MealPlan> MealPlans => Set<MealPlan>();
|
|
public DbSet<MealPlanEntry> MealPlanEntries => Set<MealPlanEntry>();
|
|
public DbSet<UserSettings> UserSettings => Set<UserSettings>();
|
|
public DbSet<CheckedShoppingItem> CheckedShoppingItems => Set<CheckedShoppingItem>();
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
base.OnModelCreating(modelBuilder);
|
|
|
|
// Recipe
|
|
modelBuilder.Entity<Recipe>(e =>
|
|
{
|
|
e.HasKey(r => r.Id);
|
|
e.HasIndex(r => r.UserId);
|
|
e.HasIndex(r => r.ExternalId);
|
|
e.HasMany(r => r.Ingredients)
|
|
.WithOne(i => i.Recipe)
|
|
.HasForeignKey(i => i.RecipeId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
// RecipeIngredient
|
|
modelBuilder.Entity<RecipeIngredient>(e =>
|
|
{
|
|
e.HasKey(i => i.Id);
|
|
});
|
|
|
|
// MealPlan
|
|
modelBuilder.Entity<MealPlan>(e =>
|
|
{
|
|
e.HasKey(p => p.Id);
|
|
e.HasIndex(p => new { p.UserId, p.WeekStart }).IsUnique();
|
|
e.HasMany(p => p.Entries)
|
|
.WithOne(en => en.MealPlan)
|
|
.HasForeignKey(en => en.MealPlanId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
// MealPlanEntry
|
|
modelBuilder.Entity<MealPlanEntry>(e =>
|
|
{
|
|
e.HasKey(en => en.Id);
|
|
e.HasOne(en => en.Recipe)
|
|
.WithMany()
|
|
.HasForeignKey(en => en.RecipeId)
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
});
|
|
|
|
// UserSettings
|
|
modelBuilder.Entity<UserSettings>(e =>
|
|
{
|
|
e.HasKey(s => s.UserId);
|
|
});
|
|
|
|
// CheckedShoppingItem
|
|
modelBuilder.Entity<CheckedShoppingItem>(e =>
|
|
{
|
|
e.HasKey(c => c.Id);
|
|
e.HasIndex(c => new { c.MealPlanId, c.UserId, c.ItemName });
|
|
});
|
|
}
|
|
}
|