diff --git a/src/main/java/flipnote/group/adapter/in/web/GroupController.java b/src/main/java/flipnote/group/adapter/in/web/GroupController.java index 4972362..5eabf88 100644 --- a/src/main/java/flipnote/group/adapter/in/web/GroupController.java +++ b/src/main/java/flipnote/group/adapter/in/web/GroupController.java @@ -1,15 +1,21 @@ package flipnote.group.adapter.in.web; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import flipnote.group.api.dto.request.ChangeGroupRequestDto; import flipnote.group.api.dto.request.CreateGroupRequestDto; +import flipnote.group.api.dto.response.ChangeGroupResponseDto; import flipnote.group.api.dto.response.CreateGroupResponseDto; +import flipnote.group.application.port.in.ChangeGroupUseCase; import flipnote.group.application.port.in.CreateGroupUseCase; +import flipnote.group.application.port.in.command.ChangeGroupCommand; import flipnote.group.application.port.in.command.CreateGroupCommand; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -20,6 +26,7 @@ public class GroupController { private final CreateGroupUseCase createGroupUseCase; + private final ChangeGroupUseCase changeGroupUseCase; /** * 그룹 생성 API @@ -33,6 +40,7 @@ public ResponseEntity createGroup( @RequestBody @Valid CreateGroupRequestDto req) { CreateGroupCommand cmd = new CreateGroupCommand( + userId, req.name(), req.category(), req.description(), @@ -42,9 +50,40 @@ public ResponseEntity createGroup( req.imageRefId() ); - var result = createGroupUseCase.create(cmd, userId); + var result = createGroupUseCase.create(cmd); CreateGroupResponseDto res = CreateGroupResponseDto.from(result.groupId()); return ResponseEntity.ok(res); } + /** + * 그룹 수정 API + * @param userId + * @param groupId + * @param req + * @return + */ + @PutMapping("/{groupId}") + public ResponseEntity changeGroup( + @RequestHeader("X-USER-ID") Long userId, + @PathVariable Long groupId, + @RequestBody @Valid ChangeGroupRequestDto req) { + + ChangeGroupCommand cmd = new ChangeGroupCommand( + groupId, + userId, + req.name(), + req.category(), + req.description(), + req.joinPolicy(), + req.visibility(), + req.maxMember(), + req.imageRefId() + ); + + var result = changeGroupUseCase.change(cmd); + + ChangeGroupResponseDto res = ChangeGroupResponseDto.from(result); + return ResponseEntity.ok(res); + } + } diff --git a/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java b/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java index c3e9968..e2650d7 100644 --- a/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java +++ b/src/main/java/flipnote/group/adapter/out/entity/GroupEntity.java @@ -1,5 +1,6 @@ package flipnote.group.adapter.out.entity; +import flipnote.group.application.port.in.command.ChangeGroupCommand; import flipnote.group.application.port.in.command.CreateGroupCommand; import flipnote.group.domain.model.BaseEntity; import flipnote.group.domain.model.group.Category; @@ -66,4 +67,20 @@ private GroupEntity(String name, Category category, String description, JoinPoli this.imageRefId = imageRefId; this.memberCount = memberCount; } + + /** + * 업데이트 + * @param cmd + */ + public void change( + ChangeGroupCommand cmd + ) { + this.name = cmd.name(); + this.category = cmd.category(); + this.description = cmd.description(); + this.joinPolicy = cmd.joinPolicy(); + this.visibility = cmd.visibility(); + this.maxMember = cmd.maxMember(); + this.imageRefId = cmd.imageRefId(); + } } diff --git a/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java b/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java index 63d3372..a9bf8c8 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/GroupRepositoryAdapter.java @@ -1,5 +1,7 @@ package flipnote.group.adapter.out.persistence; +import java.util.Optional; + import org.springframework.stereotype.Repository; import flipnote.group.adapter.out.entity.GroupEntity; @@ -15,9 +17,47 @@ public class GroupRepositoryAdapter implements GroupRepositoryPort { private final GroupRepository groupRepository; + /** + * 그룹 저장 + * @param group + * @return + */ @Override public Long saveNewGroup(Group group) { GroupEntity entity = GroupMapper.createNewEntity(group); return groupRepository.save(entity).getId(); } + + @Override + public Group findById(Long id) { + GroupEntity groupEntity = groupRepository.findById(id).orElseThrow( + () -> new IllegalArgumentException("Group not Exist") + ); + return GroupMapper.toDomain(groupEntity); + } + + /** + * 그룹 수정 + * @param group + */ + @Override + public Group update(Group group) { + + GroupEntity groupEntity = groupRepository.findById(group.getId()).orElseThrow( + () -> new IllegalArgumentException("group not Exist") + ); + + groupEntity.change( + group.getName(), + group.getCategory(), + group.getDescription(), + group.getJoinPolicy(), + group.getVisibility(), + group.getMaxMember(), + group.getImageRefId() + ); + + return GroupMapper.toDomain(groupEntity); + } + } diff --git a/src/main/java/flipnote/group/adapter/out/persistence/mapper/GroupMapper.java b/src/main/java/flipnote/group/adapter/out/persistence/mapper/GroupMapper.java index c89f7f0..77d472e 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/mapper/GroupMapper.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/mapper/GroupMapper.java @@ -28,4 +28,25 @@ public static GroupEntity createNewEntity(Group domain) { .memberCount(domain.getMemberCount()) .build(); } + + /** + * 엔티티 -> 도메인 + * @param e + * @return + */ + public static Group toDomain(GroupEntity e) { + return Group.restore( + e.getId(), + e.getName(), + e.getCategory(), + e.getDescription(), + e.getJoinPolicy(), + e.getVisibility(), + e.getMaxMember(), + e.getImageRefId(), + e.getMemberCount(), + e.getCreatedAt(), + e.getModifiedAt() + ); + } } diff --git a/src/main/java/flipnote/group/api/dto/request/ChangeGroupRequestDto.java b/src/main/java/flipnote/group/api/dto/request/ChangeGroupRequestDto.java new file mode 100644 index 0000000..c95c330 --- /dev/null +++ b/src/main/java/flipnote/group/api/dto/request/ChangeGroupRequestDto.java @@ -0,0 +1,20 @@ +package flipnote.group.api.dto.request; + +import flipnote.group.domain.model.group.Category; +import flipnote.group.domain.model.group.JoinPolicy; +import flipnote.group.domain.model.group.Visibility; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +public record ChangeGroupRequestDto( + @NotBlank String name, + @NotNull Category category, + @NotBlank String description, + @NotNull JoinPolicy joinPolicy, + @NotNull Visibility visibility, + @NotNull @Min(1) @Max(100) Integer maxMember, + Long imageRefId +) { +} diff --git a/src/main/java/flipnote/group/api/dto/response/ChangeGroupResponseDto.java b/src/main/java/flipnote/group/api/dto/response/ChangeGroupResponseDto.java new file mode 100644 index 0000000..add99f9 --- /dev/null +++ b/src/main/java/flipnote/group/api/dto/response/ChangeGroupResponseDto.java @@ -0,0 +1,46 @@ +package flipnote.group.api.dto.response; + +import java.time.LocalDateTime; + +import flipnote.group.application.port.in.result.ChangeGroupResult; +import flipnote.group.domain.model.group.Category; +import flipnote.group.domain.model.group.Group; +import flipnote.group.domain.model.group.JoinPolicy; +import flipnote.group.domain.model.group.Visibility; + +public record ChangeGroupResponseDto( + String name, + + Category category, + + String description, + + JoinPolicy joinPolicy, + + Visibility visibility, + + Integer maxMember, + + Long imageRefId, + + LocalDateTime createdAt, + + LocalDateTime modifiedAt +) { + public static ChangeGroupResponseDto from(ChangeGroupResult result) { + + Group group = result.group(); + + return new ChangeGroupResponseDto( + group.getName(), + group.getCategory(), + group.getDescription(), + group.getJoinPolicy(), + group.getVisibility(), + group.getMaxMember(), + group.getImageRefId(), + group.getCreatedAt(), + group.getModifiedAt() + ); + } +} diff --git a/src/main/java/flipnote/group/application/port/in/ChangeGroupUseCase.java b/src/main/java/flipnote/group/application/port/in/ChangeGroupUseCase.java new file mode 100644 index 0000000..fc6f38f --- /dev/null +++ b/src/main/java/flipnote/group/application/port/in/ChangeGroupUseCase.java @@ -0,0 +1,8 @@ +package flipnote.group.application.port.in; + +import flipnote.group.application.port.in.command.ChangeGroupCommand; +import flipnote.group.application.port.in.result.ChangeGroupResult; + +public interface ChangeGroupUseCase { + ChangeGroupResult change(ChangeGroupCommand cmd); +} diff --git a/src/main/java/flipnote/group/application/port/in/CreateGroupUseCase.java b/src/main/java/flipnote/group/application/port/in/CreateGroupUseCase.java index d58a135..c670d61 100644 --- a/src/main/java/flipnote/group/application/port/in/CreateGroupUseCase.java +++ b/src/main/java/flipnote/group/application/port/in/CreateGroupUseCase.java @@ -4,5 +4,5 @@ import flipnote.group.application.port.in.result.CreateGroupResult; public interface CreateGroupUseCase { - CreateGroupResult create(CreateGroupCommand cmd, Long userId); + CreateGroupResult create(CreateGroupCommand cmd); } diff --git a/src/main/java/flipnote/group/application/port/in/command/ChangeGroupCommand.java b/src/main/java/flipnote/group/application/port/in/command/ChangeGroupCommand.java new file mode 100644 index 0000000..c7cc7ba --- /dev/null +++ b/src/main/java/flipnote/group/application/port/in/command/ChangeGroupCommand.java @@ -0,0 +1,19 @@ +package flipnote.group.application.port.in.command; + +import flipnote.group.domain.model.group.Category; +import flipnote.group.domain.model.group.JoinPolicy; +import flipnote.group.domain.model.group.Visibility; + +public record ChangeGroupCommand( + Long groupId, + Long userId, + String name, + Category category, + String description, + JoinPolicy joinPolicy, + Visibility visibility, + int maxMember, + Long imageRefId +) { + +} diff --git a/src/main/java/flipnote/group/application/port/in/command/CreateGroupCommand.java b/src/main/java/flipnote/group/application/port/in/command/CreateGroupCommand.java index 40a2f58..f12640f 100644 --- a/src/main/java/flipnote/group/application/port/in/command/CreateGroupCommand.java +++ b/src/main/java/flipnote/group/application/port/in/command/CreateGroupCommand.java @@ -5,6 +5,7 @@ import flipnote.group.domain.model.group.Visibility; public record CreateGroupCommand( + Long userId, String name, Category category, String description, diff --git a/src/main/java/flipnote/group/application/port/in/result/ChangeGroupResult.java b/src/main/java/flipnote/group/application/port/in/result/ChangeGroupResult.java new file mode 100644 index 0000000..32b2499 --- /dev/null +++ b/src/main/java/flipnote/group/application/port/in/result/ChangeGroupResult.java @@ -0,0 +1,8 @@ +package flipnote.group.application.port.in.result; + +import flipnote.group.domain.model.group.Group; + +public record ChangeGroupResult( + Group group +) { +} diff --git a/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java b/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java index 8622b41..5858851 100644 --- a/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java +++ b/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java @@ -1,7 +1,5 @@ package flipnote.group.application.port.out; -import flipnote.group.domain.model.member.GroupMemberRole; - public interface GroupMemberRepositoryPort { void saveOwner(Long groupId, Long userId); } diff --git a/src/main/java/flipnote/group/application/port/out/GroupRepositoryPort.java b/src/main/java/flipnote/group/application/port/out/GroupRepositoryPort.java index b1a2f7c..5bc40cf 100644 --- a/src/main/java/flipnote/group/application/port/out/GroupRepositoryPort.java +++ b/src/main/java/flipnote/group/application/port/out/GroupRepositoryPort.java @@ -4,4 +4,8 @@ public interface GroupRepositoryPort { Long saveNewGroup(Group group); + + Group findById(Long id); + + Group update(Group group); } diff --git a/src/main/java/flipnote/group/application/service/ChangeGroupService.java b/src/main/java/flipnote/group/application/service/ChangeGroupService.java new file mode 100644 index 0000000..f42fab6 --- /dev/null +++ b/src/main/java/flipnote/group/application/service/ChangeGroupService.java @@ -0,0 +1,41 @@ +package flipnote.group.application.service; + +import java.util.Optional; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import flipnote.group.adapter.out.entity.GroupEntity; +import flipnote.group.adapter.out.persistence.mapper.GroupMapper; +import flipnote.group.application.port.in.ChangeGroupUseCase; +import flipnote.group.application.port.in.command.ChangeGroupCommand; +import flipnote.group.application.port.in.result.ChangeGroupResult; +import flipnote.group.application.port.out.GroupRepositoryPort; +import flipnote.group.domain.model.group.Group; +import flipnote.group.infrastructure.persistence.jpa.GroupRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ChangeGroupService implements ChangeGroupUseCase { + + private final GroupRepository jpaGroupRepository; + + /** + * 그룹 수정 + * @param cmd + * @return + */ + @Override + @Transactional + public ChangeGroupResult change(ChangeGroupCommand cmd) { + + GroupEntity entity = jpaGroupRepository.findById(cmd.groupId()).orElseThrow( + () -> new IllegalArgumentException("group not Exists") + ); + + entity.change(cmd); + + return new ChangeGroupResult(GroupMapper.toDomain(entity)); + } +} diff --git a/src/main/java/flipnote/group/application/service/CreateGroupService.java b/src/main/java/flipnote/group/application/service/CreateGroupService.java index 5ad6e36..88bd774 100644 --- a/src/main/java/flipnote/group/application/service/CreateGroupService.java +++ b/src/main/java/flipnote/group/application/service/CreateGroupService.java @@ -22,12 +22,11 @@ public class CreateGroupService implements CreateGroupUseCase { /** * 그룹 생성 * @param cmd - * @param userId * @return */ @Override @Transactional - public CreateGroupResult create(CreateGroupCommand cmd, Long userId) { + public CreateGroupResult create(CreateGroupCommand cmd) { //도메인 생성 및 검증 var domainGroup = Group.create(cmd); @@ -36,7 +35,7 @@ public CreateGroupResult create(CreateGroupCommand cmd, Long userId) { Long groupId = groupRepository.saveNewGroup(domainGroup); //그룹 멤버 저장 - groupMemberRepository.saveOwner(groupId, userId); + groupMemberRepository.saveOwner(groupId, cmd.userId()); return new CreateGroupResult(groupId); } diff --git a/src/main/java/flipnote/group/domain/model/group/Group.java b/src/main/java/flipnote/group/domain/model/group/Group.java index e65508d..04dc07a 100644 --- a/src/main/java/flipnote/group/domain/model/group/Group.java +++ b/src/main/java/flipnote/group/domain/model/group/Group.java @@ -1,5 +1,8 @@ package flipnote.group.domain.model.group; +import java.time.LocalDateTime; + +import flipnote.group.application.port.in.command.ChangeGroupCommand; import flipnote.group.application.port.in.command.CreateGroupCommand; import lombok.AccessLevel; import lombok.Builder; @@ -8,7 +11,6 @@ import lombok.Setter; @Getter -@Setter @NoArgsConstructor(access = AccessLevel.PRIVATE) public class Group { @@ -24,6 +26,9 @@ public class Group { private Long imageRefId; private int memberCount; + private LocalDateTime createdAt; + private LocalDateTime modifiedAt; + /** * 신규로 그룹 생성 * @param cmd @@ -59,7 +64,7 @@ public static Group create(CreateGroupCommand cmd) { * @param memberCount * @return */ - public static Group getGroup( + public static Group restore( Long id, String name, Category category, @@ -68,7 +73,9 @@ public static Group getGroup( Visibility visibility, int maxMember, Long imageRefId, - int memberCount + int memberCount, + LocalDateTime createdAt, + LocalDateTime modifiedAt ) { Group g = new Group(); g.id = id; @@ -80,6 +87,8 @@ public static Group getGroup( g.maxMember = maxMember; g.imageRefId = imageRefId; g.memberCount = memberCount; + g.createdAt = createdAt; + g.modifiedAt = modifiedAt; return g; }