diff --git a/src/main/java/goorm/kgu/familynote/domain/family/family/application/FamilyService.java b/src/main/java/goorm/kgu/familynote/domain/family/family/application/FamilyService.java index f36e5c9..7192dcf 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/family/application/FamilyService.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/family/application/FamilyService.java @@ -1,13 +1,18 @@ package goorm.kgu.familynote.domain.family.family.application; +import java.util.List; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import goorm.kgu.familynote.domain.family.family.domain.Family; import goorm.kgu.familynote.domain.family.family.domain.FamilyRepository; import goorm.kgu.familynote.domain.family.family.presentation.exception.FamilyNotFoundException; +import goorm.kgu.familynote.domain.family.family.presentation.response.FamilyListResponse; import goorm.kgu.familynote.domain.family.family.presentation.response.FamilyResponse; +import goorm.kgu.familynote.domain.family.member.domain.FamilyMember; import goorm.kgu.familynote.domain.user.application.UserService; +import goorm.kgu.familynote.domain.user.domain.User; import lombok.RequiredArgsConstructor; @Service @@ -24,11 +29,21 @@ public FamilyResponse getFamily(Long familyId) { } @Transactional - public Family createFamily() { - Family family = Family.createNewFamily(); + public Family createFamily(String familyName) { + Family family = Family.createNewFamily(familyName); return familyRepository.save(family); } + @Transactional + public FamilyListResponse getMyFamilyList() { + User user = userService.me(); + List familyMembers = user.getFamilyMembers(); + List family = familyMembers.stream() + .map(FamilyMember::getFamily) + .toList(); + return FamilyListResponse.of(family, user.getNickname()); + } + public Family getFamilyById(Long familyId) { return familyRepository.findById(familyId) .orElseThrow(FamilyNotFoundException::new); diff --git a/src/main/java/goorm/kgu/familynote/domain/family/family/domain/Family.java b/src/main/java/goorm/kgu/familynote/domain/family/family/domain/Family.java index 014a802..eb5f4b6 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/family/domain/Family.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/family/domain/Family.java @@ -6,6 +6,7 @@ import goorm.kgu.familynote.common.domain.BaseTimeEntity; import goorm.kgu.familynote.domain.family.member.domain.FamilyMember; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -30,11 +31,16 @@ public class Family extends BaseTimeEntity { @GeneratedValue(strategy = IDENTITY) private Long id; + @Column(nullable = false) + private String familyName; + @OneToMany(mappedBy = "family", fetch = FetchType.LAZY) private List familyMembers; - public static Family createNewFamily() { - return Family.builder().build(); + public static Family createNewFamily(String familyName) { + return Family.builder() + .familyName(familyName) + .build(); } } diff --git a/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/FamilyController.java b/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/FamilyController.java index ea129b4..91bd2d4 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/FamilyController.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/FamilyController.java @@ -8,6 +8,7 @@ import goorm.kgu.familynote.common.exception.ExceptionResponse; import goorm.kgu.familynote.domain.family.family.application.FamilyService; +import goorm.kgu.familynote.domain.family.family.presentation.response.FamilyListResponse; import goorm.kgu.familynote.domain.family.family.presentation.response.FamilyResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -51,4 +52,28 @@ public ResponseEntity getFamily( FamilyResponse response = familyService.getFamily(familyId); return ResponseEntity.ok(response); } + + @Operation(summary = "가족 그룹 목록 조회", description = "내가 속한 가족 그룹 목록을 조회합니다.") + @ApiResponses({ + @ApiResponse( + responseCode = "200", + description = "가족 그룹 목록 조회 성공", + content = @Content(schema = @Schema(implementation = FamilyListResponse.class)) + ), + @ApiResponse( + responseCode = "403", + description = "사용자 인증에 실패하였습니다.", + content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "가족 그룹이 존재하지 않습니다./ 사용자를 찾을 수 없습니다.", + content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) + ) + }) + @GetMapping("/list") + public ResponseEntity getFamilyList() { + FamilyListResponse response = familyService.getMyFamilyList(); + return ResponseEntity.ok(response); + } } diff --git a/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/response/FamilyListResponse.java b/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/response/FamilyListResponse.java new file mode 100644 index 0000000..b0fa15d --- /dev/null +++ b/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/response/FamilyListResponse.java @@ -0,0 +1,29 @@ +package goorm.kgu.familynote.domain.family.family.presentation.response; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +import java.util.List; +import java.util.stream.Collectors; + +import goorm.kgu.familynote.domain.family.family.domain.Family; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; + +@Builder +public record FamilyListResponse( + @Schema( + description = "가족 그룹 목록", + example = "[{\"familyId\": 1, \"familyName\": \"행복한 우리집\", \"myName\": \"이한음\", \"familyMembers\": [{\"familyMemberId\": 1, \"nickName\": \"이한음\"}, {\"familyMemberId\": 2, \"nickName\": \"전민주\"}]}]", + requiredMode = REQUIRED + ) + List contents +) { + public static FamilyListResponse of(List familyList, String myName) { + return FamilyListResponse.builder() + .contents(familyList.stream() + .map(family -> FamilyResponse.of(family, myName)) + .collect(Collectors.toList()) + ) + .build(); + } +} diff --git a/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/response/FamilyResponse.java b/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/response/FamilyResponse.java index 630b0f9..c8b03b1 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/response/FamilyResponse.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/family/presentation/response/FamilyResponse.java @@ -1,21 +1,37 @@ package goorm.kgu.familynote.domain.family.family.presentation.response; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + import java.util.List; import goorm.kgu.familynote.domain.family.family.domain.Family; import goorm.kgu.familynote.domain.family.member.presentation.response.FamilyMemberResponse; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; @Builder public record FamilyResponse( + @Schema(description = "가족 그룹 ID", example = "1", requiredMode = REQUIRED) Long familyId, + + @Schema(description = "가족 그룹 이름", example = "행복한 우리집", requiredMode = REQUIRED) + String familyName, + + @Schema(description = "내 이름", example = "이한음", requiredMode = REQUIRED) String myName, + + @Schema( + description = "가족 구성원 목록", + example = "[{\"familyMemberId\": 1, \"nickName\": \"이한음\"}, {\"familyMemberId\": 2, \"nickName\": \"전민주\"}]", + requiredMode = REQUIRED + ) List familyMembers ) { public static FamilyResponse of(Family family, String myName) { return FamilyResponse.builder() .familyId(family.getId()) + .familyName(family.getFamilyName()) .myName(myName) .familyMembers(FamilyMemberResponse.of(family.getFamilyMembers())) .build(); diff --git a/src/main/java/goorm/kgu/familynote/domain/family/member/application/FamilyMemberService.java b/src/main/java/goorm/kgu/familynote/domain/family/member/application/FamilyMemberService.java index b34b811..b63d8bb 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/member/application/FamilyMemberService.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/member/application/FamilyMemberService.java @@ -24,13 +24,15 @@ public class FamilyMemberService { @Transactional public FamilyPersistResponse saveFamilyMember(FamilyMemberCreateRequest request) { - Family family = familyService.createFamily(); + Family family = familyService.createFamily(request.familyName()); List users = request.userIds(); users.forEach(userId -> { User user = userService.getUserById(userId); FamilyMember familyMember = FamilyMember.create(family, user); familyMemberRepository.save(familyMember); }); + FamilyMember me = FamilyMember.create(family, userService.me()); + familyMemberRepository.save(me); return FamilyPersistResponse.of(family.getId()); } diff --git a/src/main/java/goorm/kgu/familynote/domain/family/member/domain/FamilyMember.java b/src/main/java/goorm/kgu/familynote/domain/family/member/domain/FamilyMember.java index 34e765a..49c6fc9 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/member/domain/FamilyMember.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/member/domain/FamilyMember.java @@ -30,8 +30,6 @@ public class FamilyMember extends BaseTimeEntity { @GeneratedValue(strategy = IDENTITY) private Long id; - private String role; - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; diff --git a/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/request/FamilyMemberCreateRequest.java b/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/request/FamilyMemberCreateRequest.java index 4dd4e13..27c6613 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/request/FamilyMemberCreateRequest.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/request/FamilyMemberCreateRequest.java @@ -8,6 +8,9 @@ public record FamilyMemberCreateRequest( @Schema(description = "가족 구성원 유저 ID", example = "[1, 2, 3]", requiredMode = REQUIRED) - List userIds + List userIds, + + @Schema(description = "가족 그룹 이름", example = "행복한 우리집", requiredMode = REQUIRED) + String familyName ) { } diff --git a/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/response/FamilyMemberResponse.java b/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/response/FamilyMemberResponse.java index fe1ac5c..e12527f 100644 --- a/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/response/FamilyMemberResponse.java +++ b/src/main/java/goorm/kgu/familynote/domain/family/member/presentation/response/FamilyMemberResponse.java @@ -1,14 +1,19 @@ package goorm.kgu.familynote.domain.family.member.presentation.response; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + import java.util.List; import java.util.stream.Collectors; import goorm.kgu.familynote.domain.family.member.domain.FamilyMember; +import io.swagger.v3.oas.annotations.media.Schema; public record FamilyMemberResponse( + @Schema(description = "가족 구성원 ID", example = "1", requiredMode = REQUIRED) Long familyMemberId, - String nickName, - String role + + @Schema(description = "닉네임", example = "이한음", requiredMode = REQUIRED) + String nickName ) { public static List of(List familyMembers) { @@ -20,8 +25,7 @@ public static List of(List familyMembers) { public static FamilyMemberResponse of(FamilyMember familyMember) { return new FamilyMemberResponse( familyMember.getId(), - familyMember.getUser().getNickname(), - familyMember.getRole() + familyMember.getUser().getNickname() ); } } diff --git a/src/main/java/goorm/kgu/familynote/domain/user/domain/User.java b/src/main/java/goorm/kgu/familynote/domain/user/domain/User.java index 3e34745..95713ef 100644 --- a/src/main/java/goorm/kgu/familynote/domain/user/domain/User.java +++ b/src/main/java/goorm/kgu/familynote/domain/user/domain/User.java @@ -1,19 +1,27 @@ package goorm.kgu.familynote.domain.user.domain; +import static jakarta.persistence.CascadeType.ALL; +import static jakarta.persistence.FetchType.LAZY; import static jakarta.persistence.GenerationType.IDENTITY; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.List; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import goorm.kgu.familynote.common.domain.BaseTimeEntity; +import goorm.kgu.familynote.domain.family.member.domain.FamilyMember; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -41,6 +49,9 @@ public class User extends BaseTimeEntity implements UserDetails { private String refreshToken; + @OneToMany(mappedBy = "user", fetch = LAZY, cascade = ALL, orphanRemoval = true) + List familyMembers = new ArrayList<>(); + public static User create(String nickname, String password) { return User.builder() .nickname(nickname)