Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package konkuk.thip.attendancecheck.adapter.out.persistence;

import konkuk.thip.attendancecheck.adapter.out.mapper.AttendanceCheckMapper;
import konkuk.thip.attendancecheck.adapter.out.persistence.repository.AttendanceCheckRepository;
import konkuk.thip.attendancecheck.adapter.out.persistence.repository.AttendanceCheckJpaRepository;
import konkuk.thip.attendancecheck.application.port.out.AttendanceCheckCommandPort;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
Expand All @@ -10,7 +10,7 @@
@RequiredArgsConstructor
public class AttendanceCheckCommandPersistenceAdapter implements AttendanceCheckCommandPort {

private final AttendanceCheckRepository attendanceCheckRepository;
private final AttendanceCheckJpaRepository attendanceCheckJpaRepository;
private final AttendanceCheckMapper attendanceCheckMapper;

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package konkuk.thip.attendancecheck.adapter.out.persistence;

import konkuk.thip.attendancecheck.adapter.out.mapper.AttendanceCheckMapper;
import konkuk.thip.attendancecheck.adapter.out.persistence.repository.AttendanceCheckRepository;
import konkuk.thip.attendancecheck.adapter.out.persistence.repository.AttendanceCheckJpaRepository;
import konkuk.thip.attendancecheck.application.port.out.AttendanceCheckQueryPort;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
Expand All @@ -10,7 +10,7 @@
@RequiredArgsConstructor
public class AttendanceCheckQueryPersistenceAdapter implements AttendanceCheckQueryPort {

private final AttendanceCheckRepository jpaRepository;
private final AttendanceCheckJpaRepository jpaRepository;
private final AttendanceCheckMapper attendanceCheckMapper;

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import konkuk.thip.attendancecheck.adapter.out.jpa.AttendanceCheckJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface AttendanceCheckRepository extends JpaRepository<AttendanceCheckJpaEntity, Long> {
public interface AttendanceCheckJpaRepository extends JpaRepository<AttendanceCheckJpaEntity, Long> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ public enum ErrorCode implements ResponseCode {
/**
* 75000 : follow error
*/
FOLLOW_NOT_FOUND(HttpStatus.NOT_FOUND, 75001, "존재하지 않는 FOLLOW 입니다."),
USER_ALREADY_UNFOLLOWED(HttpStatus.BAD_REQUEST, 75002, "이미 언팔로우한 사용자입니다."),
USER_CANNOT_FOLLOW_SELF(HttpStatus.BAD_REQUEST, 75003, "사용자는 자신을 팔로우할 수 없습니다."),


FOLLOW_NOT_FOUND(HttpStatus.NOT_FOUND, 75000, "존재하지 않는 FOLLOW 입니다."),
USER_ALREADY_UNFOLLOWED(HttpStatus.BAD_REQUEST, 75001, "이미 언팔로우한 사용자입니다."),
USER_CANNOT_FOLLOW_SELF(HttpStatus.BAD_REQUEST, 75002, "사용자는 자신을 팔로우할 수 없습니다."),
FOLLOW_COUNT_IS_ZERO(HttpStatus.BAD_REQUEST, 75003, "사용자의 팔로우 수가 0일때는 언팔로우는 불가능합니다."),

/**
* 80000 : book error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public record MemberSearchResult(
String nickname,
String imageUrl,
String alias,
int subscriberCount
int followerCount
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import konkuk.thip.room.adapter.out.jpa.CategoryJpaEntity;
import konkuk.thip.room.adapter.out.jpa.RoomJpaEntity;
import konkuk.thip.room.adapter.out.mapper.RoomMapper;
import konkuk.thip.room.adapter.out.persistence.repository.CategoryJpaRepository;
import konkuk.thip.room.adapter.out.persistence.repository.category.CategoryJpaRepository;
import konkuk.thip.room.adapter.out.persistence.repository.RoomJpaRepository;
import konkuk.thip.room.application.port.out.RoomCommandPort;
import konkuk.thip.room.domain.Room;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import konkuk.thip.common.exception.code.ErrorCode;
import konkuk.thip.room.adapter.out.jpa.RoomParticipantJpaEntity;
import konkuk.thip.room.adapter.out.mapper.RoomParticipantMapper;
import konkuk.thip.room.adapter.out.persistence.repository.RoomParticipantJpaRepository;
import konkuk.thip.room.adapter.out.persistence.repository.roomparticipant.RoomParticipantJpaRepository;
import konkuk.thip.room.application.port.out.RoomParticipantCommandPort;
import konkuk.thip.room.domain.RoomParticipant;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package konkuk.thip.room.adapter.out.persistence.repository;
package konkuk.thip.room.adapter.out.persistence.repository.category;

import konkuk.thip.room.adapter.out.jpa.CategoryJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package konkuk.thip.room.adapter.out.persistence.repository;
package konkuk.thip.room.adapter.out.persistence.repository.roomparticipant;

import konkuk.thip.room.adapter.out.jpa.RoomParticipantJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import konkuk.thip.room.adapter.in.web.response.RoomGetMemberListResponse;
import konkuk.thip.room.application.port.in.RoomGetMemberListUseCase;
import konkuk.thip.room.application.port.out.RoomCommandPort;
import konkuk.thip.room.application.port.out.RoomParticipantCommandPort;
import konkuk.thip.room.domain.Room;
import konkuk.thip.user.application.port.out.FollowingQueryPort;
import konkuk.thip.room.domain.RoomParticipant;
import konkuk.thip.user.application.port.out.UserCommandPort;
import konkuk.thip.room.application.port.out.RoomParticipantCommandPort;
import konkuk.thip.user.domain.User;
import konkuk.thip.room.domain.RoomParticipant;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -23,7 +22,6 @@ public class RoomGetMemberListService implements RoomGetMemberListUseCase {
private final RoomCommandPort roomCommandPort;
private final RoomParticipantCommandPort roomParticipantCommandPort;
private final UserCommandPort userCommandPort;
private final FollowingQueryPort followingQueryPort;

@Override
@Transactional(readOnly = true)
Expand All @@ -35,29 +33,26 @@ public RoomGetMemberListResponse getRoomMemberList(Long roomId) {
// 2. 방 참여자(UserRoom) 전체 조회
List<RoomParticipant> roomParticipants = roomParticipantCommandPort.findAllByRoomId(room.getId());


// 3. 참여자 userId 목록 추출
List<Long> userIds = roomParticipants.stream()
.map(RoomParticipant::getUserId)
.toList();

// 4. 배치 쿼리로 유저 정보, 팔로워 수 조회
// 4. 배치 쿼리로 유저 정보만 조회
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Map<Long, User> userMap = userCommandPort.findByIds(userIds);
Map<Long, Integer> subscriberCountMap = followingQueryPort.countByFollowingUserIds(userIds);

// 5. 각 userRoom에 대해 DTO 조립
// 5. 각 roomParticipant에 대해 DTO 조립
List<RoomGetMemberListResponse.MemberSearchResult> userList = roomParticipants.stream()
.map(userRoom -> {
Long userId = userRoom.getUserId();
.map(roomParticipant -> {
Long userId = roomParticipant.getUserId();
User user = userMap.get(userId);
int subscriberCount = subscriberCountMap.getOrDefault(userId, 0);

return RoomGetMemberListResponse.MemberSearchResult.builder()
.userId(userId)
.nickname(user.getNickname())
.imageUrl(user.getAlias().getImageUrl())
.alias(user.getAlias().getValue())
.subscriberCount(subscriberCount)
.followerCount(user.getFollowerCount())
.build();
})
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,14 @@ public record UserFollowersResponse(
boolean isFirst,
boolean isLast
) {
@Builder
public record Follower(
Long userId,
String nickname,
String profileImageUrl,
String aliasName,
Integer followingCount
Integer followerCount
){
public static Follower of(Long userId, String nickname, String profileImageUrl, String aliasName, Integer followingCount) {
return new Follower(
userId,
nickname,
profileImageUrl,
aliasName,
followingCount
);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class FollowingJpaEntity extends BaseJpaEntity {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private UserJpaEntity followerUserJpaEntity;
private UserJpaEntity userJpaEntity;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "following_user_id")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public class UserJpaEntity extends BaseJpaEntity {
@Column(name = "oauth2_id", length = 50, nullable = false)
private String oauth2Id;

@Builder.Default
private Integer followerCount = 0; // 팔로워 수

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private UserRole role;
Expand All @@ -35,4 +38,8 @@ public class UserJpaEntity extends BaseJpaEntity {
@JoinColumn(name = "user_alias_id", nullable = false)
private AliasJpaEntity aliasForUserJpaEntity;

public void updateFollowerCount(int followerCount) {
this.followerCount = followerCount;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ public class FollowingMapper {

public FollowingJpaEntity toJpaEntity(UserJpaEntity followerUserJpaEntity, UserJpaEntity followingUserJpaEntity) {
return FollowingJpaEntity.builder()
.followerUserJpaEntity(followerUserJpaEntity)
.userJpaEntity(followerUserJpaEntity)
.followingUserJpaEntity(followingUserJpaEntity)
.build();
}

public Following toDomainEntity(FollowingJpaEntity followingJpaEntity) {
return Following.builder()
.id(followingJpaEntity.getFollowingId())
.followerUserId(followingJpaEntity.getFollowerUserJpaEntity().getUserId())
.userId(followingJpaEntity.getUserJpaEntity().getUserId())
.followingUserId(followingJpaEntity.getFollowingUserJpaEntity().getUserId())
.createdAt(followingJpaEntity.getCreatedAt())
.modifiedAt(followingJpaEntity.getModifiedAt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public UserJpaEntity toJpaEntity(User user, AliasJpaEntity aliasJpaEntity) {
.imageUrl(user.getAlias().getImageUrl())
.role(UserRole.from(user.getUserRole()))
.oauth2Id(user.getOauth2Id())
.followerCount(user.getFollowerCount())
.aliasForUserJpaEntity(aliasJpaEntity)
.build();
}
Expand All @@ -26,6 +27,7 @@ public User toDomainEntity(UserJpaEntity userJpaEntity) {
.nickname(userJpaEntity.getNickname())
.userRole(userJpaEntity.getRole().getType())
.oauth2Id(userJpaEntity.getOauth2Id())
.followerCount(userJpaEntity.getFollowerCount())
.alias(Alias.from(userJpaEntity.getAliasForUserJpaEntity().getValue()))
.createdAt(userJpaEntity.getCreatedAt())
.modifiedAt(userJpaEntity.getModifiedAt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import konkuk.thip.user.adapter.out.jpa.FollowingJpaEntity;
import konkuk.thip.user.adapter.out.jpa.UserJpaEntity;
import konkuk.thip.user.adapter.out.mapper.FollowingMapper;
import konkuk.thip.user.adapter.out.persistence.repository.following.FollowingJpaRepository;
import konkuk.thip.user.adapter.out.mapper.UserMapper;
import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository;
import konkuk.thip.user.adapter.out.persistence.repository.UserJpaRepository;
import konkuk.thip.user.adapter.out.persistence.repository.following.FollowingJpaRepository;
import konkuk.thip.user.application.port.out.FollowingCommandPort;
import konkuk.thip.user.domain.Following;
import konkuk.thip.user.domain.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

Expand All @@ -22,8 +25,10 @@ public class FollowingCommandPersistenceAdapter implements FollowingCommandPort

private final FollowingJpaRepository followingJpaRepository;
private final UserJpaRepository userJpaRepository;
private final AliasJpaRepository aliasJpaRepository;

private final FollowingMapper followingMapper;
private final UserMapper userMapper;

@Override //ACTIVE, INACTIVE 모두 조회
public Optional<Following> findByUserIdAndTargetUserId(Long userId, Long targetUserId) {
Expand All @@ -32,21 +37,32 @@ public Optional<Following> findByUserIdAndTargetUserId(Long userId, Long targetU
}

@Override
public void save(Following following) { // insert용
UserJpaEntity userJpaEntity = userJpaRepository.findById(following.getFollowerUserId()).orElseThrow(
public void save(Following following, User targetUser) { // insert용
UserJpaEntity userJpaEntity = userJpaRepository.findById(following.getUserId()).orElseThrow(
() -> new EntityNotFoundException(USER_NOT_FOUND));

UserJpaEntity targetUser = userJpaRepository.findById(following.getFollowingUserId()).orElseThrow(
() -> new EntityNotFoundException(USER_NOT_FOUND));
UserJpaEntity targetUserJpaEntity = updateUserFollowerCount(targetUser);
followingJpaRepository.save(followingMapper.toJpaEntity(userJpaEntity, targetUserJpaEntity));

followingJpaRepository.save(followingMapper.toJpaEntity(userJpaEntity, targetUser));
}

@Override
public void updateStatus(Following following) { // 상태변경 용
FollowingJpaEntity entity = followingJpaRepository.findByUserAndTargetUser(following.getFollowerUserId(), following.getFollowingUserId())
public void updateStatus(Following following, User targetUser) { // 상태변경 용
updateUserFollowerCount(targetUser);

FollowingJpaEntity entity = followingJpaRepository.findByUserAndTargetUser(following.getUserId(), following.getFollowingUserId())
.orElseThrow(() -> new EntityNotFoundException(FOLLOW_NOT_FOUND));

entity.setStatus(following.getStatus());
}

private UserJpaEntity updateUserFollowerCount(User targetUser) {
UserJpaEntity userJpaEntity = userJpaRepository.findById(targetUser.getId()).orElseThrow(
() -> new EntityNotFoundException(USER_NOT_FOUND)
);

userJpaEntity.updateFollowerCount(targetUser.getFollowerCount());
userJpaRepository.save(userJpaEntity);
return userJpaEntity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,46 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Repository
@RequiredArgsConstructor
public class FollowingQueryPersistenceAdapter implements FollowingQueryPort {

private final FollowingJpaRepository followingJpaRepository;

@Override
public Map<Long, Integer> countByFollowingUserIds(List<Long> userIds) {
return followingJpaRepository.countByFollowingUserIds(userIds);
}

@Override
public UserFollowersResponse getFollowersByUserId(Long userId, String cursor, int size) {
LocalDateTime nextCursor = null;
if (cursor != null && !cursor.isBlank()) {
nextCursor = DateUtil.parseDateTime(cursor);
nextCursor = DateUtil.parseDateTime(cursor);
}

List<FollowingJpaEntity> followerEntities =
followingJpaRepository.findFollowersByUserIdBeforeCreatedAt(userId, nextCursor, size);

List<UserJpaEntity> followers = followerEntities.stream()
.map(FollowingJpaEntity::getFollowerUserJpaEntity) // 팔로워 사용자
.map(FollowingJpaEntity::getUserJpaEntity) // 팔로워 사용자
.toList();

Map<Long, Integer> followingCountMap = countByFollowingUserIds(
followers.stream().map(UserJpaEntity::getUserId).toList()
);

List<UserFollowersResponse.Follower> followerList = followers.stream()
.map(follower -> UserFollowersResponse.Follower.of(follower.getUserId(), follower.getNickname(), follower.getAliasForUserJpaEntity().getImageUrl(), follower.getAliasForUserJpaEntity().getValue(), followingCountMap.getOrDefault(follower.getUserId(), 0)))
.map(follower -> UserFollowersResponse.Follower.builder()
.userId(follower.getUserId())
.nickname(follower.getNickname())
.profileImageUrl(follower.getAliasForUserJpaEntity().getImageUrl())
.aliasName(follower.getAliasForUserJpaEntity().getValue())
.followerCount(follower.getFollowerCount())
.build())
.toList();

boolean isLast = followerEntities.size() < size;
nextCursor = isLast ? null :
nextCursor = isLast ? null :
followerEntities.get(followerEntities.size() - 1).getCreatedAt();

return UserFollowersResponse.builder()
.followerList(followerList)
.size(followerList.size())
.nextCursor(nextCursor)
.isFirst(cursor == null) // cursor가 null이면 첫 페이지
.isFirst(cursor == null) // cursor가 null이면 첫 페이지
.isLast(isLast)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity;
import konkuk.thip.user.adapter.out.jpa.UserJpaEntity;
import konkuk.thip.user.adapter.out.mapper.UserMapper;
import konkuk.thip.user.adapter.out.persistence.repository.AliasJpaRepository;
import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository;
import konkuk.thip.user.adapter.out.persistence.repository.UserJpaRepository;
import konkuk.thip.user.application.port.out.UserCommandPort;
import konkuk.thip.user.domain.User;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package konkuk.thip.user.adapter.out.persistence;

import konkuk.thip.user.adapter.out.mapper.UserMapper;
import konkuk.thip.user.adapter.out.persistence.repository.AliasJpaRepository;
import konkuk.thip.user.adapter.out.persistence.repository.alias.AliasJpaRepository;
import konkuk.thip.user.adapter.out.persistence.repository.UserJpaRepository;
import konkuk.thip.user.application.port.in.dto.UserViewAliasChoiceResult;
import konkuk.thip.user.application.port.out.UserQueryPort;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package konkuk.thip.user.adapter.out.persistence.repository;
package konkuk.thip.user.adapter.out.persistence.repository.alias;

import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;
Expand Down
Loading