diff --git a/BeReadyBackend/DTO/Achievements/GetSuccessDto.cs b/BeReadyBackend/DTO/Achievements/GetSuccessDto.cs new file mode 100644 index 0000000..7bbb9f7 --- /dev/null +++ b/BeReadyBackend/DTO/Achievements/GetSuccessDto.cs @@ -0,0 +1,8 @@ +namespace BeReadyBackend.DTO.Achievements; + +public class GetSuccessDto +{ + public int Id { get; set; } + public string? Label { get; set; } + public string? Description { get; set; } +} \ No newline at end of file diff --git a/BeReadyBackend/DTO/Achievements/UnlockSuccessDto.cs b/BeReadyBackend/DTO/Achievements/UnlockSuccessDto.cs new file mode 100644 index 0000000..20e4d45 --- /dev/null +++ b/BeReadyBackend/DTO/Achievements/UnlockSuccessDto.cs @@ -0,0 +1,7 @@ +namespace BeReadyBackend.DTO.Achievements; + +public class UnlockAchievementDto +{ + public int AchievementId { get; set; } + public int UserId { get; set; } +} \ No newline at end of file diff --git a/BeReadyBackend/Endpoints/Achievements/GetAllAchievementsEndpoint.cs b/BeReadyBackend/Endpoints/Achievements/GetAllAchievementsEndpoint.cs new file mode 100644 index 0000000..6e93e66 --- /dev/null +++ b/BeReadyBackend/Endpoints/Achievements/GetAllAchievementsEndpoint.cs @@ -0,0 +1,19 @@ +using BeReadyBackend.DTO.Achievements; +using BeReadyBackend.Repositories; +using FastEndpoints; + +namespace BeReadyBackend.Endpoints.Achievements; + +public class GetAllAchievementsEndpoint(AchievementsRepository achievementsRepository) : EndpointWithoutRequest> +{ + public override void Configure() + { + Get("/Achievements/"); + AllowAnonymous(); + } + + public override async Task HandleAsync(CancellationToken ct) + { + await Send.OkAsync(await achievementsRepository.ProjectToListAsync(ct), ct); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Endpoints/Achievements/GetUserAchievementsEndpoint.cs b/BeReadyBackend/Endpoints/Achievements/GetUserAchievementsEndpoint.cs new file mode 100644 index 0000000..f667988 --- /dev/null +++ b/BeReadyBackend/Endpoints/Achievements/GetUserAchievementsEndpoint.cs @@ -0,0 +1,41 @@ +using BeReadyBackend.DTO.Achievements; +using BeReadyBackend.Models; +using BeReadyBackend.Repositories; +using BeReadyBackend.Specifications.Achievements; +using BeReadyBackend.Specifications.UserAchievements; +using BeReadyBackend.Specifications.Users; +using FastEndpoints; + +namespace BeReadyBackend.Endpoints.Achievements; + +public class UserAchievementsRequest +{ + public int UserId { get; set; } +} + +public class GetUserAchievementsEndpoint( + UsersRepository usersRepository, + UserAchievementsRepository userAchievementsRepository) + : Endpoint> +{ + public override void Configure() + { + Get("/Achievements/Users/{@UserId}/", x => new {x.UserId}); + AllowAnonymous(); + } + + public override async Task HandleAsync(UserAchievementsRequest req, CancellationToken ct) + { + User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(req.UserId), ct); + + if (user is null) + { + await Send.NotFoundAsync(ct); + return; + } + + List userAchievements = await userAchievementsRepository.ProjectToListAsync(new GetUserAchievementByUserIdSpec(req.UserId), ct); + + await Send.OkAsync(userAchievements, ct); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Endpoints/Achievements/UnlockAchievementEndpoint.cs b/BeReadyBackend/Endpoints/Achievements/UnlockAchievementEndpoint.cs new file mode 100644 index 0000000..b84bb4c --- /dev/null +++ b/BeReadyBackend/Endpoints/Achievements/UnlockAchievementEndpoint.cs @@ -0,0 +1,44 @@ +using BeReadyBackend.DTO.Achievements; +using BeReadyBackend.Models; +using BeReadyBackend.Repositories; +using BeReadyBackend.Specifications.Achievements; +using BeReadyBackend.Specifications.UserAchievements; +using BeReadyBackend.Specifications.Users; +using FastEndpoints; + +namespace BeReadyBackend.Endpoints.Achievements; + +public class UnlockAchievementEndpoint( + UserAchievementsRepository userAchievementsRepository, + AchievementsRepository achievementsRepository, + UsersRepository usersRepository, + AutoMapper.IMapper mapper) : Endpoint +{ + public override void Configure() + { + Post("/Achievements/{@AchievementId}/Users/{@UserId}/", x => new {x.AchievementId, x.UserId}); + AllowAnonymous(); + } + + public override async Task HandleAsync(UnlockAchievementDto req, CancellationToken ct) + { + User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(req.UserId), ct); + Achievement? achievement = await achievementsRepository.SingleOrDefaultAsync(new GetAchievementByIdSpec(req.AchievementId), ct); + + if (user is null || achievement is null) + { + await Send.NotFoundAsync(ct); + return; + } + + UserAchievement? userAchievement = await userAchievementsRepository.SingleOrDefaultAsync(new GetUserAchievementByIdSpec(req.UserId, req.AchievementId), ct); + if (userAchievement is not null) + { + await Send.StringAsync("Le succès est déjà attribué à cet utilisateur", 500, cancellation: ct); + return; + } + + await userAchievementsRepository.AddAsync(mapper.Map(req), ct); + await Send.OkAsync(ct); + } +} \ No newline at end of file diff --git a/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs b/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs index dd327db..ef0c5d1 100644 --- a/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs +++ b/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs @@ -1,4 +1,6 @@ using AutoMapper; +using BeReadyBackend.DTO.Achievements; +using BeReadyBackend.Models; namespace BeReadyBackend.MappingProfiles; @@ -6,6 +8,6 @@ public class DtoToEntityMappings : Profile { public DtoToEntityMappings() { - + CreateMap(); } } \ No newline at end of file diff --git a/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs b/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs index 66ab0da..56296cd 100644 --- a/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs +++ b/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs @@ -1,4 +1,6 @@ using AutoMapper; +using BeReadyBackend.DTO.Achievements; +using BeReadyBackend.Models; namespace BeReadyBackend.MappingProfiles; @@ -6,5 +8,11 @@ public class EntityToDtoMappings : Profile { public EntityToDtoMappings() { + CreateMap(); + + CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Achievement!.Id)) + .ForMember(dest => dest.Label, opt => opt.MapFrom(src => src.Achievement!.Label)) + .ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Achievement!.Description)); } } \ No newline at end of file diff --git a/BeReadyBackend/Specifications/Achievements/GetAchievementByIdSpec.cs b/BeReadyBackend/Specifications/Achievements/GetAchievementByIdSpec.cs new file mode 100644 index 0000000..0ebaf23 --- /dev/null +++ b/BeReadyBackend/Specifications/Achievements/GetAchievementByIdSpec.cs @@ -0,0 +1,13 @@ +using Ardalis.Specification; +using BeReadyBackend.Models; + +namespace BeReadyBackend.Specifications.Achievements; + +public class GetAchievementByIdSpec : SingleResultSpecification +{ + public GetAchievementByIdSpec(int achievementId) + { + Query + .Where(x => x.Id == achievementId); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Specifications/UserAchievements/GetUserAchievementByIdSpec.cs b/BeReadyBackend/Specifications/UserAchievements/GetUserAchievementByIdSpec.cs new file mode 100644 index 0000000..508a9be --- /dev/null +++ b/BeReadyBackend/Specifications/UserAchievements/GetUserAchievementByIdSpec.cs @@ -0,0 +1,13 @@ +using Ardalis.Specification; +using BeReadyBackend.Models; + +namespace BeReadyBackend.Specifications.UserAchievements; + +public class GetUserAchievementByIdSpec : SingleResultSpecification +{ + public GetUserAchievementByIdSpec(int userId, int achievementId) + { + Query + .Where(x => x.UserId == userId && x.AchievementId == achievementId); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Specifications/UserAchievements/GetUserAchievementByUserIdSpec.cs b/BeReadyBackend/Specifications/UserAchievements/GetUserAchievementByUserIdSpec.cs new file mode 100644 index 0000000..7c93746 --- /dev/null +++ b/BeReadyBackend/Specifications/UserAchievements/GetUserAchievementByUserIdSpec.cs @@ -0,0 +1,14 @@ +using Ardalis.Specification; +using BeReadyBackend.Models; + +namespace BeReadyBackend.Specifications.UserAchievements; + +public class GetUserAchievementByUserIdSpec : Specification +{ + public GetUserAchievementByUserIdSpec(int userId) + { + Query + .Include(x => x.Achievement) + .Where(x => x.UserId == userId); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Specifications/Users/GetUserByIdSpec.cs b/BeReadyBackend/Specifications/Users/GetUserByIdSpec.cs new file mode 100644 index 0000000..2a51d31 --- /dev/null +++ b/BeReadyBackend/Specifications/Users/GetUserByIdSpec.cs @@ -0,0 +1,13 @@ +using Ardalis.Specification; +using BeReadyBackend.Models; + +namespace BeReadyBackend.Specifications.Users; + +public class GetUserByIdSpec : SingleResultSpecification +{ + public GetUserByIdSpec(int userId) + { + Query + .Where(x => x.Id == userId); + } +} \ No newline at end of file