Compare commits

...

5 Commits

Author SHA1 Message Date
Elias Jansson
5169889753 EF conversion and local DB
Some checks failed
continuous-integration/drone/push Build is failing
2025-06-02 23:32:28 +02:00
Elias Jansson
3b0ea79748 Merge
Some checks failed
continuous-integration/drone/push Build is failing
2025-06-02 09:21:56 +02:00
Elias Jansson
600df026d5 Merge 2025-06-02 09:21:48 +02:00
elias
0cf9059195 Test
Some checks failed
continuous-integration/drone/push Build is failing
2025-06-02 09:06:43 +02:00
Elias Jansson
801e21842a Dev branch
All checks were successful
continuous-integration/drone/push Build is passing
2025-05-31 22:44:15 +02:00
53 changed files with 1867 additions and 5501 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"dotnet.defaultSolution": "Aberwyn.sln"
}

View File

@@ -56,8 +56,21 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Migrations\" />
<Folder Include="Views\NewFolder\" /> <Folder Include="Views\NewFolder\" />
<Folder Include="wwwroot\images\meals\" /> <Folder Include="wwwroot\images\meals\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Update="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="appsettings.Production.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project> </Project>

View File

@@ -14,9 +14,9 @@
<hr /> <hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div> <div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-floating"> <div class="form-floating">
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" /> <label asp-for="Input.UserName"></label>
<label asp-for="Input.Email" class="form-label"></label> <input asp-for="Input.UserName" />
<span asp-validation-for="Input.Email" class="text-danger"></span> <span asp-validation-for="Input.UserName" class="text-danger"></span>
</div> </div>
<div class="form-floating"> <div class="form-floating">
<input asp-for="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" /> <input asp-for="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" />
@@ -48,36 +48,6 @@
</form> </form>
</section> </section>
</div> </div>
<div class="col-md-6 col-md-offset-2">
<section>
<h3>Use another service to log in.</h3>
<hr />
@{
if ((Model.ExternalLogins?.Count ?? 0) == 0)
{
<div>
<p>
There are no external authentication services configured. See this <a href="https://go.microsoft.com/fwlink/?LinkID=532715">article
about setting up this ASP.NET application to support logging in via external services</a>.
</p>
</div>
}
else
{
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in Model.ExternalLogins!)
{
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
}
</p>
</div>
</form>
}
}
</section>
</div>
</div> </div>
@section Scripts { @section Scripts {

View File

@@ -61,27 +61,14 @@ namespace Aberwyn.Areas.Identity.Pages.Account
/// </summary> /// </summary>
public class InputModel public class InputModel
{ {
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[Required] [Required]
[EmailAddress] [Display(Name = "Användarnamn")]
public string Email { get; set; } public string UserName { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[Required] [Required]
[DataType(DataType.Password)] [DataType(DataType.Password)]
public string Password { get; set; } public string Password { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; } public bool RememberMe { get; set; }
} }
@@ -112,7 +99,7 @@ namespace Aberwyn.Areas.Identity.Pages.Account
{ {
// This doesn't count login failures towards account lockout // This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true // To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false); var result = await _signInManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded) if (result.Succeeded)
{ {
_logger.LogInformation("User logged in."); _logger.LogInformation("User logged in.");

View File

@@ -53,6 +53,11 @@ namespace Aberwyn.Areas.Identity.Pages.Account.Manage
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases. /// directly from your code. This API may change or be removed in future releases.
/// </summary> /// </summary>
///
[Required]
[Display(Name = "Användarnamn")]
public string UserName { get; set; }
[Required] [Required]
[DataType(DataType.Password)] [DataType(DataType.Password)]
[Display(Name = "Current password")] [Display(Name = "Current password")]

View File

@@ -2,19 +2,33 @@
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Aberwyn.Models; using Aberwyn.Models;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
namespace Aberwyn.Controllers namespace Aberwyn.Controllers
{ {
[Authorize(Roles = "Admin")] [Authorize(Roles = "Admin")]
public class AdminController : Controller public class AdminController : Controller
{ {
private readonly UserManager<ApplicationUser> _userManager; private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager; private readonly RoleManager<IdentityRole> _roleManager;
private readonly IConfiguration _configuration;
private readonly IHostEnvironment _env;
private readonly ApplicationDbContext _context;
public AdminController(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager) public AdminController(
UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager,
IConfiguration configuration,
IHostEnvironment env,
ApplicationDbContext context)
{ {
_userManager = userManager; _userManager = userManager;
_roleManager = roleManager; _roleManager = roleManager;
_configuration = configuration;
_env = env;
_context = context;
} }
public async Task<IActionResult> Index() public async Task<IActionResult> Index()
@@ -86,6 +100,220 @@ namespace Aberwyn.Controllers
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
[HttpPost]
[Authorize(Roles = "Admin")]
public IActionResult ImportMealsFromProd()
{
var prodService = MenuService.CreateWithConfig(_configuration, _env, useProdDb: true);
var devService = new MenuService(_context); // injicerad context används
var prodMeals = prodService.GetMealsDetailed();
foreach (var meal in prodMeals)
{
// Kopiera utan ID (för att undvika konflikt) och spara
var newMeal = new Meal
{
Name = meal.Name,
Description = meal.Description,
ProteinType = meal.ProteinType,
Category = meal.Category,
CarbType = meal.CarbType,
RecipeUrl = meal.RecipeUrl,
ImageUrl = meal.ImageUrl,
IsAvailable = meal.IsAvailable,
CreatedAt = meal.CreatedAt,
Instructions = meal.Instructions,
ImageData = meal.ImageData,
ImageMimeType = meal.ImageMimeType,
Ingredients = meal.Ingredients.Select(i => new Ingredient
{
Quantity = i.Quantity,
Item = i.Item
}).ToList()
};
devService.SaveOrUpdateMealWithIngredients(newMeal);
}
return Content("Import klar!");
}
[HttpPost]
[Authorize(Roles = "Admin")]
public IActionResult ImportMenusFromProd()
{
var prodService = MenuService.CreateWithConfig(_configuration, _env, useProdDb: true);
var devService = new MenuService(_context);
var allProdMenus = prodService.GetAllWeeklyMenus();
var allMeals = devService.GetMeals();
foreach (var menu in allProdMenus)
{
var newMenu = new WeeklyMenu
{
DayOfWeek = menu.DayOfWeek,
WeekNumber = menu.WeekNumber,
Year = menu.Year,
Cook = menu.Cook,
BreakfastMealId = null,
LunchMealId = null,
DinnerMealId = null
};
if (!string.IsNullOrEmpty(menu.BreakfastMealName))
newMenu.BreakfastMealId = allMeals.FirstOrDefault(m => m.Name == menu.BreakfastMealName)?.Id;
if (!string.IsNullOrEmpty(menu.LunchMealName))
newMenu.LunchMealId = allMeals.FirstOrDefault(m => m.Name == menu.LunchMealName)?.Id;
if (!string.IsNullOrEmpty(menu.DinnerMealName))
newMenu.DinnerMealId = allMeals.FirstOrDefault(m => m.Name == menu.DinnerMealName)?.Id;
_context.WeeklyMenus.Add(newMenu);
}
_context.SaveChanges();
TempData["Message"] = "Import av veckomenyer klar.";
return RedirectToAction("Index");
}
[HttpPost]
[Authorize(Roles = "Admin")]
public IActionResult ImportBudgetFromProd()
{
// Hämta connection till produktion
using var prodContext = ApplicationDbContextFactory.CreateWithConfig(_configuration, _env, useProdDb: true);
// Importera definitioner först
var prodCategoryDefs = prodContext.BudgetCategoryDefinitions.ToList();
var prodItemDefs = prodContext.BudgetItemDefinitions.ToList();
foreach (var def in prodCategoryDefs)
{
if (!_context.BudgetCategoryDefinitions.Any(d => d.Name == def.Name))
{
_context.BudgetCategoryDefinitions.Add(new BudgetCategoryDefinition
{
Name = def.Name,
Color = def.Color ?? "#cccccc"
});
}
}
foreach (var def in prodItemDefs)
{
if (!_context.BudgetItemDefinitions.Any(d => d.Name == def.Name))
{
_context.BudgetItemDefinitions.Add(new BudgetItemDefinition { Name = def.Name });
}
}
_context.SaveChanges(); // Se till att ID:n finns för FK:n nedan
// Ladda definitioner i minnet för snabb lookup
var devCategoryDefs = _context.BudgetCategoryDefinitions.ToList();
var devItemDefs = _context.BudgetItemDefinitions.ToList();
// Importera budgetperioder med kategorier och items
var prodPeriods = prodContext.BudgetPeriods
.Include(p => p.Categories)
.ThenInclude(c => c.Items)
.ToList();
foreach (var period in prodPeriods)
{
var exists = _context.BudgetPeriods
.Any(p => p.Year == period.Year && p.Month == period.Month);
if (exists)
continue;
var newPeriod = new BudgetPeriod
{
Year = period.Year,
Month = period.Month,
Categories = period.Categories.Select(c => new BudgetCategory
{
Name = c.Name,
Color = string.IsNullOrWhiteSpace(c.Color) ? "#cccccc" : c.Color,
Order = c.Order,
BudgetCategoryDefinitionId = devCategoryDefs
.FirstOrDefault(d => d.Name == c.Definition?.Name)?.Id,
Items = c.Items.Select(i => new BudgetItem
{
Name = i.Name,
Amount = i.Amount,
IsExpense = i.IsExpense,
IncludeInSummary = i.IncludeInSummary,
Order = i.Order,
BudgetItemDefinitionId = devItemDefs
.FirstOrDefault(d => d.Name == i.BudgetItemDefinition?.Name)?.Id
}).ToList()
}).ToList()
};
_context.BudgetPeriods.Add(newPeriod);
}
_context.SaveChanges();
TempData["Message"] = "✅ Import av budgetdata från produktion är klar.";
return RedirectToAction("Index");
}
//Todo
[HttpGet]
public IActionResult Todo()
{
return View();
}
[HttpGet]
public IActionResult GetTodoTasks()
{
var tasks = _context.TodoTasks
.OrderByDescending(t => t.CreatedAt)
.ToList();
return Json(tasks);
}
[HttpPost]
public IActionResult AddTodoTask([FromBody] TodoTask task)
{
if (string.IsNullOrWhiteSpace(task?.Title))
return BadRequest("Titel krävs");
task.CreatedAt = DateTime.UtcNow;
_context.TodoTasks.Add(task);
_context.SaveChanges();
return Json(task);
}
[HttpPost]
public IActionResult UpdateTodoTask([FromBody] TodoTask task)
{
var existing = _context.TodoTasks.FirstOrDefault(t => t.Id == task.Id);
if (existing == null)
return NotFound();
existing.Title = task.Title;
existing.Status = task.Status;
existing.Priority = task.Priority;
_context.SaveChanges();
return Ok();
}
} }
public class AdminUserViewModel public class AdminUserViewModel

View File

@@ -23,6 +23,7 @@ namespace Aberwyn.Controllers
public FoodMenuController(MenuService menuService, IConfiguration configuration, IHostEnvironment env, ApplicationDbContext context) public FoodMenuController(MenuService menuService, IConfiguration configuration, IHostEnvironment env, ApplicationDbContext context)
{ {
_menuService = menuService; _menuService = menuService;
_configuration = configuration; _configuration = configuration;
_env = env; _env = env;
_context = context; _context = context;
@@ -61,10 +62,10 @@ namespace Aberwyn.Controllers
return RedirectToAction("PizzaOrder"); return RedirectToAction("PizzaOrder");
} }
// Sätt session så vi vet att det är en uppdatering // S<EFBFBD>tt session s<EFBFBD> vi vet att det <EFBFBD>r en uppdatering
HttpContext.Session.SetInt32("LastPizzaOrderId", order.Id); HttpContext.Session.SetInt32("LastPizzaOrderId", order.Id);
// Visa formuläret // Visa formul<EFBFBD>ret
TempData["ForceShowForm"] = "true"; TempData["ForceShowForm"] = "true";
return RedirectToAction("PizzaOrder"); return RedirectToAction("PizzaOrder");
@@ -85,7 +86,7 @@ namespace Aberwyn.Controllers
{ {
if (string.IsNullOrWhiteSpace(customerName) || string.IsNullOrWhiteSpace(pizzaName)) if (string.IsNullOrWhiteSpace(customerName) || string.IsNullOrWhiteSpace(pizzaName))
{ {
TempData["Error"] = "Fyll i både namn och pizza!"; TempData["Error"] = "Fyll i b<EFBFBD>de namn och pizza!";
return RedirectToAction("PizzaOrder"); return RedirectToAction("PizzaOrder");
} }
@@ -101,10 +102,10 @@ namespace Aberwyn.Controllers
order.CustomerName = customerName.Trim(); order.CustomerName = customerName.Trim();
order.PizzaName = pizzaName.Trim(); order.PizzaName = pizzaName.Trim();
order.IngredientsJson = ingredients; order.IngredientsJson = ingredients;
order.Status = "Unconfirmed";// återställ status om du vill order.Status = "Unconfirmed";// <EFBFBD>terst<EFBFBD>ll status om du vill
_context.SaveChanges(); _context.SaveChanges();
TempData["Success"] = $"Din beställning har uppdaterats!"; TempData["Success"] = $"Din best<EFBFBD>llning har uppdaterats!";
return RedirectToAction("PizzaOrder"); return RedirectToAction("PizzaOrder");
} }
} }
@@ -126,7 +127,7 @@ namespace Aberwyn.Controllers
HttpContext.Session.SetInt32("LastPizzaOrderId", order.Id); HttpContext.Session.SetInt32("LastPizzaOrderId", order.Id);
TempData["Success"] = $"Tack {order.CustomerName}! Din pizza är beställd!"; TempData["Success"] = $"Tack {order.CustomerName}! Din pizza <EFBFBD>r best<EFBFBD>lld!";
return RedirectToAction("PizzaOrder"); return RedirectToAction("PizzaOrder");
} }
@@ -182,7 +183,7 @@ namespace Aberwyn.Controllers
[Authorize(Roles = "Chef")] [Authorize(Roles = "Chef")]
public IActionResult Veckomeny(int? week, int? year) public IActionResult Veckomeny(int? week, int? year)
{ {
var menuService = new MenuService(_configuration, _env); var menuService = _menuService;
var today = DateTime.Today; var today = DateTime.Today;
int resolvedWeek = week ?? ISOWeek.GetWeekOfYear(today); int resolvedWeek = week ?? ISOWeek.GetWeekOfYear(today);
@@ -195,14 +196,13 @@ namespace Aberwyn.Controllers
WeekNumber = resolvedWeek, WeekNumber = resolvedWeek,
Year = resolvedYear, Year = resolvedYear,
WeeklyMenus = menus, WeeklyMenus = menus,
AvailableCooks = menuService.GetUsers()
}; };
var recent = menuService var recent = menuService
.GetMenuEntriesByDateRange(DateTime.Now.AddDays(-28), DateTime.Now) .GetMenuEntriesByDateRange(DateTime.Now.AddDays(-28), DateTime.Now)
.Select(x => new WeeklyMenuViewModel.RecentMenuEntry .Select(x => new WeeklyMenuViewModel.RecentMenuEntry
{ {
Date = x.Date, Date = x.CreatedAt,
BreakfastMealName = x.BreakfastMealName, BreakfastMealName = x.BreakfastMealName,
LunchMealName = x.LunchMealName, LunchMealName = x.LunchMealName,
DinnerMealName = x.DinnerMealName DinnerMealName = x.DinnerMealName
@@ -219,24 +219,24 @@ namespace Aberwyn.Controllers
public IActionResult AddMealAjax([FromBody] Meal meal) public IActionResult AddMealAjax([FromBody] Meal meal)
{ {
if (meal == null || string.IsNullOrWhiteSpace(meal.Name)) if (meal == null || string.IsNullOrWhiteSpace(meal.Name))
return BadRequest("Ogiltigt måltidsobjekt."); return BadRequest("Ogiltigt m<EFBFBD>ltidsobjekt.");
var service = new MenuService(_configuration, _env); var service = _menuService;
// Kontrollera om en måltid med samma namn redan finns // Kontrollera om en m<EFBFBD>ltid med samma namn redan finns
var existing = service.GetMeals() var existing = service.GetMeals()
.FirstOrDefault(m => m.Name.Equals(meal.Name, StringComparison.OrdinalIgnoreCase)); .FirstOrDefault(m => m.Name.Equals(meal.Name, StringComparison.OrdinalIgnoreCase));
if (existing == null) if (existing == null)
{ {
// Fyll i CreatedAt om det inte sätts automatiskt i databasen // Fyll i CreatedAt om det inte s<EFBFBD>tts automatiskt i databasen
meal.CreatedAt = DateTime.Now; meal.CreatedAt = DateTime.Now;
service.SaveOrUpdateMeal(meal); service.SaveOrUpdateMeal(meal);
existing = meal; existing = meal;
} }
else else
{ {
// Om måltiden finns men saknar data (t.ex. är bara ett namn) kan vi uppdatera den // Om m<EFBFBD>ltiden finns men saknar data (t.ex. <EFBFBD>r bara ett namn) kan vi uppdatera den
existing.Description = meal.Description; existing.Description = meal.Description;
existing.ProteinType = meal.ProteinType; existing.ProteinType = meal.ProteinType;
existing.CarbType = meal.CarbType; existing.CarbType = meal.CarbType;
@@ -258,7 +258,7 @@ namespace Aberwyn.Controllers
public IActionResult MealAdmin() public IActionResult MealAdmin()
{ {
var service = new MenuService(_configuration, _env); var service = _menuService;
var meals = service.GetMealsDetailed(); var meals = service.GetMealsDetailed();
return View("MealAdmin", meals); return View("MealAdmin", meals);
} }
@@ -269,7 +269,7 @@ namespace Aberwyn.Controllers
if (string.IsNullOrWhiteSpace(term)) if (string.IsNullOrWhiteSpace(term))
return Json(new List<string>()); return Json(new List<string>());
var menuService = new MenuService(_configuration, _env); var menuService = _menuService;
var meals = menuService.GetMeals(); var meals = menuService.GetMeals();
var result = meals var result = meals
@@ -285,7 +285,7 @@ namespace Aberwyn.Controllers
[HttpPost] [HttpPost]
public IActionResult SaveVeckomeny(IFormCollection form, int week, int year) public IActionResult SaveVeckomeny(IFormCollection form, int week, int year)
{ {
var menuService = new MenuService(_configuration, _env); var menuService = _menuService;
var allMeals = menuService.GetMeals(); var allMeals = menuService.GetMeals();
var model = new MenuViewModel var model = new MenuViewModel
@@ -368,6 +368,7 @@ namespace Aberwyn.Controllers
return RedirectToAction("Veckomeny", new { week, year }); return RedirectToAction("Veckomeny", new { week, year });
} }
private bool GetRestaurantStatus() private bool GetRestaurantStatus()
{ {
var value = _context.AppSettings.FirstOrDefault(s => s.Key == "RestaurantIsOpen")?.Value; var value = _context.AppSettings.FirstOrDefault(s => s.Key == "RestaurantIsOpen")?.Value;
@@ -436,7 +437,7 @@ namespace Aberwyn.Controllers
[Authorize(Roles = "Chef")] [Authorize(Roles = "Chef")]
public IActionResult UpdatePizzaAvailability(List<int> availableIds) public IActionResult UpdatePizzaAvailability(List<int> availableIds)
{ {
availableIds ??= new List<int>(); // Om null, ersätt med tom lista availableIds ??= new List<int>(); // Om null, ers<EFBFBD>tt med tom lista
var allPizzas = _menuService.GetMealsByCategory("Pizza"); var allPizzas = _menuService.GetMealsByCategory("Pizza");

View File

@@ -9,6 +9,7 @@ namespace Aberwyn.Controllers
{ {
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly IHostEnvironment _env; private readonly IHostEnvironment _env;
private readonly MenuService _menuService;
public MealController(IConfiguration configuration, IHostEnvironment env) public MealController(IConfiguration configuration, IHostEnvironment env)
{ {
@@ -18,7 +19,7 @@ namespace Aberwyn.Controllers
[HttpGet] [HttpGet]
public IActionResult View(int id, bool edit = false) public IActionResult View(int id, bool edit = false)
{ {
var service = new MenuService(_configuration, _env); var service = _menuService;
var meal = service.GetMealById(id); var meal = service.GetMealById(id);
ViewData["IsEditing"] = edit; // → här ViewData["IsEditing"] = edit; // → här
@@ -37,7 +38,7 @@ namespace Aberwyn.Controllers
{ {
try try
{ {
var service = new MenuService(_configuration, _env); var service = _menuService;
var meal = service.GetMealById(id); var meal = service.GetMealById(id);
if (meal == null) if (meal == null)
@@ -75,7 +76,7 @@ namespace Aberwyn.Controllers
[HttpGet] [HttpGet]
public IActionResult Edit(int? id) public IActionResult Edit(int? id)
{ {
var service = new MenuService(_configuration, _env); var service = _menuService;
var meal = id.HasValue ? service.GetMealById(id.Value) : new Meal(); var meal = id.HasValue ? service.GetMealById(id.Value) : new Meal();
return View("Meal", meal); return View("Meal", meal);
} }
@@ -83,7 +84,7 @@ namespace Aberwyn.Controllers
[HttpPost] [HttpPost]
public IActionResult SaveMeal(Meal meal, IFormFile ImageFile, string ExistingImageUrl) public IActionResult SaveMeal(Meal meal, IFormFile ImageFile, string ExistingImageUrl)
{ {
var service = new MenuService(_configuration, _env); var service = _menuService;
if (ImageFile != null && ImageFile.Length > 0) if (ImageFile != null && ImageFile.Length > 0)
{ {
@@ -116,7 +117,7 @@ namespace Aberwyn.Controllers
[HttpPost] [HttpPost]
public IActionResult DeleteMeal(int id) public IActionResult DeleteMeal(int id)
{ {
var service = new MenuService(_configuration, _env); var service = _menuService;
//service.DeleteMeal(id); //service.DeleteMeal(id);
return RedirectToAction("Edit"); // eller tillbaka till lista return RedirectToAction("Edit"); // eller tillbaka till lista
} }

View File

@@ -13,9 +13,9 @@ namespace Aberwyn.Controllers
{ {
private readonly MenuService _menuService; private readonly MenuService _menuService;
public MealMenuApiController(IConfiguration configuration, IHostEnvironment env) public MealMenuApiController(MenuService menuService, IConfiguration configuration, IHostEnvironment env)
{ {
_menuService = new MenuService(configuration, env); _menuService = menuService;
} }
[HttpGet("menu")] [HttpGet("menu")]

View File

@@ -11,15 +11,26 @@ namespace Aberwyn.Data
{ {
} }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<WeeklyMenu>().ToTable("WeeklyMenu");
}
public DbSet<BudgetPeriod> BudgetPeriods { get; set; } public DbSet<BudgetPeriod> BudgetPeriods { get; set; }
public DbSet<BudgetCategory> BudgetCategories { get; set; } public DbSet<BudgetCategory> BudgetCategories { get; set; }
public DbSet<BudgetItem> BudgetItems { get; set; } public DbSet<BudgetItem> BudgetItems { get; set; }
public DbSet<PushSubscriber> PushSubscribers { get; set; } public DbSet<PushSubscriber> PushSubscribers { get; set; }
public DbSet<PizzaOrder> PizzaOrders { get; set; } public DbSet<PizzaOrder> PizzaOrders { get; set; }
public DbSet<AppSetting> AppSettings { get; set; } public DbSet<AppSetting> AppSettings { get; set; }
public DbSet<TodoTask> TodoTasks { get; set; }
public DbSet<BudgetItemDefinition> BudgetItemDefinitions { get; set; } public DbSet<BudgetItemDefinition> BudgetItemDefinitions { get; set; }
public DbSet<BudgetCategoryDefinition> BudgetCategoryDefinitions { get; set; } public DbSet<BudgetCategoryDefinition> BudgetCategoryDefinitions { get; set; }
public DbSet<Meal> Meals { get; set; }
public DbSet<WeeklyMenu> WeeklyMenus { get; set; }
public DbSet<Ingredient> Ingredients { get; set; }
} }
} }

View File

@@ -13,13 +13,14 @@ namespace Aberwyn.Data
var basePath = Directory.GetCurrentDirectory(); var basePath = Directory.GetCurrentDirectory();
var config = new ConfigurationBuilder() var config = new ConfigurationBuilder()
.SetBasePath(basePath) .SetBasePath(basePath)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json", optional: false)
.AddJsonFile("appsettings.Development.json", optional: true)
.AddEnvironmentVariables()
.Build(); .Build();
var connectionString = config.GetConnectionString("DefaultConnection"); var connectionString = config.GetConnectionString("DefaultConnection");
File.WriteAllText("connection-log.txt", $"Connection string: {connectionString}");
File.WriteAllText("connection-log.txt", $"Connection string: {connectionString}");
Console.WriteLine($"Anslutningssträng: {connectionString}"); Console.WriteLine($"Anslutningssträng: {connectionString}");
if (string.IsNullOrEmpty(connectionString)) if (string.IsNullOrEmpty(connectionString))
@@ -34,5 +35,22 @@ namespace Aberwyn.Data
return new ApplicationDbContext(optionsBuilder.Options); return new ApplicationDbContext(optionsBuilder.Options);
} }
public static ApplicationDbContext CreateWithConfig(IConfiguration config, IHostEnvironment env, bool useProdDb = false)
{
var connectionString = useProdDb
? config.GetConnectionString("ProdConnection") // <--- FIX HÄR
: config.GetConnectionString("DefaultConnection");
if (string.IsNullOrWhiteSpace(connectionString))
throw new InvalidOperationException("Connection string saknas.");
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 36)));
return new ApplicationDbContext(optionsBuilder.Options);
}
} }
} }

View File

@@ -11,7 +11,7 @@ namespace Aberwyn.Data
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>(); var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>(); var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
string[] roles = { "Admin" }; string[] roles = { "Admin", "Chef", "Budget" };
foreach (var role in roles) foreach (var role in roles)
{ {
@@ -19,14 +19,15 @@ namespace Aberwyn.Data
await roleManager.CreateAsync(new IdentityRole(role)); await roleManager.CreateAsync(new IdentityRole(role));
} }
string adminEmail = "tai@zcz.se"; string adminUsername = "admin";
string adminEmail = "admin@localhost";
string password = "Admin123!"; string password = "Admin123!";
if (await userManager.FindByEmailAsync(adminEmail) == null) if (await userManager.FindByEmailAsync(adminEmail) == null)
{ {
var user = new ApplicationUser var user = new ApplicationUser
{ {
UserName = adminEmail, UserName = adminUsername,
Email = adminEmail, Email = adminEmail,
EmailConfirmed = true EmailConfirmed = true
}; };

View File

@@ -1,591 +1,218 @@
using MySql.Data.MySqlClient; // Nya versionen av MenuService med Entity Framework
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Aberwyn.Models; using Aberwyn.Models;
using Microsoft.EntityFrameworkCore;
using System.Globalization; using System.Globalization;
namespace Aberwyn.Data namespace Aberwyn.Data
{ {
public class MenuService public class MenuService
{ {
private readonly IConfiguration _configuration; private readonly ApplicationDbContext _context;
private readonly IHostEnvironment _env;
public MenuService(IConfiguration configuration, IHostEnvironment env) // Detta är DI-konstruktorn används som vanligt i controllers
public MenuService(ApplicationDbContext context)
{ {
_configuration = configuration; _context = context;
_env = env;
} }
private MySqlConnection GetConnection() // Detta är en alternativ konstruktör används manuellt vid t.ex. import
public static MenuService CreateWithConfig(IConfiguration config, IHostEnvironment env, bool useProdDb = false)
{ {
var connectionString = _env.IsDevelopment() var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
? _configuration.GetConnectionString("DefaultConnection")
: _configuration.GetConnectionString("ProductionConnection");
return new MySqlConnection(connectionString); var connStr = useProdDb
} ? config.GetConnectionString("ProdConnection")
public List<User> GetUsers() : config.GetConnectionString("DefaultConnection");
{
var users = new List<User>();
using (var connection = GetConnection())
{
connection.Open();
string query = @"SELECT userID, Username, Name FROM Nevyn.tblUsers WHERE Chef = 1";
using (var cmd = new MySqlCommand(query, connection)) builder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
using (var reader = cmd.ExecuteReader()) var context = new ApplicationDbContext(builder.Options);
return new MenuService(context);
}
public void UpdateWeeklyMenu(MenuViewModel model)
{ {
while (reader.Read()) var existing = _context.WeeklyMenus
.Where(w => w.WeekNumber == model.WeekNumber && w.Year == model.Year)
.ToList();
_context.WeeklyMenus.RemoveRange(existing);
_context.WeeklyMenus.AddRange(model.WeeklyMenus);
_context.SaveChanges();
}
public int AddMeal(Meal meal)
{ {
users.Add(new User SaveMeal(meal);
{ return meal.Id;
UserID = reader.GetInt32("userID"),
Username = reader.GetString("Username"),
Name = reader.GetString("Name")
});
}
}
}
return users;
} }
public void SaveMeal(Meal meal) public void SaveMeal(Meal meal)
{ {
if (string.IsNullOrWhiteSpace(meal?.Name)) if (string.IsNullOrWhiteSpace(meal?.Name)) return;
return;
meal.Name = meal.Name.Trim(); meal.Name = meal.Name.Trim();
meal.CreatedAt = meal.CreatedAt == default ? DateTime.Now : meal.CreatedAt;
using var connection = GetConnection(); if (meal.Id == 0)
connection.Open(); _context.Meals.Add(meal);
else
_context.Meals.Update(meal);
var query = @" _context.SaveChanges();
INSERT INTO Meals
(Name, Description, RecipeUrl, CreatedAt)
VALUES (@name, @desc, @url, CURRENT_TIMESTAMP);";
using var cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("@name", meal.Name);
cmd.Parameters.AddWithValue("@desc", meal.Description ?? "");
cmd.Parameters.AddWithValue("@url", meal.RecipeUrl ?? "");
try
{
cmd.ExecuteNonQuery();
meal.Id = (int)cmd.LastInsertedId;
}
catch (MySqlException ex) when (ex.Number == 1062)
{
Console.WriteLine($"⚠️ Måltiden '{meal.Name}' finns redan i databasen.");
}
catch (Exception ex)
{
Console.WriteLine($"❌ Fel vid sparning av måltid '{meal.Name}': {ex.Message}");
}
} }
public List<WeeklyMenu> GetWeeklyMenu(int weekNumber, int year) public List<WeeklyMenu> GetAllWeeklyMenus()
{ {
var weeklyMenu = new List<WeeklyMenu>(); var menus = _context.WeeklyMenus.ToList();
using (var connection = GetConnection())
{
connection.Open();
string query = @"
SELECT wm.Id, wm.DayOfWeek, wm.DinnerMealId, wm.LunchMealId, wm.BreakfastMealId,
wm.WeekNumber, wm.Year, wm.Cook,
dm.Name AS DinnerMealName,
lm.Name AS LunchMealName,
bm.Name AS BreakfastMealName
FROM WeeklyMenu wm
LEFT JOIN Meals dm ON wm.DinnerMealId = dm.Id
LEFT JOIN Meals lm ON wm.LunchMealId = lm.Id
LEFT JOIN Meals bm ON wm.BreakfastMealId = bm.Id
WHERE wm.WeekNumber = @weekNumber AND wm.Year = @year";
using (var cmd = new MySqlCommand(query, connection)) var allMeals = _context.Meals.ToDictionary(m => m.Id, m => m.Name);
{
cmd.Parameters.AddWithValue("@weekNumber", weekNumber);
cmd.Parameters.AddWithValue("@year", year);
using (var reader = cmd.ExecuteReader()) foreach (var wm in menus)
{ {
while (reader.Read()) wm.BreakfastMealName = wm.BreakfastMealId.HasValue && allMeals.TryGetValue(wm.BreakfastMealId.Value, out var breakfast)
{ ? breakfast
weeklyMenu.Add(new WeeklyMenu : null;
{
Id = reader.GetInt32("Id"), wm.LunchMealName = wm.LunchMealId.HasValue && allMeals.TryGetValue(wm.LunchMealId.Value, out var lunch)
DayOfWeek = reader.GetInt32("DayOfWeek"), ? lunch
DinnerMealId = reader.IsDBNull(reader.GetOrdinal("DinnerMealId")) ? (int?)null : reader.GetInt32(reader.GetOrdinal("DinnerMealId")), : null;
LunchMealId = reader.IsDBNull(reader.GetOrdinal("LunchMealId")) ? (int?)null : reader.GetInt32(reader.GetOrdinal("LunchMealId")),
BreakfastMealId = reader.IsDBNull(reader.GetOrdinal("BreakfastMealId")) ? (int?)null : reader.GetInt32(reader.GetOrdinal("BreakfastMealId")), wm.DinnerMealName = wm.DinnerMealId.HasValue && allMeals.TryGetValue(wm.DinnerMealId.Value, out var dinner)
WeekNumber = reader.GetInt32("WeekNumber"), ? dinner
Year = reader.GetInt32("Year"), : null;
Cook = reader.IsDBNull(reader.GetOrdinal("Cook")) ? null : reader.GetString(reader.GetOrdinal("Cook")),
DinnerMealName = reader.IsDBNull(reader.GetOrdinal("DinnerMealName")) ? null : reader.GetString(reader.GetOrdinal("DinnerMealName")),
LunchMealName = reader.IsDBNull(reader.GetOrdinal("LunchMealName")) ? null : reader.GetString(reader.GetOrdinal("LunchMealName")),
BreakfastMealName = reader.IsDBNull(reader.GetOrdinal("BreakfastMealName")) ? null : reader.GetString(reader.GetOrdinal("BreakfastMealName"))
});
}
}
}
}
return weeklyMenu;
} }
return menus;
}
public List<Ingredient> GetIngredientsForMeal(int mealId) public List<Ingredient> GetIngredientsForMeal(int mealId)
{ {
var ingredients = new List<Ingredient>(); return _context.Ingredients
using var conn = GetConnection(); .Where(i => i.MealId == mealId)
conn.Open(); .ToList();
string query = "SELECT Id, MealId, Quantity, Item FROM Ingredients WHERE MealId = @mealId";
using var cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@mealId", mealId);
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
ingredients.Add(new Ingredient
{
Id = reader.GetInt32("Id"),
MealId = reader.GetInt32("MealId"),
Quantity = reader.GetString("Quantity"),
Item = reader.GetString("Item")
});
}
return ingredients;
} }
public void SaveIngredients(int mealId, List<Ingredient> ingredients) public void SaveIngredients(int mealId, List<Ingredient> ingredients)
{ {
using var conn = GetConnection(); var existing = _context.Ingredients.Where(i => i.MealId == mealId);
conn.Open(); _context.Ingredients.RemoveRange(existing);
_context.Ingredients.AddRange(ingredients);
using var tx = conn.BeginTransaction(); _context.SaveChanges();
// Ta bort gamla
var deleteCmd = new MySqlCommand("DELETE FROM Ingredients WHERE MealId = @mealId", conn, tx);
deleteCmd.Parameters.AddWithValue("@mealId", mealId);
deleteCmd.ExecuteNonQuery();
foreach (var ingredient in ingredients)
{
var insertCmd = new MySqlCommand(
"INSERT INTO Ingredients (MealId, Quantity, Item) VALUES (@mealId, @quantity, @item)",
conn, tx);
insertCmd.Parameters.AddWithValue("@mealId", mealId);
insertCmd.Parameters.AddWithValue("@quantity", ingredient.Quantity ?? "");
insertCmd.Parameters.AddWithValue("@item", ingredient.Item ?? "");
insertCmd.ExecuteNonQuery();
}
tx.Commit();
} }
public List<Meal> GetMeals() public List<Meal> GetMeals()
{ {
var meals = new List<Meal>(); return _context.Meals.ToList();
using (var connection = GetConnection())
{
connection.Open();
string query = @"
SELECT Id, Name, ImageUrl, ImageData, ImageMimeType, Category, IsAvailable
FROM Meals";
using (var cmd = new MySqlCommand(query, connection))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
meals.Add(new Meal
{
Id = reader.GetInt32("Id"),
Name = reader.GetString("Name"),
ImageData = reader.IsDBNull(reader.GetOrdinal("ImageData")) ? null : (byte[])reader["ImageData"],
ImageMimeType = reader.IsDBNull(reader.GetOrdinal("ImageMimeType")) ? null : reader.GetString(reader.GetOrdinal("ImageMimeType")),
ImageUrl = reader.IsDBNull(reader.GetOrdinal("ImageUrl")) ? null : reader.GetString(reader.GetOrdinal("ImageUrl")),
Category = reader.IsDBNull(reader.GetOrdinal("Category")) ? null : reader.GetString(reader.GetOrdinal("Category")),
IsAvailable = reader.IsDBNull(reader.GetOrdinal("IsAvailable")) ? true : reader.GetBoolean(reader.GetOrdinal("IsAvailable"))
});
}
}
}
return meals;
} }
public List<Meal> GetMealsDetailed() public List<Meal> GetMealsDetailed()
{ {
var meals = new List<Meal>(); return _context.Meals
.OrderByDescending(m => m.CreatedAt)
using (var connection = GetConnection()) .ToList();
{
connection.Open();
string query = @"
SELECT Id, Name, Description, ProteinType, CarbType, RecipeUrl, CreatedAt, ImageUrl, ImageData, ImageMimeType
FROM Meals
ORDER BY CreatedAt DESC";
using (var cmd = new MySqlCommand(query, connection))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
meals.Add(new Meal
{
Id = reader.GetInt32(reader.GetOrdinal("Id")),
Name = reader.GetString(reader.GetOrdinal("Name")),
Description = reader.IsDBNull(reader.GetOrdinal("Description")) ? null : reader.GetString(reader.GetOrdinal("Description")),
ProteinType = reader.IsDBNull(reader.GetOrdinal("ProteinType")) ? null : reader.GetString(reader.GetOrdinal("ProteinType")),
CarbType = reader.IsDBNull(reader.GetOrdinal("CarbType")) ? null : reader.GetString(reader.GetOrdinal("CarbType")),
RecipeUrl = reader.IsDBNull(reader.GetOrdinal("RecipeUrl")) ? null : reader.GetString(reader.GetOrdinal("RecipeUrl")),
ImageUrl = reader.IsDBNull(reader.GetOrdinal("ImageUrl")) ? null : reader.GetString(reader.GetOrdinal("ImageUrl")),
CreatedAt = reader.GetDateTime(reader.GetOrdinal("CreatedAt")),
ImageData = reader.IsDBNull(reader.GetOrdinal("ImageData")) ? null : (byte[])reader["ImageData"],
ImageMimeType = reader.IsDBNull(reader.GetOrdinal("ImageMimeType")) ? null : reader.GetString(reader.GetOrdinal("ImageMimeType"))
});
}
}
}
return meals;
} }
public Meal GetMealById(int id) public Meal GetMealById(int id)
{ {
using var connection = GetConnection(); var meal = _context.Meals
connection.Open(); .Include(m => m.Ingredients)
.FirstOrDefault(m => m.Id == id);
string query = @"SELECT Id, Name, Description, ProteinType, CarbType, RecipeUrl, CreatedAt, ImageUrl, ImageData, ImageMimeType, Instructions FROM Meals WHERE Id = @id"; return meal;
using var cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("@id", id);
using var reader = cmd.ExecuteReader();
if (reader.Read())
{
return new Meal
{
Id = reader.GetInt32(reader.GetOrdinal("Id")),
Name = reader.GetString(reader.GetOrdinal("Name")),
Description = reader.IsDBNull(reader.GetOrdinal("Description")) ? null : reader.GetString(reader.GetOrdinal("Description")),
ProteinType = reader.IsDBNull(reader.GetOrdinal("ProteinType")) ? null : reader.GetString(reader.GetOrdinal("ProteinType")),
CarbType = reader.IsDBNull(reader.GetOrdinal("CarbType")) ? null : reader.GetString(reader.GetOrdinal("CarbType")),
RecipeUrl = reader.IsDBNull(reader.GetOrdinal("RecipeUrl")) ? null : reader.GetString(reader.GetOrdinal("RecipeUrl")),
ImageUrl = reader.IsDBNull(reader.GetOrdinal("ImageUrl")) ? null : reader.GetString(reader.GetOrdinal("ImageUrl")),
CreatedAt = reader.GetDateTime(reader.GetOrdinal("CreatedAt")),
ImageData = reader.IsDBNull(reader.GetOrdinal("ImageData")) ? null : (byte[])reader["ImageData"],
ImageMimeType = reader.IsDBNull(reader.GetOrdinal("ImageMimeType")) ? null : reader.GetString(reader.GetOrdinal("ImageMimeType")),
Instructions = reader.IsDBNull(reader.GetOrdinal("Instructions")) ? null : reader.GetString(reader.GetOrdinal("Instructions")),
Ingredients = GetIngredientsForMeal(id)
};
}
return null;
} }
public void DeleteMeal(int id) public void DeleteMeal(int id)
{ {
using var connection = GetConnection(); var meal = _context.Meals.Find(id);
connection.Open(); if (meal != null)
string query = "DELETE FROM Meals WHERE Id = @id"; {
using var cmd = new MySqlCommand(query, connection); _context.Meals.Remove(meal);
cmd.Parameters.AddWithValue("@id", id); _context.SaveChanges();
cmd.ExecuteNonQuery(); }
} }
public void SaveOrUpdateMeal(Meal meal) public void SaveOrUpdateMeal(Meal meal)
{ {
using var conn = new MySqlConnection(_configuration.GetConnectionString("DefaultConnection")); SaveMeal(meal);
conn.Open();
using var cmd = conn.CreateCommand();
if (meal.Id == 0)
{
cmd.CommandText = @"
INSERT INTO Meals
(Name, Description, ProteinType, CarbType, RecipeUrl, CreatedAt, ImageUrl, ImageData, ImageMimeType, Instructions, Category, IsAvailable)
VALUES
(@Name, @Description, @ProteinType, @CarbType, @RecipeUrl, @CreatedAt, @ImageUrl, @ImageData, @ImageMimeType, @Instructions, @Category, @IsAvailable);
SELECT LAST_INSERT_ID();";
}
else
{
cmd.CommandText = @"
UPDATE Meals
SET Name = @Name,
Description = @Description,
ProteinType = @ProteinType,
CarbType = @CarbType,
RecipeUrl = @RecipeUrl,
ImageUrl = @ImageUrl,
ImageData = @ImageData,
ImageMimeType = @ImageMimeType,
Instructions = @Instructions,
Category = @Category,
IsAvailable = @IsAvailable
WHERE Id = @Id";
cmd.Parameters.AddWithValue("@Id", meal.Id);
} }
cmd.Parameters.AddWithValue("@Name", meal.Name ?? "");
cmd.Parameters.AddWithValue("@Description", meal.Description ?? "");
cmd.Parameters.AddWithValue("@ProteinType", meal.ProteinType ?? "");
cmd.Parameters.AddWithValue("@CarbType", meal.CarbType ?? "");
cmd.Parameters.AddWithValue("@RecipeUrl", meal.RecipeUrl ?? "");
cmd.Parameters.AddWithValue("@CreatedAt", meal.CreatedAt == default ? DateTime.Now : meal.CreatedAt);
cmd.Parameters.AddWithValue("@ImageUrl", meal.ImageUrl ?? "");
cmd.Parameters.AddWithValue("@ImageData", (object?)meal.ImageData ?? DBNull.Value);
cmd.Parameters.AddWithValue("@ImageMimeType", meal.ImageMimeType ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@Instructions", meal.Instructions ?? "");
cmd.Parameters.AddWithValue("@Category", meal.Category ?? "");
cmd.Parameters.AddWithValue("@IsAvailable", meal.IsAvailable ? 1 : 0);
if (meal.Id == 0)
{
var insertedId = Convert.ToInt32(cmd.ExecuteScalar());
meal.Id = insertedId;
}
else
{
cmd.ExecuteNonQuery();
}
}
public void UpdateWeeklyMenu(MenuViewModel menuData)
{
if (menuData == null || menuData.WeeklyMenus == null)
throw new ArgumentNullException(nameof(menuData), "Menu data or weekly menus cannot be null.");
using (var connection = GetConnection())
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
foreach (var menu in menuData.WeeklyMenus)
{
int dayOfWeek = menu.DayOfWeek;
string updateQuery = @"
UPDATE WeeklyMenu
SET
BreakfastMealId = @breakfastMealId,
LunchMealId = @lunchMealId,
DinnerMealId = @dinnerMealId,
Cook = @cook
WHERE DayOfWeek = @dayOfWeek
AND WeekNumber = @weekNumber
AND Year = @year;";
using (var cmd = new MySqlCommand(updateQuery, connection, transaction))
{
cmd.Parameters.AddWithValue("@dayOfWeek", dayOfWeek);
cmd.Parameters.AddWithValue("@breakfastMealId", menu.BreakfastMealId ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@lunchMealId", menu.LunchMealId ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@dinnerMealId", menu.DinnerMealId ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@weekNumber", menu.WeekNumber);
cmd.Parameters.AddWithValue("@year", menu.Year);
cmd.Parameters.AddWithValue("@cook", menu.Cook ?? (object)DBNull.Value);
int rowsAffected = cmd.ExecuteNonQuery();
if (rowsAffected == 0)
{
string insertQuery = @"
INSERT INTO WeeklyMenu
(DayOfWeek, WeekNumber, Year, BreakfastMealId, LunchMealId, DinnerMealId, Cook)
VALUES (@dayOfWeek, @weekNumber, @year, @breakfastMealId, @lunchMealId, @dinnerMealId, @cook);";
using var insertCmd = new MySqlCommand(insertQuery, connection, transaction);
insertCmd.Parameters.AddWithValue("@dayOfWeek", dayOfWeek);
insertCmd.Parameters.AddWithValue("@breakfastMealId", menu.BreakfastMealId ?? (object)DBNull.Value);
insertCmd.Parameters.AddWithValue("@lunchMealId", menu.LunchMealId ?? (object)DBNull.Value);
insertCmd.Parameters.AddWithValue("@dinnerMealId", menu.DinnerMealId ?? (object)DBNull.Value);
insertCmd.Parameters.AddWithValue("@weekNumber", menu.WeekNumber);
insertCmd.Parameters.AddWithValue("@year", menu.Year);
insertCmd.Parameters.AddWithValue("@cook", menu.Cook ?? (object)DBNull.Value);
insertCmd.ExecuteNonQuery();
}
}
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
Console.WriteLine($"Error updating weekly menu: {ex.Message}");
throw;
}
}
}
}
public int AddMeal(Meal meal)
{
using (var connection = GetConnection())
{
connection.Open();
string query = @"
INSERT INTO Meals (Name, Description, ProteinType, CarbType, RecipeUrl, CreatedAt)
VALUES (@name, @description, @proteinType, @carbType, @recipeUrl, NOW());
SELECT LAST_INSERT_ID();";
using (var cmd = new MySqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("@name", meal.Name);
cmd.Parameters.AddWithValue("@description", string.IsNullOrWhiteSpace(meal.Description) ? (object)DBNull.Value : meal.Description);
cmd.Parameters.AddWithValue("@proteinType", string.IsNullOrWhiteSpace(meal.ProteinType) ? (object)DBNull.Value : meal.ProteinType);
cmd.Parameters.AddWithValue("@carbType", string.IsNullOrWhiteSpace(meal.CarbType) ? (object)DBNull.Value : meal.CarbType);
cmd.Parameters.AddWithValue("@recipeUrl", string.IsNullOrWhiteSpace(meal.RecipeUrl) ? (object)DBNull.Value : meal.RecipeUrl);
var result = cmd.ExecuteScalar();
return result != null ? Convert.ToInt32(result) : 0;
}
}
}
private int GetDayOfWeek(string day)
{
return day switch
{
"Monday" => 1,
"Tuesday" => 2,
"Wednesday" => 3,
"Thursday" => 4,
"Friday" => 5,
"Saturday" => 6,
"Sunday" => 7,
_ => throw new System.ArgumentException("Invalid day name")
};
}
public void SaveOrUpdateMealWithIngredients(Meal meal) public void SaveOrUpdateMealWithIngredients(Meal meal)
{ {
// Spara/uppdatera måltid SaveMeal(meal);
SaveOrUpdateMeal(meal);
// Om måltiden har ingredienser spara dem
if (meal.Ingredients != null && meal.Ingredients.Count > 0) if (meal.Ingredients != null && meal.Ingredients.Count > 0)
{ {
SaveIngredients(meal.Id, meal.Ingredients); SaveIngredients(meal.Id, meal.Ingredients);
} }
} }
public List<Meal> GetMealsByCategory(string category) public List<Meal> GetMealsByCategory(string category)
{ {
var meals = new List<Meal>(); return _context.Meals
.Where(m => m.Category == category)
using var connection = GetConnection(); .Include(m => m.Ingredients)
connection.Open(); .OrderBy(m => m.Name)
.ToList();
string query = @" }
SELECT m.Id, m.Name, m.Category, m.Description, m.ImageUrl, m.ImageData, m.ImageMimeType, m.IsAvailable, public List<WeeklyMenu> GetWeeklyMenu(int weekNumber, int year)
i.Id AS IngredientId, i.Quantity, i.Item
FROM Meals m
LEFT JOIN Ingredients i ON m.Id = i.MealId
WHERE m.Category = @category
ORDER BY m.Name, i.Id";
using var cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("@category", category);
using var reader = cmd.ExecuteReader();
Dictionary<int, Meal> mealMap = new();
while (reader.Read())
{ {
int mealId = reader.GetInt32("Id"); var menus = _context.WeeklyMenus
.Where(m => m.WeekNumber == weekNumber && m.Year == year)
.ToList();
if (!mealMap.ContainsKey(mealId)) var allMeals = _context.Meals.ToDictionary(m => m.Id, m => m.Name);
{
mealMap[mealId] = new Meal
{
Id = mealId,
Name = reader.GetString("Name"),
Category = reader.IsDBNull(reader.GetOrdinal("Category")) ? null : reader.GetString("Category"),
Description = reader.IsDBNull(reader.GetOrdinal("Description")) ? null : reader.GetString("Description"),
ImageUrl = reader.IsDBNull(reader.GetOrdinal("ImageUrl")) ? null : reader.GetString("ImageUrl"),
ImageData = reader.IsDBNull(reader.GetOrdinal("ImageData")) ? null : (byte[])reader["ImageData"],
ImageMimeType = reader.IsDBNull(reader.GetOrdinal("ImageMimeType")) ? null : reader.GetString("ImageMimeType"),
Ingredients = new List<Ingredient>(),
IsAvailable = reader.IsDBNull(reader.GetOrdinal("IsAvailable")) ? true : reader.GetBoolean(reader.GetOrdinal("IsAvailable")),
}; foreach (var wm in menus)
{
wm.BreakfastMealName = wm.BreakfastMealId.HasValue && allMeals.TryGetValue(wm.BreakfastMealId.Value, out var breakfast)
? breakfast
: null;
wm.LunchMealName = wm.LunchMealId.HasValue && allMeals.TryGetValue(wm.LunchMealId.Value, out var lunch)
? lunch
: null;
wm.DinnerMealName = wm.DinnerMealId.HasValue && allMeals.TryGetValue(wm.DinnerMealId.Value, out var dinner)
? dinner
: null;
} }
if (!reader.IsDBNull(reader.GetOrdinal("IngredientId"))) return menus;
{
mealMap[mealId].Ingredients.Add(new Ingredient
{
Id = reader.GetInt32("IngredientId"),
MealId = mealId,
Quantity = reader.IsDBNull(reader.GetOrdinal("Quantity")) ? "" : reader.GetString("Quantity"),
Item = reader.IsDBNull(reader.GetOrdinal("Item")) ? "" : reader.GetString("Item")
});
}
} }
return mealMap.Values.ToList();
}
public List<WeeklyMenu> GetMenuEntriesByDateRange(DateTime startDate, DateTime endDate) public List<WeeklyMenu> GetMenuEntriesByDateRange(DateTime startDate, DateTime endDate)
{ {
var results = new List<WeeklyMenu>(); var results = new List<WeeklyMenu>();
// Hitta start- och slut-år/veckonummer
int startWeek = ISOWeek.GetWeekOfYear(startDate); int startWeek = ISOWeek.GetWeekOfYear(startDate);
int startYear = startDate.Year;
int endWeek = ISOWeek.GetWeekOfYear(endDate); int endWeek = ISOWeek.GetWeekOfYear(endDate);
int startYear = startDate.Year;
int endYear = endDate.Year; int endYear = endDate.Year;
// Loopar över alla veckor från start → slut for (int y = startYear; y <= endYear; y++)
var allMenus = new List<WeeklyMenu>();
int w = startWeek, y = startYear;
while (y < endYear || (y == endYear && w <= endWeek))
{ {
allMenus.AddRange(GetWeeklyMenu(w, y)); int fromWeek = y == startYear ? startWeek : 1;
int toWeek = y == endYear ? endWeek : ISOWeek.GetWeeksInYear(y);
// öka vecka, hantera årsskifte for (int w = fromWeek; w <= toWeek; w++)
int weeksInYear = ISOWeek.GetWeeksInYear(y);
if (w == weeksInYear)
{ {
w = 1; var menus = GetWeeklyMenu(w, y);
y++; foreach (var menu in menus)
}
else
{ {
w++;
}
}
// Filtrera på datumintervall
foreach (var menu in allMenus)
{
// Konvertera DayOfWeek (1=Mon…7=Sun) till System.DayOfWeek
var dow = (DayOfWeek)(menu.DayOfWeek % 7); var dow = (DayOfWeek)(menu.DayOfWeek % 7);
var date = ISOWeek.ToDateTime(menu.Year, menu.WeekNumber, dow); var date = ISOWeek.ToDateTime(menu.Year, menu.WeekNumber, dow);
if (date.Date >= startDate.Date && date.Date <= endDate.Date) if (date.Date >= startDate.Date && date.Date <= endDate.Date)
{ {
menu.Date = date; // Se till att WeeklyMenu har en Date-property menu.CreatedAt = date;
results.Add(menu); results.Add(menu);
} }
} }
}
}
return results; return results;
} }
} }
} }
// Models for Meals and WeeklyMenu

View File

@@ -1,16 +1,23 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
RUN apt-get update && \
apt-get install -y locales && \
locale-gen sv_SE.UTF-8
ENV LANG=sv_SE.UTF-8
ENV LANGUAGE=sv_SE:sv
ENV LC_ALL=sv_SE.UTF-8
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
WORKDIR /app WORKDIR /app
EXPOSE 80 EXPOSE 80
EXPOSE 443 EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src WORKDIR /src
COPY ["Aberwyn/Aberwyn.csproj", "Aberwyn/"] COPY ["Aberwyn.csproj", "."]
RUN dotnet restore "Aberwyn/Aberwyn.csproj" RUN dotnet restore "Aberwyn.csproj"
COPY . . COPY . .
WORKDIR "/src/Aberwyn"
RUN dotnet build "Aberwyn.csproj" -c Release -o /app/build RUN dotnet build "Aberwyn.csproj" -c Release -o /app/build
FROM build AS publish FROM build AS publish

View File

@@ -0,0 +1,38 @@
version: '3.8'
services:
aberwyn-app:
image: aberwyn:latest
build:
context: ../
dockerfile: Dockerfile
ports:
- "5000:80"
environment:
ASPNETCORE_ENVIRONMENT: Development
DB_NAME: aberwyn_dev
depends_on:
- mysql
networks:
- aberwyn-net
mysql:
image: mysql:8
container_name: aberwyn-mysql-dev
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: aberwyn_dev
MYSQL_USER: aberwyn
MYSQL_PASSWORD: 3edc4RFV
volumes:
- mysql-dev-data:/var/lib/mysql
networks:
- aberwyn-net
volumes:
mysql-dev-data:
networks:
aberwyn-net:

View File

@@ -0,0 +1,38 @@
version: '3.8'
services:
aberwyn-app:
image: aberwyn:latest
build:
context: ../
dockerfile: Dockerfile
ports:
- "8080:80"
environment:
ASPNETCORE_ENVIRONMENT: Production
DB_NAME: aberwyn_prod
depends_on:
- mysql
networks:
- aberwyn-net
mysql:
image: mysql:8
container_name: aberwyn-mysql-prod
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: aberwyn_prod
MYSQL_USER: aberwyn
MYSQL_PASSWORD: 3edc4RFV
volumes:
- mysql-prod-data:/var/lib/mysql
networks:
- aberwyn-net
volumes:
mysql-prod-data:
networks:
aberwyn-net:

View File

@@ -1,269 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250506132522_CreateIdentitySchema")]
partial class CreateIdentitySchema
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,259 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class CreateIdentitySchema : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Name = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
UserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedUserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Email = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedEmail = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
EmailConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
PasswordHash = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
SecurityStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PhoneNumber = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PhoneNumberConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
TwoFactorEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(type: "datetime(6)", nullable: true),
LockoutEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
AccessFailedCount = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
RoleId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ProviderKey = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ProviderDisplayName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
RoleId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Name = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}

View File

@@ -1,375 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250515202922_CreateBudgetSchema")]
partial class CreateBudgetSchema
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Person")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,101 +0,0 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class CreateBudgetSchema : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "BudgetPeriods",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Year = table.Column<int>(type: "int", nullable: false),
Month = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetPeriods", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetCategories",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Color = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
BudgetPeriodId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetCategories", x => x.Id);
table.ForeignKey(
name: "FK_BudgetCategories_BudgetPeriods_BudgetPeriodId",
column: x => x.BudgetPeriodId,
principalTable: "BudgetPeriods",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetItems",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Person = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Amount = table.Column<decimal>(type: "decimal(65,30)", nullable: false),
IsExpense = table.Column<bool>(type: "tinyint(1)", nullable: false),
IncludeInSummary = table.Column<bool>(type: "tinyint(1)", nullable: false),
BudgetCategoryId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetItems", x => x.Id);
table.ForeignKey(
name: "FK_BudgetItems_BudgetCategories_BudgetCategoryId",
column: x => x.BudgetCategoryId,
principalTable: "BudgetCategories",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_BudgetCategories_BudgetPeriodId",
table: "BudgetCategories",
column: "BudgetPeriodId");
migrationBuilder.CreateIndex(
name: "IX_BudgetItems_BudgetCategoryId",
table: "BudgetItems",
column: "BudgetCategoryId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BudgetItems");
migrationBuilder.DropTable(
name: "BudgetCategories");
migrationBuilder.DropTable(
name: "BudgetPeriods");
}
}
}

View File

@@ -1,374 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250515204407_MakePersonNullable")]
partial class MakePersonNullable
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Person")
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,43 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class MakePersonNullable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Person",
table: "BudgetItems",
type: "longtext",
nullable: true,
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "BudgetItems",
keyColumn: "Person",
keyValue: null,
column: "Person",
value: "");
migrationBuilder.AlterColumn<string>(
name: "Person",
table: "BudgetItems",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "longtext",
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
}
}

View File

@@ -1,380 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250519213736_AddOrderToBudgetCategory")]
partial class AddOrderToBudgetCategory
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Order")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,59 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddOrderToBudgetCategory : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Person",
table: "BudgetItems");
migrationBuilder.AddColumn<int>(
name: "Order",
table: "BudgetPeriods",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "Order",
table: "BudgetItems",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "Order",
table: "BudgetCategories",
type: "int",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Order",
table: "BudgetPeriods");
migrationBuilder.DropColumn(
name: "Order",
table: "BudgetItems");
migrationBuilder.DropColumn(
name: "Order",
table: "BudgetCategories");
migrationBuilder.AddColumn<string>(
name: "Person",
table: "BudgetItems",
type: "longtext",
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
}
}
}

View File

@@ -1,380 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250522074358_AddMealImageData")]
partial class AddMealImageData
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Order")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,19 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddMealImageData : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@@ -1,403 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250523075931_AddPushSubscribers")]
partial class AddPushSubscribers
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Order")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Auth")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Endpoint")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("P256DH")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PushSubscribers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,38 +0,0 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddPushSubscribers : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "PushSubscribers",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Endpoint = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
P256DH = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Auth = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_PushSubscribers", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PushSubscribers");
}
}
}

View File

@@ -1,403 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250524103706_AddPizzaOrder")]
partial class AddPizzaOrder
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Order")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Auth")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Endpoint")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("P256DH")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PushSubscribers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,19 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddPizzaOrder : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@@ -1,432 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250524121511_AddPizzaOrderTable")]
partial class AddPizzaOrderTable
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Order")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("CustomerName")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("IngredientsJson")
.HasColumnType("longtext");
b.Property<DateTime>("OrderedAt")
.HasColumnType("datetime(6)");
b.Property<string>("PizzaName")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PizzaOrders");
});
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Auth")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Endpoint")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("P256DH")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PushSubscribers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,42 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddPizzaOrderTable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "PizzaOrders",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CustomerName = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
PizzaName = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IngredientsJson = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Status = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
OrderedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PizzaOrders", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PizzaOrders");
}
}
}

View File

@@ -1,451 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250524173316_AddAppSettings")]
partial class AddAppSettings
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.AppSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Key")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("AppSettings");
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Order")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("CustomerName")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("IngredientsJson")
.HasColumnType("longtext");
b.Property<DateTime>("OrderedAt")
.HasColumnType("datetime(6)");
b.Property<string>("PizzaName")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PizzaOrders");
});
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Auth")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Endpoint")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("P256DH")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PushSubscribers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetCategory");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,36 +0,0 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddAppSettings : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AppSettings",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Key = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AppSettings", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AppSettings");
}
}
}

View File

@@ -1,516 +0,0 @@
// <auto-generated />
using System;
using Aberwyn.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Aberwyn.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20250526121643_AddBudgetDefinitions")]
partial class AddBudgetDefinitions
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.AppSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Key")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("AppSettings");
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int?>("BudgetCategoryDefinitionId")
.HasColumnType("int");
b.Property<int>("BudgetPeriodId")
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryDefinitionId");
b.HasIndex("BudgetPeriodId");
b.ToTable("BudgetCategories");
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategoryDefinition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Color")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("BudgetCategoryDefinition");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<decimal>("Amount")
.HasColumnType("decimal(65,30)");
b.Property<int>("BudgetCategoryId")
.HasColumnType("int");
b.Property<int?>("BudgetItemDefinitionId")
.HasColumnType("int");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("Order")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BudgetCategoryId");
b.HasIndex("BudgetItemDefinitionId");
b.ToTable("BudgetItems");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItemDefinition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("DefaultCategory")
.HasColumnType("longtext");
b.Property<bool>("IncludeInSummary")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsExpense")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("BudgetItemDefinition");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Month")
.HasColumnType("int");
b.Property<int>("Order")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("BudgetPeriods");
});
modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("CustomerName")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("IngredientsJson")
.HasColumnType("longtext");
b.Property<DateTime>("OrderedAt")
.HasColumnType("datetime(6)");
b.Property<string>("PizzaName")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PizzaOrders");
});
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Auth")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Endpoint")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("P256DH")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PushSubscribers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategoryDefinition", "BudgetItemDefinition")
.WithMany()
.HasForeignKey("BudgetCategoryDefinitionId");
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
.WithMany("Categories")
.HasForeignKey("BudgetPeriodId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("BudgetPeriod");
b.Navigation("BudgetItemDefinition");
});
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
{
b.HasOne("Aberwyn.Models.BudgetCategory", "BudgetCategory")
.WithMany("Items")
.HasForeignKey("BudgetCategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.BudgetItemDefinition", "BudgetItemDefinition")
.WithMany()
.HasForeignKey("BudgetItemDefinitionId");
b.Navigation("BudgetCategory");
b.Navigation("BudgetItemDefinition");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Aberwyn.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
{
b.Navigation("Categories");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,118 +0,0 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddBudgetDefinitions : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "BudgetItemDefinitionId",
table: "BudgetItems",
type: "int",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "BudgetCategoryDefinitionId",
table: "BudgetCategories",
type: "int",
nullable: true);
migrationBuilder.CreateTable(
name: "BudgetCategoryDefinition",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Color = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetCategoryDefinition", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetItemDefinition",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
DefaultCategory = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsExpense = table.Column<bool>(type: "tinyint(1)", nullable: false),
IncludeInSummary = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetItemDefinition", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_BudgetItems_BudgetItemDefinitionId",
table: "BudgetItems",
column: "BudgetItemDefinitionId");
migrationBuilder.CreateIndex(
name: "IX_BudgetCategories_BudgetCategoryDefinitionId",
table: "BudgetCategories",
column: "BudgetCategoryDefinitionId");
migrationBuilder.AddForeignKey(
name: "FK_BudgetCategories_BudgetCategoryDefinition_BudgetCategoryDefi~",
table: "BudgetCategories",
column: "BudgetCategoryDefinitionId",
principalTable: "BudgetCategoryDefinition",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_BudgetItems_BudgetItemDefinition_BudgetItemDefinitionId",
table: "BudgetItems",
column: "BudgetItemDefinitionId",
principalTable: "BudgetItemDefinition",
principalColumn: "Id");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BudgetCategories_BudgetCategoryDefinition_BudgetCategoryDefi~",
table: "BudgetCategories");
migrationBuilder.DropForeignKey(
name: "FK_BudgetItems_BudgetItemDefinition_BudgetItemDefinitionId",
table: "BudgetItems");
migrationBuilder.DropTable(
name: "BudgetCategoryDefinition");
migrationBuilder.DropTable(
name: "BudgetItemDefinition");
migrationBuilder.DropIndex(
name: "IX_BudgetItems_BudgetItemDefinitionId",
table: "BudgetItems");
migrationBuilder.DropIndex(
name: "IX_BudgetCategories_BudgetCategoryDefinitionId",
table: "BudgetCategories");
migrationBuilder.DropColumn(
name: "BudgetItemDefinitionId",
table: "BudgetItems");
migrationBuilder.DropColumn(
name: "BudgetCategoryDefinitionId",
table: "BudgetCategories");
}
}
}

View File

@@ -1,111 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class AddBudgetItemDefinitions : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BudgetCategories_BudgetCategoryDefinition_BudgetCategoryDefi~",
table: "BudgetCategories");
migrationBuilder.DropForeignKey(
name: "FK_BudgetItems_BudgetItemDefinition_BudgetItemDefinitionId",
table: "BudgetItems");
migrationBuilder.DropPrimaryKey(
name: "PK_BudgetItemDefinition",
table: "BudgetItemDefinition");
migrationBuilder.DropPrimaryKey(
name: "PK_BudgetCategoryDefinition",
table: "BudgetCategoryDefinition");
migrationBuilder.RenameTable(
name: "BudgetItemDefinition",
newName: "BudgetItemDefinitions");
migrationBuilder.RenameTable(
name: "BudgetCategoryDefinition",
newName: "BudgetCategoryDefinitions");
migrationBuilder.AddPrimaryKey(
name: "PK_BudgetItemDefinitions",
table: "BudgetItemDefinitions",
column: "Id");
migrationBuilder.AddPrimaryKey(
name: "PK_BudgetCategoryDefinitions",
table: "BudgetCategoryDefinitions",
column: "Id");
migrationBuilder.AddForeignKey(
name: "FK_BudgetCategories_BudgetCategoryDefinitions_BudgetCategoryDef~",
table: "BudgetCategories",
column: "BudgetCategoryDefinitionId",
principalTable: "BudgetCategoryDefinitions",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_BudgetItems_BudgetItemDefinitions_BudgetItemDefinitionId",
table: "BudgetItems",
column: "BudgetItemDefinitionId",
principalTable: "BudgetItemDefinitions",
principalColumn: "Id");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BudgetCategories_BudgetCategoryDefinitions_BudgetCategoryDef~",
table: "BudgetCategories");
migrationBuilder.DropForeignKey(
name: "FK_BudgetItems_BudgetItemDefinitions_BudgetItemDefinitionId",
table: "BudgetItems");
migrationBuilder.DropPrimaryKey(
name: "PK_BudgetItemDefinitions",
table: "BudgetItemDefinitions");
migrationBuilder.DropPrimaryKey(
name: "PK_BudgetCategoryDefinitions",
table: "BudgetCategoryDefinitions");
migrationBuilder.RenameTable(
name: "BudgetItemDefinitions",
newName: "BudgetItemDefinition");
migrationBuilder.RenameTable(
name: "BudgetCategoryDefinitions",
newName: "BudgetCategoryDefinition");
migrationBuilder.AddPrimaryKey(
name: "PK_BudgetItemDefinition",
table: "BudgetItemDefinition",
column: "Id");
migrationBuilder.AddPrimaryKey(
name: "PK_BudgetCategoryDefinition",
table: "BudgetCategoryDefinition",
column: "Id");
migrationBuilder.AddForeignKey(
name: "FK_BudgetCategories_BudgetCategoryDefinition_BudgetCategoryDefi~",
table: "BudgetCategories",
column: "BudgetCategoryDefinitionId",
principalTable: "BudgetCategoryDefinition",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_BudgetItems_BudgetItemDefinition_BudgetItemDefinitionId",
table: "BudgetItems",
column: "BudgetItemDefinitionId",
principalTable: "BudgetItemDefinition",
principalColumn: "Id");
}
}
}

View File

@@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Aberwyn.Migrations namespace Aberwyn.Migrations
{ {
[DbContext(typeof(ApplicationDbContext))] [DbContext(typeof(ApplicationDbContext))]
[Migration("20250526133558_AddBudgetItemDefinitions")] [Migration("20250602131723_InitCleanSlate")]
partial class AddBudgetItemDefinitions partial class InitCleanSlate
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
{ {
@@ -236,6 +236,78 @@ namespace Aberwyn.Migrations
b.ToTable("BudgetPeriods"); b.ToTable("BudgetPeriods");
}); });
modelBuilder.Entity("Aberwyn.Models.Ingredient", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Item")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("MealId")
.HasColumnType("int");
b.Property<string>("Quantity")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("MealId");
b.ToTable("Ingredients");
});
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("CarbType")
.HasColumnType("longtext");
b.Property<string>("Category")
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<byte[]>("ImageData")
.HasColumnType("longblob");
b.Property<string>("ImageMimeType")
.HasColumnType("longtext");
b.Property<string>("ImageUrl")
.HasColumnType("longtext");
b.Property<string>("Instructions")
.HasColumnType("longtext");
b.Property<bool>("IsAvailable")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("ProteinType")
.HasColumnType("longtext");
b.Property<string>("RecipeUrl")
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("Meals");
});
modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b => modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -288,6 +360,81 @@ namespace Aberwyn.Migrations
b.ToTable("PushSubscribers"); b.ToTable("PushSubscribers");
}); });
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("AssignedTo")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsArchived")
.HasColumnType("tinyint(1)");
b.Property<int>("Priority")
.HasColumnType("int");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("TodoTasks");
});
modelBuilder.Entity("Aberwyn.Models.WeeklyMenu", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int?>("BreakfastMealId")
.HasColumnType("int");
b.Property<string>("Cook")
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<int>("DayOfWeek")
.HasColumnType("int");
b.Property<int?>("DinnerMealId")
.HasColumnType("int");
b.Property<int?>("LunchMealId")
.HasColumnType("int");
b.Property<int>("WeekNumber")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("WeeklyMenu", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{ {
b.Property<string>("Id") b.Property<string>("Id")
@@ -418,7 +565,7 @@ namespace Aberwyn.Migrations
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b => modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{ {
b.HasOne("Aberwyn.Models.BudgetCategoryDefinition", "BudgetItemDefinition") b.HasOne("Aberwyn.Models.BudgetCategoryDefinition", "Definition")
.WithMany() .WithMany()
.HasForeignKey("BudgetCategoryDefinitionId"); .HasForeignKey("BudgetCategoryDefinitionId");
@@ -430,7 +577,7 @@ namespace Aberwyn.Migrations
b.Navigation("BudgetPeriod"); b.Navigation("BudgetPeriod");
b.Navigation("BudgetItemDefinition"); b.Navigation("Definition");
}); });
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b => modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
@@ -450,6 +597,15 @@ namespace Aberwyn.Migrations
b.Navigation("BudgetItemDefinition"); b.Navigation("BudgetItemDefinition");
}); });
modelBuilder.Entity("Aberwyn.Models.Ingredient", b =>
{
b.HasOne("Aberwyn.Models.Meal", null)
.WithMany("Ingredients")
.HasForeignKey("MealId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{ {
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
@@ -510,6 +666,11 @@ namespace Aberwyn.Migrations
{ {
b.Navigation("Categories"); b.Navigation("Categories");
}); });
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
{
b.Navigation("Ingredients");
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }

View File

@@ -0,0 +1,599 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Aberwyn.Migrations
{
public partial class InitCleanSlate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AppSettings",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Key = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AppSettings", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Name = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
UserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedUserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Email = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedEmail = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
EmailConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
PasswordHash = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
SecurityStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PhoneNumber = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PhoneNumberConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
TwoFactorEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(type: "datetime(6)", nullable: true),
LockoutEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
AccessFailedCount = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetCategoryDefinitions",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Color = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetCategoryDefinitions", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetItemDefinitions",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
DefaultCategory = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsExpense = table.Column<bool>(type: "tinyint(1)", nullable: false),
IncludeInSummary = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetItemDefinitions", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetPeriods",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Year = table.Column<int>(type: "int", nullable: false),
Month = table.Column<int>(type: "int", nullable: false),
Order = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetPeriods", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "Meals",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ProteinType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Category = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
CarbType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
RecipeUrl = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ImageUrl = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsAvailable = table.Column<bool>(type: "tinyint(1)", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ImageData = table.Column<byte[]>(type: "longblob", nullable: true),
ImageMimeType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Instructions = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_Meals", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "PizzaOrders",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
CustomerName = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
PizzaName = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IngredientsJson = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Status = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
OrderedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PizzaOrders", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "PushSubscribers",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Endpoint = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
P256DH = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Auth = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_PushSubscribers", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "TodoTasks",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Title = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Priority = table.Column<int>(type: "int", nullable: false),
Status = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
AssignedTo = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsArchived = table.Column<bool>(type: "tinyint(1)", nullable: false),
Tags = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_TodoTasks", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "WeeklyMenu",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
DayOfWeek = table.Column<int>(type: "int", nullable: false),
BreakfastMealId = table.Column<int>(type: "int", nullable: true),
LunchMealId = table.Column<int>(type: "int", nullable: true),
DinnerMealId = table.Column<int>(type: "int", nullable: true),
Cook = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
WeekNumber = table.Column<int>(type: "int", nullable: false),
Year = table.Column<int>(type: "int", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_WeeklyMenu", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
RoleId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ProviderKey = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ProviderDisplayName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
RoleId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Name = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetCategories",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Color = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
BudgetPeriodId = table.Column<int>(type: "int", nullable: false),
Order = table.Column<int>(type: "int", nullable: false),
BudgetCategoryDefinitionId = table.Column<int>(type: "int", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetCategories", x => x.Id);
table.ForeignKey(
name: "FK_BudgetCategories_BudgetCategoryDefinitions_BudgetCategoryDef~",
column: x => x.BudgetCategoryDefinitionId,
principalTable: "BudgetCategoryDefinitions",
principalColumn: "Id");
table.ForeignKey(
name: "FK_BudgetCategories_BudgetPeriods_BudgetPeriodId",
column: x => x.BudgetPeriodId,
principalTable: "BudgetPeriods",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "Ingredients",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
MealId = table.Column<int>(type: "int", nullable: false),
Quantity = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Item = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_Ingredients", x => x.Id);
table.ForeignKey(
name: "FK_Ingredients_Meals_MealId",
column: x => x.MealId,
principalTable: "Meals",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "BudgetItems",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Amount = table.Column<decimal>(type: "decimal(65,30)", nullable: false),
IsExpense = table.Column<bool>(type: "tinyint(1)", nullable: false),
IncludeInSummary = table.Column<bool>(type: "tinyint(1)", nullable: false),
Order = table.Column<int>(type: "int", nullable: false),
BudgetItemDefinitionId = table.Column<int>(type: "int", nullable: true),
BudgetCategoryId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BudgetItems", x => x.Id);
table.ForeignKey(
name: "FK_BudgetItems_BudgetCategories_BudgetCategoryId",
column: x => x.BudgetCategoryId,
principalTable: "BudgetCategories",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_BudgetItems_BudgetItemDefinitions_BudgetItemDefinitionId",
column: x => x.BudgetItemDefinitionId,
principalTable: "BudgetItemDefinitions",
principalColumn: "Id");
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_BudgetCategories_BudgetCategoryDefinitionId",
table: "BudgetCategories",
column: "BudgetCategoryDefinitionId");
migrationBuilder.CreateIndex(
name: "IX_BudgetCategories_BudgetPeriodId",
table: "BudgetCategories",
column: "BudgetPeriodId");
migrationBuilder.CreateIndex(
name: "IX_BudgetItems_BudgetCategoryId",
table: "BudgetItems",
column: "BudgetCategoryId");
migrationBuilder.CreateIndex(
name: "IX_BudgetItems_BudgetItemDefinitionId",
table: "BudgetItems",
column: "BudgetItemDefinitionId");
migrationBuilder.CreateIndex(
name: "IX_Ingredients_MealId",
table: "Ingredients",
column: "MealId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AppSettings");
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "BudgetItems");
migrationBuilder.DropTable(
name: "Ingredients");
migrationBuilder.DropTable(
name: "PizzaOrders");
migrationBuilder.DropTable(
name: "PushSubscribers");
migrationBuilder.DropTable(
name: "TodoTasks");
migrationBuilder.DropTable(
name: "WeeklyMenu");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
migrationBuilder.DropTable(
name: "BudgetCategories");
migrationBuilder.DropTable(
name: "BudgetItemDefinitions");
migrationBuilder.DropTable(
name: "Meals");
migrationBuilder.DropTable(
name: "BudgetCategoryDefinitions");
migrationBuilder.DropTable(
name: "BudgetPeriods");
}
}
}

View File

@@ -234,6 +234,78 @@ namespace Aberwyn.Migrations
b.ToTable("BudgetPeriods"); b.ToTable("BudgetPeriods");
}); });
modelBuilder.Entity("Aberwyn.Models.Ingredient", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Item")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("MealId")
.HasColumnType("int");
b.Property<string>("Quantity")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("MealId");
b.ToTable("Ingredients");
});
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("CarbType")
.HasColumnType("longtext");
b.Property<string>("Category")
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<byte[]>("ImageData")
.HasColumnType("longblob");
b.Property<string>("ImageMimeType")
.HasColumnType("longtext");
b.Property<string>("ImageUrl")
.HasColumnType("longtext");
b.Property<string>("Instructions")
.HasColumnType("longtext");
b.Property<bool>("IsAvailable")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("ProteinType")
.HasColumnType("longtext");
b.Property<string>("RecipeUrl")
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("Meals");
});
modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b => modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -286,6 +358,81 @@ namespace Aberwyn.Migrations
b.ToTable("PushSubscribers"); b.ToTable("PushSubscribers");
}); });
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("AssignedTo")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsArchived")
.HasColumnType("tinyint(1)");
b.Property<int>("Priority")
.HasColumnType("int");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("TodoTasks");
});
modelBuilder.Entity("Aberwyn.Models.WeeklyMenu", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int?>("BreakfastMealId")
.HasColumnType("int");
b.Property<string>("Cook")
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<int>("DayOfWeek")
.HasColumnType("int");
b.Property<int?>("DinnerMealId")
.HasColumnType("int");
b.Property<int?>("LunchMealId")
.HasColumnType("int");
b.Property<int>("WeekNumber")
.HasColumnType("int");
b.Property<int>("Year")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("WeeklyMenu", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{ {
b.Property<string>("Id") b.Property<string>("Id")
@@ -416,7 +563,7 @@ namespace Aberwyn.Migrations
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b => modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
{ {
b.HasOne("Aberwyn.Models.BudgetCategoryDefinition", "BudgetItemDefinition") b.HasOne("Aberwyn.Models.BudgetCategoryDefinition", "Definition")
.WithMany() .WithMany()
.HasForeignKey("BudgetCategoryDefinitionId"); .HasForeignKey("BudgetCategoryDefinitionId");
@@ -428,7 +575,7 @@ namespace Aberwyn.Migrations
b.Navigation("BudgetPeriod"); b.Navigation("BudgetPeriod");
b.Navigation("BudgetItemDefinition"); b.Navigation("Definition");
}); });
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b => modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
@@ -448,6 +595,15 @@ namespace Aberwyn.Migrations
b.Navigation("BudgetItemDefinition"); b.Navigation("BudgetItemDefinition");
}); });
modelBuilder.Entity("Aberwyn.Models.Ingredient", b =>
{
b.HasOne("Aberwyn.Models.Meal", null)
.WithMany("Ingredients")
.HasForeignKey("MealId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{ {
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
@@ -508,6 +664,11 @@ namespace Aberwyn.Migrations
{ {
b.Navigation("Categories"); b.Navigation("Categories");
}); });
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
{
b.Navigation("Ingredients");
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }

View File

@@ -7,4 +7,20 @@
public string Value { get; set; } public string Value { get; set; }
} }
public class TodoTask
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Priority { get; set; }
public string Status { get; set; } // e.g., "ideas", "doing", "done"
public DateTime CreatedAt { get; set; }
public string AssignedTo { get; set; } // Ex: namn eller användarnamn
public bool IsArchived { get; set; }
public string Tags { get; set; } // Komma-separerad t.ex. "frontend,bug"
}
} }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using Aberwyn.Data; using Aberwyn.Data;
using Aberwyn.Models; using Aberwyn.Models;
@@ -11,21 +12,26 @@ namespace Aberwyn.Models
public int WeekNumber { get; set; } // Week number for the menu public int WeekNumber { get; set; } // Week number for the menu
public int Year { get; set; } // Year for the menu public int Year { get; set; } // Year for the menu
} }
public class WeeklyMenu public class WeeklyMenu
{ {
public int Id { get; set; } public int Id { get; set; }
public int DayOfWeek { get; set; } public int DayOfWeek { get; set; }
public int? BreakfastMealId { get; set; } // 👈 Lägg till denna public int? BreakfastMealId { get; set; }
public int? LunchMealId { get; set; } public int? LunchMealId { get; set; }
public int? DinnerMealId { get; set; } public int? DinnerMealId { get; set; }
public string Cook { get; set; } public string? Cook { get; set; }
public int WeekNumber { get; set; } public int WeekNumber { get; set; }
public int Year { get; set; } public int Year { get; set; }
public string BreakfastMealName { get; set; } // 👈 Och denna public DateTime CreatedAt { get; set; }
public string LunchMealName { get; set; }
public string DinnerMealName { get; set; } [NotMapped] public string? BreakfastMealName { get; set; }
public DateTime Date { get; set; } [NotMapped] public string? LunchMealName { get; set; }
} [NotMapped] public string? DinnerMealName { get; set; }
}
public class RecentMenuEntry public class RecentMenuEntry
{ {
@@ -34,23 +40,27 @@ namespace Aberwyn.Models
public string LunchMealName { get; set; } public string LunchMealName { get; set; }
public string DinnerMealName { get; set; } public string DinnerMealName { get; set; }
} }
public class Meal public class Meal
{ {
public int Id { get; set; } public int Id { get; set; }
public string Name { get; set; } public string Name { get; set; } // Behåll som obligatorisk
public string Description { get; set; }
public string ProteinType { get; set; } public string? Description { get; set; }
public string Category { get; set; } public string? ProteinType { get; set; }
public string CarbType { get; set; } public string? Category { get; set; }
public string RecipeUrl { get; set; } public string? CarbType { get; set; }
public string ImageUrl { get; set; } public string? RecipeUrl { get; set; }
public string? ImageUrl { get; set; }
public bool IsAvailable { get; set; } public bool IsAvailable { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public byte[] ImageData { get; set; }
public string ImageMimeType { get; set; } // t.ex. "image/jpeg" public byte[]? ImageData { get; set; } // 👈 Viktigt!
public string Instructions { get; set; } // 👈 Tillagningstext public string? ImageMimeType { get; set; } // 👈 Viktigt!
public string? Instructions { get; set; } // 👈 Viktigt!
public List<Ingredient> Ingredients { get; set; } = new(); public List<Ingredient> Ingredients { get; set; } = new();
} }
public class Ingredient public class Ingredient
{ {
public int Id { get; set; } public int Id { get; set; }

View File

@@ -10,7 +10,23 @@ using Aberwyn.Models;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args); var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.AddEnvironmentVariables()
.Build();
Console.WriteLine("📦 DEBUG: laddad raw-connectionstring: " + config.GetConnectionString("DefaultConnection"));
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
EnvironmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"
});
builder.Configuration.AddConfiguration(config);
Console.WriteLine("🌍 Miljö: " + builder.Environment.EnvironmentName);
Console.WriteLine("🔗 Connection string: " + builder.Configuration.GetConnectionString("DefaultConnection"));
// Add services to the container. // Add services to the container.
builder.Services.AddControllersWithViews() builder.Services.AddControllersWithViews()
@@ -32,12 +48,15 @@ builder.Services.AddRazorPages();
builder.Services.AddHttpClient(); builder.Services.AddHttpClient();
// Configure your DbContext with MySQLs // Configure your DbContext with MySQLs
Console.WriteLine("🔗 Connection string: " + builder.Configuration.GetConnectionString("DefaultConnection"));
builder.Services.AddDbContext<ApplicationDbContext>(options => builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql( options.UseMySql(
builder.Configuration.GetConnectionString("DefaultConnection"), builder.Configuration.GetConnectionString("DefaultConnection"),
new MySqlServerVersion(new Version(8, 0, 36)) new MySqlServerVersion(new Version(8, 0, 36)),
)); mySqlOptions => mySqlOptions.EnableRetryOnFailure()
)
);
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options => builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
@@ -82,10 +101,11 @@ builder.Services.Configure<RequestLocalizationOptions>(options =>
options.SupportedCultures = supportedCultures; options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures; options.SupportedUICultures = supportedCultures;
}); });
builder.Configuration
.SetBasePath(Directory.GetCurrentDirectory()) //builder.Configuration
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) // .SetBasePath(Directory.GetCurrentDirectory())
.AddEnvironmentVariables(); // .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true)
// .AddEnvironmentVariables();
builder.Services.AddSingleton<PushNotificationService>(sp => builder.Services.AddSingleton<PushNotificationService>(sp =>
{ {
var config = sp.GetRequiredService<IConfiguration>(); var config = sp.GetRequiredService<IConfiguration>();
@@ -124,17 +144,37 @@ app.MapRazorPages();
using (var scope = app.Services.CreateScope()) using (var scope = app.Services.CreateScope())
{ {
var services = scope.ServiceProvider; var services = scope.ServiceProvider;
await IdentityDataInitializer.SeedData(services);
}
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
await IdentityDataInitializer.SeedData(services);
var context = services.GetRequiredService<ApplicationDbContext>(); var context = services.GetRequiredService<ApplicationDbContext>();
await TestDataSeeder.SeedBudget(context); // Vänta tills databasen är redo
int retries = 10;
while (retries > 0)
{
try
{
context.Database.OpenConnection(); // bara testa öppna anslutningen
context.Database.CloseConnection();
break; // lyckades!
}
catch
{
retries--;
Console.WriteLine("⏳ Väntar på databas...");
Thread.Sleep(3000);
}
}
// Kör alla EF-migrationer automatiskt
context.Database.Migrate();
// Skapa standardroller och admin
await IdentityDataInitializer.SeedData(services);
// (valfritt) Lägg in exempelbudgetdata
// await TestDataSeeder.SeedBudget(context);
} }
app.Run(); app.Run();

View File

@@ -8,14 +8,21 @@
} }
}, },
"profiles": { "profiles": {
"Aberwyn": { "Aberwyn (Dev)": {
"commandName": "Project", "commandName": "Project",
"launchBrowser": true, "launchBrowser": true,
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
}, },
"applicationUrl": "https://localhost:7290;http://localhost:5290", "applicationUrl": "https://localhost:7290;http://localhost:5290"
"dotnetRunMessages": true },
"Aberwyn (Prod)": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"applicationUrl": "https://localhost:7290;http://localhost:5290"
}, },
"IIS Express": { "IIS Express": {
"commandName": "IISExpress", "commandName": "IISExpress",
@@ -31,5 +38,5 @@
"publishAllPorts": true, "publishAllPorts": true,
"useSSL": true "useSSL": true
} }
} }
} }

View File

@@ -84,6 +84,19 @@
<button type="submit" class="btn btn-warning mt-2">Skicka testnotis</button> <button type="submit" class="btn btn-warning mt-2">Skicka testnotis</button>
</form> </form>
<hr />
<h3>Importera måltider från produktion</h3>
<form method="post" asp-action="ImportMealsFromProd">
<button type="submit" class="btn btn-danger">Importera alla måltider</button>
</form>
<form method="post" asp-action="ImportMenusFromProd">
<button type="submit" class="btn btn-danger mt-2">Importera veckomenyer</button>
</form>
<form method="post" asp-action="ImportBudgetFromProd">
<button type="submit" class="btn btn-danger mt-2">Importera budgetdata</button>
</form>
<script> <script>
async function sendPush(event) { async function sendPush(event) {
event.preventDefault(); // 🚫 stoppa formuläret från att göra vanlig POST event.preventDefault(); // 🚫 stoppa formuläret från att göra vanlig POST

View File

@@ -0,0 +1,110 @@
@{
ViewData["Title"] = "Todo";
}
<!DOCTYPE html>
<html lang="sv" ng-app="todoApp">
<head>
<meta charset="utf-8" />
<title>@ViewData["Title"]</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<script src="~/js/todo.js" asp-append-version="true"></script>
<style>
.todo-board {
padding: 20px;
font-family: sans-serif;
}
.todo-columns {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.todo-column {
background: #f1f5f9;
border-radius: 8px;
padding: 10px;
width: 250px;
min-height: 200px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.todo-column h2 {
margin-top: 0;
}
.todo-task {
background: white;
padding: 8px;
border-radius: 6px;
margin-bottom: 6px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
cursor: move;
}
input[type="text"] {
width: 100%;
margin-top: 8px;
padding: 6px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
margin-top: 6px;
padding: 6px 10px;
background-color: #3b82f6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.priority-low {
border-left: 4px solid #10b981;
}
.priority-medium {
border-left: 4px solid #f59e0b;
}
.priority-high {
border-left: 4px solid #ef4444;
}
</style>
</head>
<body ng-controller="TodoController" class="todo-board" ng-init="LoadTasks()">
<h1>🗂️ Min idé-board</h1>
<div class="todo-columns">
<div class="todo-column"
ng-repeat="col in Columns"
droppable-column
ng-attr-column-id="{{col.Id}}"
on-drop="MoveTask(task, columnId)">
<h2>{{ col.Title }}</h2>
<div class="todo-task {{ PriorityClass(task.Priority) }}"
ng-repeat="task in FilteredTasks(col.Id) track by task.Id"
draggable-task
task="task">
{{ task.Title }}
<div>
<small>Prioritet:
<select ng-model="task.Priority" ng-change="UpdatePriority(task)">
<option value="1">Låg</option>
<option value="2">Medel</option>
<option value="3">Hög</option>
</select>
</small>
</div>
</div>
<div ng-if="col.Id === 'ideas'">
<input type="text" ng-model="NewTask.Title" placeholder="Ny idé..." />
<select ng-model="NewTask.Priority">
<option value="1">Låg</option>
<option value="2">Medel</option>
<option value="3">Hög</option>
</select>
<button type="button" ng-click="AddTask()">Lägg till</button>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,5 +1,5 @@
@{ @{
ViewData["Title"] = "Welcome to Aberwyn!"; ViewData["Title"] = "Welcome to Lewel!";
} }
<!DOCTYPE html> <!DOCTYPE html>
@@ -12,7 +12,7 @@
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h1>Välkommen</h1> Kika på <a href="/Home/Menu" class="button">Menyn</a> om du vill <h1>Välkommen</h1> Kika på <a href="/Home/Menu" class="button">Menyn</a> om du vill.
</div> </div>
</body> </body>
</html> </html>

View File

@@ -1,4 +1,4 @@
@using Microsoft.AspNetCore.Identity @using Microsoft.AspNetCore.Identity
@using Aberwyn.Models @using Aberwyn.Models
@inject SignInManager<ApplicationUser> SignInManager @inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager @inject UserManager<ApplicationUser> UserManager
@@ -32,7 +32,7 @@ else
<form method="post" asp-area="Identity" asp-page="/Account/Login" style="padding: 12px; display: flex; flex-direction: column; gap: 8px;"> <form method="post" asp-area="Identity" asp-page="/Account/Login" style="padding: 12px; display: flex; flex-direction: column; gap: 8px;">
<input type="hidden" name="ReturnUrl" value="/" /> <input type="hidden" name="ReturnUrl" value="/" />
<input name="Input.Email" type="email" placeholder="E-post" required style="padding: 6px; font-size: 14px;" /> <input name="Input.Email" type="email" placeholder="E-post" required style="padding: 6px; font-size: 14px;" />
<input name="Input.Password" type="password" placeholder="Lösenord" required style="padding: 6px; font-size: 14px;" /> <input name="Input.Password" type="password" placeholder="Lösenord" required style="padding: 6px; font-size: 14px;" />
<button type="submit" style="background-color: #3A4E62; color: white; border: none; padding: 6px 10px; border-radius: 4px; font-size: 14px;"> <button type="submit" style="background-color: #3A4E62; color: white; border: none; padding: 6px 10px; border-radius: 4px; font-size: 14px;">
Logga in Logga in
</button> </button>
@@ -54,7 +54,7 @@ else
}); });
}); });
// Förhindra att klick i dropdownen stänger den // Förhindra att klick i dropdownen stänger den
document.querySelectorAll('.auth-dropdown').forEach(dropdown => { document.querySelectorAll('.auth-dropdown').forEach(dropdown => {
dropdown.addEventListener('click', e => e.stopPropagation()); dropdown.addEventListener('click', e => e.stopPropagation());
}); });

View File

@@ -4,5 +4,10 @@
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
},
"ConnectionStrings": {
"DefaultConnection": "Server=mysql;Database=aberwyn_dev;User=aberwyn;Password=3edc4RFV;",
"ProdConnection": "Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV;"
} }
} }

View File

@@ -0,0 +1,5 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=mysql;Database=aberwyn_prod;User=aberwyn;Password=3edc4RFV;"
}
}

View File

@@ -7,8 +7,7 @@
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV;", "DefaultConnection": "Server=mysql;Database=aberwyn_dev;User=aberwyn;Password=3edc4RFV;"
"ProductionConnection": "Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV;"
}, },
"VapidKeys": { "VapidKeys": {
"Subject": "mailto:e@zcz.se", "Subject": "mailto:e@zcz.se",

View File

@@ -1 +1 @@
Connection string: Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV; Connection string: Server=127.0.0.1;Port=3306;Database=aberwyn_dev;User=root;Password=rootpass;

120
Aberwyn/wwwroot/js/todo.js Normal file
View File

@@ -0,0 +1,120 @@
var app = angular.module("todoApp", []);
app.controller("TodoController", function ($scope, $http) {
$scope.Columns = [
{ Id: "ideas", Title: "💡 Idéer" },
{ Id: "doing", Title: "🔧 Pågående" },
{ Id: "done", Title: "✅ Klart" }
];
$scope.Tasks = [];
$scope.NewTask = {
Title: '',
Priority: 2
};
$scope.LoadTasks = function () {
$http.get("/Admin/GetTodoTasks").then(res => {
$scope.Tasks = res.data;
});
};
$scope.AddTask = function () {
const title = $scope.NewTask.Title;
const priority = $scope.NewTask.Priority;
if (typeof title !== 'string' || !title.trim()) {
return;
}
const task = {
Title: title.trim(),
Status: "ideas",
Priority: priority
};
$http.post("/Admin/AddTodoTask", task, {
headers: { 'Content-Type': 'application/json' }
}).then(res => {
$scope.Tasks.push(res.data);
$scope.NewTask.Title = '';
$scope.NewTask.Priority = 2;
}, err => {
console.error("Fel vid POST:", err);
});
};
$scope.MoveTask = function (droppedTask, newStatus) {
const task = $scope.Tasks.find(t => t.Id === droppedTask.Id);
if (!task || task.Status === newStatus) return;
task.Status = newStatus;
$http.post("/Admin/UpdateTodoTask", task)
.catch(err => console.error("Fel vid uppdatering:", err));
};
$scope.UpdatePriority = function (task) {
$http.post("/Admin/UpdateTodoTask", task);
};
$scope.PriorityClass = function (priority) {
return {
1: 'priority-low',
2: 'priority-medium',
3: 'priority-high'
}[priority];
};
$scope.FilteredTasks = function (status) {
if (!$scope.Tasks || !$scope.Tasks.length) return [];
return $scope.Tasks.filter(t => (t.Status || '').toLowerCase() === status.toLowerCase());
};
$scope.LoadTasks();
});
app.directive("droppableColumn", function () {
return {
restrict: "A",
scope: {
columnId: "@",
onDrop: "&"
},
link: function (scope, element) {
element.on("dragover", function (e) {
e.preventDefault();
element.css("background-color", "#e0f2fe");
});
element.on("dragleave", function () {
element.css("background-color", "");
});
element.on("drop", function (e) {
e.preventDefault();
const data = e.dataTransfer.getData("text/plain");
const task = JSON.parse(data);
scope.onDrop({ task: task, columnId: scope.columnId });
element.css("background-color", "");
scope.$apply();
});
}
};
});
app.directive("draggableTask", function () {
return {
restrict: "A",
scope: {
task: "=",
onTaskDrop: "&"
},
link: function (scope, element) {
element.attr("draggable", true);
element.on("dragstart", function (e) {
e.dataTransfer.setData("text/plain", JSON.stringify(scope.task));
});
}
};
});