Added AchievementService.cs for gestion of achievements

This commit is contained in:
2026-05-14 18:16:19 +01:00
parent 62fb8ec932
commit f11e5e274b
10 changed files with 175 additions and 114 deletions
@@ -1,18 +0,0 @@
using BeReadyBackend.DTO.Achievements;
using BeReadyBackend.Repositories;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Achievements;
public class GetAllAchievementsEndpoint(AchievementsRepository achievementsRepository) : EndpointWithoutRequest<List<GetAchievementDto>>
{
public override void Configure()
{
Get("/Achievements/");
}
public override async Task HandleAsync(CancellationToken ct)
{
await Send.OkAsync(await achievementsRepository.ProjectToListAsync<GetAchievementDto>(ct), ct);
}
}
@@ -1,27 +0,0 @@
using BeReadyBackend.DTO.Achievements;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Achievements;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Achievements;
public class GetLockedAchievementsEndpoint(
AchievementsRepository achievementsRepository,
UserService userService)
: EndpointWithoutRequest<List<GetAchievementDto>>
{
public override void Configure()
{
Get("/Achievements/Locked/Users/");
}
public override async Task HandleAsync(CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
List<GetAchievementDto> achievementsLocked = await achievementsRepository.ProjectToListAsync<GetAchievementDto>(new GetLockedAchievementsSpec(userId), ct);
await Send.OkAsync(achievementsLocked, ct);
}
}
@@ -1,50 +0,0 @@
using BeReadyBackend.DTO.Achievements;
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Achievements;
using BeReadyBackend.Specifications.UserAchievements;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Achievements;
public class UnlockAchievementEndpoint(
UserAchievementsRepository userAchievementsRepository,
AchievementsRepository achievementsRepository,
UserService userService) : Endpoint<UnlockAchievementDto>
{
public override void Configure()
{
Post("/Achievements/{@AchievementId}/Users/", x => new { x.AchievementId });
Description(x => x.Accepts<UnlockAchievementDto>());
}
public override async Task HandleAsync(UnlockAchievementDto req, CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
Achievement? achievement = await achievementsRepository.SingleOrDefaultAsync(new GetAchievementByIdSpec(req.AchievementId), ct);
if (achievement is null)
{
await Send.NotFoundAsync(ct);
return;
}
UserAchievement? userAchievement = await userAchievementsRepository.SingleOrDefaultAsync(new GetUserAchievementByIdSpec(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;
}
userAchievement = new UserAchievement
{
UserId = userId,
AchievementId = req.AchievementId
};
await userAchievementsRepository.AddAsync(userAchievement, ct);
await Send.NoContentAsync(ct);
}
}
@@ -6,8 +6,7 @@ using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class GetAllFriendRequestsEndpoint(UserFriendsRepository userFriendsRepository, UserService userService, AutoMapper.IMapper mapper)
: EndpointWithoutRequest<List<GetFriendRequestDto>>
public class GetAllFriendRequestsEndpoint(UserFriendsRepository userFriendsRepository, UserService userService): EndpointWithoutRequest<List<GetFriendRequestDto>>
{
public override void Configure()
{
@@ -6,8 +6,7 @@ using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class GetAllFriendsEndpoint(UserFriendsRepository userFriendsRepository, UsersRepository usersRepository, UserService userService, AutoMapper.IMapper mapper)
: EndpointWithoutRequest<List<GetFriendDto>>
public class GetAllFriendsEndpoint(UserFriendsRepository userFriendsRepository, UserService userService) : EndpointWithoutRequest<List<GetFriendDto>>
{
public override void Configure()
{
@@ -17,7 +16,6 @@ public class GetAllFriendsEndpoint(UserFriendsRepository userFriendsRepository,
public override async Task HandleAsync(CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
await Send.OkAsync(await userFriendsRepository.ProjectToListAsync<GetFriendDto>(new GetFriendsByUserIdSpec(userId), ct), ct);
}
}
@@ -7,7 +7,8 @@ using FastEndpoints;
namespace BeReadyBackend.Endpoints.Users;
public class GetUserDetailsEndpoint(UsersRepository usersRepository, UserService userService, AutoMapper.IMapper mapper) : EndpointWithoutRequest<GetUserDetailsDto>
public class GetUserDetailsEndpoint(UsersRepository usersRepository, UserService userService, AutoMapper.IMapper mapper, AchievementService achievementService)
: EndpointWithoutRequest<GetUserDetailsDto>
{
public override void Configure()
{
@@ -18,6 +19,7 @@ public class GetUserDetailsEndpoint(UsersRepository usersRepository, UserService
{
int userId = userService.GetUserIdFromToken();
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
await achievementService.CheckAchievement(userId);
await Send.OkAsync(mapper.Map<GetUserDetailsDto>(user), ct);
}
@@ -0,0 +1,144 @@
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Specifications.Achievements;
using BeReadyBackend.Specifications.Friends;
using BeReadyBackend.Specifications.Posts;
using BeReadyBackend.Specifications.UserAchievements;
using BeReadyBackend.Specifications.Users;
namespace BeReadyBackend.Services;
public class AchievementService(
UsersRepository usersRepository,
AchievementsRepository achievementsRepository,
UserAchievementsRepository userAchievementsRepository,
UserPostsRepository userPostsRepository,
UserFriendsRepository userFriendsRepository)
{
public async Task Unlock(int userId, int achievementId)
{
Achievement? achievement = await achievementsRepository.SingleOrDefaultAsync(new GetAchievementByIdSpec(achievementId));
if (achievement is null) return;
bool alreadyUnlocked = await userAchievementsRepository.CountAsync(new GetUserAchievementByIdSpec(userId, achievement.Id)) > 0;
if (alreadyUnlocked) return;
UserAchievement userAchievement = new()
{
UserId = userId,
AchievementId = achievement.Id
};
await userAchievementsRepository.AddAsync(userAchievement);
}
public async Task CheckAchievement(int userId)
{
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId));
if (user is null) return;
int challengesCounter = await usersRepository.CountAsync(new GetProofOrChallengeByUserIdSpec(userId));
int likedCounter = await userPostsRepository.CountAsync(new GetPostsLikedByUserSpec(userId));
int friendsCounter = await userFriendsRepository.CountAsync(new GetFriendsByUserIdSpec(userId));
int friendsRequestsCounter = await userFriendsRepository.CountAsync(new GetFriendRequestSpec(userId));
int achievementsCounter = await userAchievementsRepository.CountAsync(new GetAchievementUnlockedSpec(userId));
switch (challengesCounter)
{
case 1:
await Unlock(userId, 1);
break;
case 10:
await Unlock(userId, 12);
break;
case 20:
await Unlock(userId, 3);
break;
case 50:
await Unlock(userId, 29);
break;
case 100:
await Unlock(userId, 32);
break;
}
switch (user.Series)
{
case 5:
await Unlock(userId, 2);
break;
case 7:
await Unlock(userId, 39);
break;
case 10:
await Unlock(userId, 4);
break;
case 30:
await Unlock(userId, 40);
break;
}
switch (likedCounter)
{
case 50:
await Unlock(userId, 37);
break;
case 100:
await Unlock(userId, 9);
break;
case 200:
await Unlock(userId, 38);
break;
}
switch (user.TotalLikes)
{
case 50:
await Unlock(userId, 13);
break;
case 500:
await Unlock(userId, 44);
break;
case 1000:
await Unlock(userId, 33);
break;
}
switch (friendsCounter)
{
case 5:
await Unlock(userId, 18);
break;
case 10:
await Unlock(userId, 19);
break;
case 20:
await Unlock(userId, 36);
break;
}
switch (friendsRequestsCounter)
{
case 10:
await Unlock(userId, 21);
break;
}
switch (achievementsCounter)
{
case 5:
await Unlock(userId,22);
break;
case 20:
await Unlock(userId, 23);
break;
case 23:
await Unlock(userId, 46);
break;
}
if (DateTime.Now >= DateTime.Today.AddHours(20)) await Unlock(userId, 25);
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Achievements;
public class GetAchievementUnlockedSpec : Specification<UserAchievement>
{
public GetAchievementUnlockedSpec(int userId)
{
Query
.Where(x => x.UserId == userId);
}
}
@@ -1,13 +0,0 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Achievements;
public class GetLockedAchievementsSpec : Specification<Achievement>
{
public GetLockedAchievementsSpec(int userId)
{
Query
.Where(x => x.UserAchievements != null && x.UserAchievements.All(y => y.UserId != userId));
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Posts;
public class GetPostsLikedByUserSpec : Specification<UserPost>
{
public GetPostsLikedByUserSpec(int userId)
{
Query
.Where(x => x.UserId == userId);
}
}