Skip to content

Commit

Permalink
merge(GroupInfo) : 그룹 정보 보기 API 구현
Browse files Browse the repository at this point in the history
[✨ feat] 그룹 정보 보기 API 구현
  • Loading branch information
jsoonworld authored Feb 17, 2025
2 parents b22e4d7 + 372a1df commit 81100fd
Show file tree
Hide file tree
Showing 27 changed files with 493 additions and 64 deletions.
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ repositories {
mavenCentral()
}

ext {
set('queryDslVersion', "5.0.0")
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
Expand All @@ -38,6 +42,12 @@ dependencies {

// Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'

// QueryDSL
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}

tasks.named('test') {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/org/noostak/global/config/QueryDslConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.noostak.global.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QueryDslConfig {

@PersistenceContext
private EntityManager entityManager;

@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
18 changes: 14 additions & 4 deletions src/main/java/org/noostak/group/api/GroupController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import org.noostak.global.success.SuccessResponse;
import org.noostak.group.application.GroupService;
import org.noostak.group.dto.request.GroupCreateRequest;
import org.noostak.group.dto.response.GroupCreateResponse;
import org.noostak.group.dto.response.GroupsRetrieveResponse;
import org.noostak.group.dto.response.create.GroupCreateResponse;
import org.noostak.group.dto.response.info.GroupInfoResponse;
import org.noostak.group.dto.response.retrieve.GroupsRetrieveResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

import static org.noostak.group.common.success.GroupSuccessCode.GROUP_CREATED;
import static org.noostak.group.common.success.GroupSuccessCode.GROUP_RETRIEVED;
import static org.noostak.group.common.success.GroupSuccessCode.*;

@RestController
@RequestMapping("/api/v1/groups")
Expand Down Expand Up @@ -41,4 +41,14 @@ public ResponseEntity<SuccessResponse<GroupsRetrieveResponse>> getGroups(
GroupsRetrieveResponse groups = groupService.findGroups(memberId);
return ResponseEntity.ok(SuccessResponse.of(GROUP_RETRIEVED, groups));
}

@GetMapping("/{groupId}/members")
public ResponseEntity<SuccessResponse<GroupInfoResponse>> getGroupInfo(
// @AuthenticationPrincipal Long memberId,
@PathVariable Long groupId
) {
Long memberId = 1L;
GroupInfoResponse groupInfo = groupService.getGroupInfo(memberId, groupId);
return ResponseEntity.ok(SuccessResponse.of(GROUP_INFO, groupInfo));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.noostak.group.application;

import org.noostak.group.dto.request.GroupCreateRequest;
import org.noostak.group.dto.response.GroupCreateInternalResponse;
import org.noostak.group.dto.response.create.GroupCreateInternalResponse;

import java.io.IOException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
import org.noostak.group.domain.vo.GroupName;
import org.noostak.group.domain.vo.GroupProfileImageKey;
import org.noostak.group.dto.request.GroupCreateRequest;
import org.noostak.group.dto.response.GroupCreateInternalResponse;
import org.noostak.group.dto.response.create.GroupCreateInternalResponse;
import org.noostak.infra.KeyAndUrl;
import org.noostak.infra.S3DirectoryPath;
import org.noostak.infra.S3Service;
import org.noostak.member.domain.Member;
import org.noostak.member.domain.MemberRepository;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.noostak.group.application;

import org.noostak.group.dto.response.info.GroupInfoResponse;

public interface GroupInfoService {
GroupInfoResponse getGroupInfo(Long memberId, Long groupId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package org.noostak.group.application;

import lombok.RequiredArgsConstructor;
import org.noostak.group.common.exception.GroupErrorCode;
import org.noostak.group.common.exception.GroupException;
import org.noostak.group.domain.Group;
import org.noostak.group.domain.GroupRepository;
import org.noostak.group.dto.response.info.GroupInfoResponse;
import org.noostak.group.dto.response.info.GroupMemberInfoResponse;
import org.noostak.group.dto.response.info.GroupSummaryResponse;
import org.noostak.infra.S3Service;
import org.noostak.member.domain.Member;
import org.noostak.membergroup.domain.MemberGroupRepository;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class GroupInfoServiceImpl implements GroupInfoService {

private final GroupRepository groupRepository;
private final MemberGroupRepository memberGroupRepository;
private final S3Service s3Service;

@Override
public GroupInfoResponse getGroupInfo(final Long memberId, final Long groupId) {
Group group = findGroupById(groupId);

Member member = findMemberInGroup(memberId, groupId);
GroupMemberInfoResponse myInfoResponse = convertToGroupMemberInfo(member);


GroupMemberInfoResponse groupHostInfo = findGroupHost(groupId);

List<GroupMemberInfoResponse> groupMembersInfo = findGroupMembers(groupId);

GroupSummaryResponse groupSummaryResponse = convertToGroupSummaryResponse(group, groupHostInfo, groupMembersInfo);

return GroupInfoResponse.of(myInfoResponse, groupSummaryResponse);
}

private Member findMemberInGroup(Long memberId, Long groupId) {
return memberGroupRepository.findMembersByGroupId(groupId).stream()
.filter(m -> m.getMemberId().equals(memberId))
.findFirst()
.orElseThrow(() -> new GroupException(GroupErrorCode.MEMBER_NOT_FOUND));
}

private Group findGroupById(Long groupId) {
return groupRepository.findById(groupId)
.orElseThrow(() -> new GroupException(GroupErrorCode.GROUP_NOT_FOUND));
}

private GroupMemberInfoResponse findGroupHost(Long groupId) {
Member host = memberGroupRepository.findGroupHostByGroupId(groupId);
if (host == null) throw new GroupException(GroupErrorCode.GROUP_MEMBER_NOT_FOUND);

return convertToGroupMemberInfo(host);
}

private List<GroupMemberInfoResponse> findGroupMembers(Long groupId) {
return memberGroupRepository.findMembersByGroupId(groupId).stream()
.map(this::convertToGroupMemberInfo)
.toList();
}

private GroupMemberInfoResponse convertToGroupMemberInfo(Member member) {
return GroupMemberInfoResponse.of(
member.getName().value(),
s3Service.getImageUrl(member.getKey().value())
);
}

private GroupSummaryResponse convertToGroupSummaryResponse(Group group, GroupMemberInfoResponse hostInfo, List<GroupMemberInfoResponse> membersInfo) {
String groupProfileImageUrl = getGroupProfileImageUrl(group);

return GroupSummaryResponse.of(
hostInfo,
group.getName().value(),
groupProfileImageUrl,
group.getCount().value(),
group.getCode().value(),
membersInfo
);
}

private String getGroupProfileImageUrl(Group group) {
return s3Service.getImageUrl(group.getKey().value());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.noostak.group.application;

import org.noostak.group.dto.response.GroupsRetrieveResponse;
import org.noostak.group.dto.response.retrieve.GroupsRetrieveResponse;

public interface GroupRetrieveService {
GroupsRetrieveResponse findGroups(Long memberId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
import lombok.RequiredArgsConstructor;
import org.noostak.group.common.exception.GroupErrorCode;
import org.noostak.group.common.exception.GroupException;
import org.noostak.group.domain.Groups;
import org.noostak.group.dto.response.GroupInternalRetrieveResponse;
import org.noostak.group.dto.response.GroupRetrieveResponse;
import org.noostak.group.dto.response.GroupsRetrieveResponse;
import org.noostak.group.domain.Group;
import org.noostak.group.dto.response.retrieve.GroupRetrieveResponse;
import org.noostak.group.dto.response.retrieve.GroupsRetrieveResponse;
import org.noostak.infra.S3Service;
import org.noostak.membergroup.domain.MemberGroup;
import org.noostak.membergroup.domain.MemberGroupRepository;
import org.noostak.membergroup.domain.MemberGroups;
import org.springframework.stereotype.Service;

import java.util.List;
Expand All @@ -24,35 +21,28 @@ public class GroupRetrieveServiceImpl implements GroupRetrieveService {

@Override
public GroupsRetrieveResponse findGroups(Long memberId) {
MemberGroups memberGroups = getMemberGroups(memberId);
Groups groups = convertToGroups(memberGroups);
List<Group> groups = getGroupsByMemberId(memberId);
validateGroups(groups);
return convertToResponse(groups);
}

private MemberGroups getMemberGroups(Long memberId) {
List<MemberGroup> foundMemberGroups = memberGroupRepository.findByMemberId(memberId);
MemberGroups memberGroups = MemberGroups.of(foundMemberGroups);
private List<Group> getGroupsByMemberId(Long memberId) {
return memberGroupRepository.findGroupsByMemberId(memberId);
}

if (memberGroups.isEmpty()) {
private void validateGroups(List<Group> groups) {
if (groups.isEmpty()) {
throw new GroupException(GroupErrorCode.GROUP_NOT_FOUND);
}

return memberGroups;
}

private Groups convertToGroups(MemberGroups memberGroups) {
return Groups.of(memberGroups.toGroups());
}

private GroupsRetrieveResponse convertToResponse(Groups groups) {
List<GroupInternalRetrieveResponse> internalResponses = groups.getGroups().stream()
.map(group -> GroupInternalRetrieveResponse.of(group, s3Service.getImageUrl(group.getKey().value())))
private GroupsRetrieveResponse convertToResponse(List<Group> groups) {
List<GroupRetrieveResponse> groupResponses = groups.stream()
.map(group -> GroupRetrieveResponse.of(
group,
s3Service.getImageUrl(group.getKey().value())
))
.toList();

List<GroupRetrieveResponse> groupResponses = internalResponses.stream()
.map(internal -> GroupRetrieveResponse.of(internal.group(), internal.groupProfileImageUrl()))
.toList();

return GroupsRetrieveResponse.of(groupResponses);
}
}
12 changes: 9 additions & 3 deletions src/main/java/org/noostak/group/application/GroupService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

import lombok.RequiredArgsConstructor;
import org.noostak.group.dto.request.GroupCreateRequest;
import org.noostak.group.dto.response.GroupCreateInternalResponse;
import org.noostak.group.dto.response.GroupCreateResponse;
import org.noostak.group.dto.response.GroupsRetrieveResponse;
import org.noostak.group.dto.response.create.GroupCreateInternalResponse;
import org.noostak.group.dto.response.create.GroupCreateResponse;
import org.noostak.group.dto.response.info.GroupInfoResponse;
import org.noostak.group.dto.response.retrieve.GroupsRetrieveResponse;
import org.springframework.stereotype.Service;

import java.io.IOException;
Expand All @@ -15,6 +16,7 @@ public class GroupService {

private final GroupCreateService groupCreateService;
private final GroupRetrieveService groupRetrieveService;
private final GroupInfoService groupInfoService;

public GroupCreateResponse createGroup(Long memberId, GroupCreateRequest request) throws IOException {
GroupCreateInternalResponse response = groupCreateService.createGroup(memberId, request);
Expand All @@ -24,4 +26,8 @@ public GroupCreateResponse createGroup(Long memberId, GroupCreateRequest request
public GroupsRetrieveResponse findGroups(Long memberId) {
return groupRetrieveService.findGroups(memberId);
}

public GroupInfoResponse getGroupInfo(Long memberId, Long groupId) {
return groupInfoService.getGroupInfo(memberId, groupId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public enum GroupErrorCode implements ErrorCode {

GROUP_NOT_FOUND(HttpStatus.NOT_FOUND, "그룹을 찾을 수 없습니다."),
GROUP_MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "그룹 멤버를 찾을 수 없습니다."),

MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "멤버를 찾을 수 없습니다.")
;

public static final String PREFIX = "[GROUP ERROR] ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public enum GroupSuccessCode implements SuccessCode {
GROUP_CREATED(HttpStatus.CREATED, "그룹이 성공적으로 생성되었습니다."),

GROUP_RETRIEVED(HttpStatus.OK, "그룹이 성공적으로 조회되었습니다."),

GROUP_INFO(HttpStatus.OK, "그룹 정보가 성공적으로 조회되었습니다.")
;

private final HttpStatus status;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.noostak.group.dto.response;
package org.noostak.group.dto.response.create;


import org.noostak.group.domain.Group;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.noostak.group.dto.response;
package org.noostak.group.dto.response.create;

import org.noostak.group.domain.Group;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.noostak.group.dto.response.info;

public record GroupInfoResponse(
GroupMemberInfoResponse myInfo,
GroupSummaryResponse groupInfo
) {
public static GroupInfoResponse of(final GroupMemberInfoResponse myInfo, final GroupSummaryResponse groupInfo) {
return new GroupInfoResponse(myInfo, groupInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.noostak.group.dto.response.info;

public record GroupMemberInfoResponse(
String memberName,
String memberProfileImageUrl
) {
public static GroupMemberInfoResponse of(final String memberName, final String memberProfileImageUrl) {
return new GroupMemberInfoResponse(memberName, memberProfileImageUrl);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.noostak.group.dto.response.info;

import java.util.List;

public record GroupSummaryResponse(
GroupMemberInfoResponse groupHostInfo,
String groupName,
String groupProfileImageUrl,
Long groupMemberCount,
String groupInvitationCode,
List<GroupMemberInfoResponse> groupMemberInfo
) {
public static GroupSummaryResponse of(final GroupMemberInfoResponse groupHostInfo, final String groupName, final String groupProfileImageUrl, final Long groupMemberCount, final String groupInvitationCode, final List<GroupMemberInfoResponse> groupMemberInfo) {
return new GroupSummaryResponse(groupHostInfo, groupName, groupProfileImageUrl, groupMemberCount, groupInvitationCode, groupMemberInfo);}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.noostak.group.dto.response;
package org.noostak.group.dto.response.retrieve;

import org.noostak.group.domain.Group;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.noostak.group.dto.response;
package org.noostak.group.dto.response.retrieve;

import org.noostak.group.domain.Group;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.noostak.group.dto.response;
package org.noostak.group.dto.response.retrieve;

import java.util.List;

Expand Down
Loading

0 comments on commit 81100fd

Please sign in to comment.