From 5beabefeac8e02fd627e6ce9aef150949e7e2ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=85=B8=EA=B2=BD=EB=AF=BC?= Date: Sun, 26 Feb 2023 21:09:33 +0900 Subject: [PATCH] =?UTF-8?q?fix=20:=20=ED=98=B8=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=A0=91=EA=B7=BC=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=84=A4=EC=A0=95=20(#459)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix : 호스트 이벤트 접근 권한 설정 * fix : 내가 관리중인 이벤트 권한 적용 * feat : 호스트 초대 거절 추가 --- .../api/event/model/mapper/EventMapper.java | 2 +- .../api/host/controller/HostController.java | 8 +++- .../host/service/ReadHostEventsUseCase.java | 4 ++ .../api/host/service/RejectHostUseCase.java | 30 +++++++++++++ .../domains/host/adaptor/HostAdaptor.java | 9 ++++ .../domain/domains/host/domain/Host.java | 13 ++++-- .../domain/domains/host/domain/HostUser.java | 2 +- .../host/repository/HostCustomRepository.java | 5 +++ .../repository/HostCustomRepositoryImpl.java | 45 ++++++++++++++++++- .../domains/host/service/HostService.java | 5 +++ 10 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 DuDoong-Api/src/main/java/band/gosrock/api/host/service/RejectHostUseCase.java diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/event/model/mapper/EventMapper.java b/DuDoong-Api/src/main/java/band/gosrock/api/event/model/mapper/EventMapper.java index baaa23b6..5208c419 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/event/model/mapper/EventMapper.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/event/model/mapper/EventMapper.java @@ -80,7 +80,7 @@ public Page toEventProfileResponsePage(Long userId, Pageab } public Slice toEventProfileResponseSlice(Long userId, Pageable pageable) { - List hosts = hostAdaptor.findAllByHostUsers_UserId(userId); + List hosts = hostAdaptor.querySliceHostsByActiveUserId(userId); List hostIds = hosts.stream().map(Host::getId).toList(); Slice events = eventAdaptor.querySliceEventsByHostIdIn(hostIds, pageable); return events.map(event -> this.toEventProfileResponse(hosts, event)); diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/host/controller/HostController.java b/DuDoong-Api/src/main/java/band/gosrock/api/host/controller/HostController.java index dcaa9aa5..ebacb045 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/host/controller/HostController.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/host/controller/HostController.java @@ -39,6 +39,7 @@ public class HostController { private final UpdateHostUserRoleUseCase updateHostUserRoleUseCase; private final InviteHostUseCase inviteHostUseCase; private final JoinHostUseCase joinHostUseCase; + private final RejectHostUseCase rejectHostUseCase; @Operation(summary = "내가 속한 호스트 리스트를 가져옵니다.") @GetMapping @@ -80,6 +81,12 @@ public HostDetailResponse joinHost(@PathVariable Long hostId) { return joinHostUseCase.execute(hostId); } + @Operation(summary = "호스트 초대를 거절합니다.") + @PostMapping("/{hostId}/reject") + public HostDetailResponse rejectHost(@PathVariable Long hostId) { + return rejectHostUseCase.execute(hostId); + } + @Operation(summary = "다른 유저를 호스트 유저로 초대합니다.") @PostMapping("/{hostId}/invite") public HostDetailResponse inviteHost( @@ -95,7 +102,6 @@ public HostDetailResponse patchHostUserRole( return updateHostUserRoleUseCase.execute(hostId, updateHostUserRoleRequest); } - // todo :: 슈퍼 호스트 이상으로? @Operation(summary = "호스트 정보를 변경합니다. 매니저 이상만 가능합니다.") @PatchMapping("/{hostId}/profile") public HostDetailResponse patchHostById( diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/host/service/ReadHostEventsUseCase.java b/DuDoong-Api/src/main/java/band/gosrock/api/host/service/ReadHostEventsUseCase.java index 8f74ed99..07d9d84c 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/host/service/ReadHostEventsUseCase.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/host/service/ReadHostEventsUseCase.java @@ -1,6 +1,9 @@ package band.gosrock.api.host.service; +import static band.gosrock.api.common.aop.hostRole.FindHostFrom.HOST_ID; +import static band.gosrock.api.common.aop.hostRole.HostQualification.GUEST; +import band.gosrock.api.common.aop.hostRole.HostRolesAllowed; import band.gosrock.api.common.page.PageResponse; import band.gosrock.api.host.model.dto.response.HostEventProfileResponse; import band.gosrock.common.annotation.UseCase; @@ -18,6 +21,7 @@ public class ReadHostEventsUseCase { private final HostAdaptor hostAdaptor; private final EventAdaptor eventAdaptor; + @HostRolesAllowed(role = GUEST, findHostFrom = HOST_ID) public PageResponse execute(Long hostId, Pageable pageable) { Host host = hostAdaptor.findById(hostId); return PageResponse.of( diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/host/service/RejectHostUseCase.java b/DuDoong-Api/src/main/java/band/gosrock/api/host/service/RejectHostUseCase.java new file mode 100644 index 00000000..15e37ea8 --- /dev/null +++ b/DuDoong-Api/src/main/java/band/gosrock/api/host/service/RejectHostUseCase.java @@ -0,0 +1,30 @@ +package band.gosrock.api.host.service; + + +import band.gosrock.api.common.UserUtils; +import band.gosrock.api.host.model.dto.response.HostDetailResponse; +import band.gosrock.api.host.model.mapper.HostMapper; +import band.gosrock.common.annotation.UseCase; +import band.gosrock.domain.domains.host.adaptor.HostAdaptor; +import band.gosrock.domain.domains.host.domain.Host; +import band.gosrock.domain.domains.host.service.HostService; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@UseCase +@RequiredArgsConstructor +public class RejectHostUseCase { + + private final UserUtils userUtils; + private final HostService hostService; + private final HostAdaptor hostAdaptor; + private final HostMapper hostMapper; + + @Transactional + public HostDetailResponse execute(Long hostId) { + final Long userId = userUtils.getCurrentUserId(); + final Host host = hostAdaptor.findById(hostId); + + return hostMapper.toHostDetailResponse(hostService.removeHostUser(host, userId)); + } +} diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/adaptor/HostAdaptor.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/adaptor/HostAdaptor.java index f8909824..3e06bd63 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/adaptor/HostAdaptor.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/adaptor/HostAdaptor.java @@ -38,4 +38,13 @@ public Page findAllByHostUsers_UserId(Long userId, Pageable pageable) { public List findAllByHostUsers_UserId(Long userId) { return hostRepository.findAllByHostUsers_UserId(userId); } + + /** 자신이 속해있는 호스트 리스트 중 초대 수락한 호스트만 가져오는 쿼리 요청 */ + public List querySliceHostsByActiveUserId(Long userId) { + return hostRepository.queryHostsByActiveUserId(userId); + } + + public Slice querySliceHostsByActiveUserId(Long userId, Pageable pageable) { + return hostRepository.querySliceHostsByActiveUserId(userId, pageable); + } } diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/Host.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/Host.java index 43e699d7..0152aab1 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/Host.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/Host.java @@ -43,7 +43,11 @@ public class Host extends BaseTimeEntity { private String slackUrl; // 단방향 oneToMany 매핑 - @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @OneToMany( + mappedBy = "host", + cascade = CascadeType.ALL, + orphanRemoval = true, + fetch = FetchType.EAGER) @OrderBy("createdAt DESC") private final Set hostUsers = new HashSet<>(); @@ -113,6 +117,11 @@ public void setHostUserRole(Long userId, HostRole role) { .setHostRole(role); } + public void removeHostUser(Long userId) { + if (this.isActiveHostUserId(userId)) throw AlreadyJoinedHostException.EXCEPTION; + this.hostUsers.remove(this.getHostUserByUserId(userId)); + } + /** 해당 유저가 호스트에 이미 속하는지 확인하는 검증 로직입니다 */ public void validateHostUserIdExistence(Long userId) { if (this.hasHostUserId(userId)) { @@ -124,8 +133,6 @@ public void validateHostUserExistence(HostUser hostUser) { validateHostUserIdExistence(hostUser.getUserId()); } - // todo :: 여기서부터 테스트 진행 - /** 해당 유저가 호스트에 속하는지 확인하는 검증 로직입니다 */ public void validateHostUser(Long userId) { if (!this.hasHostUserId(userId)) throw ForbiddenHostException.EXCEPTION; diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/HostUser.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/HostUser.java index 81c4736f..b3e8fe35 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/HostUser.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/domain/HostUser.java @@ -25,7 +25,7 @@ public class HostUser extends BaseTimeEntity { private Long id; // 소속 호스트 아이디 - @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "host_id") private Host host; diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepository.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepository.java index 99f6b4b2..55d3dbef 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepository.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepository.java @@ -2,9 +2,14 @@ import band.gosrock.domain.domains.host.domain.Host; +import java.util.List; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; public interface HostCustomRepository { Slice querySliceHostsByUserId(Long id, Pageable pageable); + + List queryHostsByActiveUserId(Long id); + + Slice querySliceHostsByActiveUserId(Long id, Pageable pageable); } diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepositoryImpl.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepositoryImpl.java index 4fb2f285..5a00dcac 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepositoryImpl.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/repository/HostCustomRepositoryImpl.java @@ -5,6 +5,8 @@ import band.gosrock.domain.common.util.SliceUtil; import band.gosrock.domain.domains.host.domain.Host; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; import lombok.RequiredArgsConstructor; @@ -22,12 +24,51 @@ public Slice querySliceHostsByUserId(Long userId, Pageable pageable) { queryFactory .select(host) .from(host, hostUser) - .where(hostUser.userId.eq(userId), host.hostUsers.contains(hostUser)) + .where(hostUserIdEq(userId), host.hostUsers.contains(hostUser)) .offset(pageable.getOffset()) - .orderBy(host.id.desc()) + .orderBy(hostIdDesc()) .limit(pageable.getPageSize() + 1) .fetch(); return SliceUtil.valueOf(hosts, pageable); } + + @Override + public List queryHostsByActiveUserId(Long userId) { + return queryFactory + .select(host) + .from(host, hostUser) + .where(hostUserIdEq(userId), host.hostUsers.contains(hostUser), hostUserActive()) + .fetch(); + } + + @Override + public Slice querySliceHostsByActiveUserId(Long userId, Pageable pageable) { + List hosts = + queryFactory + .select(host) + .from(host, hostUser) + .where( + hostUserIdEq(userId), + host.hostUsers.contains(hostUser), + hostUserActive()) + .offset(pageable.getOffset()) + .orderBy(hostIdDesc()) + .limit(pageable.getPageSize() + 1) + .fetch(); + + return SliceUtil.valueOf(hosts, pageable); + } + + private BooleanExpression hostUserIdEq(Long userId) { + return hostUser.userId.eq(userId); + } + + private BooleanExpression hostUserActive() { + return hostUser.active.isTrue(); + } + + private OrderSpecifier hostIdDesc() { + return host.id.desc(); + } } diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/service/HostService.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/service/HostService.java index f9e759d8..916d7db7 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/service/HostService.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/host/service/HostService.java @@ -55,6 +55,11 @@ public Host activateHostUser(Host host, Long userId) { return hostRepository.save(host); } + public Host removeHostUser(Host host, Long userId) { + host.removeHostUser(userId); + return hostRepository.save(host); + } + public void validateDuplicatedSlackUrl(Host host, String url) { if (StringUtils.equals(host.getSlackUrl(), url)) { throw InvalidSlackUrlException.EXCEPTION;