Add dto and services

This commit is contained in:
2025-04-10 01:27:46 +02:00
parent 3537465588
commit 69a3570a60
23 changed files with 283 additions and 10 deletions

View File

@@ -0,0 +1,17 @@
using GameIdeas.Shared.Dto;
using GameIdeas.WebAPI.Services;
using Microsoft.AspNetCore.Mvc;
namespace GameIdeas.WebAPI.Controllers;
[ApiController]
[Route("api/[controller]")]
public class GameController(GameService gameService) : Controller
{
[HttpGet("Search")]
public async Task<IEnumerable<GameDto>> FetchGames([FromQuery] GameFilterDto filter)
{
return await gameService.SearchGames(filter);
}
}

View File

@@ -11,6 +11,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.4">

View File

@@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace GameIdeas.WebAPI.Migrations
{
[DbContext(typeof(GameIdeasContext))]
[Migration("20250409210640_InitialCreate")]
[Migration("20250409225125_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
@@ -176,7 +176,7 @@ namespace GameIdeas.WebAPI.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Libelle")
b.Property<string>("Label")
.IsRequired()
.HasColumnType("text");

View File

@@ -31,7 +31,7 @@ namespace GameIdeas.WebAPI.Migrations
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Libelle = table.Column<string>(type: "text", nullable: false)
Label = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{

View File

@@ -173,7 +173,7 @@ namespace GameIdeas.WebAPI.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Libelle")
b.Property<string>("Label")
.IsRequired()
.HasColumnType("text");

View File

@@ -0,0 +1,36 @@
using AutoMapper;
using GameIdeas.Shared.Dto;
using GameIdeas.Shared.Model;
namespace GameIdeas.WebAPI.Profiles;
public class CategoryProfile : Profile
{
public CategoryProfile()
{
CreateMap<Platform, PlatformDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Label, o => o.MapFrom(s => s.Label))
.ReverseMap();
CreateMap<Property, PropertyDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Label, o => o.MapFrom(s => s.Label))
.ReverseMap();
CreateMap<Tag, TagDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Label, o => o.MapFrom(s => s.Label))
.ReverseMap();
CreateMap<Developer, DeveloperDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Name, o => o.MapFrom(s => s.Name))
.ReverseMap();
CreateMap<Publisher, PublisherDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Name, o => o.MapFrom(s => s.Name))
.ReverseMap();
}
}

View File

@@ -0,0 +1,31 @@
using AutoMapper;
using GameIdeas.Shared.Dto;
using GameIdeas.Shared.Model;
namespace GameIdeas.WebAPI.Profiles;
public class GameProfile : Profile
{
public GameProfile()
{
CreateMap<Game, GameDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Title, o => o.MapFrom(s => s.Title))
.ForMember(d => d.ReleaseDate, o => o.MapFrom(s => s.ReleaseDate))
.ForMember(d => d.CreationDate, o => o.MapFrom(s => s.CreationDate))
.ForPath(d => d.CreationUser!.Id, o => o.MapFrom(s => s.CreationUserId))
.ForMember(d => d.CreationUser, o => o.MapFrom(s => s.CreationUser))
.ForMember(d => d.ModificationDate, o => o.MapFrom(s => s.ModificationDate))
.ForPath(d => d.ModificationUser!.Id, o => o.MapFrom(s => s.ModificationUserId))
.ForMember(d => d.ModificationUser, o => o.MapFrom(s => s.ModificationUser))
.ForMember(d => d.StorageSpace, o => o.MapFrom(s => s.StorageSpace))
.ForMember(d => d.Description, o => o.MapFrom(s => s.Description))
.ForMember(d => d.Interest, o => o.MapFrom(s => s.Interest))
.ForMember(d => d.Platforms, o => o.MapFrom(s => s.GamePlatforms.Select(p => new PlatformDto() { Id = p.Platform.Id, Label = p.Platform.Label, Url = p.Url })))
.ForMember(d => d.Properties, o => o.MapFrom(s => s.GameProperties.Select(p => p.Property)))
.ForMember(d => d.Tags, o => o.MapFrom(s => s.GameTags.Select(t => t.Tag)))
.ForMember(d => d.Publishers, o => o.MapFrom(s => s.GamePublishers.Select(p => p.Publisher)))
.ForMember(d => d.Developers, o => o.MapFrom(s => s.GameDevelopers.Select(gd => gd.Developer)))
.ReverseMap();
}
}

View File

@@ -0,0 +1,22 @@
using AutoMapper;
using GameIdeas.Shared.Dto;
using GameIdeas.Shared.Enum;
using GameIdeas.Shared.Model;
namespace GameIdeas.WebAPI.Profiles;
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<User, UserDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Username, o => o.MapFrom(s => s.Username))
.ForMember(d => d.Password, o => o.MapFrom(s => s.Password))
.ForMember(d => d.Role, o => o.MapFrom(s => s.Role))
.ForMember(d => d.CreationGames, o => o.MapFrom(s => s.CreationGames))
.ForMember(d => d.ModificationGames, o => o.MapFrom(s => s.ModificationGames))
.ReverseMap();
}
}

View File

@@ -1,5 +1,7 @@
using GameIdeas.Resources;
using GameIdeas.WebAPI.Context;
using GameIdeas.WebAPI.Profiles;
using GameIdeas.WebAPI.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Data;
@@ -32,6 +34,12 @@ services.AddDbContext<GameIdeasContext>(dbContextOptions);
services.AddSingleton<TranslationService>();
services.AddSingleton<Translations>();
services.AddScoped<GameService>();
services.AddAutoMapper(typeof(GameProfile).Assembly);
services.AddAutoMapper(typeof(UserProfile).Assembly);
services.AddAutoMapper(typeof(CategoryProfile).Assembly);
services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
services.AddOpenApi();

View File

@@ -0,0 +1,60 @@
using AutoMapper;
using GameIdeas.Shared.Dto;
using GameIdeas.Shared.Enum;
using GameIdeas.Shared.Model;
using GameIdeas.WebAPI.Context;
using Microsoft.EntityFrameworkCore;
namespace GameIdeas.WebAPI.Services;
public class GameService(GameIdeasContext context, IMapper mapper)
{
public async Task<IEnumerable<GameDto>> SearchGames(GameFilterDto filter)
{
var query = context.Games
.Include(g => g.CreationUser)
.Include(g => g.ModificationUser)
.Include(g => g.GamePlatforms).ThenInclude(p => p.Platform)
.Include(g => g.GameProperties).ThenInclude(p => p.Property)
.Include(g => g.GameTags).ThenInclude(p => p.Tag)
.Include(g => g.GamePublishers).ThenInclude(p => p.Publisher)
.Include(g => g.GameDevelopers).ThenInclude(p => p.Developer)
.AsQueryable();
ApplyFilter(ref query);
var games = await query
.OrderBy(g => g.Title)
.Skip(filter.CurrentPage * filter.NumberPerPage)
.Take(filter.NumberPerPage)
.ToListAsync();
List<Game> gamesTest = [ new ()
{
Id = 1,
Title = "Test",
CreationDate = DateTime.Today - TimeSpan.FromHours(-12),
CreationUser = new User() { Id = 1, Username = "Test", Role = (int)Role.Administrator },
CreationUserId = 1,
Description = "Test",
GameDevelopers = [ new() { Developer = new Developer() { Id = 1, Name = "THQNordic"} }],
GamePlatforms = [ new() { Platform = new Platform() { Id = 1, Label = "Steam" }, Url = "steam.com?app=55554131" }],
GameProperties = [ new () { Property = new Property() { Id = 1, Label = "Coop"} }],
GamePublishers = [ new () { Publisher = new Publisher() { Id = 1, Name = "Take-Two"} }],
GameTags = [ new () { Tag = new Tag() { Id = 1, Label = "RPG" } }],
Interest = 5,
ModificationDate = DateTime.Today ,
ModificationUser = new User() { Id = 2, Username = "Test 2", Role = (int)Role.Member },
ModificationUserId = 2,
ReleaseDate = new DateTime(2025, 2, 1),
StorageSpace = 40
} ];
return mapper.Map<IEnumerable<GameDto>>(gamesTest);
}
private void ApplyFilter(ref IQueryable<Game> query)
{
}
}

View File

@@ -0,0 +1,5 @@
namespace GameIdeas.WebAPI.Services;
public class UserService
{
}