Created endpoints to manage friends

This commit is contained in:
2026-02-22 12:02:44 +01:00
parent a701909d9d
commit f1ef5302c1
19 changed files with 283 additions and 45 deletions
-1
View File
@@ -27,7 +27,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="DTO\Friends\" />
<Folder Include="DTO\Groups\" />
<Folder Include="DTO\Messages\" />
<Folder Include="DTO\RandomChallenges\" />
@@ -0,0 +1,7 @@
namespace BeReadyBackend.DTO.Friends;
public class GetFriendDto
{
public string? Username { get; set; }
public int Score { get; set; }
}
@@ -0,0 +1,7 @@
namespace BeReadyBackend.DTO.Friends;
public class GetFriendRequestDto
{
public string? Username { get; set; }
public int Score { get; set; }
}
@@ -1,15 +1,12 @@
using BeReadyBackend.DTO.Achievements;
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Achievements;
using BeReadyBackend.Specifications.Users;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Achievements;
public class GetLockedAchievementsEndpoint(
UsersRepository usersRepository,
AchievementsRepository achievementsRepository,
UserService userService)
: EndpointWithoutRequest<List<GetAchievementDto>>
@@ -18,19 +15,11 @@ public class GetLockedAchievementsEndpoint(
{
Get("/Achievements/Locked/Users/");
}
public override async Task HandleAsync(CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
if (user is null)
{
await Send.NotFoundAsync(ct);
return;
}
List<GetAchievementDto> achievementsLocked = await achievementsRepository.ProjectToListAsync<GetAchievementDto>(new GetLockedAchievementsSpec(userId), ct);
await Send.OkAsync(achievementsLocked, ct);
@@ -1,15 +1,12 @@
using BeReadyBackend.DTO.Achievements;
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.UserAchievements;
using BeReadyBackend.Specifications.Users;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Achievements;
public class GetUserAchievementsEndpoint(
UsersRepository usersRepository,
UserAchievementsRepository userAchievementsRepository,
UserService userService)
: EndpointWithoutRequest<List<GetAchievementDto>>
@@ -22,14 +19,6 @@ public class GetUserAchievementsEndpoint(
public override async Task HandleAsync(CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
if (user is null)
{
await Send.NotFoundAsync(ct);
return;
}
List<GetAchievementDto> userAchievements = await userAchievementsRepository.ProjectToListAsync<GetAchievementDto>(new GetUserAchievementByUserIdSpec(userId), ct);
@@ -4,7 +4,6 @@ using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Achievements;
using BeReadyBackend.Specifications.UserAchievements;
using BeReadyBackend.Specifications.Users;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Achievements;
@@ -12,7 +11,6 @@ namespace BeReadyBackend.Endpoints.Achievements;
public class UnlockAchievementEndpoint(
UserAchievementsRepository userAchievementsRepository,
AchievementsRepository achievementsRepository,
UsersRepository usersRepository,
UserService userService,
AutoMapper.IMapper mapper) : Endpoint<UnlockAchievementDto>
{
@@ -25,10 +23,9 @@ public class UnlockAchievementEndpoint(
{
int userId = userService.GetUserIdFromToken();
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
Achievement? achievement = await achievementsRepository.SingleOrDefaultAsync(new GetAchievementByIdSpec(req.AchievementId), ct);
if (user is null || achievement is null)
if (achievement is null)
{
await Send.NotFoundAsync(ct);
return;
@@ -0,0 +1,45 @@
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Friends;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class AcceptFriendRequest
{
public int FriendId { get; set; }
}
public class AcceptFriendRequestEndpoint(UserService userService, UserFriendsRepository userFriendsRepository) : Endpoint<AcceptFriendRequest>
{
public override void Configure()
{
Put("/Friends/{@FriendId}/Request/");
}
public override async Task HandleAsync(AcceptFriendRequest req, CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
UserFriend? userFriend = await userFriendsRepository.SingleOrDefaultAsync(new GetFriendRequestByIdsSpec(req.FriendId, userId), ct);
if (userFriend is null)
{
await Send.NotFoundAsync(ct);
return;
}
userFriend.IsAccepted = true;
UserFriend friend = new()
{
UserId = userId,
FriendId = req.FriendId,
IsAccepted = true
};
await userFriendsRepository.AddAsync(friend, ct);
await userFriendsRepository.SaveChangesAsync(ct);
await Send.OkAsync(ct);
}
}
@@ -0,0 +1,37 @@
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Friends;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class DeleteFriendRequest
{
public int FriendId { get; set; }
}
public class DeleteFriendEndpoint(UserFriendsRepository userFriendsRepository, UserService userService) : Endpoint<DeleteFriendRequest>
{
public override void Configure()
{
Delete("/Friends/");
}
public override async Task HandleAsync(DeleteFriendRequest req, CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
UserFriend? userFriend = await userFriendsRepository.SingleOrDefaultAsync(new GetFriendByCriteriaSpec(userId, req.FriendId), ct);
UserFriend? friendUser = await userFriendsRepository.SingleOrDefaultAsync(new GetFriendByCriteriaSpec(req.FriendId, userId), ct);
if (userFriend is null || friendUser is null)
{
await Send.NotFoundAsync(ct);
return;
}
await userFriendsRepository.DeleteAsync(userFriend, ct);
await userFriendsRepository.DeleteAsync(friendUser, ct);
await Send.OkAsync(ct);
}
}
@@ -0,0 +1,22 @@
using BeReadyBackend.DTO.Friends;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Friends;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class GetAllFriendRequestsEndpoint(UserFriendsRepository userFriendsRepository, UserService userService, AutoMapper.IMapper mapper) : EndpointWithoutRequest<List<GetFriendRequestDto>>
{
public override void Configure()
{
Get("/Friends/Requests/");
}
public override async Task HandleAsync(CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
await Send.OkAsync(await userFriendsRepository.ProjectToListAsync<GetFriendRequestDto>(new GetFriendRequestSpec(userId), ct), ct);
}
}
@@ -0,0 +1,23 @@
using BeReadyBackend.DTO.Friends;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Friends;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class GetAllFriendsEndpoint(UserFriendsRepository userFriendsRepository, UsersRepository usersRepository, UserService userService, AutoMapper.IMapper mapper)
: EndpointWithoutRequest<List<GetFriendDto>>
{
public override void Configure()
{
Get("/Friends/");
}
public override async Task HandleAsync(CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
await Send.OkAsync(await userFriendsRepository.ProjectToListAsync<GetFriendDto>(new GetFriendsByUserIdSpec(userId), ct), ct);
}
}
@@ -0,0 +1,35 @@
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Friends;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class RejectFriendRequest
{
public int FriendId { get; set; }
}
public class RejectFriendRequestEndpoint(UserService userService, UserFriendsRepository userFriendsRepository) : Endpoint<RejectFriendRequest>
{
public override void Configure()
{
Delete("/Friends/{@FriendId}/Request/");
}
public override async Task HandleAsync(RejectFriendRequest req, CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
UserFriend? userFriend = await userFriendsRepository.SingleOrDefaultAsync(new GetFriendRequestByIdsSpec(req.FriendId, userId), ct);
if (userFriend is null)
{
await Send.NotFoundAsync(ct);
return;
}
await userFriendsRepository.DeleteAsync(userFriend, ct);
await Send.OkAsync(ct);
}
}
@@ -0,0 +1,39 @@
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Friends;
using FastEndpoints;
namespace BeReadyBackend.Endpoints.Friends;
public class SendFriendRequest
{
public int FriendId { get; set; }
}
public class SendFriendRequestEndpoint(UserFriendsRepository userFriendsRepository, UserService userService, AutoMapper.IMapper mapper) : Endpoint<SendFriendRequest>
{
public override void Configure()
{
Post("/Friends/{@Id}/", x => new {x.FriendId});
}
public override async Task HandleAsync(SendFriendRequest req, CancellationToken ct)
{
int userId = userService.GetUserIdFromToken();
UserFriend? userFriend = await userFriendsRepository.SingleOrDefaultAsync(new GetFriendByCriteriaSpec(userId, req.FriendId), ct);
if (userFriend is not null)
{
await Send.StringAsync("Cet utilisateur est déjà ami avec cette personne", 400, cancellation: ct);
return;
}
userFriend = mapper.Map<UserFriend>(req);
userFriend.UserId = userId;
userFriend.IsAccepted = false;
await userFriendsRepository.AddAsync(userFriend, ct);
await Send.OkAsync(ct);
}
}
@@ -1,5 +1,4 @@
using BeReadyBackend.Models;
using BeReadyBackend.Repositories;
using BeReadyBackend.Repositories;
using BeReadyBackend.Services;
using BeReadyBackend.Specifications.Users;
using FastEndpoints;
@@ -17,15 +16,7 @@ public class DeleteUserEndpoint(UsersRepository usersRepository, UserService use
{
int userId = userService.GetUserIdFromToken();
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
if (user == null)
{
await Send.NotFoundAsync(ct);
return;
}
await usersRepository.DeleteAsync(user, ct);
await usersRepository.DeleteAsync((await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct))!, ct);
await Send.OkAsync(ct);
}
}
@@ -19,12 +19,6 @@ public class GetUserDetailsEndpoint(UsersRepository usersRepository, UserService
int userId = userService.GetUserIdFromToken();
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
if (user is null)
{
await Send.NotFoundAsync(ct);
return;
}
await Send.OkAsync(mapper.Map<GetUserDetailsDto>(user), ct);
}
@@ -1,5 +1,6 @@
using AutoMapper;
using BeReadyBackend.DTO.Achievements;
using BeReadyBackend.DTO.Friends;
using BeReadyBackend.DTO.Users;
using BeReadyBackend.Models;
@@ -35,5 +36,13 @@ public class EntityToDtoMappings : Profile
.ForMember(dest => dest.ChallengeTitle, opt => opt.MapFrom(src => src.Title))
.ForMember(dest => dest.ChallengeDescription, opt => opt.MapFrom(src => src.Description))
.ForMember(dest => dest.ChallengeDuration, opt => opt.MapFrom(src => src.Duration));
CreateMap<UserFriend, GetFriendDto>()
.ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.Friend!.Username))
.ForMember(dest => dest.Score, opt => opt.MapFrom(src => src.Friend!.Score));
CreateMap<UserFriend, GetFriendRequestDto>()
.ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.User!.Username))
.ForMember(dest => dest.Score, opt => opt.MapFrom(src => src.User!.Score));
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Friends;
public class GetFriendByCriteriaSpec : SingleResultSpecification<UserFriend>
{
public GetFriendByCriteriaSpec(int userId, int friendId)
{
Query
.Where(x => x.UserId == userId && x.FriendId == friendId && x.IsAccepted);
}
}
@@ -0,0 +1,13 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Friends;
public class GetFriendRequestByIdsSpec : SingleResultSpecification<UserFriend>
{
public GetFriendRequestByIdsSpec(int userId, int friendId)
{
Query
.Where(x => x.UserId == userId && x.FriendId == friendId && !x.IsAccepted);
}
}
@@ -0,0 +1,14 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Friends;
public class GetFriendRequestSpec : Specification<UserFriend>
{
public GetFriendRequestSpec(int friendId)
{
Query
.Include(x => x.User)
.Where(x => !x.IsAccepted && x.FriendId == friendId);
}
}
@@ -0,0 +1,15 @@
using Ardalis.Specification;
using BeReadyBackend.Models;
namespace BeReadyBackend.Specifications.Friends;
public class GetFriendsByUserIdSpec : Specification<UserFriend>
{
public GetFriendsByUserIdSpec(int userId)
{
Query
.Include(x => x.User)
.Include(x => x.Friend)
.Where(x => x.UserId == userId && x.IsAccepted);
}
}