Added endpoints to generate challenges

This commit is contained in:
2026-03-11 22:04:21 +01:00
parent c1735c6369
commit 461a3b759e
13 changed files with 233 additions and 16 deletions
+2
View File
@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeEditing/SuppressNullableWarningFix/Enabled/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>
-4
View File
@@ -27,8 +27,4 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
</ItemGroup>
<ItemGroup>
<Folder Include="DTO\RandomChallenges\" />
</ItemGroup>
</Project>
@@ -0,0 +1,9 @@
namespace BeReadyBackend.DTO.RandomChallenges;
public class GetRandomChallengeDto
{
public int Id { get; set; }
public string? Libelle { get; set; }
public int Duration { get; set; }
public bool IsAlreadyPast { get; set; }
}
@@ -1,6 +1,55 @@
namespace BeReadyBackend.Endpoints.RandomChallenges;
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Specifications.RandomChallenges;
using BeReadyBackend.Specifications.Users;
using FastEndpoints;
public class GenerateRandomChallengeEndpoint
namespace BeReadyBackend.Endpoints.RandomChallenges;
public class GenerateRandomChallengeEndpoint(
RandomChallengesRepository randomChallengesRepository,
UserRandomChallengesRepository userRandomChallengesRepository,
UsersRepository usersRepository)
: EndpointWithoutRequest
{
public override void Configure()
{
Post("/RandomChallenges/");
}
public override async Task HandleAsync(CancellationToken ct)
{
RandomChallenge? randomChallenge = await randomChallengesRepository.FirstOrDefaultAsync(new GetRandomChallengesNotAlreadyPastSpec(), ct);
if (randomChallenge is null)
{
await Send.StringAsync("Il n'y a plus de défis en stock", 500, cancellation: ct);
return;
}
List<User> userList = await usersRepository.ListAsync(new GetAllUsersSpec(), ct);
// foreach (User user in userList)
// {
// UserRandomChallenge userRandomChallenge = new()
// {
// UserId = user.Id,
// RandomChallengeId = randomChallenge.Id
// };
//
// await userRandomChallengesRepository.AddAsync(userRandomChallenge, ct);
// }
List<UserRandomChallenge> userRandomChallenges = userList.Select(user => new UserRandomChallenge
{
UserId = user.Id,
RandomChallengeId = randomChallenge.Id
}).ToList();
await userRandomChallengesRepository.AddRangeAsync(userRandomChallenges, ct);
randomChallenge.IsAlreadyPast = true;
await randomChallengesRepository.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}
@@ -1,6 +1,45 @@
namespace BeReadyBackend.Endpoints.RandomChallenges;
using BeReadyBackend.DTO.RandomChallenges;
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.RandomChallenges;
using FastEndpoints;
public class GetRandomChallengeEndpoint
namespace BeReadyBackend.Endpoints.RandomChallenges;
public class GetRandomChallengeRequest
{
public int RandomChallengeId { get; set; }
}
public class GetRandomChallengeEndpoint(
RandomChallengesRepository randomChallengesRepository,
UserRandomChallengesRepository userRandomChallengesRepository,
UserService usersService)
: Endpoint<GetRandomChallengeRequest, GetRandomChallengeDto>
{
public override void Configure()
{
Get("/RandomChallenges/{@RandomChallengeId}", x => new { x.RandomChallengeId });
}
public override async Task HandleAsync(GetRandomChallengeRequest req, CancellationToken ct)
{
int userId = usersService.GetUserIdFromToken();
UserRandomChallenge? randomChallenge = await userRandomChallengesRepository.SingleOrDefaultAsync(new GetRandomChallengeByCriteriaSpec(req.RandomChallengeId, userId), ct);
if (randomChallenge is null)
{
await Send.NotFoundAsync(ct);
return;
}
if (randomChallenge.Proof is not null)
{
await Send.StringAsync("Preuve déjà déposée", 400, cancellation: ct);
return;
}
await Send.OkAsync(await randomChallengesRepository.ProjectToSingleAsync<GetRandomChallengeDto>(new GetRandomChallengeByIdSpec(req.RandomChallengeId), ct), ct);
}
}
@@ -1,5 +1,58 @@
namespace BeReadyBackend.Endpoints.RandomChallenges;
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.RandomChallenges;
using BeReadyBackend.Specifications.Users;
using FastEndpoints;
public class PatchProofEndpoint
namespace BeReadyBackend.Endpoints.RandomChallenges;
public class RandomChallengeProofRequest
{
public int RandomChallengeId { get; set; }
public string? Proof { get; set; }
}
public class PatchProofEndpoint(
UsersRepository usersRepository,
UserRandomChallengesRepository userRandomChallengesRepository,
UserService userService,
AutoMapper.IMapper mapper) : Endpoint<RandomChallengeProofRequest>
{
public override void Configure()
{
Patch("/RandomChallenge/{@RandomChallengeId}/Proof", x => new { x.RandomChallengeId });
}
public override async Task HandleAsync(RandomChallengeProofRequest req, CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
UserRandomChallenge? userRandomChallenge =
await userRandomChallengesRepository.SingleOrDefaultAsync(new GetRandomChallengeByCriteriaSpec(req.RandomChallengeId, userId), ct);
if (userRandomChallenge is null)
{
await Send.NotFoundAsync(ct);
return;
}
if (userRandomChallenge.Proof is not null)
{
await Send.StringAsync("Vous avez déjà déposé une preuve",400, cancellation:ct);
return;
}
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
if (user is null)
{
await Send.NotFoundAsync(ct);
return;
}
mapper.Map(req, userRandomChallenge);
user.Score++; // 1pts bonus
await userRandomChallengesRepository.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}
@@ -28,9 +28,16 @@ public class GetAllUserChallengesEndpoint(UsersRepository usersRepository, UserS
List<GetUserChallengeDto> challenges = [];
if (user.UserRandomChallenges is not null)
challenges.AddRange(user.UserRandomChallenges.Select(x => mapper.Map<GetUserChallengeDto>(x.RandomChallenge)));
challenges.AddRange(
user.UserRandomChallenges
.Where(x => x.Proof is not null)
.Select(x => mapper.Map<GetUserChallengeDto>(x.RandomChallenge))
);
if (user.UserGroups is not null)
challenges.AddRange(user.UserGroups.Select(x => mapper.Map<GetUserChallengeDto>(x.Group)));
challenges.AddRange(
user.UserGroups.Select(x => mapper.Map<GetUserChallengeDto>(x.Group))
);
await Send.OkAsync(challenges, ct);
}
@@ -28,9 +28,16 @@ public class GetAllUserProofsEndpoint(UsersRepository usersRepository, UserServi
List<GetUserProofDto> proofs = [];
if (user.UserRandomChallenges is not null)
proofs.AddRange(user.UserRandomChallenges.Select(x => mapper.Map<GetUserProofDto>(x.RandomChallenge)));
proofs.AddRange(
user.UserRandomChallenges
.Where(x => x.Proof is not null)
.Select(x => mapper.Map<GetUserProofDto>(x.RandomChallenge))
);
if (user.UserGroups is not null)
proofs.AddRange(user.UserGroups.Select(x => mapper.Map<GetUserProofDto>(x.Group)));
proofs.AddRange(
user.UserGroups.Select(x => mapper.Map<GetUserProofDto>(x.Group))
);
await Send.OkAsync(proofs, ct);
}
@@ -3,6 +3,7 @@ using BeReadyBackend.DTO.Achievements;
using BeReadyBackend.DTO.Friends;
using BeReadyBackend.DTO.Groups;
using BeReadyBackend.DTO.Messages;
using BeReadyBackend.DTO.RandomChallenges;
using BeReadyBackend.DTO.Users;
using BeReadyBackend.Models;
@@ -69,5 +70,7 @@ public class EntityToDtoMappings : Profile
CreateMap<UserGroup, GetGroupRankingDto>()
.ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.User!.Username));
CreateMap<RandomChallenge, GetRandomChallengeDto>();
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.RandomChallenges;
public class GetRandomChallengeByCriteriaSpec : SingleResultSpecification<UserRandomChallenge>
{
public GetRandomChallengeByCriteriaSpec(int challengeId, int userId)
{
Query
.Where(x => x.RandomChallengeId == challengeId && x.UserId == userId);
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.RandomChallenges;
public class GetRandomChallengeByIdSpec : SingleResultSpecification<RandomChallenge>
{
public GetRandomChallengeByIdSpec(int randomChallengeId)
{
Query
.Where(x => x.Id == randomChallengeId);
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.RandomChallenges;
public class GetRandomChallengesNotAlreadyPastSpec : Specification<RandomChallenge>
{
public GetRandomChallengesNotAlreadyPastSpec()
{
Query
.Where(x => !x.IsAlreadyPast);
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Users;
public class GetAllUsersSpec : Specification<User>
{
public GetAllUsersSpec()
{
Query
.Where(x => x.Id != 0);
}
}