Added endpoints and logic for user following system.
This commit is contained in:
parent
e69008a582
commit
6097b0df7e
|
@ -1,12 +1,10 @@
|
|||
package nl.andrewlalis.gymboard_api.domains.auth.controller;
|
||||
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dto.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.service.TokenService;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.service.UserService;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
|
|
|
@ -3,12 +3,11 @@ package nl.andrewlalis.gymboard_api.domains.auth.controller;
|
|||
import nl.andrewlalis.gymboard_api.domains.auth.dto.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.service.UserService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
public class UserController {
|
||||
|
@ -66,4 +65,26 @@ public class UserController {
|
|||
) {
|
||||
return userService.updatePreferences(user.getId(), payload);
|
||||
}
|
||||
|
||||
@PostMapping(path = "/auth/users/{userId}/followers")
|
||||
public ResponseEntity<Void> followUser(@AuthenticationPrincipal User myUser, @PathVariable String userId) {
|
||||
userService.followUser(myUser.getId(), userId);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@DeleteMapping(path = "/auth/users/{userId}/followers")
|
||||
public ResponseEntity<Void> unfollowUser(@AuthenticationPrincipal User myUser, @PathVariable String userId) {
|
||||
userService.unfollowUser(myUser.getId(), userId);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@GetMapping(path = "/auth/me/followers")
|
||||
public Page<UserResponse> getFollowers(@AuthenticationPrincipal User user, Pageable pageable) {
|
||||
return userService.getFollowers(user.getId(), pageable);
|
||||
}
|
||||
|
||||
@GetMapping(path = "/auth/me/following")
|
||||
public Page<UserResponse> getFollowing(@AuthenticationPrincipal User user, Pageable pageable) {
|
||||
return userService.getFollowing(user.getId(), pageable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package nl.andrewlalis.gymboard_api.domains.auth.dao;
|
||||
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.UserFollowing;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserFollowingRepository extends JpaRepository<UserFollowing, Long> {
|
||||
boolean existsByFollowedUserAndFollowingUser(User followedUser, User followingUser);
|
||||
|
||||
@Modifying
|
||||
void deleteByFollowedUserAndFollowingUser(User followedUser, User followingUser);
|
||||
|
||||
Page<UserFollowing> findAllByFollowedUserOrderByCreatedAtDesc(User followedUser, Pageable pageable);
|
||||
Page<UserFollowing> findAllByFollowingUserOrderByCreatedAtDesc(User followingUser, Pageable pageable);
|
||||
}
|
|
@ -10,7 +10,10 @@ import java.time.LocalDateTime;
|
|||
* have impacts on the notifications that a user can receive.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "auth_user_following")
|
||||
@Table(
|
||||
name = "auth_user_following",
|
||||
uniqueConstraints = @UniqueConstraint(columnNames = {"followed_user_id", "following_user_id"})
|
||||
)
|
||||
public class UserFollowing {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
|
|
@ -5,15 +5,14 @@ import jakarta.mail.internet.MimeMessage;
|
|||
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.dto.*;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.PasswordResetCode;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.UserActivationCode;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.UserPersonalDetails;
|
||||
import nl.andrewlalis.gymboard_api.domains.auth.model.*;
|
||||
import nl.andrewlalis.gymboard_api.util.StringGenerator;
|
||||
import nl.andrewlalis.gymboard_api.util.ULID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
|
@ -38,6 +37,7 @@ public class UserService {
|
|||
private final UserPreferencesRepository userPreferencesRepository;
|
||||
private final UserActivationCodeRepository activationCodeRepository;
|
||||
private final PasswordResetCodeRepository passwordResetCodeRepository;
|
||||
private final UserFollowingRepository userFollowingRepository;
|
||||
private final ULID ulid;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final JavaMailSender mailSender;
|
||||
|
@ -51,7 +51,7 @@ public class UserService {
|
|||
UserPreferencesRepository userPreferencesRepository,
|
||||
UserActivationCodeRepository activationCodeRepository,
|
||||
PasswordResetCodeRepository passwordResetCodeRepository,
|
||||
ULID ulid,
|
||||
UserFollowingRepository userFollowingRepository, ULID ulid,
|
||||
PasswordEncoder passwordEncoder,
|
||||
JavaMailSender mailSender
|
||||
) {
|
||||
|
@ -60,6 +60,7 @@ public class UserService {
|
|||
this.userPreferencesRepository = userPreferencesRepository;
|
||||
this.activationCodeRepository = activationCodeRepository;
|
||||
this.passwordResetCodeRepository = passwordResetCodeRepository;
|
||||
this.userFollowingRepository = userFollowingRepository;
|
||||
this.ulid = ulid;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.mailSender = mailSender;
|
||||
|
@ -276,4 +277,40 @@ public class UserService {
|
|||
p = userPreferencesRepository.save(p);
|
||||
return new UserPreferencesResponse(p);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void followUser(String followerId, String followedId) {
|
||||
User follower = userRepository.findById(followerId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
User followed = userRepository.findById(followedId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
|
||||
if (!userFollowingRepository.existsByFollowedUserAndFollowingUser(followed, follower)) {
|
||||
userFollowingRepository.save(new UserFollowing(followed, follower));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void unfollowUser(String followerId, String followedId) {
|
||||
User follower = userRepository.findById(followerId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
User followed = userRepository.findById(followedId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
|
||||
userFollowingRepository.deleteByFollowedUserAndFollowingUser(followed, follower);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<UserResponse> getFollowers(String userId, Pageable pageable) {
|
||||
User user = userRepository.findById(userId)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
return userFollowingRepository.findAllByFollowedUserOrderByCreatedAtDesc(user, pageable)
|
||||
.map(UserFollowing::getFollowingUser)
|
||||
.map(UserResponse::new);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<UserResponse> getFollowing(String userId, Pageable pageable) {
|
||||
User user = userRepository.findById(userId)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||
return userFollowingRepository.findAllByFollowingUserOrderByCreatedAtDesc(user, pageable)
|
||||
.map(UserFollowing::getFollowedUser)
|
||||
.map(UserResponse::new);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue