66import com .danielagapov .spawn .user .api .dto .FriendUser .RecommendedFriendUserDTO ;
77import com .danielagapov .spawn .user .api .dto .Profile .UserProfileInfoDTO ;
88import com .danielagapov .spawn .shared .util .EntityType ;
9+ import com .danielagapov .spawn .shared .util .UserRelationshipType ;
910import com .danielagapov .spawn .shared .util .UserStatus ;
1011import com .danielagapov .spawn .shared .exceptions .Base .BaseNotFoundException ;
1112import com .danielagapov .spawn .shared .exceptions .Base .BaseSaveException ;
1213import com .danielagapov .spawn .shared .exceptions .Base .BasesNotFoundException ;
1314import com .danielagapov .spawn .shared .exceptions .Logger .ILogger ;
1415import com .danielagapov .spawn .shared .util .UserMapper ;
16+ import com .danielagapov .spawn .social .api .dto .CreateFriendRequestDTO ;
1517import com .danielagapov .spawn .social .internal .domain .Friendship ;
18+ import com .danielagapov .spawn .social .internal .services .IFriendRequestService ;
1619import com .danielagapov .spawn .user .internal .domain .User ;
1720import com .danielagapov .spawn .social .internal .repositories .IFriendshipRepository ;
1821import com .danielagapov .spawn .auth .internal .repositories .IUserIdExternalIdMapRepository ;
@@ -46,6 +49,7 @@ public class UserService implements IUserService {
4649 private final ILogger logger ;
4750 private final IUserSearchQueryService userSearchQueryService ;
4851 private final IUserFriendshipQueryService friendshipQueryService ;
52+ private final IFriendRequestService friendRequestService ;
4953 private final CacheManager cacheManager ;
5054 private final ApplicationEventPublisher eventPublisher ;
5155 private final IUserIdExternalIdMapRepository userIdExternalIdMapRepository ;
@@ -59,6 +63,7 @@ public UserService(IUserRepository repository,
5963 IS3Service s3Service , ILogger logger ,
6064 IUserSearchQueryService userSearchQueryService ,
6165 IUserFriendshipQueryService friendshipQueryService ,
66+ IFriendRequestService friendRequestService ,
6267 CacheManager cacheManager ,
6368 ApplicationEventPublisher eventPublisher ,
6469 IUserIdExternalIdMapRepository userIdExternalIdMapRepository ) {
@@ -68,6 +73,7 @@ public UserService(IUserRepository repository,
6873 this .logger = logger ;
6974 this .userSearchQueryService = userSearchQueryService ;
7075 this .friendshipQueryService = friendshipQueryService ;
76+ this .friendRequestService = friendRequestService ;
7177 this .cacheManager = cacheManager ;
7278 this .eventPublisher = eventPublisher ;
7379 this .userIdExternalIdMapRepository = userIdExternalIdMapRepository ;
@@ -434,6 +440,112 @@ public BaseUserDTO getBaseUserById(UUID id) {
434440 }
435441 }
436442
443+ @ Override
444+ public BaseUserDTO getBaseUserByIdWithRelationship (UUID id , UUID requestingUserId ) {
445+ try {
446+ User user = repository .findById (id )
447+ .orElseThrow (() -> new BaseNotFoundException (EntityType .User , id ));
448+
449+ // Hide admin user from front-end
450+ if (isAdminUser (user )) {
451+ throw new BaseNotFoundException (EntityType .User , id );
452+ }
453+
454+ BaseUserDTO dto = UserMapper .toDTO (user );
455+
456+ // If requestingUserId is provided and different from the target user, determine relationship
457+ if (requestingUserId != null && !requestingUserId .equals (id )) {
458+ UserRelationshipType relationshipStatus = determineRelationshipStatus (requestingUserId , id );
459+ dto .setRelationshipStatus (relationshipStatus );
460+
461+ // Get pending friend request ID if applicable
462+ UUID pendingRequestId = getPendingFriendRequestId (requestingUserId , id , relationshipStatus );
463+ dto .setPendingFriendRequestId (pendingRequestId );
464+ }
465+
466+ return dto ;
467+ } catch (Exception e ) {
468+ logger .error ("Error getting user with relationship: " + LoggingUtils .formatUserIdInfo (id ) + ": " + e .getMessage ());
469+ throw e ;
470+ }
471+ }
472+
473+ /**
474+ * Determines the relationship status between the requesting user and a target user.
475+ *
476+ * @param requestingUserId The ID of the user making the request
477+ * @param targetUserId The ID of the target user
478+ * @return UserRelationshipType representing the current relationship status
479+ */
480+ private UserRelationshipType determineRelationshipStatus (UUID requestingUserId , UUID targetUserId ) {
481+ try {
482+ // Check if they are already friends
483+ if (friendshipQueryService .isUserFriendOfUser (requestingUserId , targetUserId )) {
484+ return UserRelationshipType .FRIEND ;
485+ }
486+
487+ // Check for outgoing friend request (requesting user sent to target user)
488+ List <CreateFriendRequestDTO > outgoingRequests = friendRequestService .getSentFriendRequestsByUserId (requestingUserId );
489+ boolean hasOutgoingRequest = outgoingRequests .stream ()
490+ .anyMatch (request -> request .getReceiverUserId ().equals (targetUserId ));
491+
492+ if (hasOutgoingRequest ) {
493+ return UserRelationshipType .OUTGOING_FRIEND_REQUEST ;
494+ }
495+
496+ // Check for incoming friend request (target user sent to requesting user)
497+ List <CreateFriendRequestDTO > incomingRequests = friendRequestService .getIncomingCreateFriendRequestsByUserId (requestingUserId );
498+ boolean hasIncomingRequest = incomingRequests .stream ()
499+ .anyMatch (request -> request .getSenderUserId ().equals (targetUserId ));
500+
501+ if (hasIncomingRequest ) {
502+ return UserRelationshipType .INCOMING_FRIEND_REQUEST ;
503+ }
504+
505+ // Default to recommended friend if no existing relationship
506+ return UserRelationshipType .RECOMMENDED_FRIEND ;
507+
508+ } catch (Exception e ) {
509+ logger .error ("Error determining relationship status between users " + requestingUserId + " and " + targetUserId + ": " + e .getMessage ());
510+ return UserRelationshipType .RECOMMENDED_FRIEND ;
511+ }
512+ }
513+
514+ /**
515+ * Gets the pending friend request ID if there is one between the users.
516+ *
517+ * @param requestingUserId The ID of the user making the request
518+ * @param targetUserId The ID of the target user
519+ * @param relationshipStatus The current relationship status
520+ * @return UUID of the pending friend request, or null if none exists
521+ */
522+ private UUID getPendingFriendRequestId (UUID requestingUserId , UUID targetUserId , UserRelationshipType relationshipStatus ) {
523+ try {
524+ if (relationshipStatus == UserRelationshipType .OUTGOING_FRIEND_REQUEST ) {
525+ // Find the outgoing request ID
526+ List <CreateFriendRequestDTO > outgoingRequests = friendRequestService .getSentFriendRequestsByUserId (requestingUserId );
527+ return outgoingRequests .stream ()
528+ .filter (request -> request .getReceiverUserId ().equals (targetUserId ))
529+ .map (CreateFriendRequestDTO ::getId )
530+ .findFirst ()
531+ .orElse (null );
532+ } else if (relationshipStatus == UserRelationshipType .INCOMING_FRIEND_REQUEST ) {
533+ // Find the incoming request ID
534+ List <CreateFriendRequestDTO > incomingRequests = friendRequestService .getIncomingCreateFriendRequestsByUserId (requestingUserId );
535+ return incomingRequests .stream ()
536+ .filter (request -> request .getSenderUserId ().equals (targetUserId ))
537+ .map (CreateFriendRequestDTO ::getId )
538+ .findFirst ()
539+ .orElse (null );
540+ }
541+
542+ return null ;
543+ } catch (Exception e ) {
544+ logger .error ("Error getting pending friend request ID between users " + requestingUserId + " and " + targetUserId + ": " + e .getMessage ());
545+ return null ;
546+ }
547+ }
548+
437549 @ Override
438550 public BaseUserDTO updateUser (UUID id , UserUpdateDTO updateDTO ) {
439551 try {
0 commit comments