Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions config/guild-server-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ spring:
hikari:
data-source-properties:
serverTimezone: Asia/Seoul
jpa:
hibernate:
ddl-auto: none

cloud:
aws:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import com.asyncgate.guild_server.dto.request.DirectChannelCreateRequest;
import com.asyncgate.guild_server.dto.response.DirectResponse;
import com.asyncgate.guild_server.dto.response.DirectResponses;
import com.asyncgate.guild_server.service.DirectService;
import com.asyncgate.guild_server.support.response.SuccessResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand All @@ -27,4 +25,14 @@ public SuccessResponse<DirectResponse> create(
directService.create(currentUserId, request)
);
}

@GetMapping
public SuccessResponse<DirectResponses> get(
final @AuthenticationPrincipal String currentUserId
) {
return SuccessResponse.ok(
directService.getDirectList(currentUserId)
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
import lombok.Builder;
import lombok.Getter;

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

@Getter
public class Direct {

private final String id;
private LocalDateTime createdDate;

@Builder
private Direct(String id, String name) {
private Direct(String id, LocalDateTime createdDate) {
this.id = id;
this.createdDate = createdDate;
}

public static Direct create() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.UUID;

@Getter
Expand All @@ -11,8 +12,17 @@ public class DirectMember {
private final String directId;
private final String memberId;
private final String memberName;
private LocalDateTime createdDate;

@Builder
private DirectMember(String id, String directId, String memberId, String memberName, LocalDateTime createdDate) {
this.id = id;
this.directId = directId;
this.memberId = memberId;
this.memberName = memberName;
this.createdDate = createdDate;
}

private DirectMember(String id, String directId, String memberId, String memberName) {
this.id = id;
this.directId = directId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.asyncgate.guild_server.client.UserClientInfoResponses;

public record DirectResponse(String directId,UserClientInfoResponses members) {
public record DirectResponse(String directId, UserClientInfoResponses members) {
public static DirectResponse of(final String directId, final UserClientInfoResponses members) {
return new DirectResponse(directId, members);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.asyncgate.guild_server.dto.response;

import java.util.List;

public record DirectResponses(List<DirectResponse> directResponses) {

public static DirectResponses from(final List<DirectResponse> directResponses) {
return new DirectResponses(directResponses);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@Entity
@Table(name = "direct")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class DirectEntity {
public class DirectEntity extends BaseEntity {

@Id
private String id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@
@Entity
@Table(name = "direct_member")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class DirectMemberEntity {
public class DirectMemberEntity extends BaseEntity {

@Id
private String id;
private String directId;
private String memberId;
private String memberName;

@Builder
private DirectMemberEntity(String id, String memberId, String memberName) {
private DirectMemberEntity(String id, String directId, String memberId, String memberName) {
this.id = id;
this.directId = directId;
this.memberId = memberId;
this.memberName = memberName;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.asyncgate.guild_server.repository;

import com.asyncgate.guild_server.entity.DirectMemberEntity;
import com.asyncgate.guild_server.entity.QDirectMemberEntity;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@RequiredArgsConstructor
public class DirectMemberQueryDslRepository {

private final JPAQueryFactory queryFactory;
private final QDirectMemberEntity directMemberEntity = QDirectMemberEntity.directMemberEntity;

public List<DirectMemberEntity> getDirectMessageList(final String currentUserId) {
return queryFactory
.select(directMemberEntity)
.from(directMemberEntity)
.where(
directMemberEntity.memberId.eq(currentUserId),
directMemberEntity.deleted.isFalse()
)
.fetch();

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@

public interface DirectMemberRepository {
void saveAll(List<DirectMember> directMembers);

List<DirectMember> getDirectMessageList(String currentUserId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@
public class DirectMemberRepositoryImpl implements DirectMemberRepository {

private final DirectMemberJpaRepository jpaRepository;
private final DirectMemberQueryDslRepository queryDslRepository;

@Override
public void saveAll(List<DirectMember> directMembers) {
public void saveAll(final List<DirectMember> directMembers) {
jpaRepository.saveAll(
directMembers.stream()
.map(DomainUtil.DirectMemberMapper::toEntity)
.toList()
);
}

@Override
public List<DirectMember> getDirectMessageList(final String currentUserId) {
return queryDslRepository.getDirectMessageList(currentUserId).stream()
.map(
DomainUtil.DirectMemberMapper::toDomain
)
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class DirectRepositoryImpl implements DirectRepository {
private final DirectJpaRepository jpaRepository;

@Override
public void save(Direct direct) {
public void save(final Direct direct) {
jpaRepository.save(
DomainUtil.DirectMapper.toEntity(direct)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import com.asyncgate.guild_server.dto.request.DirectChannelCreateRequest;
import com.asyncgate.guild_server.dto.response.DirectResponse;
import com.asyncgate.guild_server.dto.response.DirectResponses;

public interface DirectService {
DirectResponse create(String currentUserId, DirectChannelCreateRequest request);

DirectResponses getDirectList(String currentUserId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

import com.asyncgate.guild_server.client.UserClient;
import com.asyncgate.guild_server.client.UserClientInfoResponses;
import com.asyncgate.guild_server.client.UserClientInfoResponses.UserClientInfoResponse;
import com.asyncgate.guild_server.domain.Direct;
import com.asyncgate.guild_server.domain.DirectMember;
import com.asyncgate.guild_server.dto.request.DirectChannelCreateRequest;
import com.asyncgate.guild_server.dto.response.DirectResponse;
import com.asyncgate.guild_server.dto.response.DirectResponses;
import com.asyncgate.guild_server.repository.DirectMemberRepository;
import com.asyncgate.guild_server.repository.DirectRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -46,4 +50,50 @@ public DirectResponse create(final String currentUserId, final DirectChannelCrea

return DirectResponse.of(direct.getId(), usersInfo);
}

@Override
public DirectResponses getDirectList(final String currentUserId) {
// 1. 현재 사용자의 다이렉트 메시지 목록 조회
List<DirectMember> directMembers = directMemberRepository.getDirectMessageList(currentUserId);

// 2. 다이렉트 ID별로 DirectMember 그룹화
Map<String, List<DirectMember>> directGroups = directMembers.stream()
.collect(Collectors.groupingBy(DirectMember::getDirectId));

// 3. 모든 그룹에서 고유한 사용자 ID 수집 (한 번의 배치 API 호출을 위함)
Set<String> uniqueMemberIds = directMembers.stream()
.map(DirectMember::getMemberId)
.collect(Collectors.toSet());

// 4. 배치 API 호출로 모든 사용자 프로필 정보 조회
UserClientInfoResponses userInfos = userClient
.getUsersInfo(new ArrayList<>(uniqueMemberIds))
.getResult();

// 5. 사용자 ID별 프로필 정보를 빠르게 조회할 수 있도록 Map으로 변환
Map<String, UserClientInfoResponse> userInfoMap = userInfos.responses().stream()
.collect(
Collectors.toMap(
UserClientInfoResponse::userId,
Function.identity()
)
);

// 6. 각 다이렉트 그룹별로 응답 객체를 생성
List<DirectResponse> responses = directGroups.entrySet().stream()
.map(entry -> {
String directId = entry.getKey();
List<DirectMember> membersInGroup = entry.getValue();

// 해당 그룹에 속한 멤버들의 프로필 정보를 매핑 (null은 필터링)
List<UserClientInfoResponse> memberProfiles = membersInGroup.stream()
.map(directMember -> userInfoMap.get(directMember.getMemberId()))
.filter(Objects::nonNull)
.toList();

return DirectResponse.of(directId, new UserClientInfoResponses(memberProfiles));
}).toList();
return DirectResponses.from(responses);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public static DirectEntity toEntity(final Direct domain) {
public static Direct toDomain(final DirectEntity entity) {
return Direct.builder()
.id(entity.getId())
.createdDate(entity.getCreatedDate())
.build();
}
}
Expand All @@ -109,6 +110,7 @@ public static class DirectMemberMapper {
public static DirectMemberEntity toEntity(final DirectMember directMember) {
return DirectMemberEntity.builder()
.id(directMember.getId())
.directId(directMember.getDirectId())
.memberId(directMember.getMemberId())
.memberName(directMember.getMemberName())
.build();
Expand All @@ -119,6 +121,7 @@ public static DirectMember toDomain(final DirectMemberEntity entity) {
.id(entity.getId())
.memberId(entity.getMemberId())
.memberName(entity.getMemberName())
.createdDate(entity.getCreatedDate())
.build();
}
}
Expand Down
Loading