Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 57bea7b54c | |||
|
|
465f9afc99 | ||
|
|
e3eb2dc7cb | ||
|
|
256ce76af1 | ||
|
|
b286fed88a | ||
|
|
bc77e39c72 | ||
|
|
eba00ffbf2 | ||
|
|
c44fbfdca9 | ||
|
|
84c6c45a0b | ||
|
|
83a71a6f1d | ||
|
|
fcd27943bf | ||
|
|
acbb72de3f | ||
|
|
c4efcc249b | ||
|
|
4da4a34443 | ||
|
|
77d3c741b1 | ||
|
|
e626daa7bc | ||
|
|
fe8e54b868 | ||
|
|
908bc469c6 | ||
|
|
3d6aa2d424 | ||
|
|
fd6759e3d0 | ||
|
|
4c60508d6d | ||
|
|
628f25a8be | ||
|
|
2e1e0f4670 | ||
|
|
a33ed400f1 | ||
|
|
5169889753 | ||
|
|
3b0ea79748 | ||
|
|
600df026d5 | ||
|
|
801e21842a |
15
.drone.yml
15
.drone.yml
@@ -4,13 +4,9 @@ name: default
|
||||
|
||||
steps:
|
||||
- name: build-dotnet
|
||||
image: mcr.microsoft.com/dotnet/sdk:6.0
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
LC_ALL: en_US.UTF-8
|
||||
DOTNET_CLI_UI_LANGUAGE: en-US
|
||||
image: alpine
|
||||
commands:
|
||||
- dotnet publish Aberwyn/Aberwyn.csproj -c Release -o out
|
||||
- echo "Docker build will handle dotnet publish"
|
||||
|
||||
- name: build-docker
|
||||
image: plugins/docker
|
||||
@@ -38,9 +34,10 @@ steps:
|
||||
from_secret: unraid_ssh_private_key
|
||||
script:
|
||||
- docker pull 192.168.1.9:3000/tai/aberwyn/aberwyn:latest
|
||||
- docker stop Aberwyn || true
|
||||
- docker rm Aberwyn || true
|
||||
- docker run -d --name='Aberwyn' --net='br0' -e TZ='Europe/Berlin' -p 80:80 192.168.1.9:3000/tai/aberwyn/aberwyn:latest
|
||||
- docker stop aberwyn || true
|
||||
- docker rm aberwyn || true
|
||||
- docker volume create aberwyn_config || true
|
||||
- docker run -d --name=aberwyn --net=br0 -e TZ=Europe/Berlin -p 80:80 -v aberwyn_config:/app/infrastructure 192.168.1.9:3000/tai/aberwyn/aberwyn:latest
|
||||
|
||||
- name: notify-result
|
||||
image: alpine
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -360,4 +360,8 @@ MigrationBackup/
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
|
||||
# Setupfil för Aberwyn
|
||||
infrastructure/setup.json
|
||||
Aberwyn/Infrastructure/setup.json
|
||||
|
||||
@@ -11,10 +11,6 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{423CD237-7404-4355-868F-CE5861835258}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{423CD237-7404-4355-868F-CE5861835258}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{423CD237-7404-4355-868F-CE5861835258}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{423CD237-7404-4355-868F-CE5861835258}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F5586986-B726-4E05-B31B-2E24CA5B2B89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F5586986-B726-4E05-B31B-2E24CA5B2B89}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F5586986-B726-4E05-B31B-2E24CA5B2B89}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -4,9 +4,9 @@ name: default
|
||||
|
||||
steps:
|
||||
- name: build-dotnet
|
||||
image: mcr.microsoft.com/dotnet/sdk:6.0
|
||||
image: alpine
|
||||
commands:
|
||||
- dotnet publish Aberwyn/Aberwyn.csproj -c Release -o out
|
||||
- echo "Docker build will handle dotnet publish"
|
||||
|
||||
- name: build-docker
|
||||
image: plugins/docker
|
||||
@@ -18,6 +18,37 @@ steps:
|
||||
password:
|
||||
from_secret: gitea_token
|
||||
dockerfile: Aberwyn/Dockerfile
|
||||
context: Aberwyn
|
||||
context: .
|
||||
tags:
|
||||
- latest
|
||||
insecure: true
|
||||
|
||||
- name: restart-unraid-container
|
||||
image: appleboy/drone-ssh
|
||||
settings:
|
||||
host: 192.168.1.108
|
||||
port: 22
|
||||
username:
|
||||
from_secret: unraid_ssh_user
|
||||
key:
|
||||
from_secret: unraid_ssh_private_key
|
||||
script:
|
||||
- docker pull 192.168.1.9:3000/tai/aberwyn/aberwyn:latest
|
||||
- docker stop Aberwyn || true
|
||||
- docker rm Aberwyn || true
|
||||
- docker run -d --name='Aberwyn' --net='br0' -e TZ='Europe/Berlin' -p 80:80 192.168.1.9:3000/tai/aberwyn/aberwyn:latest
|
||||
|
||||
- name: notify-result
|
||||
image: alpine
|
||||
when:
|
||||
status:
|
||||
- success
|
||||
- failure
|
||||
commands:
|
||||
- apk add --no-cache curl
|
||||
- |
|
||||
if [ "$DRONE_BUILD_STATUS" = "success" ]; then
|
||||
curl -X POST http://192.168.1.196:8123/api/webhook/aberwyn_update_success
|
||||
else
|
||||
curl -X POST http://192.168.1.196:8123/api/webhook/aberwyn_update_failed
|
||||
fi
|
||||
|
||||
@@ -10,18 +10,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="NewFolder\**" />
|
||||
<Content Remove="NewFolder\**" />
|
||||
<EmbeddedResource Remove="NewFolder\**" />
|
||||
<None Remove="NewFolder\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Data\BudgetService.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="Views\Home\Budget.cshtml" />
|
||||
<Compile Remove="Views\NewFolder\**" />
|
||||
<Content Remove="Views\NewFolder\**" />
|
||||
<EmbeddedResource Remove="Views\NewFolder\**" />
|
||||
<None Remove="Views\NewFolder\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -35,6 +27,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.36" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.36" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.36">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
@@ -52,12 +45,25 @@
|
||||
<!-- Övrigt -->
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.18" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.9" />
|
||||
<PackageReference Include="WebPush" Version="1.0.12" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\NewFolder\" />
|
||||
<Folder Include="Migrations\" />
|
||||
<Folder Include="wwwroot\images\meals\" />
|
||||
</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>
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
<hr />
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-floating">
|
||||
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" />
|
||||
<label asp-for="Input.Email" class="form-label"></label>
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
<label asp-for="Input.UserName"></label>
|
||||
<input asp-for="Input.UserName" />
|
||||
<span asp-validation-for="Input.UserName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input asp-for="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" />
|
||||
@@ -48,36 +48,6 @@
|
||||
</form>
|
||||
</section>
|
||||
</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>
|
||||
|
||||
@section Scripts {
|
||||
|
||||
@@ -61,27 +61,14 @@ namespace Aberwyn.Areas.Identity.Pages.Account
|
||||
/// </summary>
|
||||
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]
|
||||
[EmailAddress]
|
||||
public string Email { get; set; }
|
||||
[Display(Name = "Användarnamn")]
|
||||
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]
|
||||
[DataType(DataType.Password)]
|
||||
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; }
|
||||
}
|
||||
|
||||
@@ -112,7 +99,7 @@ namespace Aberwyn.Areas.Identity.Pages.Account
|
||||
{
|
||||
// This doesn't count login failures towards account lockout
|
||||
// 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, isPersistent: true, lockoutOnFailure: false);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
_logger.LogInformation("User logged in.");
|
||||
|
||||
@@ -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
|
||||
/// directly from your code. This API may change or be removed in future releases.
|
||||
/// </summary>
|
||||
///
|
||||
[Required]
|
||||
[Display(Name = "Användarnamn")]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required]
|
||||
[DataType(DataType.Password)]
|
||||
[Display(Name = "Current password")]
|
||||
|
||||
@@ -3,9 +3,7 @@ using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Aberwyn.Models;
|
||||
using Aberwyn.Data;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
@@ -13,31 +11,28 @@ namespace Aberwyn.Controllers
|
||||
[Authorize(Roles = "Admin")]
|
||||
public class AdminController : Controller
|
||||
{
|
||||
private readonly MenuService _menuService;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly RoleManager<IdentityRole> _roleManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly IHostEnvironment _env;
|
||||
private readonly MenuService _menuService;
|
||||
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public AdminController(
|
||||
IConfiguration configuration,
|
||||
IHostEnvironment env,
|
||||
MenuService menuService,
|
||||
ApplicationDbContext context,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
RoleManager<IdentityRole> roleManager)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_env = env;
|
||||
_menuService = menuService;
|
||||
_context = context;
|
||||
_userManager = userManager;
|
||||
_roleManager = roleManager;
|
||||
}
|
||||
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public AdminController(
|
||||
MenuService menuService,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
RoleManager<IdentityRole> roleManager,
|
||||
IConfiguration configuration,
|
||||
IHostEnvironment env,
|
||||
ApplicationDbContext context)
|
||||
{
|
||||
_menuService = menuService;
|
||||
_userManager = userManager;
|
||||
_roleManager = roleManager;
|
||||
_configuration = configuration;
|
||||
_env = env;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
@@ -109,89 +104,293 @@ public AdminController(
|
||||
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
|
||||
[Authorize(Roles = "Admin")]
|
||||
public IActionResult ImportMenusFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
|
||||
{
|
||||
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
|
||||
var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
|
||||
|
||||
using var customContext = new ApplicationDbContext(optionsBuilder.Options);
|
||||
var sourceService = new MenuService(customContext);
|
||||
var devService = new MenuService(_context);
|
||||
|
||||
var sourceMenus = sourceService.GetAllWeeklyMenus();
|
||||
var devMeals = devService.GetMeals();
|
||||
|
||||
foreach (var menu in sourceMenus)
|
||||
{
|
||||
Quantity = i.Quantity,
|
||||
Item = i.Item
|
||||
}).ToList()
|
||||
};
|
||||
var newMenu = new WeeklyMenu
|
||||
{
|
||||
DayOfWeek = menu.DayOfWeek,
|
||||
WeekNumber = menu.WeekNumber,
|
||||
Year = menu.Year,
|
||||
Cook = menu.Cook,
|
||||
BreakfastMealId = null,
|
||||
LunchMealId = null,
|
||||
DinnerMealId = null
|
||||
};
|
||||
|
||||
devService.SaveOrUpdateMealWithIngredients(newMeal);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(menu.BreakfastMealName))
|
||||
newMenu.BreakfastMealId = devMeals.FirstOrDefault(m => m.Name == menu.BreakfastMealName)?.Id;
|
||||
|
||||
return Content("Import klar!");
|
||||
}
|
||||
[HttpPost]
|
||||
[Authorize(Roles = "Admin")]
|
||||
[HttpPost]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public IActionResult ImportMenusFromProd()
|
||||
{
|
||||
var prodService = MenuService.CreateWithConfig(_configuration, _env, useProdDb: true);
|
||||
var devService = new MenuService(_context);
|
||||
if (!string.IsNullOrEmpty(menu.LunchMealName))
|
||||
newMenu.LunchMealId = devMeals.FirstOrDefault(m => m.Name == menu.LunchMealName)?.Id;
|
||||
|
||||
var allProdMenus = prodService.GetAllWeeklyMenus();
|
||||
var allMeals = devService.GetMeals();
|
||||
if (!string.IsNullOrEmpty(menu.DinnerMealName))
|
||||
newMenu.DinnerMealId = devMeals.FirstOrDefault(m => m.Name == menu.DinnerMealName)?.Id;
|
||||
|
||||
foreach (var menu in allProdMenus)
|
||||
{
|
||||
var newMenu = new WeeklyMenu
|
||||
_context.WeeklyMenus.Add(newMenu);
|
||||
}
|
||||
|
||||
_context.SaveChanges();
|
||||
TempData["Message"] = $"✅ Import av veckomenyer från extern databas klar ({sourceMenus.Count}).";
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
[HttpPost]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public IActionResult GenerateThumbnails()
|
||||
{
|
||||
DayOfWeek = menu.DayOfWeek,
|
||||
BreakfastMealId = menu.BreakfastMealName != null
|
||||
? allMeals.FirstOrDefault(m => m.Name == menu.BreakfastMealName)?.Id
|
||||
: null,
|
||||
LunchMealId = menu.LunchMealName != null
|
||||
? allMeals.FirstOrDefault(m => m.Name == menu.LunchMealName)?.Id
|
||||
: null,
|
||||
DinnerMealId = menu.DinnerMealName != null
|
||||
? allMeals.FirstOrDefault(m => m.Name == menu.DinnerMealName)?.Id
|
||||
: null,
|
||||
WeekNumber = menu.WeekNumber,
|
||||
Year = menu.Year,
|
||||
Cook = menu.Cook
|
||||
};
|
||||
var count = _menuService.GenerateMissingThumbnails();
|
||||
return Ok($"{count} thumbnails skapades.");
|
||||
}
|
||||
|
||||
_context.WeeklyMenus.Add(newMenu);
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public IActionResult ImportMealsFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
|
||||
{
|
||||
var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr), mySqlOptions => mySqlOptions.CommandTimeout(180));
|
||||
using var customContext = new ApplicationDbContext(optionsBuilder.Options);
|
||||
|
||||
var customService = new MenuService(customContext);
|
||||
var devService = new MenuService(_context);
|
||||
|
||||
try
|
||||
{
|
||||
var importedMeals = customService.GetMealsDetailed(); // Ska inkludera Ingredients
|
||||
foreach (var meal in importedMeals)
|
||||
{
|
||||
var newMeal = new Meal
|
||||
{
|
||||
Id = meal.Id, // 👈 Viktigt!
|
||||
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
|
||||
{
|
||||
MealId = meal.Id, // 👈 Koppla till rätt måltid
|
||||
Quantity = i.Quantity,
|
||||
Item = i.Item
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
devService.SaveOrUpdateMealWithIngredients(newMeal);
|
||||
}
|
||||
|
||||
TempData["Message"] = $"✅ {importedMeals.Count} måltider importerade från extern databas.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
TempData["Message"] = $"❌ Fel vid import: {ex.Message}";
|
||||
}
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public IActionResult ImportBudgetFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
|
||||
{
|
||||
var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
|
||||
|
||||
using var sourceContext = new ApplicationDbContext(optionsBuilder.Options);
|
||||
|
||||
var categoryDefs = sourceContext.BudgetCategoryDefinitions.ToList();
|
||||
var itemDefs = sourceContext.BudgetItemDefinitions.ToList();
|
||||
|
||||
foreach (var def in categoryDefs)
|
||||
{
|
||||
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 itemDefs)
|
||||
{
|
||||
if (!_context.BudgetItemDefinitions.Any(d => d.Name == def.Name))
|
||||
{
|
||||
_context.BudgetItemDefinitions.Add(new BudgetItemDefinition { Name = def.Name });
|
||||
}
|
||||
}
|
||||
|
||||
_context.SaveChanges();
|
||||
|
||||
var devCategoryDefs = _context.BudgetCategoryDefinitions.ToList();
|
||||
var devItemDefs = _context.BudgetItemDefinitions.ToList();
|
||||
|
||||
var periods = sourceContext.BudgetPeriods
|
||||
.Include(p => p.Categories)
|
||||
.ThenInclude(c => c.Items)
|
||||
.ToList();
|
||||
|
||||
foreach (var period in periods)
|
||||
{
|
||||
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 extern databas klar ({periods.Count} månader).";
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(task?.Title))
|
||||
return BadRequest("Titel krävs");
|
||||
|
||||
task.CreatedAt = DateTime.UtcNow;
|
||||
|
||||
task.Status ??= "ideas";
|
||||
task.Tags ??= "";
|
||||
task.AssignedTo ??= null;
|
||||
task.Description ??= "";
|
||||
|
||||
_context.TodoTasks.Add(task);
|
||||
_context.SaveChanges();
|
||||
|
||||
return Json(task);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 👇 Returnera hela stacktracen som JSON för felsökning
|
||||
return StatusCode(500, ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[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;
|
||||
existing.Description = task.Description;
|
||||
existing.Tags = task.Tags;
|
||||
existing.AssignedTo = task.AssignedTo;
|
||||
existing.IsArchived = task.IsArchived;
|
||||
|
||||
_context.SaveChanges();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
[HttpPost]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public IActionResult TestDbConnection(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword)
|
||||
{
|
||||
var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};";
|
||||
|
||||
try
|
||||
{
|
||||
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
builder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
|
||||
|
||||
using var context = new ApplicationDbContext(builder.Options);
|
||||
context.Database.OpenConnection();
|
||||
context.Database.CloseConnection();
|
||||
|
||||
return Json(new { success = true, message = "✅ Anslutning lyckades!" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Json(new { success = false, message = $"❌ Anslutning misslyckades: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_context.SaveChanges();
|
||||
TempData["Message"] = "Import av veckomenyer klar.";
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class AdminUserViewModel
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public string Email { get; set; }
|
||||
public List<string> Roles { get; set; }
|
||||
}
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public string Email { get; set; }
|
||||
public List<string> Roles { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace Aberwyn.Controllers
|
||||
.GetMenuEntriesByDateRange(DateTime.Now.AddDays(-28), DateTime.Now)
|
||||
.Select(x => new WeeklyMenuViewModel.RecentMenuEntry
|
||||
{
|
||||
Date = x.Date,
|
||||
Date = x.CreatedAt,
|
||||
BreakfastMealName = x.BreakfastMealName,
|
||||
LunchMealName = x.LunchMealName,
|
||||
DinnerMealName = x.DinnerMealName
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using Aberwyn.Models;
|
||||
using Aberwyn.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.ImageSharp;
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
@@ -10,28 +12,45 @@ namespace Aberwyn.Controllers
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly IHostEnvironment _env;
|
||||
private readonly MenuService _menuService;
|
||||
|
||||
public MealController(IConfiguration configuration, IHostEnvironment env)
|
||||
public MealController(MenuService menuService, IConfiguration configuration, IHostEnvironment env)
|
||||
{
|
||||
_menuService = menuService;
|
||||
_configuration = configuration;
|
||||
_env = env;
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult View(int id, bool edit = false)
|
||||
[HttpGet("/meal")]
|
||||
public IActionResult Index()
|
||||
{
|
||||
var service = _menuService;
|
||||
var meal = service.GetMealById(id);
|
||||
return View("Index");
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult View(int? id, bool edit = false)
|
||||
{
|
||||
Meal meal;
|
||||
|
||||
ViewData["IsEditing"] = edit; // → här
|
||||
|
||||
if (meal == null)
|
||||
if (id.HasValue)
|
||||
{
|
||||
return NotFound();
|
||||
meal = _menuService.GetMealById(id.Value);
|
||||
if (meal == null)
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
meal = new Meal
|
||||
{
|
||||
Name = "",
|
||||
Description = "",
|
||||
Ingredients = new List<Ingredient>(),
|
||||
IsAvailable = true,
|
||||
CreatedAt = DateTime.Now
|
||||
};
|
||||
}
|
||||
|
||||
ViewData["IsEditing"] = edit;
|
||||
return View("View", meal);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
[Route("Meal/Tooltip/{id}")]
|
||||
public IActionResult Tooltip(int id)
|
||||
@@ -69,6 +88,15 @@ namespace Aberwyn.Controllers
|
||||
return StatusCode(500, $"<pre>{ex.Message}</pre>");
|
||||
}
|
||||
}
|
||||
[HttpGet("Meal/Thumbnail/{id}")]
|
||||
public IActionResult Thumbnail(int id)
|
||||
{
|
||||
var meal = _menuService.GetMealById(id);
|
||||
if (meal == null || meal.ThumbnailData == null)
|
||||
return NotFound();
|
||||
|
||||
return File(meal.ThumbnailData, "image/webp"); // eller image/jpeg om du använder det
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -92,6 +120,8 @@ namespace Aberwyn.Controllers
|
||||
ImageFile.CopyTo(ms);
|
||||
meal.ImageData = ms.ToArray();
|
||||
meal.ImageMimeType = ImageFile.ContentType;
|
||||
meal.ThumbnailData = GenerateThumbnail(ImageFile);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -110,8 +140,21 @@ namespace Aberwyn.Controllers
|
||||
}
|
||||
|
||||
|
||||
private byte[] GenerateThumbnail(IFormFile file)
|
||||
{
|
||||
using var image = SixLabors.ImageSharp.Image.Load(file.OpenReadStream());
|
||||
image.Mutate(x => x.Resize(new ResizeOptions
|
||||
{
|
||||
Mode = ResizeMode.Max,
|
||||
Size = new Size(300, 300) // eller vad du vill för korten
|
||||
}));
|
||||
|
||||
using var ms = new MemoryStream();
|
||||
image.SaveAsWebp(ms); // kräver ImageSharp.Webp-paketet
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpPost]
|
||||
|
||||
@@ -4,6 +4,8 @@ using Aberwyn.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
@@ -28,12 +30,23 @@ namespace Aberwyn.Controllers
|
||||
[HttpGet("getMeals")]
|
||||
public IActionResult GetMeals()
|
||||
{
|
||||
var meals = _menuService.GetMealsDetailed(); // Hämtar med ImageData
|
||||
var mealDtos = meals.Select(MealDto.FromMeal).ToList();
|
||||
var meals = _menuService.GetMealsSlim(true);
|
||||
var mealDtos = meals.Select(m => MealDto.FromMeal(m, includeThumbnail: true)).ToList(); // 👈 fix
|
||||
return Ok(mealDtos);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("getWeeklyMenu")]
|
||||
public IActionResult GetWeeklyMenu(int weekNumber, int year)
|
||||
{
|
||||
var menuDtos = _menuService.GetWeeklyMenuDto(weekNumber, year);
|
||||
Console.WriteLine("Hämtar meals: " + menuDtos);
|
||||
return Ok(menuDtos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpPut("menu")]
|
||||
public IActionResult SaveMenu([FromBody] MenuViewModel weeklyMenu)
|
||||
{
|
||||
@@ -55,5 +68,44 @@ namespace Aberwyn.Controllers
|
||||
|
||||
return StatusCode(500, "Failed to add meal.");
|
||||
}
|
||||
|
||||
#region Skolmat
|
||||
[HttpGet("skolmat")]
|
||||
public async Task<IActionResult> GetSkolmat(int week, [FromQuery] string sensor = "sensor.engelbrektsskolan")
|
||||
{
|
||||
var token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3M2Q5ODIyYzU4ZWI0MjM4OWEyMGQ2MWQ2MWVhOWYzYyIsImlhdCI6MTc0OTE1MzY1MCwiZXhwIjoyMDY0NTEzNjUwfQ.8C_dKm7P1BbFVJKc_wT76YnQqiZxkP9EzrsLbfD0Ml8";
|
||||
var client = new HttpClient();
|
||||
client.BaseAddress = new Uri("http://192.168.1.196:8123/");
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
var res = await client.GetAsync($"/api/states/{sensor}");
|
||||
|
||||
if (!res.IsSuccessStatusCode)
|
||||
return StatusCode((int)res.StatusCode, $"Kunde inte hämta data för {sensor}");
|
||||
|
||||
var json = await res.Content.ReadAsStringAsync();
|
||||
var doc = JsonDocument.Parse(json);
|
||||
|
||||
var attr = doc.RootElement.GetProperty("attributes");
|
||||
|
||||
if (!attr.TryGetProperty("calendar", out var calendar))
|
||||
return NotFound("Ingen kalender hittades i attributen");
|
||||
|
||||
if (!calendar.TryGetProperty(week.ToString(), out var weekData))
|
||||
return NotFound("Ingen skolmat för vecka " + week);
|
||||
|
||||
var result = new List<object>();
|
||||
foreach (var day in weekData.EnumerateArray())
|
||||
{
|
||||
var weekday = day.GetProperty("weekday").GetString();
|
||||
var date = day.GetProperty("date").GetString();
|
||||
var courses = day.GetProperty("courses").EnumerateArray().Select(c => c.GetString()).ToList();
|
||||
|
||||
result.Add(new { weekday, date, courses });
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Aberwyn.Data;
|
||||
using Aberwyn.Models;
|
||||
using System.Linq;
|
||||
using Aberwyn.Services;
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
@@ -9,11 +10,14 @@ namespace Aberwyn.Controllers
|
||||
{
|
||||
private readonly MenuService _menuService;
|
||||
private readonly ApplicationDbContext _context;
|
||||
private readonly PizzaNotificationService _pizzaNotifier;
|
||||
|
||||
public PizzaController(MenuService menuService, ApplicationDbContext context)
|
||||
public PizzaController(PizzaNotificationService pizzaNotifier,MenuService menuService, ApplicationDbContext context)
|
||||
{
|
||||
_menuService = menuService;
|
||||
_context = context;
|
||||
_pizzaNotifier = pizzaNotifier;
|
||||
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -50,6 +54,7 @@ namespace Aberwyn.Controllers
|
||||
|
||||
_context.PizzaOrders.Add(order);
|
||||
_context.SaveChanges();
|
||||
_pizzaNotifier.NotifyPizzaSubscribersAsync(pizzaName, customerName);
|
||||
|
||||
TempData["Success"] = "Beställningen har lagts!";
|
||||
return RedirectToAction("Order");
|
||||
|
||||
@@ -3,6 +3,9 @@ using Aberwyn.Models;
|
||||
using Lib.Net.Http.WebPush;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Aberwyn.Services;
|
||||
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
@@ -12,19 +15,37 @@ namespace Aberwyn.Controllers
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
private readonly PushNotificationService _notificationService;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly PizzaNotificationService _pizzaNotifier;
|
||||
|
||||
public PushController(ApplicationDbContext context, PushNotificationService notificationService)
|
||||
|
||||
public PushController(ApplicationDbContext context,
|
||||
PushNotificationService notificationService,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
PizzaNotificationService pizzaNotifier)
|
||||
{
|
||||
_context = context;
|
||||
_notificationService = notificationService;
|
||||
_userManager = userManager;
|
||||
_pizzaNotifier = pizzaNotifier;
|
||||
}
|
||||
|
||||
[HttpPost("notify-pizza")]
|
||||
public async Task<IActionResult> NotifyPizza()
|
||||
{
|
||||
var count = await _pizzaNotifier.NotifyPizzaSubscribersAsync("Capricciosa", User.Identity.Name);
|
||||
|
||||
return Ok(new { message = $"Skickade pizzanotiser till {count} användare." });
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("subscribe")]
|
||||
public async Task<IActionResult> Subscribe([FromBody] PushSubscription subscription)
|
||||
{
|
||||
var existing = await _context.PushSubscribers
|
||||
.FirstOrDefaultAsync(s => s.Endpoint == subscription.Endpoint);
|
||||
var user = await _userManager.GetUserAsync(User);
|
||||
if (user == null) return Unauthorized();
|
||||
|
||||
if (existing == null)
|
||||
{
|
||||
@@ -32,7 +53,8 @@ namespace Aberwyn.Controllers
|
||||
{
|
||||
Endpoint = subscription.Endpoint,
|
||||
P256DH = subscription.Keys["p256dh"],
|
||||
Auth = subscription.Keys["auth"]
|
||||
Auth = subscription.Keys["auth"],
|
||||
UserId = user.Id
|
||||
};
|
||||
|
||||
_context.PushSubscribers.Add(newSubscriber);
|
||||
@@ -62,7 +84,12 @@ namespace Aberwyn.Controllers
|
||||
return BadRequest("Titel och meddelande krävs.");
|
||||
}
|
||||
|
||||
var subscribers = await _context.PushSubscribers.ToListAsync();
|
||||
var subscribers = await _context.PushSubscribers
|
||||
.Include(s => s.User)
|
||||
.ThenInclude(u => u.Preferences)
|
||||
.Where(s => s.User != null && s.User.Preferences.NotifyPizza)
|
||||
.ToListAsync();
|
||||
|
||||
var payload = $"{{\"title\":\"{message.Title}\",\"body\":\"{message.Body}\"}}";
|
||||
|
||||
int successCount = 0;
|
||||
|
||||
78
Aberwyn/Controllers/SetupApiController.cs
Normal file
78
Aberwyn/Controllers/SetupApiController.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/setup")]
|
||||
public class SetupApiController : ControllerBase
|
||||
{
|
||||
[HttpPost("testdb")]
|
||||
public IActionResult TestDbConnection([FromBody] DbTestRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var builder = new MySqlConnectionStringBuilder
|
||||
{
|
||||
Server = request.Host,
|
||||
Port = uint.Parse(request.Port),
|
||||
UserID = request.User,
|
||||
Password = request.Pass,
|
||||
Database = "information_schema"
|
||||
};
|
||||
|
||||
using (var conn = new MySqlConnection(builder.ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// Kontrollera om databasen redan finns
|
||||
var checkCmd = new MySqlCommand("SELECT SCHEMA_NAME FROM SCHEMATA WHERE SCHEMA_NAME = @dbName", conn);
|
||||
checkCmd.Parameters.AddWithValue("@dbName", request.Db);
|
||||
var exists = checkCmd.ExecuteScalar();
|
||||
|
||||
if (exists != null)
|
||||
{
|
||||
return Ok(new
|
||||
{
|
||||
success = true,
|
||||
message = "Anslutning OK och databasen finns redan."
|
||||
});
|
||||
}
|
||||
|
||||
// Testa skapa en temporär databas
|
||||
var testDbName = $"testcheck_{Guid.NewGuid():N}".Substring(0, 12);
|
||||
var createCmd = new MySqlCommand($"CREATE DATABASE `{testDbName}`", conn);
|
||||
createCmd.ExecuteNonQuery();
|
||||
|
||||
var dropCmd = new MySqlCommand($"DROP DATABASE `{testDbName}`", conn);
|
||||
dropCmd.ExecuteNonQuery();
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
success = true,
|
||||
message = "Anslutning OK. Databasen finns inte, men CREATE DATABASE är tillåten."
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new
|
||||
{
|
||||
success = false,
|
||||
message = ex.Message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class DbTestRequest
|
||||
{
|
||||
public string Host { get; set; }
|
||||
public string Port { get; set; }
|
||||
public string Db { get; set; }
|
||||
public string User { get; set; }
|
||||
public string Pass { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
170
Aberwyn/Controllers/SetupController.cs
Normal file
170
Aberwyn/Controllers/SetupController.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Text.Json;
|
||||
using Aberwyn.Data;
|
||||
using Aberwyn.Models;
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
[Route("setup")]
|
||||
public class SetupController : Controller
|
||||
{
|
||||
private readonly IWebHostEnvironment _env;
|
||||
private readonly ILogger<SetupController> _logger;
|
||||
|
||||
public SetupController(IWebHostEnvironment env, ILogger<SetupController> logger)
|
||||
{
|
||||
_env = env;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
ViewBag.IsSetupMode = true;
|
||||
base.OnActionExecuting(context);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Index() => View(new SetupSettings());
|
||||
|
||||
[Authorize(Roles = "Admin")]
|
||||
[HttpPost("reset")]
|
||||
public IActionResult Reset()
|
||||
{
|
||||
var path = Path.Combine(_env.ContentRootPath, "infrastructure", "setup.json");
|
||||
|
||||
var resetSettings = new SetupSettings
|
||||
{
|
||||
IsConfigured = false,
|
||||
DbHost = "",
|
||||
DbPort = 3306,
|
||||
DbName = "",
|
||||
DbUser = "",
|
||||
DbPassword = "",
|
||||
AdminUsername = "admin",
|
||||
AdminEmail = "admin@localhost",
|
||||
AdminPassword = "Admin123!"
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(resetSettings, new JsonSerializerOptions { WriteIndented = true });
|
||||
System.IO.File.WriteAllText(path, json);
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
[HttpPost("")]
|
||||
public async Task<IActionResult> Setup([FromBody] SetupSettings model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
var allErrors = ModelState
|
||||
.Where(e => e.Value.Errors.Count > 0)
|
||||
.Select(e => new { Field = e.Key, Errors = e.Value.Errors.Select(x => x.ErrorMessage) });
|
||||
|
||||
return BadRequest(new { error = "Modellen är ogiltig", details = allErrors });
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Bygg connection string säkert
|
||||
var baseConnBuilder = new MySqlConnectionStringBuilder
|
||||
{
|
||||
Server = model.DbHost,
|
||||
Port = (uint)model.DbPort,
|
||||
UserID = model.DbUser,
|
||||
Password = model.DbPassword,
|
||||
Database = "information_schema"
|
||||
};
|
||||
|
||||
// Kontrollera om databasen redan finns
|
||||
using (var conn = new MySqlConnection(baseConnBuilder.ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
var cmd = new MySqlCommand("SELECT SCHEMA_NAME FROM SCHEMATA WHERE SCHEMA_NAME = @dbName", conn);
|
||||
cmd.Parameters.AddWithValue("@dbName", model.DbName);
|
||||
var exists = cmd.ExecuteScalar();
|
||||
|
||||
if (exists == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var createCmd = new MySqlCommand($"CREATE DATABASE `{model.DbName}`", conn);
|
||||
createCmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Kunde inte skapa databasen.");
|
||||
return BadRequest(new { error = "Databasen finns inte och kunde inte skapas.", details = ex.Message });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bygg EF-connection
|
||||
var efConnBuilder = new MySqlConnectionStringBuilder
|
||||
{
|
||||
Server = model.DbHost,
|
||||
Port = (uint)model.DbPort,
|
||||
UserID = model.DbUser,
|
||||
Password = model.DbPassword,
|
||||
Database = model.DbName
|
||||
};
|
||||
|
||||
var tempProvider = SetupService.BuildTemporaryServices(efConnBuilder.ConnectionString);
|
||||
using var scope = tempProvider.CreateScope();
|
||||
|
||||
// Skapa databastabeller
|
||||
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
|
||||
// Sätt konfig-flagga tidigt
|
||||
model.IsConfigured = true;
|
||||
|
||||
// Spara setup.json
|
||||
var filePath = Path.Combine(_env.ContentRootPath, "infrastructure", "setup.json");
|
||||
var json = JsonSerializer.Serialize(model, new JsonSerializerOptions { WriteIndented = true });
|
||||
System.IO.File.WriteAllText(filePath, json);
|
||||
|
||||
// Roller och admin
|
||||
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
|
||||
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
|
||||
|
||||
string[] roles = { "Admin", "Chef", "Budget" };
|
||||
foreach (var role in roles)
|
||||
{
|
||||
if (!await roleManager.RoleExistsAsync(role))
|
||||
await roleManager.CreateAsync(new IdentityRole(role));
|
||||
}
|
||||
|
||||
var existingUser = await userManager.FindByNameAsync(model.AdminUsername);
|
||||
if (existingUser == null)
|
||||
{
|
||||
var adminUser = new ApplicationUser
|
||||
{
|
||||
UserName = model.AdminUsername,
|
||||
Email = model.AdminEmail,
|
||||
EmailConfirmed = true
|
||||
};
|
||||
|
||||
var result = await userManager.CreateAsync(adminUser, model.AdminPassword);
|
||||
if (!result.Succeeded)
|
||||
return BadRequest(new { error = "Kunde inte skapa administratör", details = result.Errors });
|
||||
|
||||
await userManager.AddToRoleAsync(adminUser, "Admin");
|
||||
}
|
||||
|
||||
return Ok(new { message = "Installation slutförd!" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Fel vid installation.");
|
||||
return BadRequest(new { error = "Fel vid installation", details = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
public IActionResult SetupComplete() => View();
|
||||
}
|
||||
}
|
||||
61
Aberwyn/Controllers/UserController.cs
Normal file
61
Aberwyn/Controllers/UserController.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Aberwyn.Models;
|
||||
using System.Threading.Tasks;
|
||||
using Aberwyn.Data;
|
||||
|
||||
namespace Aberwyn.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class UserController : Controller
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public UserController(UserManager<ApplicationUser> userManager, ApplicationDbContext context)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Profile()
|
||||
{
|
||||
var user = await _userManager.GetUserAsync(User);
|
||||
var prefs = await _context.UserPreferences.FindAsync(user.Id) ?? new UserPreferences();
|
||||
|
||||
var model = new UserProfileViewModel
|
||||
{
|
||||
Name = user.UserName,
|
||||
Email = user.Email,
|
||||
NotifyPizza = prefs.NotifyPizza,
|
||||
NotifyMenu = prefs.NotifyMenu,
|
||||
NotifyBudget = prefs.NotifyBudget
|
||||
};
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> SaveProfile(UserProfileViewModel model)
|
||||
{
|
||||
var user = await _userManager.GetUserAsync(User);
|
||||
var prefs = await _context.UserPreferences.FindAsync(user.Id);
|
||||
|
||||
if (prefs == null)
|
||||
{
|
||||
prefs = new UserPreferences { UserId = user.Id };
|
||||
_context.UserPreferences.Add(prefs);
|
||||
}
|
||||
|
||||
prefs.NotifyPizza = model.NotifyPizza;
|
||||
prefs.NotifyMenu = model.NotifyMenu;
|
||||
prefs.NotifyBudget = model.NotifyBudget;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return RedirectToAction("Profile");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,14 @@ namespace Aberwyn.Data
|
||||
public DbSet<PushSubscriber> PushSubscribers { get; set; }
|
||||
public DbSet<PizzaOrder> PizzaOrders { get; set; }
|
||||
public DbSet<AppSetting> AppSettings { get; set; }
|
||||
public DbSet<TodoTask> TodoTasks { get; set; }
|
||||
public DbSet<BudgetItemDefinition> BudgetItemDefinitions { get; set; }
|
||||
public DbSet<BudgetCategoryDefinition> BudgetCategoryDefinitions { get; set; }
|
||||
public DbSet<Meal> Meals { get; set; }
|
||||
public DbSet<Ingredient> Ingredients { get; set; }
|
||||
public DbSet<WeeklyMenu> WeeklyMenus { get; set; }
|
||||
|
||||
|
||||
public DbSet<Ingredient> Ingredients { get; set; }
|
||||
public DbSet<UserPreferences> UserPreferences { get; set; }
|
||||
public DbSet<StoredPushSubscription> PushSubscriptions { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Aberwyn.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using static Aberwyn.Data.SetupService;
|
||||
|
||||
namespace Aberwyn.Data
|
||||
{
|
||||
@@ -10,29 +13,51 @@ namespace Aberwyn.Data
|
||||
{
|
||||
public ApplicationDbContext CreateDbContext(string[] args)
|
||||
{
|
||||
var basePath = Directory.GetCurrentDirectory();
|
||||
var config = new ConfigurationBuilder()
|
||||
.SetBasePath(basePath)
|
||||
.AddJsonFile("appsettings.json")
|
||||
.Build();
|
||||
var setup = LoadSetup();
|
||||
|
||||
|
||||
var connectionString = config.GetConnectionString("DefaultConnection");
|
||||
File.WriteAllText("connection-log.txt", $"Connection string: {connectionString}");
|
||||
|
||||
Console.WriteLine($"Anslutningssträng: {connectionString}");
|
||||
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
var csBuilder = new MySqlConnector.MySqlConnectionStringBuilder
|
||||
{
|
||||
throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
|
||||
}
|
||||
Server = setup.DbHost,
|
||||
Port = (uint)setup.DbPort,
|
||||
Database = setup.DbName,
|
||||
UserID = setup.DbUser,
|
||||
Password = setup.DbPassword,
|
||||
AllowUserVariables = true
|
||||
};
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
optionsBuilder.UseMySql(
|
||||
connectionString,
|
||||
new MySqlServerVersion(new Version(8, 0, 36)));
|
||||
optionsBuilder.UseMySql(csBuilder.ConnectionString, new MySqlServerVersion(new Version(8, 0, 36)));
|
||||
|
||||
return new ApplicationDbContext(optionsBuilder.Options);
|
||||
}
|
||||
|
||||
public static ApplicationDbContext CreateWithConfig(IHostEnvironment env, bool useProdDb = false)
|
||||
{
|
||||
var setup = SetupLoader.Load(env);
|
||||
var connStr = SetupLoader.GetConnectionString(setup);
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
optionsBuilder.UseMySql(connStr, new MySqlServerVersion(new Version(8, 0, 36)));
|
||||
|
||||
return new ApplicationDbContext(optionsBuilder.Options);
|
||||
}
|
||||
|
||||
|
||||
private static SetupSettings LoadSetup()
|
||||
{
|
||||
var basePath = Directory.GetCurrentDirectory();
|
||||
var setupPath = Path.Combine(basePath, "infrastructure", "setup.json");
|
||||
|
||||
if (!File.Exists(setupPath))
|
||||
throw new FileNotFoundException("setup.json saknas i infrastructure-mappen.");
|
||||
|
||||
var json = File.ReadAllText(setupPath);
|
||||
var setup = JsonSerializer.Deserialize<SetupSettings>(json);
|
||||
|
||||
if (setup == null || !setup.IsConfigured)
|
||||
throw new InvalidOperationException("setup.json är inte korrekt konfigurerad.");
|
||||
|
||||
return setup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Collections.Generic;
|
||||
using Aberwyn.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting; // Add this namespace
|
||||
|
||||
namespace Aberwyn.Data
|
||||
{
|
||||
public class BudgetService
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly IHostEnvironment _env; // Add this field
|
||||
|
||||
public BudgetService(IConfiguration configuration, IHostEnvironment env) // Update constructor
|
||||
{
|
||||
_configuration = configuration;
|
||||
_env = env; // Initialize the environment field
|
||||
}
|
||||
|
||||
public MySqlConnection GetConnection()
|
||||
{
|
||||
var connectionString = _env.IsDevelopment() // Use the injected environment variable
|
||||
? _configuration.GetConnectionString("DefaultConnection")
|
||||
: _configuration.GetConnectionString("ProductionConnection");
|
||||
|
||||
return new MySqlConnection(connectionString);
|
||||
}
|
||||
|
||||
public bool UpdateBudgetItem(BudgetItem item)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
string query = @"
|
||||
UPDATE tblBudgetItems
|
||||
SET Name = @name, Amount = @amount
|
||||
WHERE idtblBudgetItems = @id";
|
||||
|
||||
using (var cmd = new MySqlCommand(query, connection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@name", item.Name);
|
||||
cmd.Parameters.AddWithValue("@amount", item.Amount);
|
||||
cmd.Parameters.AddWithValue("@id", item.ID);
|
||||
return cmd.ExecuteNonQuery() > 0; // Returns true if one or more rows are updated
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<BudgetItem> GetBudgetItems(int month, int year)
|
||||
{
|
||||
var budgetItems = new List<BudgetItem>();
|
||||
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
string query = @"
|
||||
SELECT
|
||||
b.idtblBudgetItems AS id,
|
||||
b.Name AS item_name,
|
||||
b.Amount AS amount,
|
||||
c1.Name AS category,
|
||||
b.Month,
|
||||
b.Year,
|
||||
b.Description AS description
|
||||
FROM tblBudgetItems b
|
||||
LEFT JOIN tblCategories c1 ON b.Category = c1.idtblCategories
|
||||
WHERE b.Month = @month AND b.Year = @year";
|
||||
|
||||
using (var cmd = new MySqlCommand(query, connection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@month", month);
|
||||
cmd.Parameters.AddWithValue("@year", year);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
budgetItems.Add(new BudgetItem
|
||||
{
|
||||
ID = reader.GetInt32("id"),
|
||||
Name = reader.GetString("item_name"), // Updated alias
|
||||
Amount = reader.GetDecimal("amount"),
|
||||
Category = reader.GetString("category"),
|
||||
Month = reader.GetInt32("Month"),
|
||||
Year = reader.GetInt32("Year"),
|
||||
Description = reader.IsDBNull(reader.GetOrdinal("description"))
|
||||
? null
|
||||
: reader.GetString("description")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return budgetItems;
|
||||
}
|
||||
|
||||
public bool AddBudgetItem(BudgetItem item)
|
||||
{
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
string query = @"
|
||||
INSERT INTO tblBudgetItems (Name, Amount, Category, Month, Year)
|
||||
VALUES (@name, @amount, @category, @month, @year)";
|
||||
|
||||
using (var cmd = new MySqlCommand(query, connection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@name", item.Name);
|
||||
cmd.Parameters.AddWithValue("@amount", item.Amount);
|
||||
cmd.Parameters.AddWithValue("@category", item.Category);
|
||||
cmd.Parameters.AddWithValue("@month", item.Month);
|
||||
cmd.Parameters.AddWithValue("@year", item.Year);
|
||||
return cmd.ExecuteNonQuery() > 0; // Returns true if a row was inserted
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// New method to fetch all categories
|
||||
public List<string> GetCategories()
|
||||
{
|
||||
var categories = new List<string>();
|
||||
|
||||
using (var connection = GetConnection())
|
||||
{
|
||||
connection.Open();
|
||||
|
||||
string query = "SELECT Name FROM tblCategories"; // Adjust based on your table structure
|
||||
|
||||
using (var cmd = new MySqlCommand(query, connection))
|
||||
{
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
categories.Add(reader.GetString("Name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return categories;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Aberwyn.Models;
|
||||
|
||||
@@ -6,12 +7,18 @@ namespace Aberwyn.Data
|
||||
{
|
||||
public static class IdentityDataInitializer
|
||||
{
|
||||
public static async Task SeedData(IServiceProvider serviceProvider)
|
||||
public static async Task<IdentityResult> SeedData(IServiceProvider serviceProvider, SetupSettings? setup = null)
|
||||
{
|
||||
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
|
||||
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
|
||||
var config = serviceProvider.GetService<IConfiguration>();
|
||||
|
||||
string[] roles = { "Admin" };
|
||||
if (setup == null && config != null)
|
||||
{
|
||||
setup = config.GetSection("SetupSettings").Get<SetupSettings>() ?? new SetupSettings();
|
||||
}
|
||||
|
||||
string[] roles = { "Admin", "Chef", "Budget" };
|
||||
|
||||
foreach (var role in roles)
|
||||
{
|
||||
@@ -19,25 +26,38 @@ namespace Aberwyn.Data
|
||||
await roleManager.CreateAsync(new IdentityRole(role));
|
||||
}
|
||||
|
||||
string adminEmail = "tai@zcz.se";
|
||||
string password = "Admin123!";
|
||||
|
||||
if (await userManager.FindByEmailAsync(adminEmail) == null)
|
||||
var existingUser = await userManager.FindByEmailAsync(setup.AdminEmail);
|
||||
if (existingUser == null)
|
||||
{
|
||||
var user = new ApplicationUser
|
||||
{
|
||||
UserName = adminEmail,
|
||||
Email = adminEmail,
|
||||
UserName = setup.AdminUsername,
|
||||
Email = setup.AdminEmail,
|
||||
EmailConfirmed = true
|
||||
};
|
||||
|
||||
var result = await userManager.CreateAsync(user, password);
|
||||
var result = await userManager.CreateAsync(user, setup.AdminPassword);
|
||||
|
||||
if (result.Succeeded)
|
||||
await userManager.AddToRoleAsync(user, "Admin");
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
var token = await userManager.GeneratePasswordResetTokenAsync(existingUser);
|
||||
var result = await userManager.ResetPasswordAsync(existingUser, token, setup.AdminPassword);
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
await userManager.AddToRoleAsync(user, "Admin");
|
||||
var rolesForUser = await userManager.GetRolesAsync(existingUser);
|
||||
if (!rolesForUser.Contains("Admin"))
|
||||
await userManager.AddToRoleAsync(existingUser, "Admin");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// Nya versionen av MenuService med Entity Framework
|
||||
using Aberwyn.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Webp;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System.Globalization;
|
||||
|
||||
using static Aberwyn.Data.SetupService;
|
||||
|
||||
namespace Aberwyn.Data
|
||||
{
|
||||
@@ -16,20 +19,47 @@ public class MenuService
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// 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 builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
public static MenuService CreateWithSetup(IHostEnvironment env)
|
||||
{
|
||||
var setup = SetupLoader.Load(env);
|
||||
var connStr = SetupLoader.GetConnectionString(setup);
|
||||
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
builder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
|
||||
var context = new ApplicationDbContext(builder.Options);
|
||||
return new MenuService(context);
|
||||
}
|
||||
|
||||
public List<WeeklyMenuDto> GetWeeklyMenuDto(int weekNumber, int year)
|
||||
{
|
||||
var query = from wm in _context.WeeklyMenus
|
||||
where wm.WeekNumber == weekNumber && wm.Year == year
|
||||
join mDinner in _context.Meals on wm.DinnerMealId equals mDinner.Id into dinnerJoin
|
||||
from mDinner in dinnerJoin.DefaultIfEmpty()
|
||||
join mLunch in _context.Meals on wm.LunchMealId equals mLunch.Id into lunchJoin
|
||||
from mLunch in lunchJoin.DefaultIfEmpty()
|
||||
join mBreakfast in _context.Meals on wm.BreakfastMealId equals mBreakfast.Id into breakfastJoin
|
||||
from mBreakfast in breakfastJoin.DefaultIfEmpty()
|
||||
select new WeeklyMenuDto
|
||||
{
|
||||
Id = wm.Id,
|
||||
DayOfWeek = wm.DayOfWeek,
|
||||
WeekNumber = wm.WeekNumber,
|
||||
Year = wm.Year,
|
||||
BreakfastMealId = wm.BreakfastMealId,
|
||||
LunchMealId = wm.LunchMealId,
|
||||
DinnerMealId = wm.DinnerMealId,
|
||||
BreakfastMealName = mBreakfast.Name,
|
||||
LunchMealName = mLunch.Name,
|
||||
DinnerMealName = mDinner.Name,
|
||||
DinnerMealThumbnail = mDinner.ThumbnailData
|
||||
};
|
||||
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
|
||||
var connStr = useProdDb
|
||||
? config.GetConnectionString("ProdConnection")
|
||||
: config.GetConnectionString("DefaultConnection");
|
||||
|
||||
builder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
|
||||
var context = new ApplicationDbContext(builder.Options);
|
||||
|
||||
return new MenuService(context);
|
||||
}
|
||||
public void UpdateWeeklyMenu(MenuViewModel model)
|
||||
{
|
||||
var existing = _context.WeeklyMenus
|
||||
@@ -47,7 +77,30 @@ public class MenuService
|
||||
}
|
||||
|
||||
|
||||
public void SaveMeal2(Meal meal)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(meal?.Name)) return;
|
||||
|
||||
meal.Name = meal.Name.Trim();
|
||||
meal.CreatedAt = meal.CreatedAt == default ? DateTime.Now : meal.CreatedAt;
|
||||
|
||||
var existing = _context.Meals
|
||||
.AsNoTracking()
|
||||
.FirstOrDefault(m => m.Id == meal.Id);
|
||||
|
||||
if (existing == null)
|
||||
{
|
||||
// Nytt objekt – försök behålla ID:t från prod
|
||||
_context.Entry(meal).State = EntityState.Added;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Befintlig – uppdatera
|
||||
_context.Meals.Update(meal);
|
||||
}
|
||||
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void SaveMeal(Meal meal)
|
||||
{
|
||||
@@ -57,15 +110,90 @@ public class MenuService
|
||||
meal.CreatedAt = meal.CreatedAt == default ? DateTime.Now : meal.CreatedAt;
|
||||
|
||||
if (meal.Id == 0)
|
||||
{
|
||||
// Ny måltid
|
||||
_context.Meals.Add(meal);
|
||||
}
|
||||
else
|
||||
_context.Meals.Update(meal);
|
||||
{
|
||||
// Uppdatera existerande utan tracking-krockar
|
||||
var existing = _context.Meals
|
||||
.Include(m => m.Ingredients)
|
||||
.FirstOrDefault(m => m.Id == meal.Id);
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
_context.Entry(existing).CurrentValues.SetValues(meal);
|
||||
|
||||
// OBS: Ingredienser hanteras separat
|
||||
}
|
||||
}
|
||||
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
|
||||
public int GenerateMissingThumbnails()
|
||||
{
|
||||
var updatedCount = 0;
|
||||
var meals = _context.Meals
|
||||
.Where(m => m.ImageData != null && m.ThumbnailData == null)
|
||||
.ToList();
|
||||
|
||||
foreach (var meal in meals)
|
||||
{
|
||||
using var ms = new MemoryStream(meal.ImageData);
|
||||
using var image = Image.Load(ms);
|
||||
|
||||
image.Mutate(x => x.Resize(new ResizeOptions
|
||||
{
|
||||
Mode = ResizeMode.Max,
|
||||
Size = new Size(300, 300)
|
||||
}));
|
||||
|
||||
using var outStream = new MemoryStream();
|
||||
var encoder = new WebpEncoder
|
||||
{
|
||||
Quality = 75
|
||||
};
|
||||
image.Save(outStream, encoder);
|
||||
|
||||
meal.ThumbnailData = outStream.ToArray();
|
||||
updatedCount++;
|
||||
}
|
||||
|
||||
_context.SaveChanges();
|
||||
return updatedCount;
|
||||
}
|
||||
public List<Meal> GetMealsSlim(bool includeThumbnail = false)
|
||||
{
|
||||
if (includeThumbnail)
|
||||
{
|
||||
return _context.Meals
|
||||
.Select(m => new Meal
|
||||
{
|
||||
Id = m.Id,
|
||||
Name = m.Name,
|
||||
Description = m.Description,
|
||||
ThumbnailData = m.ThumbnailData
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return _context.Meals
|
||||
.Select(m => new Meal
|
||||
{
|
||||
Id = m.Id,
|
||||
Name = m.Name,
|
||||
Description = m.Description
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
{
|
||||
var menus = _context.WeeklyMenus.ToList();
|
||||
|
||||
var allMeals = _context.Meals.ToDictionary(m => m.Id, m => m.Name);
|
||||
@@ -100,10 +228,17 @@ public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
{
|
||||
var existing = _context.Ingredients.Where(i => i.MealId == mealId);
|
||||
_context.Ingredients.RemoveRange(existing);
|
||||
|
||||
foreach (var ing in ingredients)
|
||||
{
|
||||
ing.MealId = mealId;
|
||||
}
|
||||
|
||||
_context.Ingredients.AddRange(ingredients);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
|
||||
public List<Meal> GetMeals()
|
||||
{
|
||||
return _context.Meals.ToList();
|
||||
@@ -112,10 +247,12 @@ public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
public List<Meal> GetMealsDetailed()
|
||||
{
|
||||
return _context.Meals
|
||||
.Include(m => m.Ingredients) // 🧠 detta behövs!
|
||||
.OrderByDescending(m => m.CreatedAt)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
public Meal GetMealById(int id)
|
||||
{
|
||||
var meal = _context.Meals
|
||||
@@ -141,6 +278,8 @@ public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
|
||||
public void SaveOrUpdateMealWithIngredients(Meal meal)
|
||||
{
|
||||
var isNew = meal.Id == 0;
|
||||
|
||||
SaveMeal(meal);
|
||||
|
||||
if (meal.Ingredients != null && meal.Ingredients.Count > 0)
|
||||
@@ -149,6 +288,7 @@ public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<Meal> GetMealsByCategory(string category)
|
||||
{
|
||||
return _context.Meals
|
||||
@@ -157,6 +297,48 @@ public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
.OrderBy(m => m.Name)
|
||||
.ToList();
|
||||
}
|
||||
public List<WeeklyMenu> GetWeeklyMenu(int weekNumber, int year)
|
||||
{
|
||||
var menus = _context.WeeklyMenus
|
||||
.Where(m => m.WeekNumber == weekNumber && m.Year == year)
|
||||
.ToList();
|
||||
|
||||
var mealIds = menus
|
||||
.SelectMany(w => new int?[] { w.BreakfastMealId, w.LunchMealId, w.DinnerMealId })
|
||||
.Where(id => id.HasValue)
|
||||
.Select(id => id.Value)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
var allMeals = _context.Meals
|
||||
.Where(m => mealIds.Contains(m.Id))
|
||||
.Select(m => new {
|
||||
m.Id,
|
||||
m.Name,
|
||||
m.ThumbnailData // Vi tar med detta även om det bara används för middag
|
||||
})
|
||||
.ToList()
|
||||
.ToDictionary(m => m.Id, m => m);
|
||||
|
||||
|
||||
foreach (var wm in menus)
|
||||
{
|
||||
if (wm.BreakfastMealId.HasValue && allMeals.TryGetValue(wm.BreakfastMealId.Value, out var breakfast))
|
||||
wm.BreakfastMealName = breakfast.Name;
|
||||
|
||||
if (wm.LunchMealId.HasValue && allMeals.TryGetValue(wm.LunchMealId.Value, out var lunch))
|
||||
wm.LunchMealName = lunch.Name;
|
||||
|
||||
if (wm.DinnerMealId.HasValue && allMeals.TryGetValue(wm.DinnerMealId.Value, out var dinner))
|
||||
{
|
||||
wm.DinnerMealName = dinner.Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return menus;
|
||||
}
|
||||
|
||||
public List<WeeklyMenu> GetMenuEntriesByDateRange(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
@@ -180,7 +362,7 @@ public List<WeeklyMenu> GetAllWeeklyMenus()
|
||||
var date = ISOWeek.ToDateTime(menu.Year, menu.WeekNumber, dow);
|
||||
if (date.Date >= startDate.Date && date.Date <= endDate.Date)
|
||||
{
|
||||
menu.Date = date;
|
||||
menu.CreatedAt = date;
|
||||
results.Add(menu);
|
||||
}
|
||||
}
|
||||
|
||||
69
Aberwyn/Data/PizzaNotificationService.cs
Normal file
69
Aberwyn/Data/PizzaNotificationService.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using Aberwyn.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using WebPush;
|
||||
|
||||
namespace Aberwyn.Services
|
||||
{
|
||||
public class PizzaNotificationService
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
private readonly PushNotificationService _push;
|
||||
|
||||
public PizzaNotificationService(ApplicationDbContext context, PushNotificationService push)
|
||||
{
|
||||
Console.WriteLine("🍕 PizzaNotificationService constructor körs!");
|
||||
|
||||
_context = context;
|
||||
_push = push;
|
||||
}
|
||||
|
||||
public async Task<int> NotifyPizzaSubscribersAsync(string pizzaName = null, string userName = null)
|
||||
{
|
||||
var title = "Ny pizzabeställning 🍕";
|
||||
var body = "En pizza har precis beställts!";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(pizzaName))
|
||||
body = $"Pizzan '{pizzaName}' har precis beställts!";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(userName))
|
||||
body += $" (av {userName})";
|
||||
|
||||
var payload = $@"{{""title"":""{title}"",""body"":""{body}""}}";
|
||||
|
||||
var subscribers = await _context.PushSubscribers
|
||||
.Include(s => s.User)
|
||||
.ThenInclude(u => u.Preferences)
|
||||
.Where(s => s.User != null &&
|
||||
s.User.Preferences != null &&
|
||||
s.User.Preferences.NotifyPizza &&
|
||||
!string.IsNullOrEmpty(s.Endpoint) &&
|
||||
s.Endpoint.StartsWith("https://"))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
int successCount = 0;
|
||||
foreach (var sub in subscribers)
|
||||
{
|
||||
try
|
||||
{
|
||||
_push.SendNotification(sub.Endpoint, sub.P256DH, sub.Auth, payload);
|
||||
successCount++;
|
||||
}
|
||||
catch (WebPushException ex) when (ex.StatusCode == System.Net.HttpStatusCode.Gone || ex.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
{
|
||||
Console.WriteLine($"🗑️ Ogiltig prenumeration tas bort: {sub.Endpoint}");
|
||||
_context.PushSubscribers.Remove(sub);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ Misslyckades att skicka till {sub.Endpoint}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return successCount;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
73
Aberwyn/Data/SetupService.cs
Normal file
73
Aberwyn/Data/SetupService.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using Aberwyn.Models;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Aberwyn.Data
|
||||
{
|
||||
// SetupService.cs
|
||||
public class SetupService
|
||||
{
|
||||
private readonly IWebHostEnvironment _env;
|
||||
private readonly string _filePath;
|
||||
|
||||
public SetupService(IWebHostEnvironment env)
|
||||
{
|
||||
_env = env;
|
||||
_filePath = Path.Combine(_env.ContentRootPath, "infrastructure", "setup.json");
|
||||
}
|
||||
|
||||
|
||||
public SetupSettings GetSetup()
|
||||
{
|
||||
if (!File.Exists(_filePath))
|
||||
return new SetupSettings { IsConfigured = false };
|
||||
|
||||
var json = File.ReadAllText(_filePath);
|
||||
return JsonSerializer.Deserialize<SetupSettings>(json) ?? new SetupSettings { IsConfigured = false };
|
||||
}
|
||||
|
||||
|
||||
internal static IServiceProvider BuildTemporaryServices(string connectionString)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
// Konfigurera EF + Identity
|
||||
services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
|
||||
|
||||
services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
// Lägg till en tom konfiguration för att undvika null
|
||||
services.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
|
||||
|
||||
// Valfritt: Lägg till loggning om något kräver det
|
||||
services.AddLogging();
|
||||
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
public static class SetupLoader
|
||||
{
|
||||
public static SetupSettings Load(IHostEnvironment env)
|
||||
{
|
||||
var path = Path.Combine(env.ContentRootPath, "infrastructure", "setup.json");
|
||||
var json = File.ReadAllText(path);
|
||||
return JsonSerializer.Deserialize<SetupSettings>(json)!;
|
||||
}
|
||||
|
||||
public static string GetConnectionString(SetupSettings setup)
|
||||
{
|
||||
return $"server={setup.DbHost};port={setup.DbPort};database={setup.DbName};user={setup.DbUser};password={setup.DbPassword}";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
#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
|
||||
|
||||
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
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
@@ -8,9 +16,9 @@ EXPOSE 443
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||
WORKDIR /src
|
||||
COPY ["Aberwyn/Aberwyn.csproj", "Aberwyn/"]
|
||||
RUN dotnet restore "Aberwyn/Aberwyn.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/Aberwyn"
|
||||
WORKDIR /src/Aberwyn
|
||||
RUN dotnet restore "Aberwyn.csproj"
|
||||
COPY Aberwyn/. .
|
||||
RUN dotnet build "Aberwyn.csproj" -c Release -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
@@ -20,21 +28,3 @@ FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "Aberwyn.dll"]
|
||||
|
||||
version: '3.8'
|
||||
services:
|
||||
db:
|
||||
image: mysql:8
|
||||
container_name: dev-mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: aberwyn
|
||||
MYSQL_USER: aberwyn
|
||||
MYSQL_PASSWORD: devpass
|
||||
volumes:
|
||||
- mysql-data:/var/lib/mysql
|
||||
|
||||
volumes:
|
||||
mysql-data:
|
||||
|
||||
38
Aberwyn/Infrastructure/docker-compose.dev.yml
Normal file
38
Aberwyn/Infrastructure/docker-compose.dev.yml
Normal 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:
|
||||
38
Aberwyn/Infrastructure/docker-compose.prod.yml
Normal file
38
Aberwyn/Infrastructure/docker-compose.prod.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
aberwyn-app:
|
||||
image: 192.168.1.9:3000/tai/aberwyn/aberwyn:latest
|
||||
container_name: aberwyn-app-prod
|
||||
ports:
|
||||
- "8080:80"
|
||||
environment:
|
||||
ASPNETCORE_ENVIRONMENT: Production
|
||||
DB_HOST: aberwyn-mysql-prod
|
||||
DB_NAME: aberwyn_prod
|
||||
DB_USER: aberwyn
|
||||
DB_PASSWORD: 3edc4RFV
|
||||
depends_on:
|
||||
- aberwyn-mysql-prod
|
||||
networks:
|
||||
- aberwyn-net
|
||||
|
||||
aberwyn-mysql-prod:
|
||||
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:
|
||||
@@ -1,17 +0,0 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
dev-db:
|
||||
image: mysql:8
|
||||
container_name: aberwyn-dev-db
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: aberwyn
|
||||
MYSQL_USER: aberwyn
|
||||
MYSQL_PASSWORD: devpass
|
||||
volumes:
|
||||
- dev-mysql-data:/var/lib/mysql
|
||||
|
||||
volumes:
|
||||
dev-mysql-data:
|
||||
11
Aberwyn/Infrastructure/setup.json
Normal file
11
Aberwyn/Infrastructure/setup.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"AdminUsername": "admin",
|
||||
"AdminEmail": "admin@localhost",
|
||||
"AdminPassword": "Admin123!",
|
||||
"IsConfigured": true,
|
||||
"DbHost": "192.168.1.108",
|
||||
"DbPort": 3306,
|
||||
"DbName": "lewel_prod",
|
||||
"DbUser": "lewel",
|
||||
"DbPassword": "W542.Hl;)%ta"
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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("20250526133558_AddBudgetItemDefinitions")]
|
||||
partial class AddBudgetItemDefinitions
|
||||
{
|
||||
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("BudgetCategoryDefinitions");
|
||||
});
|
||||
|
||||
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("BudgetItemDefinitions");
|
||||
});
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddMealsToEf : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
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: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ProteinType = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Category = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CarbType = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
RecipeUrl = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ImageUrl = table.Column<string>(type: "longtext", nullable: false)
|
||||
.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: false),
|
||||
ImageMimeType = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Instructions = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Meals", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "WeeklyMenus",
|
||||
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: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
WeekNumber = table.Column<int>(type: "int", nullable: false),
|
||||
Year = table.Column<int>(type: "int", nullable: false),
|
||||
BreakfastMealName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
LunchMealName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
DinnerMealName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Date = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_WeeklyMenus", x => x.Id);
|
||||
})
|
||||
.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.CreateIndex(
|
||||
name: "IX_Ingredients_MealId",
|
||||
table: "Ingredients",
|
||||
column: "MealId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Ingredients");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "WeeklyMenus");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Meals");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class MakeCategoryNullable : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "RecipeUrl",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ProteinType",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Instructions",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ImageUrl",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ImageMimeType",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "ImageData",
|
||||
table: "Meals",
|
||||
type: "longblob",
|
||||
nullable: true,
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "longblob");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Description",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Category",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CarbType",
|
||||
table: "Meals",
|
||||
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: "Meals",
|
||||
keyColumn: "RecipeUrl",
|
||||
keyValue: null,
|
||||
column: "RecipeUrl",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "RecipeUrl",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Meals",
|
||||
keyColumn: "ProteinType",
|
||||
keyValue: null,
|
||||
column: "ProteinType",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ProteinType",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Meals",
|
||||
keyColumn: "Instructions",
|
||||
keyValue: null,
|
||||
column: "Instructions",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Instructions",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Meals",
|
||||
keyColumn: "ImageUrl",
|
||||
keyValue: null,
|
||||
column: "ImageUrl",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ImageUrl",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Meals",
|
||||
keyColumn: "ImageMimeType",
|
||||
keyValue: null,
|
||||
column: "ImageMimeType",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ImageMimeType",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "ImageData",
|
||||
table: "Meals",
|
||||
type: "longblob",
|
||||
nullable: false,
|
||||
defaultValue: new byte[0],
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "longblob",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Meals",
|
||||
keyColumn: "Description",
|
||||
keyValue: null,
|
||||
column: "Description",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Description",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Meals",
|
||||
keyColumn: "Category",
|
||||
keyValue: null,
|
||||
column: "Category",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Category",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "Meals",
|
||||
keyColumn: "CarbType",
|
||||
keyValue: null,
|
||||
column: "CarbType",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "CarbType",
|
||||
table: "Meals",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class CreateWeeklyMenus : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class RenameWeeklyMenusToWeeklyMenu : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,646 +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("20250601210321_AddMealNamesToWeeklyMenu")]
|
||||
partial class AddMealNamesToWeeklyMenu
|
||||
{
|
||||
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("BudgetCategoryDefinitions");
|
||||
});
|
||||
|
||||
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("BudgetItemDefinitions");
|
||||
});
|
||||
|
||||
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.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 =>
|
||||
{
|
||||
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("Aberwyn.Models.WeeklyMenu", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("BreakfastMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("BreakfastMealName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Cook")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("DayOfWeek")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("DinnerMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DinnerMealName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("LunchMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("LunchMealName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
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 =>
|
||||
{
|
||||
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", "Definition")
|
||||
.WithMany()
|
||||
.HasForeignKey("BudgetCategoryDefinitionId");
|
||||
|
||||
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("BudgetPeriodId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("BudgetPeriod");
|
||||
|
||||
b.Navigation("Definition");
|
||||
});
|
||||
|
||||
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("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 =>
|
||||
{
|
||||
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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
|
||||
{
|
||||
b.Navigation("Ingredients");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddMealNamesToWeeklyMenu : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_WeeklyMenus",
|
||||
table: "WeeklyMenus");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "WeeklyMenus",
|
||||
newName: "WeeklyMenu");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "LunchMealName",
|
||||
table: "WeeklyMenu",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "DinnerMealName",
|
||||
table: "WeeklyMenu",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Cook",
|
||||
table: "WeeklyMenu",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "BreakfastMealName",
|
||||
table: "WeeklyMenu",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_WeeklyMenu",
|
||||
table: "WeeklyMenu",
|
||||
column: "Id");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_WeeklyMenu",
|
||||
table: "WeeklyMenu");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "WeeklyMenu",
|
||||
newName: "WeeklyMenus");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "WeeklyMenus",
|
||||
keyColumn: "LunchMealName",
|
||||
keyValue: null,
|
||||
column: "LunchMealName",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "LunchMealName",
|
||||
table: "WeeklyMenus",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "WeeklyMenus",
|
||||
keyColumn: "DinnerMealName",
|
||||
keyValue: null,
|
||||
column: "DinnerMealName",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "DinnerMealName",
|
||||
table: "WeeklyMenus",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "WeeklyMenus",
|
||||
keyColumn: "Cook",
|
||||
keyValue: null,
|
||||
column: "Cook",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Cook",
|
||||
table: "WeeklyMenus",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "WeeklyMenus",
|
||||
keyColumn: "BreakfastMealName",
|
||||
keyValue: null,
|
||||
column: "BreakfastMealName",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "BreakfastMealName",
|
||||
table: "WeeklyMenus",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_WeeklyMenus",
|
||||
table: "WeeklyMenus",
|
||||
column: "Id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250531220325_AddMealsToEf")]
|
||||
partial class AddMealsToEf
|
||||
[Migration("20250602131723_InitCleanSlate")]
|
||||
partial class InitCleanSlate
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -267,34 +267,27 @@ namespace Aberwyn.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("CarbType")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Category")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<byte[]>("ImageData")
|
||||
.IsRequired()
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.Property<string>("ImageMimeType")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Instructions")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsAvailable")
|
||||
@@ -305,11 +298,9 @@ namespace Aberwyn.Migrations
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("ProteinType")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("RecipeUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -369,6 +360,46 @@ namespace Aberwyn.Migrations
|
||||
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")
|
||||
@@ -378,15 +409,10 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("BreakfastMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("BreakfastMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Cook")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("DayOfWeek")
|
||||
@@ -395,17 +421,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("DinnerMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DinnerMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("LunchMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("LunchMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("WeekNumber")
|
||||
.HasColumnType("int");
|
||||
|
||||
@@ -414,7 +432,7 @@ namespace Aberwyn.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WeeklyMenus");
|
||||
b.ToTable("WeeklyMenu", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
599
Aberwyn/Migrations/20250602131723_InitCleanSlate.cs
Normal file
599
Aberwyn/Migrations/20250602131723_InitCleanSlate.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250601201642_CreateWeeklyMenus")]
|
||||
partial class CreateWeeklyMenus
|
||||
[Migration("20250604220420_AssignedToNullable")]
|
||||
partial class AssignedToNullable
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -360,6 +360,45 @@ namespace Aberwyn.Migrations
|
||||
b.ToTable("PushSubscribers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("AssignedTo")
|
||||
.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")
|
||||
@@ -369,15 +408,10 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("BreakfastMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("BreakfastMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Cook")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("DayOfWeek")
|
||||
@@ -386,17 +420,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("DinnerMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DinnerMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("LunchMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("LunchMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("WeekNumber")
|
||||
.HasColumnType("int");
|
||||
|
||||
@@ -405,7 +431,7 @@ namespace Aberwyn.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WeeklyMenus");
|
||||
b.ToTable("WeeklyMenu", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class MakePersonNullable : Migration
|
||||
public partial class AssignedToNullable : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Person",
|
||||
table: "BudgetItems",
|
||||
name: "AssignedTo",
|
||||
table: "TodoTasks",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
@@ -22,15 +22,15 @@ namespace Aberwyn.Migrations
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.UpdateData(
|
||||
table: "BudgetItems",
|
||||
keyColumn: "Person",
|
||||
table: "TodoTasks",
|
||||
keyColumn: "AssignedTo",
|
||||
keyValue: null,
|
||||
column: "Person",
|
||||
column: "AssignedTo",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Person",
|
||||
table: "BudgetItems",
|
||||
name: "AssignedTo",
|
||||
table: "TodoTasks",
|
||||
type: "longtext",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
@@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250601204720_RenameWeeklyMenusToWeeklyMenu")]
|
||||
partial class RenameWeeklyMenusToWeeklyMenu
|
||||
[Migration("20250605062804_AddThumbnailToMeal")]
|
||||
partial class AddThumbnailToMeal
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -303,6 +303,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<string>("RecipeUrl")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<byte[]>("ThumbnailData")
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Meals");
|
||||
@@ -360,6 +363,45 @@ namespace Aberwyn.Migrations
|
||||
b.ToTable("PushSubscribers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("AssignedTo")
|
||||
.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")
|
||||
@@ -369,15 +411,10 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("BreakfastMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("BreakfastMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Cook")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("DayOfWeek")
|
||||
@@ -386,17 +423,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("DinnerMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DinnerMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("LunchMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("LunchMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("WeekNumber")
|
||||
.HasColumnType("int");
|
||||
|
||||
@@ -405,7 +434,7 @@ namespace Aberwyn.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WeeklyMenus");
|
||||
b.ToTable("WeeklyMenu", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
26
Aberwyn/Migrations/20250605062804_AddThumbnailToMeal.cs
Normal file
26
Aberwyn/Migrations/20250605062804_AddThumbnailToMeal.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddThumbnailToMeal : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<byte[]>(
|
||||
name: "ThumbnailData",
|
||||
table: "Meals",
|
||||
type: "longblob",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ThumbnailData",
|
||||
table: "Meals");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250601201238_MakeCategoryNullable")]
|
||||
partial class MakeCategoryNullable
|
||||
[Migration("20250606061016_AddUserPreferencesAndPushSubscriptions")]
|
||||
partial class AddUserPreferencesAndPushSubscriptions
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -303,6 +303,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<string>("RecipeUrl")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<byte[]>("ThumbnailData")
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Meals");
|
||||
@@ -360,6 +363,93 @@ namespace Aberwyn.Migrations
|
||||
b.ToTable("PushSubscribers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", 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.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PushSubscriptions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("AssignedTo")
|
||||
.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.UserPreferences", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<bool>("NotifyBudget")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyMenu")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyPizza")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("UserPreferences");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.WeeklyMenu", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -369,15 +459,10 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("BreakfastMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("BreakfastMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Cook")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("DayOfWeek")
|
||||
@@ -386,17 +471,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("DinnerMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DinnerMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("LunchMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("LunchMealName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("WeekNumber")
|
||||
.HasColumnType("int");
|
||||
|
||||
@@ -405,7 +482,7 @@ namespace Aberwyn.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WeeklyMenus");
|
||||
b.ToTable("WeeklyMenu", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
@@ -579,6 +656,28 @@ namespace Aberwyn.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.UserPreferences", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithOne("Preferences")
|
||||
.HasForeignKey("Aberwyn.Models.UserPreferences", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
@@ -630,6 +729,12 @@ namespace Aberwyn.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Navigation("Preferences")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
@@ -0,0 +1,76 @@
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddUserPreferencesAndPushSubscriptions : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PushSubscriptions",
|
||||
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"),
|
||||
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_PushSubscriptions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_PushSubscriptions_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserPreferences",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
NotifyPizza = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
NotifyMenu = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
NotifyBudget = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserPreferences", x => x.UserId);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserPreferences_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PushSubscriptions_UserId",
|
||||
table: "PushSubscriptions",
|
||||
column: "UserId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "PushSubscriptions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserPreferences");
|
||||
}
|
||||
}
|
||||
}
|
||||
772
Aberwyn/Migrations/20250606100439_AddPushSubscriberUserLink.Designer.cs
generated
Normal file
772
Aberwyn/Migrations/20250606100439_AddPushSubscriberUserLink.Designer.cs
generated
Normal file
@@ -0,0 +1,772 @@
|
||||
// <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("20250606100439_AddPushSubscriberUserLink")]
|
||||
partial class AddPushSubscriberUserLink
|
||||
{
|
||||
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("BudgetCategoryDefinitions");
|
||||
});
|
||||
|
||||
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("BudgetItemDefinitions");
|
||||
});
|
||||
|
||||
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.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.Property<byte[]>("ThumbnailData")
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Meals");
|
||||
});
|
||||
|
||||
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.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PushSubscribers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", 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.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PushSubscriptions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("AssignedTo")
|
||||
.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.UserPreferences", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<bool>("NotifyBudget")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyMenu")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyPizza")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("UserPreferences");
|
||||
});
|
||||
|
||||
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 =>
|
||||
{
|
||||
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", "Definition")
|
||||
.WithMany()
|
||||
.HasForeignKey("BudgetCategoryDefinitionId");
|
||||
|
||||
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("BudgetPeriodId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("BudgetPeriod");
|
||||
|
||||
b.Navigation("Definition");
|
||||
});
|
||||
|
||||
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("Aberwyn.Models.Ingredient", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.Meal", null)
|
||||
.WithMany("Ingredients")
|
||||
.HasForeignKey("MealId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.UserPreferences", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithOne("Preferences")
|
||||
.HasForeignKey("Aberwyn.Models.UserPreferences", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
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.ApplicationUser", b =>
|
||||
{
|
||||
b.Navigation("Preferences")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
|
||||
{
|
||||
b.Navigation("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
|
||||
{
|
||||
b.Navigation("Ingredients");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddPushSubscriberUserLink : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "UserId",
|
||||
table: "PushSubscribers",
|
||||
type: "varchar(255)",
|
||||
nullable: false,
|
||||
defaultValue: "")
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PushSubscribers_UserId",
|
||||
table: "PushSubscribers",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_PushSubscribers_AspNetUsers_UserId",
|
||||
table: "PushSubscribers",
|
||||
column: "UserId",
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_PushSubscribers_AspNetUsers_UserId",
|
||||
table: "PushSubscribers");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_PushSubscribers_UserId",
|
||||
table: "PushSubscribers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "UserId",
|
||||
table: "PushSubscribers");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,6 +301,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<string>("RecipeUrl")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<byte[]>("ThumbnailData")
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Meals");
|
||||
@@ -353,11 +356,104 @@ namespace Aberwyn.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PushSubscribers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", 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.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PushSubscriptions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("AssignedTo")
|
||||
.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.UserPreferences", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<bool>("NotifyBudget")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyMenu")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyPizza")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("UserPreferences");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.WeeklyMenu", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -367,13 +463,10 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("BreakfastMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("BreakfastMealName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Cook")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("DayOfWeek")
|
||||
@@ -382,15 +475,9 @@ namespace Aberwyn.Migrations
|
||||
b.Property<int?>("DinnerMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DinnerMealName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("LunchMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("LunchMealName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("WeekNumber")
|
||||
.HasColumnType("int");
|
||||
|
||||
@@ -573,6 +660,39 @@ namespace Aberwyn.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.UserPreferences", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithOne("Preferences")
|
||||
.HasForeignKey("Aberwyn.Models.UserPreferences", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
@@ -624,6 +744,12 @@ namespace Aberwyn.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Navigation("Preferences")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
|
||||
@@ -7,4 +7,20 @@
|
||||
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; } = "ideas";
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public string? AssignedTo { get; set; }
|
||||
public bool IsArchived { get; set; }
|
||||
public string Tags { get; set; } // Komma-separerad t.ex. "frontend,bug"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
public class ApplicationUser : IdentityUser
|
||||
{
|
||||
public virtual UserPreferences Preferences { get; set; }
|
||||
|
||||
// Lägg till egna fält om du vill, t.ex. public string DisplayName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Aberwyn.Data;
|
||||
using Aberwyn.Models;
|
||||
@@ -12,6 +13,25 @@ namespace Aberwyn.Models
|
||||
public int WeekNumber { get; set; } // Week number for the menu
|
||||
public int Year { get; set; } // Year for the menu
|
||||
}
|
||||
public class WeeklyMenuDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int DayOfWeek { get; set; }
|
||||
public int WeekNumber { get; set; }
|
||||
public int Year { get; set; }
|
||||
|
||||
public int? BreakfastMealId { get; set; }
|
||||
public int? LunchMealId { get; set; }
|
||||
public int? DinnerMealId { get; set; }
|
||||
|
||||
public string? BreakfastMealName { get; set; }
|
||||
public string? LunchMealName { get; set; }
|
||||
public string? DinnerMealName { get; set; }
|
||||
|
||||
public byte[]? DinnerMealThumbnail { get; set; }
|
||||
}
|
||||
|
||||
public class WeeklyMenu
|
||||
{
|
||||
public int Id { get; set; }
|
||||
@@ -22,12 +42,13 @@ public class WeeklyMenu
|
||||
public string? Cook { get; set; }
|
||||
public int WeekNumber { get; set; }
|
||||
public int Year { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[NotMapped] public string? BreakfastMealName { get; set; }
|
||||
[NotMapped] public string? BreakfastMealName { get; set; }
|
||||
[NotMapped] public string? LunchMealName { get; set; }
|
||||
[NotMapped] public string? DinnerMealName { get; set; }
|
||||
|
||||
[NotMapped] public DateTime Date { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -39,26 +60,31 @@ public class WeeklyMenu
|
||||
public string LunchMealName { get; set; }
|
||||
public string DinnerMealName { get; set; }
|
||||
}
|
||||
public class Meal
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } // Behåll som obligatorisk
|
||||
public class Meal
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
public string? ProteinType { get; set; }
|
||||
public string? Category { get; set; }
|
||||
public string? CarbType { get; set; }
|
||||
public string? RecipeUrl { get; set; }
|
||||
public string? ImageUrl { get; set; }
|
||||
public bool IsAvailable { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public string Name { get; set; } // Behåll som obligatorisk
|
||||
|
||||
public byte[]? ImageData { get; set; } // 👈 Viktigt!
|
||||
public string? ImageMimeType { get; set; } // 👈 Viktigt!
|
||||
public string? Instructions { get; set; } // 👈 Viktigt!
|
||||
public string? Description { get; set; }
|
||||
public string? ProteinType { get; set; }
|
||||
public string? Category { get; set; }
|
||||
public string? CarbType { get; set; }
|
||||
public string? RecipeUrl { get; set; }
|
||||
public string? ImageUrl { get; set; }
|
||||
|
||||
public bool IsAvailable { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public byte[]? ThumbnailData { get; set; }
|
||||
|
||||
public List<Ingredient> Ingredients { get; set; } = new();
|
||||
}
|
||||
public byte[]? ImageData { get; set; }
|
||||
public string? ImageMimeType { get; set; }
|
||||
public string? Instructions { get; set; }
|
||||
|
||||
public List<Ingredient> Ingredients { get; set; } = new();
|
||||
}
|
||||
|
||||
public class Ingredient
|
||||
{
|
||||
@@ -78,20 +104,39 @@ public class Meal
|
||||
public string? ImageData { get; set; } // base64
|
||||
public string? ImageMimeType { get; set; }
|
||||
|
||||
public static MealDto FromMeal(Meal meal)
|
||||
public static MealListDto FromMeal(Meal meal, bool includeThumbnail = false)
|
||||
{
|
||||
return new MealDto
|
||||
return new MealListDto
|
||||
{
|
||||
Id = meal.Id,
|
||||
Name = meal.Name,
|
||||
Category = meal.Category,
|
||||
IsAvailable = meal.IsAvailable,
|
||||
ImageUrl = meal.ImageUrl,
|
||||
ImageMimeType = meal.ImageMimeType,
|
||||
ImageData = meal.ImageData != null ? Convert.ToBase64String(meal.ImageData) : null
|
||||
Description = meal.Description,
|
||||
ThumbnailData = includeThumbnail && meal.ThumbnailData != null
|
||||
? Convert.ToBase64String(meal.ThumbnailData)
|
||||
: null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public class MealListDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public string? Description { get; set; }
|
||||
public string? ThumbnailData { get; set; }
|
||||
|
||||
public static MealListDto FromMeal(Meal meal, bool includeThumbnail = false)
|
||||
{
|
||||
return new MealListDto
|
||||
{
|
||||
Id = meal.Id,
|
||||
Name = meal.Name,
|
||||
Description = meal.Description,
|
||||
ThumbnailData = includeThumbnail && meal.ThumbnailData != null
|
||||
? Convert.ToBase64String(meal.ThumbnailData)
|
||||
: null
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
public string Endpoint { get; set; }
|
||||
public string P256DH { get; set; }
|
||||
public string Auth { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
}
|
||||
public class PushMessageDto
|
||||
{
|
||||
|
||||
17
Aberwyn/Models/SetupSettings.cs
Normal file
17
Aberwyn/Models/SetupSettings.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Aberwyn.Models
|
||||
{
|
||||
public class SetupSettings
|
||||
{
|
||||
public string AdminUsername { get; set; } = "admin";
|
||||
public string AdminEmail { get; set; } = "admin@localhost";
|
||||
public string AdminPassword { get; set; } = "Admin123!";
|
||||
public bool IsConfigured { get; set; }
|
||||
public string DbHost { get; set; }
|
||||
public int DbPort { get; set; }
|
||||
public string DbName { get; set; }
|
||||
public string DbUser { get; set; }
|
||||
public string DbPassword { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Aberwyn.Models
|
||||
{
|
||||
public class User
|
||||
{
|
||||
public int UserID { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
47
Aberwyn/Models/UserModel.cs
Normal file
47
Aberwyn/Models/UserModel.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Aberwyn.Models
|
||||
{
|
||||
public class UserModel
|
||||
{
|
||||
public int UserID { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
public class UserPreferences
|
||||
{
|
||||
[Key]
|
||||
public string UserId { get; set; }
|
||||
|
||||
public bool NotifyPizza { get; set; }
|
||||
public bool NotifyMenu { get; set; }
|
||||
public bool NotifyBudget { get; set; }
|
||||
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
}
|
||||
|
||||
public class StoredPushSubscription
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string UserId { get; set; }
|
||||
|
||||
public string Endpoint { get; set; }
|
||||
public string P256DH { get; set; }
|
||||
public string Auth { get; set; }
|
||||
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
}
|
||||
|
||||
public class UserProfileViewModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
public bool NotifyPizza { get; set; }
|
||||
public bool NotifyMenu { get; set; }
|
||||
public bool NotifyBudget { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,9 +13,8 @@ namespace Aberwyn.Models
|
||||
|
||||
public List<RecentMenuEntry> RecentEntries { get; set; } = new();
|
||||
public List<WeeklyMenu> WeeklyMenus { get; set; } = new();
|
||||
public List<User> AvailableCooks { get; set; } = new();
|
||||
public List<UserModel> AvailableCooks { get; set; } = new();
|
||||
|
||||
// Ny lista för översikt
|
||||
public List<WeeklyMenuViewModel> PreviousWeeks { get; set; } = new();
|
||||
public class RecentMenuEntry
|
||||
{
|
||||
|
||||
@@ -1,29 +1,81 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using Aberwyn.Data;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Aberwyn.Models;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using System.Text.Json;
|
||||
using Aberwyn.Services;
|
||||
|
||||
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();
|
||||
|
||||
// Add services to the container.
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
{
|
||||
Args = args,
|
||||
EnvironmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"
|
||||
});
|
||||
builder.Configuration.AddConfiguration(config);
|
||||
|
||||
|
||||
// Läser setup.json eller skapar en ny tom om den inte finns
|
||||
var setupFilePath = Path.Combine("infrastructure", "setup.json");
|
||||
|
||||
if (!File.Exists(setupFilePath))
|
||||
{
|
||||
var initialSettings = new SetupSettings
|
||||
{
|
||||
IsConfigured = false,
|
||||
DbPort = 3306
|
||||
};
|
||||
|
||||
var initialJson = JsonSerializer.Serialize(initialSettings, new JsonSerializerOptions { WriteIndented = true });
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(setupFilePath)!); // säkerställ att mappen finns
|
||||
File.WriteAllText(setupFilePath, initialJson);
|
||||
}
|
||||
|
||||
SetupSettings setup;
|
||||
try
|
||||
{
|
||||
using var jsonStream = File.OpenRead(setupFilePath);
|
||||
setup = JsonSerializer.Deserialize<SetupSettings>(jsonStream)!;
|
||||
|
||||
if (setup.IsConfigured)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(setup.DbHost) ||
|
||||
string.IsNullOrWhiteSpace(setup.DbName) ||
|
||||
string.IsNullOrWhiteSpace(setup.DbUser) ||
|
||||
string.IsNullOrWhiteSpace(setup.DbPassword))
|
||||
{
|
||||
throw new Exception("Databasinställningarna är ofullständiga.");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ Fel vid läsning av setup.json: {ex.Message}");
|
||||
setup = new SetupSettings { IsConfigured = false };
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Add services to the container
|
||||
builder.Services.AddControllersWithViews()
|
||||
.AddJsonOptions(opts =>
|
||||
{
|
||||
// Beh<65>ll propertynamn som i C#-klassen (PascalCase)
|
||||
opts.JsonSerializerOptions.PropertyNamingPolicy = null;
|
||||
// Ignorera null-v<>rden vid serialisering
|
||||
opts.JsonSerializerOptions.IgnoreNullValues = true;
|
||||
});
|
||||
|
||||
builder.Services.AddSession(options =>
|
||||
{
|
||||
options.IdleTimeout = TimeSpan.FromHours(1);
|
||||
options.IdleTimeout = TimeSpan.FromDays(30);
|
||||
options.Cookie.HttpOnly = true;
|
||||
options.Cookie.IsEssential = true;
|
||||
});
|
||||
@@ -31,21 +83,43 @@ builder.Services.AddSession(options =>
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddHttpClient();
|
||||
|
||||
// Configure your DbContext with MySQLs
|
||||
|
||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseMySql(
|
||||
builder.Configuration.GetConnectionString("DefaultConnection"),
|
||||
new MySqlServerVersion(new Version(8, 0, 36))
|
||||
));
|
||||
|
||||
|
||||
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
|
||||
// Registrera rätt databas och identity beroende på om setup är klar
|
||||
if (setup.IsConfigured)
|
||||
{
|
||||
options.SignIn.RequireConfirmedAccount = false;
|
||||
})
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
var csBuilder = new MySqlConnector.MySqlConnectionStringBuilder
|
||||
{
|
||||
Server = setup.DbHost,
|
||||
Port = (uint)setup.DbPort,
|
||||
Database = setup.DbName,
|
||||
UserID = setup.DbUser,
|
||||
Password = setup.DbPassword,
|
||||
AllowUserVariables = true // valfritt – ta bort om du inte använder det
|
||||
};
|
||||
|
||||
var connectionString = csBuilder.ConnectionString;
|
||||
|
||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
|
||||
|
||||
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
|
||||
{
|
||||
options.SignIn.RequireConfirmedAccount = false;
|
||||
})
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseInMemoryDatabase("TempSetup"));
|
||||
|
||||
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
}
|
||||
|
||||
// Identity inställningar
|
||||
builder.Services.Configure<IdentityOptions>(options =>
|
||||
{
|
||||
options.Password.RequireDigit = false;
|
||||
@@ -55,11 +129,10 @@ builder.Services.Configure<IdentityOptions>(options =>
|
||||
options.Password.RequireUppercase = false;
|
||||
});
|
||||
|
||||
builder.Services.AddControllersWithViews();
|
||||
// Register your services
|
||||
// Appens övriga tjänster
|
||||
builder.Services.AddScoped<MenuService>();
|
||||
|
||||
builder.Services.AddSingleton<PushNotificationService>(sp =>
|
||||
builder.Services.AddScoped<PushNotificationService>(sp =>
|
||||
{
|
||||
var config = sp.GetRequiredService<IConfiguration>();
|
||||
return new PushNotificationService(
|
||||
@@ -69,12 +142,20 @@ builder.Services.AddSingleton<PushNotificationService>(sp =>
|
||||
);
|
||||
});
|
||||
|
||||
builder.Services.AddScoped<PizzaNotificationService>();
|
||||
|
||||
builder.Services.Configure<VapidOptions>(builder.Configuration.GetSection("Vapid"));
|
||||
|
||||
builder.Services.ConfigureApplicationCookie(options =>
|
||||
{
|
||||
options.LoginPath = "/Identity/Account/Login"; // korrekt för ditt nuvarande upplägg
|
||||
options.LoginPath = "/Identity/Account/Login";
|
||||
options.ExpireTimeSpan = TimeSpan.FromDays(30);
|
||||
options.SlidingExpiration = true;
|
||||
options.Cookie.IsEssential = true;
|
||||
});
|
||||
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
builder.Services.Configure<RequestLocalizationOptions>(options =>
|
||||
{
|
||||
var supportedCultures = new[] { new CultureInfo("sv-SE") };
|
||||
@@ -82,59 +163,93 @@ builder.Services.Configure<RequestLocalizationOptions>(options =>
|
||||
options.SupportedCultures = supportedCultures;
|
||||
options.SupportedUICultures = supportedCultures;
|
||||
});
|
||||
builder.Configuration
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||
.AddEnvironmentVariables();
|
||||
builder.Services.AddSingleton<PushNotificationService>(sp =>
|
||||
{
|
||||
var config = sp.GetRequiredService<IConfiguration>();
|
||||
return new PushNotificationService(
|
||||
config["VapidKeys:Subject"],
|
||||
config["VapidKeys:PublicKey"],
|
||||
config["VapidKeys:PrivateKey"]
|
||||
);
|
||||
});
|
||||
builder.Services.AddSingleton<SetupService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
app.UseStaticFiles();
|
||||
// Middleware: om ej konfigurerad → redirect till /setup
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var setupService = context.RequestServices.GetRequiredService<SetupService>();
|
||||
var currentSetup = setupService.GetSetup();
|
||||
|
||||
var path = context.Request.Path;
|
||||
var method = context.Request.Method;
|
||||
|
||||
if (!currentSetup.IsConfigured &&
|
||||
!path.StartsWithSegments("/setup") &&
|
||||
!(path == "/setup" && method == "POST") && // 👈 tillåt POST till /setup
|
||||
!path.StartsWithSegments("/api/setup"))
|
||||
{
|
||||
context.Response.Redirect("/setup");
|
||||
return;
|
||||
}
|
||||
|
||||
await next();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Configure the HTTP request pipeline
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
app.UseSession();
|
||||
app.UseAuthentication();;
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
// Map controller endpoints (including AJAX JSON actions)
|
||||
// Routing
|
||||
app.MapControllers();
|
||||
|
||||
// Conventional MVC route
|
||||
app.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
// Map Razor Pages
|
||||
app.MapRazorPages();
|
||||
using (var scope = app.Services.CreateScope())
|
||||
|
||||
// Init: migrera databas och skapa admin
|
||||
if (setup.IsConfigured)
|
||||
{
|
||||
using var scope = app.Services.CreateScope();
|
||||
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>();
|
||||
await TestDataSeeder.SeedBudget(context);
|
||||
|
||||
int retries = 10;
|
||||
while (retries > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
context.Database.OpenConnection();
|
||||
context.Database.CloseConnection();
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
retries--;
|
||||
Console.WriteLine("⏳ Väntar på databas...");
|
||||
Thread.Sleep(3000);
|
||||
}
|
||||
}
|
||||
|
||||
context.Database.Migrate();
|
||||
|
||||
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
|
||||
var anyUsers = await userManager.Users.AnyAsync();
|
||||
|
||||
if (!anyUsers)
|
||||
{
|
||||
Console.WriteLine("🧩 Ingen användare hittades – skapar admin...");
|
||||
await IdentityDataInitializer.SeedData(services, setup);
|
||||
}
|
||||
}
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage(); // Detta ger stacktraces i browsern
|
||||
}
|
||||
|
||||
|
||||
|
||||
app.Run();
|
||||
|
||||
@@ -14,22 +14,21 @@
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:7290;http://localhost:5290",
|
||||
"dotnetRunMessages": true
|
||||
"applicationUrl": "https://localhost:7290;http://localhost:5290"
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Docker": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Docker": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +1,236 @@
|
||||
@model List<Aberwyn.Controllers.AdminUserViewModel>
|
||||
<link rel="stylesheet" href="~/css/admin.css" />
|
||||
|
||||
<h2>Användarhantering</h2>
|
||||
<h3>Skapa ny roll</h3>
|
||||
<form method="post" asp-action="CreateRole">
|
||||
<div class="form-group">
|
||||
<input type="text" name="roleName" class="form-control" placeholder="Namn på ny roll" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success mt-2">Skapa roll</button>
|
||||
</form>
|
||||
<h3>Skapa ny användare</h3>
|
||||
@if (TempData["Message"] != null)
|
||||
{
|
||||
<div class="alert alert-success">@TempData["Message"]</div>
|
||||
}
|
||||
<h2 class="mb-3">Adminpanel</h2>
|
||||
|
||||
<form method="post" asp-action="CreateUser">
|
||||
<div class="form-group">
|
||||
<label for="email">E-post:</label>
|
||||
<input type="email" name="email" class="form-control" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Lösenord:</label>
|
||||
<input type="password" name="password" class="form-control" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success mt-2">Skapa användare</button>
|
||||
</form>
|
||||
|
||||
<hr />
|
||||
<h4>Alla roller</h4>
|
||||
<ul>
|
||||
@foreach (var role in ViewBag.AllRoles as List<string>)
|
||||
{
|
||||
<li>@role</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>E-post</th>
|
||||
<th>Roller</th>
|
||||
<th>Lägg till roll</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var user in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>@user.Email</td>
|
||||
<td>
|
||||
@foreach (var role in user.Roles)
|
||||
{
|
||||
<span>@role</span>
|
||||
<form method="post" asp-action="RemoveFromRole" style="display:inline;">
|
||||
<input type="hidden" name="userId" value="@user.UserId" />
|
||||
<input type="hidden" name="role" value="@role" />
|
||||
<button type="submit" class="btn btn-sm btn-danger">Ta bort</button>
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">Roller och användare</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div>
|
||||
<h4>Skapa ny roll</h4>
|
||||
<form method="post" asp-action="CreateRole">
|
||||
<div class="form-group">
|
||||
<input type="text" name="roleName" class="form-control" placeholder="Namn på ny roll" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success mt-2">Skapa roll</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4>Skapa ny användare</h4>
|
||||
@if (TempData["Message"] != null)
|
||||
{
|
||||
<div class="alert alert-success">@TempData["Message"]</div>
|
||||
}
|
||||
|
||||
<form method="post" asp-action="CreateUser">
|
||||
<div class="form-group">
|
||||
<label for="email">E-post:</label>
|
||||
<input type="email" name="email" class="form-control" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Lösenord:</label>
|
||||
<input type="password" name="password" class="form-control" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success mt-2">Skapa användare</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">Befintliga roller och användare</div>
|
||||
<div class="card-body">
|
||||
<h5>Alla roller</h5>
|
||||
<ul>
|
||||
@foreach (var role in ViewBag.AllRoles as List<string>)
|
||||
{
|
||||
<li>@role</li>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<form method="post" asp-action="AddToRole" class="form-inline">
|
||||
<input type="hidden" name="userId" value="@user.UserId" />
|
||||
<input type="text" name="role" class="form-control" placeholder="Rollnamn" />
|
||||
<button type="submit" class="btn btn-sm btn-primary">Lägg till</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
|
||||
<h3>Testa Pushnotis</h3>
|
||||
<form onsubmit="sendPush(event)">
|
||||
<div class="form-group">
|
||||
<label for="title">Titel:</label>
|
||||
<input type="text" id="title" name="title" class="form-control" required />
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>E-post</th>
|
||||
<th>Roller</th>
|
||||
<th>Lägg till roll</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var user in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>@user.Email</td>
|
||||
<td>
|
||||
@foreach (var role in user.Roles)
|
||||
{
|
||||
<span>@role</span>
|
||||
<form method="post" asp-action="RemoveFromRole" style="display:inline;">
|
||||
<input type="hidden" name="userId" value="@user.UserId" />
|
||||
<input type="hidden" name="role" value="@role" />
|
||||
<button type="submit" class="btn btn-sm btn-danger">Ta bort</button>
|
||||
</form>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<form method="post" asp-action="AddToRole" class="form-inline">
|
||||
<input type="hidden" name="userId" value="@user.UserId" />
|
||||
<input type="text" name="role" class="form-control" placeholder="Rollnamn" />
|
||||
<button type="submit" class="btn btn-sm btn-primary">Lägg till</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="body">Meddelande:</label>
|
||||
<input type="text" id="body" name="body" class="form-control" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-warning mt-2">Skicka testnotis</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">Övriga funktioner</div>
|
||||
<div class="card-body">
|
||||
<button class="btn btn-secondary mb-3" onclick="generateThumbnails()">🖼 Generera thumbnails</button>
|
||||
|
||||
<h4>Testa Pushnotis</h4>
|
||||
<form onsubmit="sendPush(event)">
|
||||
<div class="form-group">
|
||||
<label for="title">Titel:</label>
|
||||
<input type="text" id="title" name="title" class="form-control" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="body">Meddelande:</label>
|
||||
<input type="text" id="body" name="body" class="form-control" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-warning mt-2">Skicka testnotis</button>
|
||||
</form>
|
||||
<hr />
|
||||
<h4>Skicka Pizza-notis</h4>
|
||||
<button class="btn btn-danger mt-2" onclick="sendPizzaPush()">🍕 Skicka pizzanotis</button>
|
||||
<div id="pizzaPushResult" class="mt-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-5">
|
||||
<div class="card-header">Importera från annan databas</div>
|
||||
<div class="card-body">
|
||||
<form id="customDbForm">
|
||||
<div class="form-group">
|
||||
<label>Server:</label>
|
||||
<input type="text" name="dbHost" class="form-control" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Port:</label>
|
||||
<input type="number" name="dbPort" class="form-control" value="3306" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Databas:</label>
|
||||
<input type="text" name="dbName" class="form-control" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Användarnamn:</label>
|
||||
<input type="text" name="dbUser" class="form-control" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Lösenord:</label>
|
||||
<input type="password" name="dbPassword" class="form-control" required />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<button class="btn btn-info mt-3" onclick="testDbConnection()">🔌 Testa anslutning</button>
|
||||
<div id="testResult" class="mt-2"></div>
|
||||
<button class="btn btn-primary mt-3" onclick="submitTo('ImportMealsFromCustom')">🍽 Importera måltider</button>
|
||||
<button class="btn btn-primary mt-3" onclick="submitTo('ImportMenusFromCustom')">🗓 Importera menyer</button>
|
||||
<button class="btn btn-primary mt-3" onclick="submitTo('ImportBudgetFromCustom')">💰 Importera budget</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
<script>
|
||||
async function sendPizzaPush() {
|
||||
const resultDiv = document.getElementById("pizzaPushResult");
|
||||
resultDiv.innerText = "⏳ Skickar notis...";
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/push/notify-pizza", {
|
||||
method: "POST"
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
if (response.ok) {
|
||||
resultDiv.className = "text-success mt-2";
|
||||
resultDiv.innerText = "✅ " + text;
|
||||
} else {
|
||||
resultDiv.className = "text-danger mt-2";
|
||||
resultDiv.innerText = "❌ Fel: " + text;
|
||||
}
|
||||
} catch (err) {
|
||||
resultDiv.className = "text-danger mt-2";
|
||||
resultDiv.innerText = "❌ Ett tekniskt fel uppstod.";
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
function generateThumbnails() {
|
||||
if (!confirm("Generera thumbnails för alla måltider som saknar?")) return;
|
||||
|
||||
fetch("/admin/GenerateThumbnails", {
|
||||
method: "POST"
|
||||
})
|
||||
.then(res => res.text())
|
||||
.then(msg => {
|
||||
alert("✅ " + msg);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Fel vid generering av thumbnails:", err);
|
||||
alert("❌ Ett fel uppstod vid generering av thumbnails.");
|
||||
});
|
||||
}
|
||||
|
||||
function collectFormData() {
|
||||
const form = document.getElementById("customDbForm");
|
||||
return new FormData(form); // 🔁 Byt ut till ren FormData istället för URLSearchParams
|
||||
}
|
||||
|
||||
function submitTo(action) {
|
||||
const data = collectFormData();
|
||||
|
||||
fetch(`/admin/${action}`, {
|
||||
method: "POST",
|
||||
body: data
|
||||
})
|
||||
.then(async res => {
|
||||
const text = await res.text();
|
||||
if (res.ok) {
|
||||
alert(`✅ ${action} lyckades`);
|
||||
} else {
|
||||
alert(`❌ Fel vid ${action}:\n${text}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testDbConnection() {
|
||||
const data = collectFormData();
|
||||
|
||||
fetch(`/admin/TestDbConnection`, {
|
||||
method: "POST",
|
||||
body: data
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const div = document.getElementById("testResult");
|
||||
div.innerText = data.message;
|
||||
div.className = data.success ? "text-success mt-2" : "text-danger mt-2";
|
||||
})
|
||||
.catch(err => {
|
||||
document.getElementById("testResult").innerText = "❌ Ett tekniskt fel uppstod.";
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
async function sendPush(event) {
|
||||
event.preventDefault(); // 🚫 stoppa formuläret från att göra vanlig POST
|
||||
|
||||
|
||||
148
Aberwyn/Views/Admin/Todo.cshtml
Normal file
148
Aberwyn/Views/Admin/Todo.cshtml
Normal file
@@ -0,0 +1,148 @@
|
||||
@{
|
||||
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-column input[type="text"],
|
||||
.todo-column textarea,
|
||||
.todo-column select {
|
||||
width: 100%;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
padding: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
font-family: inherit;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.todo-column textarea {
|
||||
resize: vertical;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.todo-column button {
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.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"
|
||||
ng-if="!task.IsArchived">
|
||||
|
||||
<strong>{{ task.Title }}</strong>
|
||||
|
||||
<p ng-if="task.Description">{{ task.Description }}</p>
|
||||
|
||||
<div>
|
||||
<small>🏷️ {{ task.Tags }}</small><br />
|
||||
<small>📅 {{ task.CreatedAt | date:'yyyy-MM-dd HH:mm' }}</small>
|
||||
</div>
|
||||
|
||||
<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é..." />
|
||||
<textarea ng-model="NewTask.Description" placeholder="Beskrivning"></textarea>
|
||||
<input type="text" ng-model="NewTask.Tags" placeholder="Taggar (komma-separerat)" />
|
||||
<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>
|
||||
@@ -34,13 +34,57 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="summary-cards" ng-if="budget && budget.categories.length > 0" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin: 24px 0;">
|
||||
<div class="summary-card income">Totalt inkomst<br><strong>{{ getTotalIncome() | number:0 }}</strong></div>
|
||||
<div class="summary-card expense">Total utgift<br><strong>({{ getTotalExpense() | number:0 }})</strong></div>
|
||||
<div class="summary-card savings">Sparande<br><strong>{{ getTotalSaving() | number:0 }}</strong></div>
|
||||
<div class="summary-card leftover">Pengar kvar<br><strong>{{ getLeftover() | number:0 }}</strong></div>
|
||||
<div class="budget-overview-row" ng-if="budget && budget.categories.length > 0">
|
||||
<!-- Vänster: Summering -->
|
||||
<div class="budget-summary-box compact">
|
||||
<h3>Sammanställning</h3>
|
||||
<ul class="summary-list">
|
||||
<li><span>💰 Inkomst:</span> {{ getTotalIncome() | number:0 }} kr</li>
|
||||
<li><span>💸 Utgift:</span> {{ getTotalExpense() | number:0 }} kr</li>
|
||||
<li><span>🏦 Sparande:</span> {{ getTotalSaving() | number:0 }} kr</li>
|
||||
<p>
|
||||
📈 Kvar:
|
||||
<span class="highlight leftover" ng-class="{'plus': getLeftover() >= 0, 'minus': getLeftover() < 0}">
|
||||
{{ getLeftover() | number:0 }} kr
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</ul>
|
||||
<hr>
|
||||
<ul class="category-summary-list">
|
||||
<li ng-repeat="cat in budget.categories">
|
||||
<span style="color: {{ cat.color }}">{{ cat.name }}</span>
|
||||
<span>{{ getCategorySum(cat) | number:0 }} kr</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Höger: Diagramväxling -->
|
||||
<div class="budget-chart-box compact">
|
||||
<div class="chart-row">
|
||||
<div class="chart-legend">
|
||||
<h4>Utgifter</h4>
|
||||
|
||||
<p style="font-size: 12px; margin: 4px 0 10px;">
|
||||
Totalt: <strong>{{ getTotalExpense() | number:0 }} kr</strong>
|
||||
</p>
|
||||
|
||||
<p ng-if="topExpenseCategory" style="font-size: 12px; margin-bottom: 12px;">
|
||||
Största kategori: <br>
|
||||
<strong>{{ topExpenseCategory.name }}</strong> ({{ topExpenseCategory.percent | number:1 }}%)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="chart-area">
|
||||
<canvas id="expenseChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="budget-grid" ng-if="budget && budget.categories">
|
||||
<div class="budget-card"
|
||||
ng-repeat="cat in budget.categories"
|
||||
@@ -185,6 +229,7 @@
|
||||
|
||||
</div>
|
||||
<link rel="stylesheet" href="~/css/budget.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
|
||||
<script src="~/js/budget.js"></script>
|
||||
|
||||
@@ -143,8 +143,9 @@
|
||||
</aside>
|
||||
|
||||
<datalist id="meals-list">
|
||||
@foreach (var m in ViewBag.AvailableMeals as List<Aberwyn.Models.Meal>) {
|
||||
<option value="@m.Name" />
|
||||
@foreach (var meal in (List<Meal>)ViewBag.AvailableMeals)
|
||||
{
|
||||
<option value="@meal.Id">@meal.Name</option>
|
||||
}
|
||||
</datalist>
|
||||
</form>
|
||||
|
||||
@@ -56,16 +56,37 @@
|
||||
ng-click="openMeal(getMealIdByDay(day))">
|
||||
<div class="card-content">
|
||||
<div class="day">{{day}}</div>
|
||||
<div class="meal" ng-if="menu[day].breakfastMealName">Frukost: {{menu[day].breakfastMealName}}</div>
|
||||
<div class="meal" ng-if="menu[day].lunchMealName">Lunch: {{menu[day].lunchMealName}}</div>
|
||||
<div class="meal" ng-if="menu[day].dinnerMealName">Middag: {{menu[day].dinnerMealName}}</div>
|
||||
<div class="meal" ng-if="!menu[day]">Inte bestämd</div>
|
||||
<div class="meal" ng-if="menu[day].lunchMealName">Lunch: {{menu[day].lunchMealName}}</div>
|
||||
<div class="meal" ng-if="menu[day].breakfastMealName">Frukost: {{menu[day].breakfastMealName}}</div>
|
||||
<div class="meal" ng-if="menu[day] && !menu[day].breakfastMealName && !menu[day].lunchMealName && !menu[day].dinnerMealName">Inte bestämd</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="school-meals card-view">
|
||||
<h2>Skolmat</h2>
|
||||
|
||||
|
||||
<div ng-repeat="school in schoolMealsBySchool">
|
||||
<div class="school-meal-title" ng-click="toggleSchoolExpanded(school)">
|
||||
<span class="chevron" ng-class="{ rotated: school.expanded }">▼</span>
|
||||
{{ school.name }}
|
||||
</div>
|
||||
|
||||
<div class="card-container" ng-show="school.expanded">
|
||||
<div class="meal-card" ng-repeat="day in school.days">
|
||||
<div class="card-content school-meal-card-content">
|
||||
<div class="day">{{ day.weekday }}</div>
|
||||
<div class="meal" ng-repeat="meal in day.courses">{{ meal }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
14
Aberwyn/Views/Home/Offline.cshtml
Normal file
14
Aberwyn/Views/Home/Offline.cshtml
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="sv">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Offline</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; text-align: center; padding: 2rem; background: #1F2C3C; color: white; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🌐 Du är offline</h1>
|
||||
<p>LEWEL är inte tillgänglig just nu. Kontrollera din internetanslutning och försök igen.</p>
|
||||
</body>
|
||||
</html>
|
||||
12
Aberwyn/Views/Home/Offline.cshtml.cs
Normal file
12
Aberwyn/Views/Home/Offline.cshtml.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Aberwyn.Views.Home
|
||||
{
|
||||
public class OfflineModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Aberwyn/Views/Meal/Index.cshtml
Normal file
48
Aberwyn/Views/Meal/Index.cshtml
Normal file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="sv" ng-app="mealGalleryApp">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Måltider</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
|
||||
<link rel="stylesheet" href="/css/meal-gallery.css">
|
||||
</head>
|
||||
<body ng-controller="MealGalleryController">
|
||||
<div class="meal-gallery-container" ng-controller="MealGalleryController">
|
||||
<div class="meal-gallery-header">
|
||||
<h1>Recept</h1>
|
||||
<div class="search-container">
|
||||
<input type="text" ng-model="search" placeholder="Sök recept...">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="meal-gallery-grid">
|
||||
<div class="meal-card" ng-repeat="meal in meals | filter:search">
|
||||
<img ng-src="{{ meal.ThumbnailData ? 'data:image/webp;base64,' + meal.ThumbnailData : '/images/fallback.jpg' }}"
|
||||
alt="{{ meal.Name }}">
|
||||
<div class="meal-card-content">
|
||||
<h3>{{ meal.Name }}</h3>
|
||||
<p ng-if="meal.Description">{{ meal.Description }}</p>
|
||||
<a class="btn-readmore" ng-href="/meal/view/{{ meal.Id }}">Läs mer</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
<script>
|
||||
angular.module("mealGalleryApp", []).controller("MealGalleryController", function ($scope, $http) {
|
||||
$scope.meals = [];
|
||||
$scope.search = "";
|
||||
|
||||
$http.get("/api/mealMenuApi/getMeals").then(res => {
|
||||
$scope.meals = res.data;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -64,6 +64,10 @@
|
||||
<label for="CarbType">Kolhydrat</label>
|
||||
<input type="text" name="CarbType" value="@Model.CarbType" class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Category">Kategori</label>
|
||||
<input type="text" name="Category" value="@Model.Category" class="form-control" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="RecipeUrl">Receptlänk</label>
|
||||
@@ -79,7 +83,7 @@
|
||||
<div class="form-group">
|
||||
<label>Ingredienser</label>
|
||||
<div id="ingredients-list">
|
||||
@for (int i = 0; i < Model.Ingredients.Count; i++)
|
||||
@for (int i = 0; i < (Model.Ingredients?.Count ?? 0); i++)
|
||||
{
|
||||
<div class="ingredient-row">
|
||||
<input type="text" name="Ingredients[@i].Quantity" placeholder="Mängd" value="@Model.Ingredients[i].Quantity" class="form-control ingredient-qty" />
|
||||
@@ -215,7 +219,7 @@
|
||||
closeImageModal();
|
||||
}
|
||||
});
|
||||
$(document).ready(function () {
|
||||
$(document).ready(function () {
|
||||
if ($('#Instructions').length > 0) {
|
||||
$('#Instructions').trumbowyg({
|
||||
autogrow: true,
|
||||
@@ -223,35 +227,6 @@
|
||||
});
|
||||
}
|
||||
});
|
||||
if ('serviceWorker' in navigator && 'PushManager' in window) {
|
||||
navigator.serviceWorker.register('/service-worker.js')
|
||||
.then(function (registration) {
|
||||
console.log('Service Worker registered', registration);
|
||||
return registration.pushManager.getSubscription()
|
||||
.then(async function (subscription) {
|
||||
if (subscription) {
|
||||
console.log('Already subscribed to push notifications.');
|
||||
return subscription;
|
||||
}
|
||||
const response = await fetch('/api/push/vapid-public-key');
|
||||
const vapidPublicKey = await response.text();
|
||||
const convertedVapidKey = urlBase64ToUint8Array(vapidPublicKey);
|
||||
|
||||
return registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: convertedVapidKey
|
||||
});
|
||||
});
|
||||
}).then(function (subscription) {
|
||||
return fetch('/api/push/subscribe', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(subscription),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
395
Aberwyn/Views/Setup/Index.cshtml
Normal file
395
Aberwyn/Views/Setup/Index.cshtml
Normal file
@@ -0,0 +1,395 @@
|
||||
@model Aberwyn.Models.SetupSettings
|
||||
@{
|
||||
ViewData["Title"] = "Installera Aberwyn";
|
||||
}
|
||||
|
||||
<h1>Installera Aberwyn</h1>
|
||||
|
||||
@if (ViewBag.Error != null)
|
||||
{
|
||||
<div class="alert alert-danger">@ViewBag.Error</div>
|
||||
}
|
||||
|
||||
<style>
|
||||
.setup-step {
|
||||
margin-bottom: 2rem;
|
||||
padding: 1.5rem;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
input.form-control {
|
||||
padding: 0.5rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.is-invalid {
|
||||
border-color: #dc3545;
|
||||
}
|
||||
.invalid-feedback {
|
||||
color: #dc3545;
|
||||
font-size: 0.875rem;
|
||||
display: none;
|
||||
}
|
||||
.is-invalid + .invalid-feedback {
|
||||
display: block;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
font-size: 1rem;
|
||||
border-radius: 6px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
margin-top: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.btn-primary { background-color: #6a0dad; color: white; }
|
||||
.btn-primary:hover { background-color: #5a0cab; }
|
||||
|
||||
.btn-secondary { background-color: #adb5bd; color: black; }
|
||||
.btn-secondary:hover { background-color: #9ca3af; }
|
||||
|
||||
.btn-success { background-color: #198754; color: white; }
|
||||
.btn-success:hover { background-color: #157347; }
|
||||
|
||||
.btn-danger { background-color: #dc3545; color: white; }
|
||||
.btn-danger:hover { background-color: #bb2d3b; }
|
||||
|
||||
.btn-outline-info {
|
||||
border: 1px solid #0dcaf0;
|
||||
color: #0dcaf0;
|
||||
background: none;
|
||||
}
|
||||
.btn-outline-info:hover {
|
||||
background-color: #0dcaf0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#setup-summary ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
#setup-summary li {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
.spinner {
|
||||
display: inline-block;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
border: 3px solid rgba(0,0,0,0.2);
|
||||
border-top-color: #6a0dad;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
@@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
|
||||
<form method="post" id="setup-form">
|
||||
<div id="step-1" class="setup-step">
|
||||
<h2>Steg 1: Databasinställningar</h2>
|
||||
<div class="form-group">
|
||||
<label for="DbHost">Server</label>
|
||||
<input asp-for="DbHost" name="DbHost" class="form-control" id="DbHost" required />
|
||||
<div class="invalid-feedback">Fältet är obligatoriskt</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="DbPort">Port</label>
|
||||
<input asp-for="DbPort" name="DbPort" class="form-control" id="DbPort" value="3306" required />
|
||||
<div class="invalid-feedback">Fältet är obligatoriskt</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="DbName">Databasnamn</label>
|
||||
<input asp-for="DbName" name="DbName" class="form-control" id="DbName" required />
|
||||
<div class="invalid-feedback">Fältet är obligatoriskt</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="DbUser">Användarnamn</label>
|
||||
<input asp-for="DbUser" name="DbUser" class="form-control" id="DbUser" required />
|
||||
<div class="invalid-feedback">Fältet är obligatoriskt</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="DbPassword">Lösenord</label>
|
||||
<input asp-for="DbPassword" name="DbPassword" type="password" class="form-control" id="DbPassword" required />
|
||||
<div class="invalid-feedback">Fältet är obligatoriskt</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-info" onclick="testDbConnection()">Testa anslutning</button>
|
||||
<div id="db-test-result" class="mt-2"></div>
|
||||
<button type="button" class="btn btn-primary" onclick="validateStep(1) && goToStep(2)">Nästa</button>
|
||||
</div>
|
||||
|
||||
<div id="step-2" class="setup-step" style="display: none;">
|
||||
<h2>Steg 2: Administratör</h2>
|
||||
<div class="form-group">
|
||||
<label for="AdminUsername">Admin Användarnamn</label>
|
||||
<input asp-for="AdminUsername" name="AdminUsername" class="form-control" id="AdminUsername" required />
|
||||
<div class="invalid-feedback">Fältet är obligatoriskt</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="AdminEmail">E-postadress</label>
|
||||
<input asp-for="AdminEmail" name="AdminEmail" type="email" class="form-control" id="AdminEmail" required />
|
||||
<div class="invalid-feedback">Fältet är obligatoriskt</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="AdminPassword">Lösenord</label>
|
||||
<input asp-for="AdminPassword" name="AdminPassword" type="password" class="form-control"
|
||||
id="AdminPassword"
|
||||
pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).{6,}"
|
||||
title="Minst 6 tecken, inklusive versal, gemen, siffra och specialtecken"
|
||||
required />
|
||||
<div class="invalid-feedback">Ange ett giltigt lösenord enligt kraven</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ConfirmPassword">Bekräfta lösenord</label>
|
||||
<input type="password" id="ConfirmPassword" class="form-control" required />
|
||||
<span id="password-match-status" style="margin-top: 4px; font-size: 1.2rem;"></span>
|
||||
<div class="invalid-feedback" id="confirmPasswordError">Lösenorden matchar inte</div>
|
||||
</div>
|
||||
|
||||
|
||||
<ul id="password-criteria" style="list-style: none; padding-left: 0; font-size: 0.9rem; margin-top: 0.5rem;">
|
||||
<li id="length-criteria">❌ Minst 6 tecken</li>
|
||||
<li id="uppercase-criteria">❌ Minst en stor bokstav (A–Z)</li>
|
||||
<li id="lowercase-criteria">❌ Minst en liten bokstav (a–z)</li>
|
||||
<li id="digit-criteria">❌ Minst en siffra (0–9)</li>
|
||||
<li id="special-criteria">❌ Minst ett specialtecken (!#&...)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<button type="button" class="btn btn-secondary" onclick="goToStep(1)">Tillbaka</button>
|
||||
<button type="button" class="btn btn-primary" onclick="validateAdminStep() && goToStep(3)">Nästa</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="step-3" class="setup-step" style="display: none;">
|
||||
<h2>Steg 3: Konfiguration pågår...</h2>
|
||||
<div id="setup-summary">
|
||||
<ul>
|
||||
<li><strong>Server:</strong> <span id="summary-DbHost"></span></li>
|
||||
<li><strong>Port:</strong> <span id="summary-DbPort"></span></li>
|
||||
<li><strong>Databas:</strong> <span id="summary-DbName"></span></li>
|
||||
<li><strong>Användare:</strong> <span id="summary-DbUser"></span></li>
|
||||
<li><strong>Adminnamn:</strong> <span id="summary-AdminUsername"></span></li>
|
||||
<li><strong>Admin-e-post:</strong> <span id="summary-AdminEmail"></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="setup-progress" class="mt-3">
|
||||
<p>
|
||||
Skapar databastabeller och konfigurerar administratörskonto...
|
||||
<span class="spinner"></span>
|
||||
</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-secondary" onclick="goToStep(2)">Tillbaka</button>
|
||||
<button type="button" class="btn btn-success" onclick="submitSetup()">Slutför installation</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@if (User.IsInRole("Admin"))
|
||||
{
|
||||
<form method="post" asp-action="Reset" class="mt-3" onsubmit="return confirm('Är du säker på att du vill återställa konfigurationen?')">
|
||||
<button type="submit" class="btn btn-danger">Återställ inställningar</button>
|
||||
</form>
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.5/jquery.validate.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate-unobtrusive/3.2.12/jquery.validate.unobtrusive.min.js"></script>
|
||||
|
||||
<script>
|
||||
function goToStep(step) {
|
||||
document.querySelectorAll('.setup-step').forEach(s => s.style.display = 'none');
|
||||
document.getElementById('step-' + step).style.display = 'block';
|
||||
|
||||
if (step === 3) {
|
||||
document.getElementById('summary-DbHost').textContent = document.getElementById('DbHost').value;
|
||||
document.getElementById('summary-DbPort').textContent = document.getElementById('DbPort').value;
|
||||
document.getElementById('summary-DbName').textContent = document.getElementById('DbName').value;
|
||||
document.getElementById('summary-DbUser').textContent = document.getElementById('DbUser').value;
|
||||
document.getElementById('summary-AdminUsername').textContent = document.getElementById('AdminUsername').value;
|
||||
document.getElementById('summary-AdminEmail').textContent = document.getElementById('AdminEmail').value;
|
||||
|
||||
document.getElementById('setup-progress').innerHTML = `<p>Redo att påbörja installationen.</p>`;
|
||||
}
|
||||
}
|
||||
document.getElementById('AdminPassword').addEventListener('input', function () {
|
||||
const val = this.value;
|
||||
|
||||
const hasLength = val.length >= 6;
|
||||
const hasUpper = /[A-Z]/.test(val);
|
||||
const hasLower = /[a-z]/.test(val);
|
||||
const hasDigit = /\d/.test(val);
|
||||
const hasSpecial = /[!@@#$%^&*(),.?":{}|<>_\-\\[\]\/+=~`]/.test(val); // lägg till specialtecken
|
||||
|
||||
updateCriteria('length-criteria', hasLength);
|
||||
updateCriteria('uppercase-criteria', hasUpper);
|
||||
updateCriteria('lowercase-criteria', hasLower);
|
||||
updateCriteria('digit-criteria', hasDigit);
|
||||
updateCriteria('special-criteria', hasSpecial);
|
||||
});
|
||||
|
||||
function updateCriteria(id, isValid) {
|
||||
const el = document.getElementById(id);
|
||||
if (isValid) {
|
||||
el.textContent = '✔ ' + el.textContent.slice(2);
|
||||
el.style.color = 'green';
|
||||
} else {
|
||||
el.textContent = '❌ ' + el.textContent.slice(2);
|
||||
el.style.color = 'red';
|
||||
}
|
||||
}
|
||||
|
||||
function validateStep(step) {
|
||||
let isValid = true;
|
||||
document.querySelectorAll('#step-' + step + ' [required]').forEach(field => {
|
||||
if (!field.value.trim()) {
|
||||
field.classList.add('is-invalid');
|
||||
isValid = false;
|
||||
} else {
|
||||
field.classList.remove('is-invalid');
|
||||
}
|
||||
});
|
||||
return isValid;
|
||||
}
|
||||
|
||||
function testDbConnection() {
|
||||
const host = document.getElementById('DbHost').value;
|
||||
const port = document.getElementById('DbPort').value;
|
||||
const db = document.getElementById('DbName').value;
|
||||
const user = document.getElementById('DbUser').value;
|
||||
const pass = document.getElementById('DbPassword').value;
|
||||
|
||||
const output = document.getElementById('db-test-result');
|
||||
output.innerHTML = '<span class="spinner"></span> Testar...';
|
||||
|
||||
fetch('/api/setup/testdb', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ host, port, db, user, pass })
|
||||
})
|
||||
.then(async res => {
|
||||
const text = await res.text();
|
||||
console.log("Raw:", text);
|
||||
try {
|
||||
const result = JSON.parse(text);
|
||||
if (result.success) {
|
||||
output.innerHTML = '✅ <span class="text-success">Anslutning lyckades!</span>';
|
||||
} else {
|
||||
output.innerHTML = '❌ <span class="text-danger">' + result.message + '</span>';
|
||||
}
|
||||
} catch (e) {
|
||||
output.innerHTML = '❌ <span class="text-danger">Felaktigt svar från servern: ' + text + '</span>';
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
output.innerHTML = '❌ <span class="text-danger">Nätverksfel: ' + err.message + '</span>';
|
||||
});
|
||||
}
|
||||
function validateAdminStep() {
|
||||
let valid = validateStep(2);
|
||||
const pass = document.getElementById('AdminPassword');
|
||||
const confirm = document.getElementById('ConfirmPassword');
|
||||
const confirmError = document.getElementById('confirmPasswordError');
|
||||
|
||||
if (pass.value !== confirm.value) {
|
||||
confirm.classList.add('is-invalid');
|
||||
confirmError.style.display = 'block';
|
||||
valid = false;
|
||||
} else {
|
||||
confirm.classList.remove('is-invalid');
|
||||
confirmError.style.display = 'none';
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
document.getElementById('ConfirmPassword').addEventListener('input', function () {
|
||||
const pass = document.getElementById('AdminPassword').value;
|
||||
const confirm = this.value;
|
||||
const confirmField = document.getElementById('ConfirmPassword');
|
||||
const matchStatus = document.getElementById('password-match-status');
|
||||
|
||||
if (confirm.length === 0) {
|
||||
matchStatus.innerHTML = '';
|
||||
confirmField.classList.remove('is-invalid');
|
||||
return;
|
||||
}
|
||||
|
||||
if (pass === confirm) {
|
||||
matchStatus.innerHTML = '✔';
|
||||
matchStatus.style.color = 'green';
|
||||
confirmField.classList.remove('is-invalid');
|
||||
} else {
|
||||
matchStatus.innerHTML = '❌';
|
||||
matchStatus.style.color = 'red';
|
||||
confirmField.classList.add('is-invalid');
|
||||
}
|
||||
});
|
||||
|
||||
async function submitSetup() {
|
||||
goToStep(3);
|
||||
const form = document.getElementById('setup-form');
|
||||
const formData = new FormData(form);
|
||||
const data = {};
|
||||
formData.forEach((value, key) => { data[key] = value; });
|
||||
|
||||
const resultEl = document.getElementById('setup-progress');
|
||||
resultEl.innerHTML = `<p>
|
||||
Skapar databastabeller och konfigurerar administratörskonto...
|
||||
<span class="spinner"></span>
|
||||
</p>`;
|
||||
|
||||
try {
|
||||
const response = await fetch('/setup', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
let result;
|
||||
try {
|
||||
result = JSON.parse(text);
|
||||
} catch (err) {
|
||||
throw new Error("Kunde inte tolka JSON-svar: " + text);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
resultEl.innerHTML = `
|
||||
<div class="alert alert-danger mt-3">
|
||||
❌ Fel vid installation: ${result.error || 'Okänt fel'}
|
||||
</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
resultEl.innerHTML = `
|
||||
<div class="alert alert-success mt-3">
|
||||
✅ ${result.message || 'Installation slutförd!'}
|
||||
<br />
|
||||
<button class="btn btn-success mt-3" onclick="window.location.href='/'">Gå vidare</button>
|
||||
</div>`;
|
||||
} catch (err) {
|
||||
console.error("Något gick fel:", err);
|
||||
resultEl.innerHTML = `<div class="alert alert-danger mt-3">
|
||||
❌ Fel vid installation: ${err.message}
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
}
|
||||
17
Aberwyn/Views/Setup/SetupComplete.cshtml
Normal file
17
Aberwyn/Views/Setup/SetupComplete.cshtml
Normal file
@@ -0,0 +1,17 @@
|
||||
@{
|
||||
ViewData["Title"] = "Klart!";
|
||||
}
|
||||
|
||||
<h1>✅ Aberwyn är nu installerad</h1>
|
||||
<p>Du kan nu starta om applikationen för att börja använda den.</p>
|
||||
|
||||
<a href="/" class="btn btn-primary">Till startsidan</a>
|
||||
|
||||
<hr />
|
||||
|
||||
<h3>🔄 Återställ installation</h3>
|
||||
<p>Om du vill nollställa installationen och börja om från början, klicka här:</p>
|
||||
|
||||
<form method="post" asp-action="Reset">
|
||||
<button type="submit" class="btn btn-danger">Återställ konfiguration</button>
|
||||
</form>
|
||||
@@ -21,35 +21,48 @@
|
||||
<span class="initial L2">L</span><span class="name">udwig</span>
|
||||
</h1>
|
||||
</div>
|
||||
<partial name="_LoginPartial" />
|
||||
@if (ViewBag.IsSetupMode as bool? != true)
|
||||
{
|
||||
<partial name="_LoginPartial" />
|
||||
}
|
||||
</header>
|
||||
|
||||
<div class="page-content">
|
||||
<aside class="sidebar">
|
||||
<ul class="nav-list">
|
||||
<li><a asp-controller="Home" asp-action="Index"><i class="fas fa-home"></i> Home</a></li>
|
||||
@if (User.IsInRole("Admin") || User.IsInRole("Budget"))
|
||||
{
|
||||
<li><a asp-controller="Budget" asp-action="Index"><i class="fas fa-wallet"></i> Budget</a></li>
|
||||
}
|
||||
<li><a asp-controller="Home" asp-action="Menu"><i class="fas fa-utensils"></i> Veckomeny</a></li>
|
||||
@if (ViewBag.RestaurantIsOpen as bool? == true)
|
||||
{
|
||||
<li><a asp-controller="FoodMenu" asp-action="PizzaOrder"><i class="fas fa-pizza-slice"></i> Beställ pizza</a></li>
|
||||
}
|
||||
@if (User.IsInRole("Admin") || User.IsInRole("Chef"))
|
||||
{
|
||||
<li><a asp-controller="FoodMenu" asp-action="Veckomeny"><i class="fas fa-calendar-week"></i> Administrera Veckomeny</a></li>
|
||||
<li><a asp-controller="FoodMenu" asp-action="MealAdmin"><i class="fas fa-list"></i> Måltider</a></li>
|
||||
<li><a asp-controller="FoodMenu" asp-action="PizzaAdmin"><i class="fas fa-list"></i> Pizza Admin</a></li>
|
||||
@if (ViewBag.IsSetupMode as bool? != true)
|
||||
{
|
||||
<ul class="nav-list">
|
||||
<li><a asp-controller="Home" asp-action="Index"><i class="fas fa-home"></i> Home</a></li>
|
||||
@if (User.IsInRole("Budget"))
|
||||
{
|
||||
<li><a asp-controller="Budget" asp-action="Index"><i class="fas fa-wallet"></i> Budget</a></li>
|
||||
}
|
||||
<li><a asp-controller="Home" asp-action="Menu"><i class="fas fa-utensils"></i> Veckomeny</a></li>
|
||||
@if (ViewBag.RestaurantIsOpen as bool? == true)
|
||||
{
|
||||
<li><a asp-controller="FoodMenu" asp-action="PizzaOrder"><i class="fas fa-pizza-slice"></i> Beställ pizza</a></li>
|
||||
}
|
||||
@if (User.IsInRole("Chef"))
|
||||
{
|
||||
<li><a asp-controller="FoodMenu" asp-action="Veckomeny"><i class="fas fa-calendar-week"></i> Administrera Veckomeny</a></li>
|
||||
<li><a asp-controller="FoodMenu" asp-action="MealAdmin"><i class="fas fa-list"></i> Måltider</a></li>
|
||||
<li><a asp-controller="FoodMenu" asp-action="PizzaAdmin"><i class="fas fa-list"></i> Pizza Admin</a></li>
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@if (User.IsInRole("Admin"))
|
||||
{
|
||||
<li><a asp-controller="Admin" asp-action="Index"><i class="fas fa-cog"></i> Adminpanel</a></li>
|
||||
}
|
||||
</ul>
|
||||
@if (User.IsInRole("Admin"))
|
||||
{
|
||||
<li><a asp-controller="Admin" asp-action="Index"><i class="fas fa-cog"></i> Adminpanel</a></li>
|
||||
<li><a asp-controller="Admin" asp-action="Todo"><i class="fas fa-cog"></i> Todo</a></li>
|
||||
|
||||
}
|
||||
</ul>
|
||||
} else
|
||||
{
|
||||
<ul class="nav-list">
|
||||
<li><a asp-controller="Setup" asp-action="Index"> Setup</a></li>
|
||||
</ul>
|
||||
}
|
||||
</aside>
|
||||
|
||||
<main class="main-panel">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Aberwyn.Models
|
||||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
@inject UserManager<ApplicationUser> UserManager
|
||||
@@ -13,7 +13,10 @@
|
||||
<i class="fas fa-user-circle"></i>
|
||||
</button>
|
||||
<div class="auth-dropdown">
|
||||
<span style="padding: 8px 12px; display: block;">@User.Identity.Name</span>
|
||||
<a href="/User/Profile">
|
||||
<i class="fas fa-user-cog"></i> Min profil
|
||||
</a>
|
||||
|
||||
<form method="post" asp-area="Identity" asp-page="/Account/Logout" style="margin: 0;">
|
||||
<button type="submit" class="dropdown-logout-button" style="padding: 8px 12px; width: 100%; text-align: left; background: none; border: none; cursor: pointer;">Logga ut</button>
|
||||
</form>
|
||||
@@ -31,8 +34,8 @@ else
|
||||
<div class="auth-dropdown">
|
||||
<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 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.Username" type="text" placeholder="Användarnamn" 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;">
|
||||
Logga in
|
||||
</button>
|
||||
@@ -54,7 +57,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 => {
|
||||
dropdown.addEventListener('click', e => e.stopPropagation());
|
||||
});
|
||||
|
||||
32
Aberwyn/Views/User/Profile.cshtml
Normal file
32
Aberwyn/Views/User/Profile.cshtml
Normal file
@@ -0,0 +1,32 @@
|
||||
@model Aberwyn.Models.UserProfileViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Userprofile";
|
||||
}
|
||||
|
||||
<h2>Min profil</h2>
|
||||
<form method="post" asp-action="SaveProfile">
|
||||
<div>
|
||||
<label asp-for="Name"></label>
|
||||
<input asp-for="Name" />
|
||||
</div>
|
||||
<div>
|
||||
<label asp-for="Email"></label>
|
||||
<input asp-for="Email" readonly />
|
||||
</div>
|
||||
|
||||
<h3>Pushnotiser</h3>
|
||||
<div>
|
||||
<input asp-for="NotifyPizza" type="checkbox" />
|
||||
<label asp-for="NotifyPizza">Ny pizzabeställning</label>
|
||||
</div>
|
||||
<div>
|
||||
<input asp-for="NotifyMenu" type="checkbox" />
|
||||
<label asp-for="NotifyMenu">Meny ändrad</label>
|
||||
</div>
|
||||
<div>
|
||||
<input asp-for="NotifyBudget" type="checkbox" />
|
||||
<label asp-for="NotifyBudget">Budget uppdaterad</label>
|
||||
</div>
|
||||
|
||||
<button type="submit">Spara</button>
|
||||
</form>
|
||||
@@ -6,7 +6,7 @@
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "server=dev-db;database=AberwynDev;user=xxx;password=xxx;",
|
||||
"DefaultConnection": "Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV;",
|
||||
"ProdConnection": "Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV;"
|
||||
}
|
||||
|
||||
|
||||
5
Aberwyn/appsettings.Production.json
Normal file
5
Aberwyn/appsettings.Production.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV;"
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,12 @@
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=localhost;Port=3306;Database=aberwyn;User=aberwyn;Password=devpass;"
|
||||
"DefaultConnection": "Server=192.168.1.108;Database=Nevyn;Uid=root;Pwd=3edc4RFV;"
|
||||
},
|
||||
"VapidKeys": {
|
||||
"Subject": "mailto:e@zcz.se",
|
||||
"PublicKey": "BBLmMdU3X3e79SqzAy4vIAJI0jmzRME17F9UKbO8XT1dfnO-mWIPKIrFDbIZD4_3ic7uoijK61vaGdfFUk3HUfU",
|
||||
"PrivateKey": "oranoCmCo8HXdc03juNgbeSlKE39N3DYus_eMunLsnc"
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
Connection string: Server=localhost;Port=3306;Database=aberwyn;User=aberwyn;Password=devpass;
|
||||
Connection string: Server=127.0.0.1;Port=3306;Database=aberwyn_dev;User=root;Password=rootpass;
|
||||
116
Aberwyn/wwwroot/css/admin.css
Normal file
116
Aberwyn/wwwroot/css/admin.css
Normal file
@@ -0,0 +1,116 @@
|
||||
/* ================================
|
||||
ADMIN – JUSTERAD LEWEL STIL
|
||||
================================ */
|
||||
|
||||
h2, h3, h4,h5 {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 12px;
|
||||
color: #394B5A;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
form {
|
||||
background-color: #ffffff;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 2px;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
max-width: 360px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ccc;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
button, .btn {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
border-radius: 4px;
|
||||
padding: 6px 12px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
padding: 4px 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: #e6ffed;
|
||||
color: #256029;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #b4e2c5;
|
||||
margin-bottom: 16px;
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
table.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background-color: #ffffff;
|
||||
margin-top: 8px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
table.table th,
|
||||
table.table td {
|
||||
padding: 8px 10px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
table.table th {
|
||||
background-color: #f0f4f8;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #ffffff;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
||||
overflow: hidden;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background-color: #394B5A;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#testResult {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
padding-left: 20px;
|
||||
color: #394B5A;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.form-control, .btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -88,40 +88,7 @@ body {
|
||||
background-color: #cbd5e1;
|
||||
}
|
||||
|
||||
.summary-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
margin: 16px 0 12px;
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
background-color: var(--bg-card);
|
||||
padding: 8px 10px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
min-width: 130px;
|
||||
}
|
||||
|
||||
.summary-card.income {
|
||||
border-top: 3px solid var(--card-income);
|
||||
}
|
||||
|
||||
.summary-card.expense {
|
||||
border-top: 3px solid var(--card-expense);
|
||||
color: var(--card-expense);
|
||||
}
|
||||
|
||||
.summary-card.savings {
|
||||
border-top: 3px solid var(--card-savings);
|
||||
}
|
||||
|
||||
.summary-card.leftover {
|
||||
border-top: 3px solid var(--card-leftover);
|
||||
}
|
||||
|
||||
.budget-grid {
|
||||
display: grid;
|
||||
@@ -535,3 +502,170 @@ color: var(--btn-check);
|
||||
.suggestion-list li:hover {
|
||||
background: #334155;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Summary */
|
||||
.budget-overview-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin: 8px 0 16px;
|
||||
}
|
||||
|
||||
.budget-summary-box,
|
||||
.budget-chart-box {
|
||||
flex: 1 1 250px;
|
||||
background-color: var(--bg-card);
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
|
||||
min-width: 220px;
|
||||
}
|
||||
|
||||
.budget-summary-box h3,
|
||||
.budget-chart-box h3 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-main);
|
||||
}
|
||||
|
||||
.summary-list,
|
||||
.category-summary-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.summary-list li,
|
||||
.category-summary-list li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1px 0;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
color: var(--text-main);
|
||||
}
|
||||
|
||||
.summary-list li span:first-child {
|
||||
font-weight: 600;
|
||||
color: var(--text-sub);
|
||||
}
|
||||
|
||||
.category-summary-list li {
|
||||
border-top: 1px dashed var(--border-color);
|
||||
padding: 3px 0;
|
||||
font-size: 11.5px;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.highlight.leftover.plus {
|
||||
color: #15803d;
|
||||
}
|
||||
|
||||
.highlight.leftover.minus {
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* chart */
|
||||
.chart-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.chart-legend h4 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chart-area {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
canvas {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.budget-overview-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.budget-chart-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 300px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.budget-chart-box .chart-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.budget-chart-box .chart-area {
|
||||
flex: 1;
|
||||
max-width: 420px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.budget-chart-box canvas {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.budget-overview-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.budget-summary-box,
|
||||
.budget-chart-box {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chart-row {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.chart-area {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.chart-legend {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.chart-area canvas {
|
||||
max-width: 240px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
107
Aberwyn/wwwroot/css/meal-gallery.css
Normal file
107
Aberwyn/wwwroot/css/meal-gallery.css
Normal file
@@ -0,0 +1,107 @@
|
||||
body {
|
||||
background-color: #f7f7f7;
|
||||
font-family: 'Segoe UI', sans-serif;
|
||||
color: #222;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.meal-gallery-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
.meal-gallery-header {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.meal-gallery-header h1 {
|
||||
font-size: 2.4rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
margin-top: 1rem;
|
||||
position: relative;
|
||||
max-width: 400px;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.search-container input {
|
||||
width: 100%;
|
||||
padding: 10px 38px 10px 12px;
|
||||
border-radius: 25px;
|
||||
border: 1px solid #ccc;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.search-container i {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.meal-gallery-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.meal-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.meal-card:hover {
|
||||
transform: scale(1.015);
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.meal-card img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.meal-card-content {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.meal-card-content h3 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 1.2rem;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.meal-card-content p {
|
||||
flex-grow: 1;
|
||||
font-size: 0.95rem;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.btn-readmore {
|
||||
align-self: flex-start;
|
||||
background: #007d36;
|
||||
color: white;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
font-size: 0.95rem;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.btn-readmore:hover {
|
||||
background: #005c27;
|
||||
}
|
||||
|
||||
@@ -165,11 +165,21 @@ h1 {
|
||||
|
||||
.card-view .card-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||||
grid-template-columns: repeat(7, 1fr); /* exakt 7 kolumner */
|
||||
gap: var(--spacing);
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
@media (max-width: 1024px) {
|
||||
.card-view .card-container {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.card-view .card-container {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.meal-card {
|
||||
position: relative;
|
||||
height: 160px;
|
||||
@@ -196,7 +206,6 @@ h1 {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to top, rgba(49, 130, 206, 0.3), rgba(0, 0, 0, 0.7), transparent);
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s ease;
|
||||
opacity: 1;
|
||||
@@ -215,14 +224,15 @@ h1 {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
background: rgba(0, 0, 0, 0.3); /* ev. öka från 0.4 till 0.5 */
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.card-content .day {
|
||||
font-size: 1rem;
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 1px 7px rgba(0, 0, 0, 1);
|
||||
margin-bottom: 6px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -230,9 +240,14 @@ h1 {
|
||||
}
|
||||
|
||||
.card-content .meal {
|
||||
font-size: 0.8rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.3;
|
||||
margin-bottom: 2px;
|
||||
text-shadow:
|
||||
0 0 4px rgba(0, 0, 0, 0.9),
|
||||
0 0 8px rgba(0, 0, 0, 0.7),
|
||||
0 1px 10px rgba(0, 0, 0, 1);
|
||||
|
||||
word-break: break-word;
|
||||
}
|
||||
.menu-header {
|
||||
@@ -270,3 +285,38 @@ h1 {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
|
||||
.school-meal-card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.school-meal-card-content .day {
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
flex-shrink: 0; /* Förhindrar att tryckas bort */
|
||||
}
|
||||
|
||||
.school-meal-card-content .meal {
|
||||
font-size: clamp(0.55rem, 1.0vw, 0.8rem);
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
word-break: break-word;
|
||||
overflow-y: auto;
|
||||
max-height: 100%; /* Begränsa höjden */
|
||||
}
|
||||
.school-meal-title .chevron {
|
||||
display: inline-block;
|
||||
transition: transform 0.3s ease;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.school-meal-title .chevron.rotated {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ==========================================================================
|
||||
HEADER – LEWEL DESIGN (utan meny)
|
||||
HEADER <EFBFBD> LEWEL DESIGN (utan meny)
|
||||
========================================================================== */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
@@ -106,7 +106,9 @@
|
||||
flex-direction: column;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.auth-dropdown a i {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.auth-dropdown a {
|
||||
padding: 8px 12px;
|
||||
color: #1F2C3C;
|
||||
@@ -128,7 +130,7 @@
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
LAYOUT – OMBYGGD STRUKTUR
|
||||
LAYOUT <EFBFBD> OMBYGGD STRUKTUR
|
||||
========================================================================== */
|
||||
body {
|
||||
background-color: #1F2C3C;
|
||||
@@ -174,7 +176,7 @@ body {
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
NAVIGATIONSLISTA – KOMPAKT STIL
|
||||
NAVIGATIONSLISTA <EFBFBD> KOMPAKT STIL
|
||||
========================================================================== */
|
||||
.nav-list {
|
||||
list-style: none;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user