Compare commits
1 Commits
4674529b91
..
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b357e1e13 |
@@ -9,6 +9,8 @@
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
.idea/
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
@@ -479,3 +481,5 @@ FodyWeavers.xsd
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
|
||||
# Docker
|
||||
.env
|
||||
@@ -1,40 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using WyvernInventory.Core.Interfaces.Services;
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.API.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class InventoryController(IDataObjectService<GenericInventoryItem> genericItemService)
|
||||
: ControllerBase
|
||||
{
|
||||
private readonly IDataObjectService<GenericInventoryItem> _genericItemService = genericItemService;
|
||||
|
||||
[HttpPost]
|
||||
public List<GenericInventoryItem> Get([FromBody] List<GenericInventoryItem> items)
|
||||
{
|
||||
return _genericItemService.GetAsync(_ => _).Result;
|
||||
}
|
||||
|
||||
[HttpPost("upsert")]
|
||||
public IResult Post([FromBody] List<GenericInventoryItem> items)
|
||||
{
|
||||
(int, int) results = _genericItemService.UpsertAsync(items).Result;
|
||||
|
||||
if (results.Item1 > 0 || results.Item2 > 0)
|
||||
{
|
||||
return Results.StatusCode(201);
|
||||
}
|
||||
|
||||
return Results.Ok();
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IResult Delete([FromRoute] int id)
|
||||
{
|
||||
_genericItemService.DeleteAsync(new() { new() { Id = id } }).Wait();
|
||||
|
||||
return Results.Ok();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace WyvernInventory.API.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
private static readonly string[] Summaries =
|
||||
[
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
];
|
||||
|
||||
[HttpGet(Name = "GetWeatherForecast")]
|
||||
public IEnumerable<WeatherForecast> GetBwah()
|
||||
{
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
[HttpGet("bwah", Name = "GetWeatherForecastBwah")]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
return Enumerable.Range(1, 2).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog.Events;
|
||||
using WyvernInventory.Core.Interfaces.Services;
|
||||
using WyvernInventory.Core.Models;
|
||||
using ILogger = Serilog.ILogger;
|
||||
|
||||
namespace WyvernInventory.API.Controllers.api.v1;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class InventoryItemController(IInventoryItemService inventoryItemService, ILogger logger) : ControllerBase
|
||||
{
|
||||
private readonly IInventoryItemService _inventoryItemService = inventoryItemService;
|
||||
private ILogger _logger = logger;
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult<List<InventoryItemDto>> Get([FromBody] List<InventoryItemRequest> items)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _inventoryItemService.GetAsync(items).Result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Write(LogEventLevel.Error, e, "An error occured");
|
||||
return StatusCode(500, "Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("upsert")]
|
||||
public ActionResult Post([FromBody] List<InventoryItemRequest> items)
|
||||
{
|
||||
try
|
||||
{
|
||||
(int, int) results = _inventoryItemService.UpsertAsync(items).Result;
|
||||
|
||||
if (results.Item1 > 0 || results.Item2 > 0)
|
||||
{
|
||||
return Ok(new { Created = results.Item1, Updated = results.Item2 });
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Write(LogEventLevel.Error, e, "An error occured");
|
||||
return StatusCode(500, "Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public ActionResult Delete([FromRoute] int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
int results = _inventoryItemService.DeleteAsync([new() { Id = id }]).Result;
|
||||
|
||||
return Ok(results);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Write(LogEventLevel.Error, e, "An error occured");
|
||||
return StatusCode(500, "Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using Microsoft.AspNetCore.HttpLogging;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog.Events;
|
||||
using WyvernInventory.Core.Interfaces.Services;
|
||||
using WyvernInventory.Core.Models;
|
||||
using ILogger = Serilog.ILogger;
|
||||
|
||||
namespace WyvernInventory.API.Controllers.api.v1;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class InventoryTypeController(IDataObjectService<InventoryType, InventoryTypeDto> inventoryTypeService, ILogger logger) : ControllerBase
|
||||
{
|
||||
private readonly IDataObjectService<InventoryType, InventoryTypeDto> _inventoryTypeService = inventoryTypeService;
|
||||
private ILogger _logger = logger;
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult<List<InventoryTypeDto>> Get([FromBody] List<InventoryType> items)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _inventoryTypeService.GetAsync(items).Result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Write(LogEventLevel.Error, e, "An error occured");
|
||||
return StatusCode(500, "Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("upsert")]
|
||||
public IActionResult Post([FromBody] List<InventoryType> items)
|
||||
{
|
||||
try
|
||||
{
|
||||
(int, int) results = _inventoryTypeService.UpsertAsync(items).Result;
|
||||
|
||||
if (results.Item1 > 0 || results.Item2 > 0)
|
||||
{
|
||||
return Ok(new { Created = results.Item1, Updated = results.Item2 });
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Write(LogEventLevel.Error, e, "An error occured");
|
||||
return StatusCode(500, "Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete([FromRoute] int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
int results = _inventoryTypeService.DeleteAsync([new() { Id = id }]).Result;
|
||||
|
||||
return Ok(results);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Write(LogEventLevel.Error, e, "An error occured");
|
||||
return StatusCode(500, "Internal server error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,83 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using WyvernInventory.Core.Interfaces.Repos;
|
||||
using WyvernInventory.Core.Interfaces.Services;
|
||||
using WyvernInventory.Core.Models;
|
||||
using WyvernInventory.Infrastructure.Data;
|
||||
using WyvernInventory.Infrastructure.Repos;
|
||||
using WyvernInventory.Infrastructure.Services;
|
||||
using ILogger = Serilog.ILogger;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddScoped<IDataObjectService<InventoryType, InventoryTypeDto>, InventoryTypeService>();
|
||||
builder.Services.AddScoped<IDbObjectRepo<InventoryType, InventoryTypeDto>, InventoryTypeRepo>();
|
||||
builder.Services.AddScoped<IInventoryItemService, InventoryItemService>();
|
||||
builder.Services.AddScoped<IInventoryItemRepo, InventoryItemRepo>();
|
||||
|
||||
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||
builder.Services.AddOpenApi();
|
||||
builder.Services.AddSingleton<IDbObjectRepo<GenericInventoryItem>, GenericInventoryItemRepo>();
|
||||
builder.Services.AddSingleton<IDataObjectService<GenericInventoryItem>, GenericInventoryItemService>();
|
||||
builder.Services.AddSwaggerGen();
|
||||
builder.Host.UseSerilog((context, services, configuration) =>
|
||||
configuration
|
||||
.ReadFrom.Configuration(context.Configuration)
|
||||
.ReadFrom.Services(services)
|
||||
);
|
||||
|
||||
if (builder.Configuration["Database:ConnectionString"].IsNullOrEmpty())
|
||||
{
|
||||
ILogger logger = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger();
|
||||
|
||||
logger.Fatal("Database environment variables not found");
|
||||
|
||||
Environment.Exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Services.AddDbContext<DBContext>(options =>
|
||||
{
|
||||
options
|
||||
.UseSqlServer(builder.Configuration["Database:ConnectionString"]).EnableSensitiveDataLogging();
|
||||
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
options
|
||||
.EnableSensitiveDataLogging()
|
||||
.EnableDetailedErrors()
|
||||
.LogTo(msg => { Debug.WriteLine(msg); }, [DbLoggerCategory.Database.Command.Name], LogLevel.Information);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
DBContext db = scope.ServiceProvider.GetRequiredService<DBContext>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger>();
|
||||
|
||||
if (db.Database.GetPendingMigrations().Any())
|
||||
{
|
||||
await db.Database.MigrateAsync().ConfigureAwait(false);
|
||||
|
||||
logger.Write(LogEventLevel.Information, "Migrated database");
|
||||
}
|
||||
}
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.MapOpenApi();
|
||||
}
|
||||
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:7048;http://localhost:5244",
|
||||
"applicationUrl": "https://0.0.0.0:7048;http://0.0.0.0:5244",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace WyvernInventory.API;
|
||||
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateOnly Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
@@ -9,6 +9,17 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.6"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog" Version="4.3.1" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,21 +5,42 @@ Content-Type: application/json
|
||||
|
||||
[
|
||||
{
|
||||
"name": "RTX 4070"
|
||||
"name": "RTX 4070 Ti Super"
|
||||
}
|
||||
]
|
||||
###
|
||||
|
||||
POST http://localhost:5244/inventory/upsert
|
||||
POST http://localhost:5244/api/v1/InventoryType
|
||||
Content-Type: application/json
|
||||
|
||||
[
|
||||
]
|
||||
###
|
||||
|
||||
POST http://localhost:5244/api/v1/inventorytype/upsert
|
||||
Content-Type: application/json
|
||||
|
||||
[
|
||||
{
|
||||
"name": "RTX 4070 Ti Super",
|
||||
"description": "Desktop GPU"
|
||||
},
|
||||
{
|
||||
"name": "Ryzen 9 7950X3D",
|
||||
"description": "Desktop CPU 16c/32t"
|
||||
"name": "GPU",
|
||||
"attributedefinitions": [
|
||||
{
|
||||
"name": "Brand",
|
||||
"dataType": 0
|
||||
},
|
||||
{
|
||||
"name": "VRAM_GB",
|
||||
"dataType": 1
|
||||
},
|
||||
{
|
||||
"name": "Chipset",
|
||||
"dataType": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
###
|
||||
|
||||
DELETE http://localhost:5244/api/v1/InventoryType/6
|
||||
|
||||
###
|
||||
@@ -5,5 +5,33 @@
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
"AllowedHosts": "*",
|
||||
"Serilog": {
|
||||
"Using": [
|
||||
"Serilog.Sinks.Console"
|
||||
],
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information",
|
||||
"System": "Warning",
|
||||
"Microsoft.EntityFrameworkCore": "Warning"
|
||||
}
|
||||
},
|
||||
"Enrich": [
|
||||
"FromLogContext"
|
||||
],
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Console",
|
||||
"Args": {
|
||||
"outputTemplate": "[{Timestamp:MM-dd-yyyy HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Database": {
|
||||
"ConnectionString": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
namespace WyvernInventory.Core.Interfaces.Repos;
|
||||
|
||||
public interface IDbObjectRepo<T>
|
||||
public interface IDbObjectRepo<T, TDto>
|
||||
{
|
||||
public Task<List<T>> GetAsync(Predicate<T>? filter = null);
|
||||
public Task<List<TDto>> GetAsync(List<T>? filterList = null);
|
||||
public Task<(int created, int updated)> UpsertAsync(List<T> items);
|
||||
public Task DeleteAsync(List<T> items);
|
||||
public Task<int> DeleteAsync(List<T> items);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.Core.Interfaces.Repos;
|
||||
|
||||
public interface IInventoryItemRepo
|
||||
{
|
||||
public Task<List<InventoryItemDto>> GetAsync(List<InventoryItemRequest>? filterList = null);
|
||||
public Task<(int created, int updated)> UpsertAsync(List<InventoryItemRequest> items);
|
||||
public Task<int> DeleteAsync(List<InventoryItemRequest> items);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
namespace WyvernInventory.Core.Interfaces.Services;
|
||||
|
||||
public interface IDataObjectService<T>
|
||||
public interface IDataObjectService<T, TDto>
|
||||
{
|
||||
public Task<List<T>> GetAsync(Predicate<T>? filter = null);
|
||||
public Task<List<TDto>> GetAsync(List<T>? filter = null);
|
||||
public Task<(int created, int updated)> UpsertAsync(List<T> items);
|
||||
public Task DeleteAsync(List<T> items);
|
||||
public Task<int> DeleteAsync(List<T> items);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.Core.Interfaces.Services;
|
||||
|
||||
public interface IInventoryItemService
|
||||
{
|
||||
public Task<List<InventoryItemDto>> GetAsync(List<InventoryItemRequest>? filter = null);
|
||||
public Task<(int created, int updated)> UpsertAsync(List<InventoryItemRequest> items);
|
||||
public Task<int> DeleteAsync(List<InventoryItemRequest> items);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record Computer() : GenericInventoryItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record Cpu() : GenericInventoryItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public class Enums
|
||||
{
|
||||
public enum DataType
|
||||
{
|
||||
String,
|
||||
Int,
|
||||
Decimal,
|
||||
Bool,
|
||||
DateTime
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record Gpu() : GenericInventoryItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryAttributeDefinition
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public int? TypeId { get; set; }
|
||||
public InventoryType? Type { get; set; } = null!;
|
||||
public string? Name { get; set; } = "";
|
||||
public Enums.DataType? DataType { get; set; }
|
||||
}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record GenericInventoryItem()
|
||||
public record InventoryAttributeDefinitionDto
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public Enums.DataType? DataType { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryAttributeValue
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public int? ItemId { get; set; }
|
||||
public InventoryItem? Item { get; set; } = null!;
|
||||
public int? AttributeDefinitionId { get; set; }
|
||||
public InventoryAttributeDefinition? AttributeDefinition { get; set; } = null!;
|
||||
|
||||
public string? StringValue { get; set; }
|
||||
public int? IntValue { get; set; }
|
||||
public decimal? DecimalValue { get; set; }
|
||||
public bool? BoolValue { get; set; }
|
||||
public DateTime? DateTimeValue { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryAttributeValueDto
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public int? ItemId { get; set; }
|
||||
public InventoryItemDto? Item { get; set; } = null!;
|
||||
public int? AttributeDefinitionId { get; set; }
|
||||
public InventoryAttributeDefinitionDto? AttributeDefinition { get; set; } = null!;
|
||||
|
||||
public string? StringValue { get; set; }
|
||||
public int? IntValue { get; set; }
|
||||
public decimal? DecimalValue { get; set; }
|
||||
public bool? BoolValue { get; set; }
|
||||
public DateTime? DateTimeValue { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryAttributeValueRequest
|
||||
{
|
||||
|
||||
public int? Id { get; set; }
|
||||
public int? ItemId { get; set; }
|
||||
public int? AttributeDefinitionId { get; set; }
|
||||
|
||||
public string? StringValue { get; set; }
|
||||
public int? IntValue { get; set; }
|
||||
public decimal? DecimalValue { get; set; }
|
||||
public bool? BoolValue { get; set; }
|
||||
public DateTime? DateTimeValue { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryItem
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; } = "";
|
||||
public int? TypeId { get; set; }
|
||||
public InventoryType? Type { get; set; } = null!;
|
||||
public List<InventoryAttributeValue>? AttributeValues { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryItemDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public InventoryTypeDto Type { get; set; }
|
||||
public List<InventoryAttributeValueDto> AttributeValues { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryItemRequest
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; } = "";
|
||||
public int? TypeId { get; set; }
|
||||
public List<InventoryAttributeValueRequest>? AttributeValues { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryType
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public List<InventoryAttributeDefinition> AttributeDefinitions { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record InventoryTypeDto
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public List<InventoryAttributeDefinitionDto>? AttributeDefinitions { get; set; }
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record Router() : GenericInventoryItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record StorageDrive() : GenericInventoryItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace WyvernInventory.Core.Models;
|
||||
|
||||
public record Switch() : GenericInventoryItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -8,4 +8,17 @@
|
||||
<RootNamespace>WyvernInventory.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.7" />
|
||||
<PackageReference Include="Serilog" Version="4.3.1" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Data;
|
||||
|
||||
public class DBContext : DbContext
|
||||
{
|
||||
|
||||
public DBContext(DbContextOptions<DBContext> options) : base(options) {}
|
||||
|
||||
public DbSet<InventoryItem> InventoryItems => Set<InventoryItem>();
|
||||
public DbSet<InventoryAttributeDefinition> InventoryAttributeDefinitions => Set<InventoryAttributeDefinition>();
|
||||
public DbSet<InventoryAttributeValue> InventoryAttributeValues => Set<InventoryAttributeValue>();
|
||||
public DbSet<InventoryType> InventoryTypes => Set<InventoryType>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<InventoryItem>()
|
||||
.HasOne(_ => _.Type)
|
||||
.WithMany()
|
||||
.HasForeignKey(_ => _.TypeId);
|
||||
|
||||
modelBuilder.Entity<InventoryAttributeValue>()
|
||||
.HasOne(_ => _.Item)
|
||||
.WithMany(_ => _.AttributeValues)
|
||||
.HasForeignKey(_ => _.ItemId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<InventoryAttributeValue>()
|
||||
.HasOne(_ => _.AttributeDefinition)
|
||||
.WithMany()
|
||||
.HasForeignKey(_ => _.AttributeDefinitionId)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
|
||||
modelBuilder.Entity<InventoryAttributeDefinition>()
|
||||
.HasOne(_ => _.Type)
|
||||
.WithMany(_ => _.AttributeDefinitions)
|
||||
.HasForeignKey(_ => _.TypeId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<InventoryAttributeValue>()
|
||||
.HasIndex(_ => new { _.ItemId, _.AttributeDefinitionId})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using WyvernInventory.Infrastructure.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(DBContext))]
|
||||
[Migration("20260501023055_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "10.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeDefinition", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("DataType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int?>("TypeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TypeId");
|
||||
|
||||
b.ToTable("InventoryAttributeDefinitions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeValue", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AttributeDefinitionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool?>("BoolValue")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTime?>("DateTimeValue")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<decimal?>("DecimalValue")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<int?>("IntValue")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("StringValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AttributeDefinitionId");
|
||||
|
||||
b.HasIndex("ItemId", "AttributeDefinitionId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("InventoryAttributeValues");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("TypeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TypeId");
|
||||
|
||||
b.ToTable("InventoryItems");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryType", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("InventoryTypes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeDefinition", b =>
|
||||
{
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryType", "Type")
|
||||
.WithMany("AttributeDefinitions")
|
||||
.HasForeignKey("TypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("Type");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeValue", b =>
|
||||
{
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryAttributeDefinition", "AttributeDefinition")
|
||||
.WithMany()
|
||||
.HasForeignKey("AttributeDefinitionId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryItem", "Item")
|
||||
.WithMany("AttributeValues")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("AttributeDefinition");
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryItem", b =>
|
||||
{
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryType", "Type")
|
||||
.WithMany()
|
||||
.HasForeignKey("TypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Type");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryItem", b =>
|
||||
{
|
||||
b.Navigation("AttributeValues");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryType", b =>
|
||||
{
|
||||
b.Navigation("AttributeDefinitions");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InventoryTypes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InventoryTypes", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InventoryAttributeDefinitions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
TypeId = table.Column<int>(type: "int", nullable: true),
|
||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
DataType = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InventoryAttributeDefinitions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InventoryAttributeDefinitions_InventoryTypes_TypeId",
|
||||
column: x => x.TypeId,
|
||||
principalTable: "InventoryTypes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InventoryItems",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
TypeId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InventoryItems", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InventoryItems_InventoryTypes_TypeId",
|
||||
column: x => x.TypeId,
|
||||
principalTable: "InventoryTypes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InventoryAttributeValues",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
ItemId = table.Column<int>(type: "int", nullable: false),
|
||||
AttributeDefinitionId = table.Column<int>(type: "int", nullable: false),
|
||||
StringValue = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
IntValue = table.Column<int>(type: "int", nullable: true),
|
||||
DecimalValue = table.Column<decimal>(type: "decimal(18,2)", nullable: true),
|
||||
BoolValue = table.Column<bool>(type: "bit", nullable: true),
|
||||
DateTimeValue = table.Column<DateTime>(type: "datetime2", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InventoryAttributeValues", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InventoryAttributeValues_InventoryAttributeDefinitions_AttributeDefinitionId",
|
||||
column: x => x.AttributeDefinitionId,
|
||||
principalTable: "InventoryAttributeDefinitions",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_InventoryAttributeValues_InventoryItems_ItemId",
|
||||
column: x => x.ItemId,
|
||||
principalTable: "InventoryItems",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InventoryAttributeDefinitions_TypeId",
|
||||
table: "InventoryAttributeDefinitions",
|
||||
column: "TypeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InventoryAttributeValues_AttributeDefinitionId",
|
||||
table: "InventoryAttributeValues",
|
||||
column: "AttributeDefinitionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InventoryAttributeValues_ItemId_AttributeDefinitionId",
|
||||
table: "InventoryAttributeValues",
|
||||
columns: new[] { "ItemId", "AttributeDefinitionId" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InventoryItems_TypeId",
|
||||
table: "InventoryItems",
|
||||
column: "TypeId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "InventoryAttributeValues");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "InventoryAttributeDefinitions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "InventoryItems");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "InventoryTypes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using WyvernInventory.Infrastructure.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(DBContext))]
|
||||
partial class DBContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "10.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeDefinition", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("DataType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int?>("TypeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TypeId");
|
||||
|
||||
b.ToTable("InventoryAttributeDefinitions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeValue", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AttributeDefinitionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool?>("BoolValue")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTime?>("DateTimeValue")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<decimal?>("DecimalValue")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<int?>("IntValue")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("StringValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AttributeDefinitionId");
|
||||
|
||||
b.HasIndex("ItemId", "AttributeDefinitionId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("InventoryAttributeValues");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<int>("TypeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TypeId");
|
||||
|
||||
b.ToTable("InventoryItems");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryType", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("InventoryTypes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeDefinition", b =>
|
||||
{
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryType", "Type")
|
||||
.WithMany("AttributeDefinitions")
|
||||
.HasForeignKey("TypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("Type");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryAttributeValue", b =>
|
||||
{
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryAttributeDefinition", "AttributeDefinition")
|
||||
.WithMany()
|
||||
.HasForeignKey("AttributeDefinitionId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryItem", "Item")
|
||||
.WithMany("AttributeValues")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("AttributeDefinition");
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryItem", b =>
|
||||
{
|
||||
b.HasOne("WyvernInventory.Core.Models.InventoryType", "Type")
|
||||
.WithMany()
|
||||
.HasForeignKey("TypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Type");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryItem", b =>
|
||||
{
|
||||
b.Navigation("AttributeValues");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("WyvernInventory.Core.Models.InventoryType", b =>
|
||||
{
|
||||
b.Navigation("AttributeDefinitions");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
using WyvernInventory.Core.Interfaces.Repos;
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Repos;
|
||||
|
||||
public class GenericInventoryItemRepo : IDbObjectRepo<GenericInventoryItem>
|
||||
{
|
||||
private List<GenericInventoryItem> _genericItemList = [];
|
||||
|
||||
public async Task<List<GenericInventoryItem>> GetAsync(Predicate<GenericInventoryItem>? filter = null)
|
||||
{
|
||||
List<GenericInventoryItem> result = [];
|
||||
|
||||
if (filter is null) return _genericItemList;
|
||||
|
||||
result.AddRange(_genericItemList.Where(item => filter(item)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<(int created, int updated)> UpsertAsync(List<GenericInventoryItem> items)
|
||||
{
|
||||
int created = 0;
|
||||
int updated = 0;
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.Id is not null && _genericItemList.Any(_ => _.Id == item.Id))
|
||||
{
|
||||
int index = _genericItemList.IndexOf(_genericItemList.Find(_ => _.Id == item.Id));
|
||||
_genericItemList[index] = item;
|
||||
|
||||
updated++;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Id = _genericItemList.Count;
|
||||
_genericItemList.Add(item);
|
||||
|
||||
created++;
|
||||
}
|
||||
}
|
||||
|
||||
return (created, updated);
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(List<GenericInventoryItem> items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
_genericItemList.Remove(_genericItemList.Find(_ => _.Id == item.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using WyvernInventory.Core.Interfaces.Repos;
|
||||
using WyvernInventory.Core.Models;
|
||||
using WyvernInventory.Infrastructure.Data;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Repos;
|
||||
|
||||
public class InventoryItemRepo(DBContext dbContext) : IInventoryItemRepo
|
||||
{
|
||||
private DBContext _dbContext = dbContext;
|
||||
|
||||
public async Task<List<InventoryItemDto>> GetAsync(List<InventoryItemRequest>? filterList = null)
|
||||
{
|
||||
return _dbContext.InventoryItems
|
||||
.Include(_ => _.AttributeValues)
|
||||
.Include(_ => _.Type)
|
||||
.Select(_ => new InventoryItemDto
|
||||
{
|
||||
Id = (int)_.Id!,
|
||||
Name = _.Name,
|
||||
AttributeValues = _.AttributeValues.Select(x => new InventoryAttributeValueDto
|
||||
{
|
||||
Id = x.Id,
|
||||
AttributeDefinitionId = (int)x.AttributeDefinitionId!,
|
||||
AttributeDefinition = new InventoryAttributeDefinitionDto()
|
||||
{
|
||||
Id = x.AttributeDefinitionId,
|
||||
Name = x.AttributeDefinition.Name,
|
||||
DataType = x.AttributeDefinition.DataType
|
||||
},
|
||||
StringValue = x.StringValue,
|
||||
IntValue = x.IntValue,
|
||||
DecimalValue = x.DecimalValue,
|
||||
BoolValue = x.BoolValue,
|
||||
DateTimeValue = x.DateTimeValue
|
||||
}).ToList(),
|
||||
Type = new InventoryTypeDto()
|
||||
{
|
||||
Id = _.TypeId,
|
||||
Name = _.Type.Name,
|
||||
}
|
||||
})
|
||||
.ToList<InventoryItemDto>();
|
||||
}
|
||||
|
||||
public async Task<(int created, int updated)> UpsertAsync(List<InventoryItemRequest> items)
|
||||
{
|
||||
var created = 0;
|
||||
var updated = 0;
|
||||
|
||||
var itemsToCreate = items
|
||||
.Where(_ => _.Id is null or 0)
|
||||
.Select(_ => new InventoryItem
|
||||
{
|
||||
Name = _.Name,
|
||||
AttributeValues = _.AttributeValues?.Select(x => new InventoryAttributeValue
|
||||
{
|
||||
Id = x.Id,
|
||||
AttributeDefinitionId = x.AttributeDefinitionId,
|
||||
BoolValue = x.BoolValue,
|
||||
DateTimeValue = x.DateTimeValue,
|
||||
DecimalValue = x.DecimalValue,
|
||||
IntValue = x.IntValue,
|
||||
StringValue = x.StringValue
|
||||
}).ToList(),
|
||||
TypeId = _.TypeId
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var itemsToUpdate = items
|
||||
.Where(_ => _.Id is not null and not 0)
|
||||
.Select(_ => new InventoryItem
|
||||
{
|
||||
Id = _.Id,
|
||||
Name = _.Name,
|
||||
AttributeValues = _.AttributeValues?.Select(x => new InventoryAttributeValue
|
||||
{
|
||||
Id = x.Id,
|
||||
AttributeDefinitionId = x.AttributeDefinitionId,
|
||||
BoolValue = x.BoolValue,
|
||||
DateTimeValue = x.DateTimeValue,
|
||||
DecimalValue = x.DecimalValue,
|
||||
IntValue = x.IntValue,
|
||||
StringValue = x.StringValue
|
||||
}).ToList(),
|
||||
TypeId = _.TypeId
|
||||
})
|
||||
.ToList();
|
||||
|
||||
if (itemsToCreate.Count > 0)
|
||||
{
|
||||
_dbContext.InventoryItems.AddRange(itemsToCreate);
|
||||
created = itemsToCreate.Count;
|
||||
}
|
||||
|
||||
if (itemsToUpdate.Count > 0)
|
||||
{
|
||||
List<int> idList = itemsToUpdate.Select(_ =>
|
||||
{
|
||||
if (_.Id != null) return (int)_.Id;
|
||||
throw new NullReferenceException();
|
||||
}).ToList<int>();
|
||||
|
||||
var existingItems = _dbContext.InventoryItems.ToList()
|
||||
.Where(_ => idList.Contains((int)_.Id!))
|
||||
.ToDictionary(_ => (int)_.Id!);
|
||||
|
||||
foreach (var incoming in itemsToUpdate)
|
||||
{
|
||||
if (!existingItems.TryGetValue(incoming.Id!.Value, out var existing))
|
||||
continue;
|
||||
|
||||
existing.Name = incoming.Name;
|
||||
existing.AttributeValues = incoming.AttributeValues;
|
||||
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return (created, updated);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteAsync(List<InventoryItemRequest> items)
|
||||
{
|
||||
var itemsToDelete = _dbContext.InventoryItems.Where(_ => items.Select(_ => _.Id).Contains(_.Id)).ToList();
|
||||
|
||||
_dbContext.InventoryItems.RemoveRange(itemsToDelete);
|
||||
|
||||
return await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using WyvernInventory.Core.Interfaces.Repos;
|
||||
using WyvernInventory.Core.Models;
|
||||
using WyvernInventory.Infrastructure.Data;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Repos;
|
||||
|
||||
public class InventoryTypeRepo(DBContext dbContext) : IDbObjectRepo<InventoryType, InventoryTypeDto>
|
||||
{
|
||||
private readonly DBContext _dbContext = dbContext;
|
||||
|
||||
public async Task<List<InventoryTypeDto>> GetAsync(List<InventoryType>? filterList = null)
|
||||
{
|
||||
return _dbContext.InventoryTypes
|
||||
.Include(_ => _.AttributeDefinitions)
|
||||
.Select(_ => new InventoryTypeDto
|
||||
{
|
||||
Id = _.Id,
|
||||
Name = _.Name,
|
||||
AttributeDefinitions = _.AttributeDefinitions.Select(x => new InventoryAttributeDefinitionDto
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
DataType = x.DataType
|
||||
}).ToList()
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async Task<(int created, int updated)> UpsertAsync(List<InventoryType> items)
|
||||
{
|
||||
var created = 0;
|
||||
var updated = 0;
|
||||
|
||||
var itemsToCreate = items
|
||||
.Where(_ => _.Id is null or 0)
|
||||
.ToList();
|
||||
|
||||
var itemsToUpdate = items
|
||||
.Where(_ => _.Id is not null and not 0)
|
||||
.ToList();
|
||||
|
||||
if (itemsToCreate.Count > 0)
|
||||
{
|
||||
_dbContext.InventoryTypes.AddRange(itemsToCreate);
|
||||
created = itemsToCreate.Count;
|
||||
}
|
||||
|
||||
if (itemsToUpdate.Count > 0)
|
||||
{
|
||||
List<int> idList = itemsToUpdate.Select(_ =>
|
||||
{
|
||||
if (_.Id != null) return (int)_.Id;
|
||||
throw new NullReferenceException();
|
||||
}).ToList<int>();
|
||||
|
||||
var existingItems = _dbContext.InventoryTypes.ToList()
|
||||
.Where(_ => idList.Contains((int)_.Id!))
|
||||
.ToDictionary(_ => (int)_.Id!);
|
||||
|
||||
foreach (var incoming in itemsToUpdate)
|
||||
{
|
||||
if (!existingItems.TryGetValue(incoming.Id!.Value, out var existing))
|
||||
continue;
|
||||
|
||||
existing.Name = incoming.Name;
|
||||
existing.AttributeDefinitions = incoming.AttributeDefinitions;
|
||||
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return (created, updated);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteAsync(List<InventoryType> items)
|
||||
{
|
||||
var itemsToDelete = _dbContext.InventoryTypes.Where(_ => items.Select(_ => _.Id).Contains(_.Id)).ToList();
|
||||
|
||||
_dbContext.InventoryTypes.RemoveRange(itemsToDelete);
|
||||
|
||||
return await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using WyvernInventory.Core.Interfaces.Repos;
|
||||
using WyvernInventory.Core.Interfaces.Services;
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Services;
|
||||
|
||||
public class GenericInventoryItemService(IDbObjectRepo<GenericInventoryItem> dbRepo)
|
||||
: IDataObjectService<GenericInventoryItem>
|
||||
{
|
||||
private readonly IDbObjectRepo<GenericInventoryItem> _dbRepo = dbRepo;
|
||||
|
||||
public async Task<List<GenericInventoryItem>> GetAsync(Predicate<GenericInventoryItem>? filter = null) => await _dbRepo.GetAsync(filter);
|
||||
|
||||
public async Task<(int created, int updated)> UpsertAsync(List<GenericInventoryItem> items) => await _dbRepo.UpsertAsync(items);
|
||||
|
||||
public async Task DeleteAsync(List<GenericInventoryItem> items) => await _dbRepo.DeleteAsync(items);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using WyvernInventory.Core.Interfaces.Repos;
|
||||
using WyvernInventory.Core.Interfaces.Services;
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Services;
|
||||
|
||||
public class InventoryItemService(IInventoryItemRepo repo) : IInventoryItemService
|
||||
{
|
||||
private IInventoryItemRepo _repo = repo;
|
||||
|
||||
public async Task<List<InventoryItemDto>> GetAsync(List<InventoryItemRequest>? filter = null) => await _repo.GetAsync(filter);
|
||||
|
||||
public async Task<(int created, int updated)> UpsertAsync(List<InventoryItemRequest> items) => await _repo.UpsertAsync(items);
|
||||
|
||||
public async Task<int> DeleteAsync(List<InventoryItemRequest> items) => await _repo.DeleteAsync(items);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using WyvernInventory.Core.Interfaces.Repos;
|
||||
using WyvernInventory.Core.Interfaces.Services;
|
||||
using WyvernInventory.Core.Models;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Services;
|
||||
|
||||
public class InventoryTypeService(IDbObjectRepo<InventoryType, InventoryTypeDto> repo) : IDataObjectService<InventoryType, InventoryTypeDto>
|
||||
{
|
||||
private IDbObjectRepo<InventoryType, InventoryTypeDto> _repo = repo;
|
||||
|
||||
public async Task<List<InventoryTypeDto>> GetAsync(List<InventoryType>? filter = null) => await _repo.GetAsync(filter);
|
||||
|
||||
public async Task<(int created, int updated)> UpsertAsync(List<InventoryType> items) => await _repo.UpsertAsync(items);
|
||||
|
||||
public async Task<int> DeleteAsync(List<InventoryType> items) => await _repo.DeleteAsync(items);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog.Core;
|
||||
using WyvernInventory.Infrastructure.Data;
|
||||
|
||||
namespace WyvernInventory.Infrastructure.Utils;
|
||||
|
||||
public static class DbUtils
|
||||
{
|
||||
public static bool CanConnectToDatabase(DBContext db, ILogger<Logger> logger)
|
||||
{
|
||||
if (db.Database.CanConnect())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.LogCritical("Unable to connect to DB");
|
||||
|
||||
Environment.Exit(1);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,12 @@
|
||||
<ProjectReference Include="..\WyvernInventory.Core\WyvernInventory.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -5,6 +5,7 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE4BF34F-D890-4DCD-BF09-5CAC9C7BD706}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
compose.yaml = compose.yaml
|
||||
.env = .env
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WyvernInventory.Core", "WyvernInventory.Core\WyvernInventory.Core.csproj", "{CE9A8DB9-0746-4653-BBB1-27AC278C79AE}"
|
||||
|
||||
+5
-1
@@ -4,4 +4,8 @@
|
||||
build:
|
||||
context: .
|
||||
dockerfile: WyvernInventory.API/Dockerfile
|
||||
|
||||
ports:
|
||||
- "5244:8080"
|
||||
environment:
|
||||
Database__ConnectionString: "Server=${DB_SERVER};Database=${DB_NAME};User Id=${DB_USER};Password=${DB_PASSWORD};TrustServerCertificate=True;"
|
||||
TZ: America/Chicago
|
||||
Reference in New Issue
Block a user