diff --git a/src/main/java/idorm/idormServer/auth/adapter/in/web/AuthController.java b/src/main/java/idorm/idormServer/auth/adapter/in/web/AuthController.java index e97794e9..1d4d8a50 100644 --- a/src/main/java/idorm/idormServer/auth/adapter/in/web/AuthController.java +++ b/src/main/java/idorm/idormServer/auth/adapter/in/web/AuthController.java @@ -69,8 +69,15 @@ public ResponseEntity> login( .body(SuccessResponse.from(AuthResponseCode.MEMBER_LOGIN)); } - @Operation(summary = "Access Token 재발급", security = {@SecurityRequirement(name = AUTHORIZATION), - @SecurityRequirement(name = "Refresh-Token")}) + @Auth + @Operation(summary = "Access Token 재발급", + description = "해당 API 사용법\n" + + "1. 원래 보내려던 요청을 보내기 전, access token의 payload를 통해 만료 기한을 얻습니다.\n" + + "2. 만료 기한이 지난 토큰이라면, 해당 API 요청을 보낸 후에 새로운 access token을 발급받습니다.\n" + + "3. 그 후에 원래 하려던 요청을 보내주세요.\n" + + "-> 목적 : 네트워크 요청 줄이기", + security = {@SecurityRequirement(name = AUTHORIZATION), + @SecurityRequirement(name = "Refresh-Token")}) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "MEMBER_REFRESH"), @ApiResponse(responseCode = "401", description = "UNAUTHORIZED_ACCESS_TOKEN / UNAUTHORIZED_REFRESH_TOKEN"), @@ -84,8 +91,11 @@ public ResponseEntity> refresh( @AuthInfo AuthResponse auth ) { validateExistHeader(servletRequest); + String accessToken = AuthorizationExtractor.extractAccessToken(servletRequest); String refreshToken = AuthorizationExtractor.extractRefreshToken(servletRequest); + // TODO: 만료된 access token도 받도록 처리해야 한다.(BUG) + refreshTokenUseCase.matches(refreshToken, auth.getId()); String reissueAccessToken = jwtTokenUseCase.createAccessToken(auth); @@ -114,9 +124,10 @@ public ResponseEntity> logout( } private void validateExistHeader(HttpServletRequest request) { + String accessTokenHeader = request.getHeader(AUTHORIZATION); String refreshTokenHeader = request.getHeader("Refresh-Token"); - if (Objects.isNull(refreshTokenHeader)) { + if (Objects.isNull(accessTokenHeader) || Objects.isNull(refreshTokenHeader)) { throw new UnAuthorizedRefreshTokenException(); } } diff --git a/src/main/java/idorm/idormServer/auth/adapter/out/persistence/RefreshTokenRepository.java b/src/main/java/idorm/idormServer/auth/adapter/out/persistence/RefreshTokenRepository.java index 8b5feee0..be9ae703 100644 --- a/src/main/java/idorm/idormServer/auth/adapter/out/persistence/RefreshTokenRepository.java +++ b/src/main/java/idorm/idormServer/auth/adapter/out/persistence/RefreshTokenRepository.java @@ -3,6 +3,7 @@ import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Repository; import idorm.idormServer.auth.entity.RefreshToken; @@ -12,5 +13,6 @@ public interface RefreshTokenRepository extends JpaRepository findByMemberId(Long memberId); + @Modifying void deleteAllByMemberId(Long memberId); } diff --git a/src/main/java/idorm/idormServer/calendar/adapter/in/web/TeamController.java b/src/main/java/idorm/idormServer/calendar/adapter/in/web/TeamController.java index c8dbb021..7ed4d333 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/in/web/TeamController.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/in/web/TeamController.java @@ -90,7 +90,7 @@ public ResponseEntity> deleteTeamMember( @Positive(message = "삭제할 회원 식별자는 양수만 가능합니다.") Long memberId ) { - teamUseCase.deleteMember(authResponse, memberId); + teamUseCase.deleteMember(memberId); return ResponseEntity.ok().body(SuccessResponse.from(TEAM_MEMBER_DELETED)); } diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteSleepoverCalendarAdapter.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteSleepoverCalendarAdapter.java index a249164b..f67373d5 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteSleepoverCalendarAdapter.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteSleepoverCalendarAdapter.java @@ -17,4 +17,9 @@ public class DeleteSleepoverCalendarAdapter implements DeleteSleepoverCalendarPo public void delete(SleepoverCalendar sleepoverCalendar) { sleepoverCalendarRepository.delete(sleepoverCalendar); } + + @Override + public void deleteByMemberId(Long memberId) { + sleepoverCalendarRepository.deleteByMemberId(memberId); + } } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamAdapter.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamAdapter.java index 1b471904..f36c2070 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamAdapter.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamAdapter.java @@ -1,11 +1,11 @@ package idorm.idormServer.calendar.adapter.out.persistence; +import org.springframework.stereotype.Component; + import idorm.idormServer.calendar.application.port.out.DeleteTeamPort; import idorm.idormServer.calendar.entity.Team; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - @Component @RequiredArgsConstructor public class DeleteTeamAdapter implements DeleteTeamPort { @@ -14,6 +14,6 @@ public class DeleteTeamAdapter implements DeleteTeamPort { @Override public void delete(Team team) { - teamRepository.delete(team); + teamRepository.deleteById(team.getId()); } } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamCalendarAdapter.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamCalendarAdapter.java index 3b30ff99..e2d8e60e 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamCalendarAdapter.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamCalendarAdapter.java @@ -1,12 +1,12 @@ package idorm.idormServer.calendar.adapter.out.persistence; +import org.springframework.stereotype.Component; + import idorm.idormServer.calendar.application.port.out.DeleteTeamCalendarPort; import idorm.idormServer.calendar.entity.TeamCalendar; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - @Component @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class DeleteTeamCalendarAdapter implements DeleteTeamCalendarPort { diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamMemberAdapter.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamMemberAdapter.java new file mode 100644 index 00000000..326beec3 --- /dev/null +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/DeleteTeamMemberAdapter.java @@ -0,0 +1,50 @@ +package idorm.idormServer.calendar.adapter.out.persistence; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import idorm.idormServer.calendar.application.port.out.DeleteSleepoverCalendarPort; +import idorm.idormServer.calendar.application.port.out.DeleteTeamCalendarPort; +import idorm.idormServer.calendar.application.port.out.DeleteTeamMemberPort; +import idorm.idormServer.calendar.application.port.out.DeleteTeamPort; +import idorm.idormServer.calendar.application.port.out.LoadTeamCalendarPort; +import idorm.idormServer.calendar.application.port.out.LoadTeamPort; +import idorm.idormServer.calendar.entity.Team; +import idorm.idormServer.calendar.entity.TeamCalendar; +import idorm.idormServer.member.entity.Member; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public class DeleteTeamMemberAdapter implements DeleteTeamMemberPort { + + private final LoadTeamPort loadTeamPort; + private final DeleteTeamPort deleteTeamPort; + + private final LoadTeamCalendarPort loadTeamCalendarPort; + private final DeleteTeamCalendarPort deleteTeamCalendarPort; + + private final DeleteSleepoverCalendarPort deleteSleepoverCalendarPort; + + @Override + public void deleteTeamMember(Member member) { + final Team team = loadTeamPort.findByMemberId(member.getId()); + final List teamCalendars = loadTeamCalendarPort.findByMemberId(member.getId()); + + team.deleteMember(member); + if (team.getMembers().isEmpty()) { + deleteSleepoverCalendarPort.deleteByMemberId(member.getId()); + deleteTeamPort.delete(team); + } else { + deleteSleepoverCalendarPort.deleteByMemberId(member.getId()); + teamCalendars + .forEach(teamCalendar -> { + teamCalendar.deletePariticipant(member.getId()); + if (teamCalendar.getParticipants().isEmpty()) + deleteTeamCalendarPort.delete(teamCalendar); + }); + } + } +} \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamAdapter.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamAdapter.java index fc434645..fc712145 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamAdapter.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamAdapter.java @@ -1,15 +1,14 @@ package idorm.idormServer.calendar.adapter.out.persistence; +import java.util.Optional; + +import org.springframework.stereotype.Component; + import idorm.idormServer.calendar.adapter.out.exception.NotFoundTeamException; import idorm.idormServer.calendar.application.port.out.LoadTeamPort; import idorm.idormServer.calendar.entity.Team; - -import java.util.Optional; - import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - @Component @RequiredArgsConstructor public class LoadTeamAdapter implements LoadTeamPort { @@ -24,7 +23,7 @@ public Optional findByMemberIdWithOptional(Long memberId) { @Override public Team findByMemberId(Long memberId) { - Team response = findByMemberId(memberId); + Team response = teamRepository.findByMemberId(memberId); if (response == null) { throw new NotFoundTeamException(); } diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamCalendarAdapter.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamCalendarAdapter.java index 97e53d69..5b1e9d16 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamCalendarAdapter.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/LoadTeamCalendarAdapter.java @@ -1,20 +1,19 @@ package idorm.idormServer.calendar.adapter.out.persistence; +import java.time.YearMonth; +import java.util.Collections; +import java.util.List; + +import org.springframework.stereotype.Component; + import idorm.idormServer.calendar.adapter.out.exception.NotFoundTeamCalendarException; import idorm.idormServer.calendar.application.port.out.LoadTeamCalendarPort; import idorm.idormServer.calendar.entity.Team; import idorm.idormServer.calendar.entity.TeamCalendar; import idorm.idormServer.notification.adapter.out.api.NotificationRequest; - -import java.time.YearMonth; -import java.util.Collections; -import java.util.List; - import lombok.AccessLevel; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - @Component @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class LoadTeamCalendarAdapter implements LoadTeamCalendarPort { @@ -39,7 +38,7 @@ public TeamCalendar findByIdAndMemberId(Long teamCalendarId, Long memberId) { @Override public List findByMemberId(Long memberId) { - List responses = findByMemberId(memberId); + List responses = teamCalendarRepository.findByMemberId(memberId); return responses != null ? responses : Collections.emptyList(); } diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepository.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepository.java index 51ac67bc..98202622 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepository.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepository.java @@ -1,14 +1,14 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import idorm.idormServer.calendar.entity.Period; -import idorm.idormServer.calendar.entity.SleepoverCalendar; -import idorm.idormServer.calendar.entity.Team; - import java.time.YearMonth; import java.util.List; import org.springframework.stereotype.Repository; +import idorm.idormServer.calendar.entity.Period; +import idorm.idormServer.calendar.entity.SleepoverCalendar; +import idorm.idormServer.calendar.entity.Team; + @Repository public interface SleepoverCalendarCustomRepository { @@ -21,4 +21,6 @@ public interface SleepoverCalendarCustomRepository { Long hasOverlappingDatesWithSleepoverId(Long memberId, Period period, Long sleepoverCalendarId); Long hasOverlappingDatesWithoutSleepoverId(Long memberId, Period period); + + void deleteByMemberId(Long memberId); } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepositoryImpl.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepositoryImpl.java index b43dc24d..79902d28 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepositoryImpl.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarCustomRepositoryImpl.java @@ -1,18 +1,17 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import static idorm.idormServer.calendar.entity.QSleepoverCalendar.sleepoverCalendar; -import static idorm.idormServer.calendar.entity.QTeam.team; +import static idorm.idormServer.calendar.entity.QSleepoverCalendar.*; +import static idorm.idormServer.calendar.entity.QTeam.*; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.util.List; import com.querydsl.jpa.impl.JPAQueryFactory; import idorm.idormServer.calendar.entity.Period; import idorm.idormServer.calendar.entity.SleepoverCalendar; import idorm.idormServer.calendar.entity.Team; - -import java.time.LocalDate; -import java.time.YearMonth; -import java.util.List; - import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -75,4 +74,12 @@ public Long hasOverlappingDatesWithoutSleepoverId(Long memberId, Period period) .and(sleepoverCalendar.memberId.eq(memberId))) .fetchCount(); } + + @Override + public void deleteByMemberId(Long memberId) { + queryFactory + .delete(sleepoverCalendar) + .where(sleepoverCalendar.memberId.eq(memberId)) + .execute(); + } } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarRepository.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarRepository.java index 7fc8c7fa..d19177af 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarRepository.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/SleepoverCalendarRepository.java @@ -1,15 +1,17 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import idorm.idormServer.calendar.entity.SleepoverCalendar; - import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import idorm.idormServer.calendar.entity.SleepoverCalendar; + @Repository public interface SleepoverCalendarRepository extends JpaRepository, SleepoverCalendarCustomRepository { List findByMemberId(Long memberId); + + void deleteByMemberId(Long memberId); } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarCustomRepositoryImpl.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarCustomRepositoryImpl.java index 403f084d..31d99dea 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarCustomRepositoryImpl.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarCustomRepositoryImpl.java @@ -1,9 +1,13 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import static idorm.idormServer.calendar.entity.QParticipant.participant; -import static idorm.idormServer.calendar.entity.QTeam.team; -import static idorm.idormServer.calendar.entity.QTeamCalendar.teamCalendar; -import static idorm.idormServer.notification.entity.QFcmToken.fcmToken; +import static idorm.idormServer.calendar.entity.QParticipant.*; +import static idorm.idormServer.calendar.entity.QTeam.*; +import static idorm.idormServer.calendar.entity.QTeamCalendar.*; +import static idorm.idormServer.notification.entity.QFcmToken.*; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.util.List; import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -12,11 +16,6 @@ import idorm.idormServer.calendar.entity.TeamCalendar; import idorm.idormServer.notification.adapter.out.api.NotificationRequest; import idorm.idormServer.notification.entity.FcmChannel; - -import java.time.LocalDate; -import java.time.YearMonth; -import java.util.List; - import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -40,8 +39,8 @@ public List findByMemberId(Long memberId) { return queryFactory .select(teamCalendar) .from(teamCalendar) - .join(teamCalendar.team, team) - .where(teamCalendar.participants.participants.any().memberId.eq(memberId)) + .join(teamCalendar.participants.participants, participant) + .where(participant.memberId.eq(memberId)) .fetch(); } diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarRepository.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarRepository.java index 70667e70..ebc5cc5a 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarRepository.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCalendarRepository.java @@ -1,17 +1,14 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import idorm.idormServer.calendar.entity.TeamCalendar; - -import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import idorm.idormServer.calendar.entity.TeamCalendar; + @Repository public interface TeamCalendarRepository extends JpaRepository, TeamCalendarCustomRepository { Optional findByIdAndTeamId(Long teamCalendarId, Long teamId); - - List findByTeamId(Long teamId); } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepository.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepository.java index 50a72d76..7c2a28a2 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepository.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepository.java @@ -1,9 +1,9 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import idorm.idormServer.calendar.entity.Team; - import org.springframework.stereotype.Repository; +import idorm.idormServer.calendar.entity.Team; + @Repository public interface TeamCustomRepository { diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepositoryImpl.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepositoryImpl.java index 81419d11..a4e81fd1 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepositoryImpl.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamCustomRepositoryImpl.java @@ -1,7 +1,7 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import static idorm.idormServer.calendar.entity.QTeam.team; -import static idorm.idormServer.member.entity.QMember.member; +import static idorm.idormServer.calendar.entity.QTeam.*; +import static idorm.idormServer.member.entity.QMember.*; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -11,7 +11,7 @@ @RequiredArgsConstructor public class TeamCustomRepositoryImpl implements TeamCustomRepository { - JPAQueryFactory queryFactory; + private final JPAQueryFactory queryFactory; @Override public Team findByMemberId(final Long memberId) { diff --git a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamRepository.java b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamRepository.java index 7afcac45..d3209e1a 100644 --- a/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamRepository.java +++ b/src/main/java/idorm/idormServer/calendar/adapter/out/persistence/TeamRepository.java @@ -1,11 +1,11 @@ package idorm.idormServer.calendar.adapter.out.persistence; -import idorm.idormServer.calendar.entity.Team; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import idorm.idormServer.calendar.entity.Team; + @Repository public interface TeamRepository extends JpaRepository, TeamCustomRepository { - + void deleteById(Long teamId); } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/application/TeamCalendarService.java b/src/main/java/idorm/idormServer/calendar/application/TeamCalendarService.java index 5a194e8a..10d8b789 100644 --- a/src/main/java/idorm/idormServer/calendar/application/TeamCalendarService.java +++ b/src/main/java/idorm/idormServer/calendar/application/TeamCalendarService.java @@ -1,5 +1,12 @@ package idorm.idormServer.calendar.application; +import java.util.Comparator; +import java.util.List; +import java.util.stream.IntStream; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import idorm.idormServer.auth.application.port.in.dto.AuthResponse; import idorm.idormServer.calendar.application.port.in.TeamCalendarUseCase; import idorm.idormServer.calendar.application.port.in.dto.FindOfficialCalendarsRequest; @@ -16,16 +23,8 @@ import idorm.idormServer.calendar.entity.TeamCalendar; import idorm.idormServer.member.application.port.out.LoadMemberPort; import idorm.idormServer.member.entity.Member; - -import java.util.Comparator; -import java.util.List; -import java.util.stream.IntStream; - import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -53,9 +52,9 @@ public TeamCalendarResponse save(final AuthResponse authResponse, final SaveTeam @Transactional @Override public TeamCalendarResponse update(final AuthResponse authResponse, final UpdateTeamCalendarRequest request) { - final TeamCalendar teamCalendar = loadTeamCalendarPort.findByIdAndMemberId(request.teamCalendarId(), - authResponse.getId()); final Team team = loadTeamPort.findByMemberId(authResponse.getId()); + final TeamCalendar teamCalendar = loadTeamCalendarPort.findByIdAndTeamId(request.teamCalendarId(), + team.getId()); teamCalendar.update(team, request.title(), request.content(), request.getPeriod(), request.startTime(), request.endTime(), request.targets()); diff --git a/src/main/java/idorm/idormServer/calendar/application/TeamService.java b/src/main/java/idorm/idormServer/calendar/application/TeamService.java index 0ebef5af..776dbcd1 100644 --- a/src/main/java/idorm/idormServer/calendar/application/TeamService.java +++ b/src/main/java/idorm/idormServer/calendar/application/TeamService.java @@ -1,9 +1,20 @@ package idorm.idormServer.calendar.application; +import static idorm.idormServer.member.entity.MemberStatus.*; + +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.stream.IntStream; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import idorm.idormServer.auth.application.port.in.dto.AuthResponse; import idorm.idormServer.calendar.application.port.in.TeamUseCase; import idorm.idormServer.calendar.application.port.in.dto.TeamParticipantResponse; import idorm.idormServer.calendar.application.port.in.dto.TeamResponse; +import idorm.idormServer.calendar.application.port.out.DeleteTeamMemberPort; import idorm.idormServer.calendar.application.port.out.DeleteTeamPort; import idorm.idormServer.calendar.application.port.out.LoadSleepoverCalendarPort; import idorm.idormServer.calendar.application.port.out.LoadTeamPort; @@ -12,17 +23,8 @@ import idorm.idormServer.calendar.entity.Team; import idorm.idormServer.member.application.port.out.LoadMemberPort; import idorm.idormServer.member.entity.Member; - -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.stream.IntStream; - import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -36,6 +38,7 @@ public class TeamService implements TeamUseCase { private final LoadSleepoverCalendarPort loadSleepoverCalendarPort; private final DeleteTeamPort deleteTeamPort; + private final DeleteTeamMemberPort deleteTeamMemberPort; @Override @Transactional @@ -60,12 +63,10 @@ public void addTeamMember(final AuthResponse authResponse, final Long registerMe @Override @Transactional - public void deleteMember(final AuthResponse authResponse, final Long targetId) { - final Member loginMember = loadMemberPort.loadMember(authResponse.getId()); - final Member deleteMember = loadMemberPort.loadMember(targetId); - final Team team = loadTeamPort.findByMemberId(loginMember.getId()); + public void deleteMember(final Long memberId) { + final Member member = loadMemberPort.loadMember(memberId); - team.deleteMember(deleteMember); + deleteTeamMemberPort.deleteTeamMember(member); } @Override @@ -74,7 +75,7 @@ public TeamResponse findTeam(final AuthResponse authResponse) { final List sleepoverCalendars = loadSleepoverCalendarPort.findByToday(team); List members = team.getMembers().stream() - .filter(member -> member.getMemberStatus().equals("ACTIVE")) + .filter(member -> member.getMemberStatus().equals(ACTIVE)) .sorted(Comparator.comparing(Member::getId)) .toList(); diff --git a/src/main/java/idorm/idormServer/calendar/application/port/in/TeamUseCase.java b/src/main/java/idorm/idormServer/calendar/application/port/in/TeamUseCase.java index f8e7a4b2..1bdd2b4f 100644 --- a/src/main/java/idorm/idormServer/calendar/application/port/in/TeamUseCase.java +++ b/src/main/java/idorm/idormServer/calendar/application/port/in/TeamUseCase.java @@ -7,7 +7,7 @@ public interface TeamUseCase { void addTeamMember(AuthResponse authResponse, Long registerMemberId); - void deleteMember(AuthResponse authResponse, Long memberId); + void deleteMember(Long memberId); void explodeTeam(AuthResponse authResponse); diff --git a/src/main/java/idorm/idormServer/calendar/application/port/in/dto/TeamResponse.java b/src/main/java/idorm/idormServer/calendar/application/port/in/dto/TeamResponse.java index 7a4ded4a..413737a7 100644 --- a/src/main/java/idorm/idormServer/calendar/application/port/in/dto/TeamResponse.java +++ b/src/main/java/idorm/idormServer/calendar/application/port/in/dto/TeamResponse.java @@ -3,17 +3,15 @@ import java.util.List; import idorm.idormServer.calendar.entity.Team; -import idorm.idormServer.calendar.entity.TeamStatus; public record TeamResponse( Long teamId, boolean isNeedToConfirmDeleted, List members ) { - public static TeamResponse of(final Team team, final List responses) { return new TeamResponse(team.getId(), - TeamStatus.isAlone(team.getTeamStatus()), + team.getTeamStatus().isAlone(), responses); } } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/application/port/out/DeleteSleepoverCalendarPort.java b/src/main/java/idorm/idormServer/calendar/application/port/out/DeleteSleepoverCalendarPort.java index 90b098be..065496f8 100644 --- a/src/main/java/idorm/idormServer/calendar/application/port/out/DeleteSleepoverCalendarPort.java +++ b/src/main/java/idorm/idormServer/calendar/application/port/out/DeleteSleepoverCalendarPort.java @@ -5,4 +5,6 @@ public interface DeleteSleepoverCalendarPort { void delete(SleepoverCalendar sleepoverCalendar); + + void deleteByMemberId(Long memberId); } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/calendar/application/port/out/DeleteTeamMemberPort.java b/src/main/java/idorm/idormServer/calendar/application/port/out/DeleteTeamMemberPort.java new file mode 100644 index 00000000..23e9a651 --- /dev/null +++ b/src/main/java/idorm/idormServer/calendar/application/port/out/DeleteTeamMemberPort.java @@ -0,0 +1,7 @@ +package idorm.idormServer.calendar.application.port.out; + +import idorm.idormServer.member.entity.Member; + +public interface DeleteTeamMemberPort { + void deleteTeamMember(final Member member); +} diff --git a/src/main/java/idorm/idormServer/calendar/entity/Team.java b/src/main/java/idorm/idormServer/calendar/entity/Team.java index ebe2ba64..6df0915a 100644 --- a/src/main/java/idorm/idormServer/calendar/entity/Team.java +++ b/src/main/java/idorm/idormServer/calendar/entity/Team.java @@ -1,12 +1,5 @@ package idorm.idormServer.calendar.entity; -import idorm.idormServer.calendar.adapter.out.exception.CannotExplodeTeamException; -import idorm.idormServer.calendar.adapter.out.exception.CannotRegisterTeamStatusFullException; -import idorm.idormServer.calendar.adapter.out.exception.NotFoundTeamMemberException; -import idorm.idormServer.common.entity.BaseTimeEntity; -import idorm.idormServer.calendar.adapter.out.exception.DuplicatedMemberException; -import idorm.idormServer.member.entity.Member; - import java.util.ArrayList; import java.util.List; @@ -20,6 +13,12 @@ import javax.persistence.Id; import javax.persistence.OneToMany; +import idorm.idormServer.calendar.adapter.out.exception.CannotExplodeTeamException; +import idorm.idormServer.calendar.adapter.out.exception.CannotRegisterTeamStatusFullException; +import idorm.idormServer.calendar.adapter.out.exception.DuplicatedMemberException; +import idorm.idormServer.calendar.adapter.out.exception.NotFoundTeamMemberException; +import idorm.idormServer.common.entity.BaseTimeEntity; +import idorm.idormServer.member.entity.Member; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -66,16 +65,17 @@ public void deleteMember(Member member) { throw new NotFoundTeamMemberException(); } member.removeTeam(); + this.members.remove(member); if (this.members.size() == 1) { this.teamStatus = TeamStatus.ALONE; } } public void delete(Member member) { - if (TeamStatus.isNotAlone(this.teamStatus)) { + if (teamStatus.isNotAlone()) throw new CannotExplodeTeamException(); - } member.removeTeam(); + this.members.remove(member); } private void validateParticipationInTeam(Member member) { diff --git a/src/main/java/idorm/idormServer/calendar/entity/TeamCalendar.java b/src/main/java/idorm/idormServer/calendar/entity/TeamCalendar.java index d64f95fd..aadbdb41 100644 --- a/src/main/java/idorm/idormServer/calendar/entity/TeamCalendar.java +++ b/src/main/java/idorm/idormServer/calendar/entity/TeamCalendar.java @@ -107,12 +107,6 @@ public List getParticipants() { return participants.getParticipants(); } - public List getParticipantMemberIds() { - return participants.getParticipants().stream() - .map(Participant::getMemberId) - .toList(); - } - private void validateAuthorization(final Team team) { if (!this.team.equals(team)) { throw new AccessDeniedTeamCalendarException(); diff --git a/src/main/java/idorm/idormServer/calendar/entity/TeamStatus.java b/src/main/java/idorm/idormServer/calendar/entity/TeamStatus.java index ca84cf76..561d2698 100644 --- a/src/main/java/idorm/idormServer/calendar/entity/TeamStatus.java +++ b/src/main/java/idorm/idormServer/calendar/entity/TeamStatus.java @@ -2,13 +2,14 @@ public enum TeamStatus { ACTIVE, - ALONE; + ALONE, + DELETED; - public static boolean isNotAlone(TeamStatus teamStatus) { - return !teamStatus.equals(ALONE); + public boolean isNotAlone() { + return !this.equals(ALONE); } - public static boolean isAlone(TeamStatus teamStatus) { - return teamStatus.equals(ALONE); + public boolean isAlone() { + return this.equals(ALONE); } } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/common/config/WebMvcConfig.java b/src/main/java/idorm/idormServer/common/config/WebMvcConfig.java index e5ead9c6..55695f4b 100644 --- a/src/main/java/idorm/idormServer/common/config/WebMvcConfig.java +++ b/src/main/java/idorm/idormServer/common/config/WebMvcConfig.java @@ -27,7 +27,7 @@ public void addInterceptors(InterceptorRegistry registry) { .addPathPatterns("/**") .excludePathPatterns("/swagger-ui/**", "/swagger-resources/**", "/v3/api-docs/**") .excludePathPatterns("/api/v1/email/**") - .excludePathPatterns("/api/v1/signup", "/api/v1/signin", "/api/v1/refresh") + .excludePathPatterns("/api/v1/signup", "/api/v1/signin") .excludePathPatterns("/api/v1/members/me/password") .excludePathPatterns("/test/**"); } diff --git a/src/main/java/idorm/idormServer/common/config/WebMvcLocalConfig.java b/src/main/java/idorm/idormServer/common/config/WebMvcLocalConfig.java index 8b7e2d16..14e0cec2 100644 --- a/src/main/java/idorm/idormServer/common/config/WebMvcLocalConfig.java +++ b/src/main/java/idorm/idormServer/common/config/WebMvcLocalConfig.java @@ -30,7 +30,7 @@ public void addInterceptors(InterceptorRegistry registry) { .addPathPatterns("/**") .excludePathPatterns("/swagger-ui/**", "/swagger-resources/**", "/v3/api-docs/**") .excludePathPatterns("/api/v1/email/**") - .excludePathPatterns("/api/v1/signup", "/api/v1/signin", "/api/v1/refresh") + .excludePathPatterns("/api/v1/signup", "/api/v1/signin") .excludePathPatterns("/api/v1/members/me/password") .excludePathPatterns("/test/**"); diff --git a/src/main/java/idorm/idormServer/common/util/Validator.java b/src/main/java/idorm/idormServer/common/util/Validator.java index 9332aab8..46103339 100644 --- a/src/main/java/idorm/idormServer/common/util/Validator.java +++ b/src/main/java/idorm/idormServer/common/util/Validator.java @@ -4,6 +4,8 @@ import java.util.Objects; import java.util.regex.Pattern; +import org.springframework.util.StringUtils; + import idorm.idormServer.common.exception.BaseException; import idorm.idormServer.common.exception.BaseResponseCode; import idorm.idormServer.common.exception.FieldRequiredException; @@ -14,7 +16,7 @@ public final class Validator { public static void validateNotBlank(String value) { - if (value == null || value.isBlank()) { + if (!StringUtils.hasLength(value)) { throw new FieldRequiredException(); } } @@ -24,7 +26,7 @@ public static void validateNotBlank(List values) { } public static void validateNotNull(Object object) { - if (object == null) { + if (Objects.isNull(object)) { throw new FieldRequiredException(); } } diff --git a/src/main/java/idorm/idormServer/email/application/EmailService.java b/src/main/java/idorm/idormServer/email/application/EmailService.java index fc40e4a8..b2faeecc 100644 --- a/src/main/java/idorm/idormServer/email/application/EmailService.java +++ b/src/main/java/idorm/idormServer/email/application/EmailService.java @@ -21,8 +21,8 @@ public class EmailService implements EmailUseCase { private final SaveEmailPort saveEmailPort; private final LoadEmailPort loadEmailPort; - private final GenerateVerificationCodePort verificationCodePort; private final SendEmailPort sendEmailPort; + private final GenerateVerificationCodePort verificationCodePort; @Override @Transactional diff --git a/src/main/java/idorm/idormServer/email/application/port/out/LoadEmailPort.java b/src/main/java/idorm/idormServer/email/application/port/out/LoadEmailPort.java index 5cadf18d..6f5a1510 100644 --- a/src/main/java/idorm/idormServer/email/application/port/out/LoadEmailPort.java +++ b/src/main/java/idorm/idormServer/email/application/port/out/LoadEmailPort.java @@ -5,7 +5,8 @@ import idorm.idormServer.email.entity.Email; public interface LoadEmailPort { - Optional findByEmailWithOptional(String email); - Email findByEmail(String email); + Optional findByEmailWithOptional(String email); + + Email findByEmail(String email); } diff --git a/src/main/java/idorm/idormServer/email/entity/Email.java b/src/main/java/idorm/idormServer/email/entity/Email.java index 1daaba0b..5ce845ca 100644 --- a/src/main/java/idorm/idormServer/email/entity/Email.java +++ b/src/main/java/idorm/idormServer/email/entity/Email.java @@ -31,8 +31,9 @@ public class Email { public static final int MAX_EMAIL_LENGTH = 20; - private static final String EMAIL_REGEX = "^([\\w-]+(?:\\.[\\w-]+)*)+@(inu.ac.kr)$"; public static final int CODE_LENGTH = 7; + + private static final String EMAIL_REGEX = "^([\\w-]+(?:\\.[\\w-]+)*)+@(inu.ac.kr)$"; private static final String CODE_REGEX = "^\\d{3}-\\d{3}$"; private static final long VALID_VERIFY_MINUTE = 5L; @@ -63,25 +64,25 @@ public Email(final String email, final String code) { validateConstructor(email, code); this.email = email; this.code = code; - emailStatus = EmailStatus.SEND; - registered = false; + this.emailStatus = EmailStatus.SEND; + this.registered = false; this.issuedAt = LocalDateTime.now(); } - private static void validateConstructor(final String email, final String code) { + private void validateConstructor(final String email, final String code) { Validator.validateNotBlank(email); Validator.validateNotBlank(code); Validator.validateFormat(email, EMAIL_REGEX, EmailResponseCode.INVALID_EMAIL_CHARACTER); } - public void updateVerificationCode(String code) { + public void updateVerificationCode(final String code) { validateNotSignUp(); this.code = code; this.issuedAt = LocalDateTime.now(); this.emailStatus = EmailStatus.SEND; } - public void updateReVerificationCode(String code) { + public void updateReVerificationCode(final String code) { validateSignUpEmail(); this.code = code; this.issuedAt = LocalDateTime.now(); @@ -105,7 +106,7 @@ public void reVerify(final String code) { } public void register() { - if (VERIFIED.isNot(emailStatus)) { + if (emailStatus.isNotVerified()) { throw new UnAuthorizedEmailException(); } this.registered = true; @@ -113,7 +114,7 @@ public void register() { public void validateReVerified() { validateSignUpEmail(); - if (RE_VERIFIED.isNot(emailStatus)) { + if (emailStatus.isNotReverified()) { throw new UnAuthorizedEmailException(); } validateValidTime(); @@ -129,13 +130,13 @@ private void validateValidTime() { } private void validateNotSignUp() { - if (isRegistered()) { + if (registered) { throw new DuplicatedEmailException(); } } private void validateSignUpEmail() { - if (!isRegistered()) { + if (!registered) { throw new NotFoundMemberException(); } } diff --git a/src/main/java/idorm/idormServer/email/entity/EmailStatus.java b/src/main/java/idorm/idormServer/email/entity/EmailStatus.java index 0097f703..2fd3a2b1 100644 --- a/src/main/java/idorm/idormServer/email/entity/EmailStatus.java +++ b/src/main/java/idorm/idormServer/email/entity/EmailStatus.java @@ -1,12 +1,17 @@ package idorm.idormServer.email.entity; public enum EmailStatus { - SEND, - VERIFIED, - RE_SEND, - RE_VERIFIED; + SEND, + VERIFIED, + RE_SEND, + RE_VERIFIED, + DELETED; - public boolean isNot(EmailStatus emailStatus) { - return !this.equals(emailStatus); - } + public boolean isNotVerified() { + return !this.equals(VERIFIED); + } + + public boolean isNotReverified() { + return !this.equals(RE_VERIFIED); + } } diff --git a/src/main/java/idorm/idormServer/matchingInfo/adapter/out/persistence/DeleteMatchingInfoAdapter.java b/src/main/java/idorm/idormServer/matchingInfo/adapter/out/persistence/DeleteMatchingInfoAdapter.java new file mode 100644 index 00000000..2a6594d0 --- /dev/null +++ b/src/main/java/idorm/idormServer/matchingInfo/adapter/out/persistence/DeleteMatchingInfoAdapter.java @@ -0,0 +1,18 @@ +package idorm.idormServer.matchingInfo.adapter.out.persistence; + +import org.springframework.stereotype.Component; + +import idorm.idormServer.matchingInfo.application.port.out.DeleteMatchingInfoPort; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class DeleteMatchingInfoAdapter implements DeleteMatchingInfoPort { + + private final MatchingInfoRepository matchingInfoRepository; + + @Override + public void delete(Long matchingInfoId) { + matchingInfoRepository.deleteById(matchingInfoId); + } +} diff --git a/src/main/java/idorm/idormServer/matchingInfo/adapter/out/persistence/MatchingInfoRepository.java b/src/main/java/idorm/idormServer/matchingInfo/adapter/out/persistence/MatchingInfoRepository.java index 6613930d..9f5b1b74 100644 --- a/src/main/java/idorm/idormServer/matchingInfo/adapter/out/persistence/MatchingInfoRepository.java +++ b/src/main/java/idorm/idormServer/matchingInfo/adapter/out/persistence/MatchingInfoRepository.java @@ -3,6 +3,7 @@ import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Repository; import idorm.idormServer.matchingInfo.entity.MatchingInfo; @@ -13,4 +14,7 @@ public interface MatchingInfoRepository extends JpaRepository findByMemberId(Long memberId); boolean existsByMemberId(Long memberId); + + @Modifying + void deleteById(Long matchingInfoId); } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/matchingInfo/application/port/out/DeleteMatchingInfoPort.java b/src/main/java/idorm/idormServer/matchingInfo/application/port/out/DeleteMatchingInfoPort.java new file mode 100644 index 00000000..819990cf --- /dev/null +++ b/src/main/java/idorm/idormServer/matchingInfo/application/port/out/DeleteMatchingInfoPort.java @@ -0,0 +1,6 @@ +package idorm.idormServer.matchingInfo.application.port.out; + +public interface DeleteMatchingInfoPort { + + void delete(Long matchingInfoId); +} \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/matchingMate/adapter/out/persistence/DeleteMatchingMateAdapter.java b/src/main/java/idorm/idormServer/matchingMate/adapter/out/persistence/DeleteMatchingMateAdapter.java new file mode 100644 index 00000000..f13561dd --- /dev/null +++ b/src/main/java/idorm/idormServer/matchingMate/adapter/out/persistence/DeleteMatchingMateAdapter.java @@ -0,0 +1,20 @@ +package idorm.idormServer.matchingMate.adapter.out.persistence; + +import org.springframework.stereotype.Component; + +import idorm.idormServer.matchingMate.application.port.out.DeleteMatchingMatePort; +import idorm.idormServer.member.entity.Member; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class DeleteMatchingMateAdapter implements DeleteMatchingMatePort { + + private final MatchingMateRepository matchingMateRepository; + + @Override + public void deleteByMemberWithdrawn(Member deletedMember) { + matchingMateRepository.deleteAllByMatchingInfoForTargetId(deletedMember.getMatchingInfo().getId()); + matchingMateRepository.deleteAllByOwnerId(deletedMember.getId()); + } +} \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/matchingMate/adapter/out/persistence/MatchingMateRepository.java b/src/main/java/idorm/idormServer/matchingMate/adapter/out/persistence/MatchingMateRepository.java index a98eece0..ca7799ce 100644 --- a/src/main/java/idorm/idormServer/matchingMate/adapter/out/persistence/MatchingMateRepository.java +++ b/src/main/java/idorm/idormServer/matchingMate/adapter/out/persistence/MatchingMateRepository.java @@ -1,10 +1,17 @@ package idorm.idormServer.matchingMate.adapter.out.persistence; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Repository; import idorm.idormServer.matchingMate.entity.MatchingMate; @Repository public interface MatchingMateRepository extends JpaRepository { + + @Modifying + void deleteAllByMatchingInfoForTargetId(Long matchingInfoId); + + @Modifying + void deleteAllByOwnerId(Long memberId); } diff --git a/src/main/java/idorm/idormServer/matchingMate/application/port/out/DeleteMatchingMatePort.java b/src/main/java/idorm/idormServer/matchingMate/application/port/out/DeleteMatchingMatePort.java new file mode 100644 index 00000000..6b85d583 --- /dev/null +++ b/src/main/java/idorm/idormServer/matchingMate/application/port/out/DeleteMatchingMatePort.java @@ -0,0 +1,8 @@ +package idorm.idormServer.matchingMate.application.port.out; + +import idorm.idormServer.member.entity.Member; + +public interface DeleteMatchingMatePort { + + void deleteByMemberWithdrawn(Member member); +} \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/matchingMate/entity/MatchingMate.java b/src/main/java/idorm/idormServer/matchingMate/entity/MatchingMate.java index 1b93c3ab..16d62e0a 100644 --- a/src/main/java/idorm/idormServer/matchingMate/entity/MatchingMate.java +++ b/src/main/java/idorm/idormServer/matchingMate/entity/MatchingMate.java @@ -66,22 +66,6 @@ private void validateConstructor(final Member member, final MatchingInfo matchin } - public boolean isPublic() { - return matchingInfoForTarget.getIsPublic(); - } - - public boolean isFavorite() { - return preferenceType.equals(MatePreferenceType.FAVORITE); - } - - public boolean isNonFavorite() { - return preferenceType.equals(MatePreferenceType.NONFAVORITE); - } - - public boolean isNonFavorite(final MatchingInfo matchingInfo) { - return this.matchingInfoForTarget.equals(matchingInfo) && isNonFavorite(); - } - @Override public boolean equals(Object object) { if (this == object) diff --git a/src/main/java/idorm/idormServer/member/adapter/out/persistence/LoadMemberAdapter.java b/src/main/java/idorm/idormServer/member/adapter/out/persistence/LoadMemberAdapter.java index 6ab3c326..c2c5b567 100644 --- a/src/main/java/idorm/idormServer/member/adapter/out/persistence/LoadMemberAdapter.java +++ b/src/main/java/idorm/idormServer/member/adapter/out/persistence/LoadMemberAdapter.java @@ -1,5 +1,7 @@ package idorm.idormServer.member.adapter.out.persistence; +import org.springframework.stereotype.Component; + import idorm.idormServer.auth.adapter.out.exception.LoginFailedException; import idorm.idormServer.email.adapter.out.exception.DuplicatedEmailException; import idorm.idormServer.member.adapter.out.exception.DuplicatedNicknameException; @@ -8,50 +10,50 @@ import idorm.idormServer.member.entity.Member; import idorm.idormServer.member.entity.MemberStatus; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor public class LoadMemberAdapter implements LoadMemberPort { - private final MemberRepository memberRepository; - - @Override - public Member loadMember(final Long memberId) { - return memberRepository.findByIdAndMemberStatus(memberId, MemberStatus.ACTIVE) - .orElseThrow(NotFoundMemberException::new); - } - - @Override - public Member loadMember(final String email, final String password) { - return memberRepository.findByEmailAndPasswordValueAndMemberStatus(email, password, MemberStatus.ACTIVE) - .orElseThrow(LoginFailedException::new); - } - - @Override - public Member loadMember(final String email) { - return memberRepository.findByEmailAndMemberStatus(email, MemberStatus.ACTIVE) - .orElseThrow(NotFoundMemberException::new); - } - - @Override - public Member loadMemberWithOptional(final Long memberId) { - return memberRepository.findByIdAndMemberStatus(memberId, MemberStatus.ACTIVE).orElse(null); - } - - @Override - public void validateUniqueNickname(final String nickname) { - boolean exists = memberRepository.existsByNicknameValueAndMemberStatus(nickname, MemberStatus.ACTIVE); - if (exists) { - throw new DuplicatedNicknameException(); - } - } - - @Override - public void validateUniqueEmail(final String email) { - boolean exists = memberRepository.existsByEmailAndMemberStatus(email, MemberStatus.ACTIVE); - if (exists) { - throw new DuplicatedEmailException(); - } - } + private final MemberRepository memberRepository; + + @Override + public Member loadMember(final Long memberId) { + return memberRepository.findByIdAndMemberStatus(memberId, MemberStatus.ACTIVE) + .orElseThrow(NotFoundMemberException::new); + } + + @Override + public Member loadMember(final String email, final String password) { + return memberRepository.findByEmailAndPasswordValueAndMemberStatus(email, password, MemberStatus.ACTIVE) + .orElseThrow(LoginFailedException::new); + } + + @Override + public Member loadMember(final String email) { + return memberRepository.findByEmailAndMemberStatus(email, MemberStatus.ACTIVE) + .orElseThrow(NotFoundMemberException::new); + } + + @Override + public Member loadMemberWithOptional(final Long memberId) { + return memberRepository.findByIdAndMemberStatus(memberId, MemberStatus.ACTIVE) + .orElse(null); + } + + @Override + public void validateUniqueNickname(final String nickname) { + boolean exists = memberRepository.existsByNicknameValueAndMemberStatus(nickname, MemberStatus.ACTIVE); + if (exists) { + throw new DuplicatedNicknameException(); + } + } + + @Override + public void validateUniqueEmail(final String email) { + boolean exists = memberRepository.existsByEmailAndMemberStatus(email, MemberStatus.ACTIVE); + if (exists) { + throw new DuplicatedEmailException(); + } + } } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/member/adapter/out/persistence/WithdrawAdapter.java b/src/main/java/idorm/idormServer/member/adapter/out/persistence/WithdrawAdapter.java new file mode 100644 index 00000000..ac25d725 --- /dev/null +++ b/src/main/java/idorm/idormServer/member/adapter/out/persistence/WithdrawAdapter.java @@ -0,0 +1,89 @@ +package idorm.idormServer.member.adapter.out.persistence; + +import java.util.Objects; + +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import idorm.idormServer.auth.application.port.out.DeleteRefreshTokenPort; +import idorm.idormServer.calendar.application.port.out.DeleteSleepoverCalendarPort; +import idorm.idormServer.calendar.entity.Team; +import idorm.idormServer.email.application.port.out.DeleteEmailPort; +import idorm.idormServer.email.entity.Email; +import idorm.idormServer.matchingInfo.application.port.out.DeleteMatchingInfoPort; +import idorm.idormServer.matchingMate.application.port.out.DeleteMatchingMatePort; +import idorm.idormServer.member.application.port.out.WithdrawPort; +import idorm.idormServer.member.entity.Member; +import idorm.idormServer.notification.application.port.out.DeleteFcmTokenPort; +import idorm.idormServer.photo.application.port.out.DeleteFilePort; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class WithdrawAdapter implements WithdrawPort { + + private final DeleteEmailPort deleteEmailPort; + private final DeleteFilePort deleteFilePort; + private final DeleteRefreshTokenPort deleteRefreshTokenPort; + private final DeleteFcmTokenPort deleteFcmTokenPort; + private final DeleteMatchingMatePort deleteMatchingMatePort; + private final DeleteMatchingInfoPort deleteMatchingInfoPort; + private final DeleteSleepoverCalendarPort deleteSleepoverCalendarPort; + + @Override + public void withdraw(Member member, Email email) { + deleteRefreshTokenPort.deleteAll(member.getId()); + deleteEmailPort.delete(email); + deleteFcmTokenPort.deleteAll(member.getId()); + deleteMatchingMatePort.deleteByMemberWithdrawn(member); + deleteMatchingInfoPort.delete(member.getMatchingInfo().getId()); + + if (StringUtils.hasLength(member.getProfilePhotoUrl())) { + deleteFilePort.deleteMemberPhotoFile(member.getProfilePhotoUrl()); + } + + /** + * TODO: Team 내 Member 제거 시나리오 + * + * 1. 팀이 존재하지 않는 경우 + * : 바로 반환 + * + * 2. 팀이 존재하는 경우 + * a) 탈퇴 회원이 마지막 회원인 경우 (Team.team_status == ALONE) + * 0. [a, b, c 공통] SleepoverCalendar : 모든 외박캘린더 삭제 + * 1. TeamCalendar : 모든 TeamCalendar 삭제 + * - Participant : 각 TeamCalendar를 가진 모든 Participant 삭제 + * 2. Team : TeamStatus == DELETED 변경 + * + * b) 탈퇴 회원 삭제 시 한명만 팀에 남는 경우 + * 0. [a, b, c 공통] SleepoverCalendar : 모든 외박캘린더 삭제 + * 1. [b, c 공통] Participant : 탈퇴 회원을 가진 모든 Participant 삭제 + * 2. [b, c 공통] TeamCalendar : Participant가 하나도 없는 경우 삭제 + * 3. Team : TeamStatus == ALONE 변경 + * + * c) 탈퇴 회원 삭제 후 두 명 이상 팀에 있는 경우 + * 0. [a, b, c 공통] SleepoverCalendar : 모든 외박캘린더 삭제 + * 1. [b, c 공통] Participant : 탈퇴 회원을 가진 Participant 삭제 + * 2. [b, c 공통] TeamCalendar : Participant가 하나도 없는 경우 삭제 + * 3. Team : TeamStatus == ACTIVE 유지 + */ + if (Objects.isNull(member.getTeam())) { + // no-op + } else { + deleteSleepoverCalendarPort.deleteByMemberId(member.getId()); + + if (member.getTeam().getTeamStatus().isAlone()) { + explodeTeam(member.getTeam()); + } + + // TODO -CASE 1: 탈퇴 회원 삭제 시 한 명만 남는 경우 + // TODO -CASE 2: 탈퇴 회원 삭제 시 두 명 이상 남는 경우 + } + + member.withdraw(); + } + + private void explodeTeam(Team team) { + // TODO: + } +} diff --git a/src/main/java/idorm/idormServer/member/adapter/out/persistence/WithdrawMemberAdaptor.java b/src/main/java/idorm/idormServer/member/adapter/out/persistence/WithdrawMemberAdaptor.java deleted file mode 100644 index 6af681f2..00000000 --- a/src/main/java/idorm/idormServer/member/adapter/out/persistence/WithdrawMemberAdaptor.java +++ /dev/null @@ -1,20 +0,0 @@ -package idorm.idormServer.member.adapter.out.persistence; - -import org.springframework.stereotype.Component; - -import idorm.idormServer.member.application.port.out.WithdrawMemberPort; -import idorm.idormServer.member.entity.Member; -import lombok.RequiredArgsConstructor; - -@Component -@RequiredArgsConstructor -public class WithdrawMemberAdaptor implements WithdrawMemberPort { - - private final MemberRepository memberRepository; - - @Override - public void withdraw(final Member member) { - memberRepository.delete(member); - member.withdraw(); - } -} diff --git a/src/main/java/idorm/idormServer/member/application/MemberService.java b/src/main/java/idorm/idormServer/member/application/MemberService.java index 287ba01c..955a3747 100644 --- a/src/main/java/idorm/idormServer/member/application/MemberService.java +++ b/src/main/java/idorm/idormServer/member/application/MemberService.java @@ -1,12 +1,12 @@ package idorm.idormServer.member.application; +import static idorm.idormServer.member.application.port.in.dto.MemberInfoResponse.*; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import idorm.idormServer.auth.application.port.in.dto.AuthResponse; -import idorm.idormServer.auth.application.port.out.DeleteRefreshTokenPort; import idorm.idormServer.auth.application.port.out.EncryptPort; -import idorm.idormServer.email.application.port.out.DeleteEmailPort; import idorm.idormServer.email.application.port.out.LoadEmailPort; import idorm.idormServer.email.entity.Email; import idorm.idormServer.member.application.port.in.MemberUseCase; @@ -16,7 +16,7 @@ import idorm.idormServer.member.application.port.in.dto.SignupRequest; import idorm.idormServer.member.application.port.out.LoadMemberPort; import idorm.idormServer.member.application.port.out.SaveMemberPort; -import idorm.idormServer.member.application.port.out.WithdrawMemberPort; +import idorm.idormServer.member.application.port.out.WithdrawPort; import idorm.idormServer.member.entity.Member; import lombok.RequiredArgsConstructor; @@ -27,18 +27,15 @@ public class MemberService implements MemberUseCase { private final EncryptPort encryptPort; private final LoadEmailPort loadEmailPort; - private final DeleteEmailPort deleteEmailPort; private final SaveMemberPort saveMemberPort; private final LoadMemberPort loadMemberPort; - private final WithdrawMemberPort withdrawMemberPort; - - private final DeleteRefreshTokenPort deleteRefreshTokenPort; + private final WithdrawPort withdrawPort; @Override @Transactional public void signUp(final SignupRequest request) { - Email email = loadEmailPort.findByEmail(request.email()); + final Email email = loadEmailPort.findByEmail(request.email()); loadMemberPort.validateUniqueEmail(request.email()); loadMemberPort.validateUniqueNickname(request.nickname()); @@ -51,7 +48,7 @@ public void signUp(final SignupRequest request) { @Override public MemberInfoResponse getInfo(final AuthResponse auth) { Member member = loadMemberPort.loadMember(auth.getId()); - return MemberInfoResponse.of(member); + return of(member); } @Override @@ -77,13 +74,8 @@ public void editPassword(final PasswordUpdateRequest request) { @Transactional public void withdraw(final AuthResponse authResponse) { Member deleteMember = loadMemberPort.loadMember(authResponse.getId()); - deleteRefreshTokenPort.deleteAll(authResponse.getId()); - Email deleteEmail = loadEmailPort.findByEmail(deleteMember.getEmail()); - deleteEmailPort.delete(deleteEmail); - - // TODO : 타 도메인 삭제 처리 - withdrawMemberPort.withdraw(deleteMember); + withdrawPort.withdraw(deleteMember, deleteEmail); } } \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/member/application/port/out/LoadMemberPort.java b/src/main/java/idorm/idormServer/member/application/port/out/LoadMemberPort.java index 4b79f38c..e9fc064c 100644 --- a/src/main/java/idorm/idormServer/member/application/port/out/LoadMemberPort.java +++ b/src/main/java/idorm/idormServer/member/application/port/out/LoadMemberPort.java @@ -9,6 +9,7 @@ public interface LoadMemberPort { Member loadMember(String email, String password); Member loadMember(String email); + Member loadMemberWithOptional(Long memberId); void validateUniqueNickname(String nickname); diff --git a/src/main/java/idorm/idormServer/member/application/port/out/WithdrawMemberPort.java b/src/main/java/idorm/idormServer/member/application/port/out/WithdrawMemberPort.java deleted file mode 100644 index 3b86acd9..00000000 --- a/src/main/java/idorm/idormServer/member/application/port/out/WithdrawMemberPort.java +++ /dev/null @@ -1,8 +0,0 @@ -package idorm.idormServer.member.application.port.out; - -import idorm.idormServer.member.entity.Member; - -public interface WithdrawMemberPort { - - void withdraw(Member member); -} \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/member/application/port/out/WithdrawPort.java b/src/main/java/idorm/idormServer/member/application/port/out/WithdrawPort.java new file mode 100644 index 00000000..1a5c4ce6 --- /dev/null +++ b/src/main/java/idorm/idormServer/member/application/port/out/WithdrawPort.java @@ -0,0 +1,9 @@ +package idorm.idormServer.member.application.port.out; + +import idorm.idormServer.email.entity.Email; +import idorm.idormServer.member.entity.Member; + +public interface WithdrawPort { + + void withdraw(Member member, Email email); +} \ No newline at end of file diff --git a/src/main/java/idorm/idormServer/member/entity/Member.java b/src/main/java/idorm/idormServer/member/entity/Member.java index 3a60ac21..1ad99409 100644 --- a/src/main/java/idorm/idormServer/member/entity/Member.java +++ b/src/main/java/idorm/idormServer/member/entity/Member.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -141,37 +140,12 @@ public void deleteMemberPhoto() { public void withdraw() { memberStatus = MemberStatus.DELETED; - email = null; - nickname = null; - password = null; + nickname.delete(); + password.delete(); + email = ""; profilePhotoUrl = null; - roleType = null; - matchingMates = null; - team = null; - posts = null; - comments = null; - } - - public List getFavoriteMates() { - List results = this.matchingMates.stream() - .filter(MatchingMate::isPublic) - .filter(MatchingMate::isFavorite) - .collect(Collectors.toUnmodifiableList()); - return results; - } - - public List getNonFavoriteMates() { - List results = this.matchingMates.stream() - .filter(MatchingMate::isPublic) - .filter(MatchingMate::isNonFavorite) - .collect(Collectors.toUnmodifiableList()); - return results; - } - - public boolean isNotNonFavoriteMate(final MatchingInfo matchingInfo) { - boolean result = matchingMates.stream() - .anyMatch(mate -> mate.isNonFavorite(matchingInfo)); - return !result; + this.matchingInfo = null; + this.team = null; } public void addReport(final Report report) { diff --git a/src/main/java/idorm/idormServer/member/entity/Nickname.java b/src/main/java/idorm/idormServer/member/entity/Nickname.java index 7d13e7d9..a41a5b03 100644 --- a/src/main/java/idorm/idormServer/member/entity/Nickname.java +++ b/src/main/java/idorm/idormServer/member/entity/Nickname.java @@ -50,6 +50,10 @@ void update(final String newNickname) { this.value = newNickname; } + void delete() { + this.value = ""; + } + private void validateValidUpdate() { final LocalDateTime now = LocalDateTime.now(); if (now.isBefore(this.updatedAt.plusDays(VALID_UPDATE_DAY))) { diff --git a/src/main/java/idorm/idormServer/member/entity/Password.java b/src/main/java/idorm/idormServer/member/entity/Password.java index 75eaa83b..4e65b74c 100644 --- a/src/main/java/idorm/idormServer/member/entity/Password.java +++ b/src/main/java/idorm/idormServer/member/entity/Password.java @@ -34,6 +34,10 @@ void update(final EncryptPort encryptPort, final String newPassword) { this.value = encryptPort.encrypt(newPassword); } + void delete() { + this.value = ""; + } + private static void validateConstructor(final String value) { Validator.validateNotBlank(value); Validator.validateFormat(value, PASSWORD_REGEX, MemberResponseCode.INVALID_PASSWORD_CHARACTER);