Skip to content

Commit

Permalink
feat(member): 회원 탈퇴를 할 수 있다 (#163)
Browse files Browse the repository at this point in the history
* refactor(member): 코틀린 마이그레이션

* refactor(status): 별도 패키지로 모듈화한다

- 이벤트 구조 사용

* feat(member): 회원 탈퇴 및 필요 절차들을 수행한다

* test(member): 회원 탈퇴 후 재가입할 수 있다

* feat(member.controller): 회원 탈퇴 API를 개방한다
  • Loading branch information
0chil authored Aug 8, 2024
1 parent 5bcbd8f commit 07ff594
Show file tree
Hide file tree
Showing 49 changed files with 888 additions and 557 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ default Percentile ratePercentileOf(long sessionId) {
}

Optional<AppleGame> findByOwnerIdAndSessionId(Long ownerId, Long sessionId);

void deleteAllByOwnerId(long ownerId);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
import com.snackgame.server.applegame.domain.game.AppleGame;
import com.snackgame.server.applegame.domain.game.AppleGames;
import com.snackgame.server.applegame.domain.game.Board;
import com.snackgame.server.applegame.event.GameEndEvent;
import com.snackgame.server.member.domain.Member;
import com.snackgame.server.member.domain.MemberRepository;
import com.snackgame.server.game.metadata.Metadata;
import com.snackgame.server.game.session.event.SessionEndEvent;

import lombok.RequiredArgsConstructor;

Expand All @@ -25,7 +24,6 @@ public class AppleGameService {

private final AppleGames appleGames;
private final ApplicationEventPublisher eventPublisher;
private final MemberRepository memberRepository;

public AppleGame startGameFor(Long memberId) {
AppleGame game = AppleGame.ofRandomized(memberId);
Expand Down Expand Up @@ -58,10 +56,7 @@ public AppleGame restart(Long memberId, Long sessionId) {
public GameResultResponse finish(Long memberId, Long sessionId) {
AppleGame game = appleGames.getBy(memberId, sessionId);
game.finish();
eventPublisher.publishEvent(new GameEndEvent(game));

Member member = memberRepository.getById(memberId);
member.getStatus().addExp(game.getScore());
eventPublisher.publishEvent(new SessionEndEvent(Metadata.APPLE_GAME, memberId, sessionId, game.getScore()));

return new GameResultResponse(
game.getScore(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.snackgame.server.applegame.service

import com.snackgame.server.applegame.domain.game.AppleGames
import com.snackgame.server.member.service.MemberWithdrawalOperation
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional

@Component
class AppleGameSessionWithdrawal(
private val appleGames: AppleGames
) : MemberWithdrawalOperation {

@Transactional(propagation = Propagation.MANDATORY)
override fun executeOn(memberId: Long) {
appleGames.deleteAllByOwnerId(memberId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ interface SnackgameInifiniteRepository : JpaRepository<SnackgameInfinite, Long>
nativeQuery = true
)
fun findPercentileOf(sessionId: Long): Double?

fun deleteAllByOwnerId(memberId: Long)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ import com.snackgame.server.game.snackgame.domain.SnackgameInifiniteRepository
import com.snackgame.server.game.snackgame.service.dto.SnackgameInfiniteEndResponse
import com.snackgame.server.game.snackgame.service.dto.SnackgameInfiniteResponse
import com.snackgame.server.game.snackgame.service.dto.SnackgameInfiniteUpdateRequest
import com.snackgame.server.member.domain.MemberRepository
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class SnackgameInfiniteService(
private val snackGameRepository: SnackgameInifiniteRepository,
private val memberRepository: MemberRepository,
private val eventPublisher: ApplicationEventPublisher
) {

Expand Down Expand Up @@ -59,11 +57,7 @@ class SnackgameInfiniteService(
val game = snackGameRepository.getBy(memberId, sessionId)

game.end()

eventPublisher.publishEvent(SessionEndEvent.of(game))
// TODO: 모듈화 + 이벤트 기반으로 동작하도록 분리. 게임은 게임에만 집중하도록.
val member = memberRepository.getById(memberId)
member.status.addExp(game.score.toDouble())

return SnackgameInfiniteEndResponse.of(game, snackGameRepository.ratePercentileOf(sessionId))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.snackgame.server.game.snackgame.infinite.service

import com.snackgame.server.game.snackgame.domain.SnackgameInifiniteRepository
import com.snackgame.server.member.service.MemberWithdrawalOperation
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional

@Component
class SnackgameInfiniteSessionWithdrawal(
private val snackgameInfiniteRepository: SnackgameInifiniteRepository
) : MemberWithdrawalOperation {

@Transactional(propagation = Propagation.MANDATORY)
override fun executeOn(memberId: Long) {
snackgameInfiniteRepository.deleteAllByOwnerId(memberId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.beans.ConstructorProperties
import javax.validation.constraints.PositiveOrZero

data class SnackgameInfiniteUpdateRequest @ConstructorProperties("score") constructor(
@PositiveOrZero(message = "점수는 음수일 수 없습니다")
@field:PositiveOrZero(message = "점수는 음수일 수 없습니다")
@field:Schema(example = "10")
val score: Int
val score: Int = 0
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ interface SnackgameRepository : JpaRepository<Snackgame, Long> {
@Modifying
@Query("update Snackgame set ownerId = :toMemberId where ownerId = :fromMemberId")
fun transferSessions(fromMemberId: Long, toMemberId: Long): Int

fun deleteAllByOwnerId(memberId: Long)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ import com.snackgame.server.game.snackgame.domain.SnackgameRepository
import com.snackgame.server.game.snackgame.service.dto.SnackgameEndResponse
import com.snackgame.server.game.snackgame.service.dto.SnackgameResponse
import com.snackgame.server.game.snackgame.service.dto.SnackgameUpdateRequest
import com.snackgame.server.member.domain.MemberRepository
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class SnackgameService(
private val snackGameRepository: SnackgameRepository,
private val memberRepository: MemberRepository,
private val eventPublisher: ApplicationEventPublisher
) {

Expand Down Expand Up @@ -59,11 +57,7 @@ class SnackgameService(
val game = snackGameRepository.getBy(memberId, sessionId)

game.end()

eventPublisher.publishEvent(SessionEndEvent.of(game))
// TODO: 모듈화 + 이벤트 기반으로 동작하도록 분리. 게임은 게임에만 집중하도록.
val member = memberRepository.getById(memberId)
member.status.addExp(game.score.toDouble())

return SnackgameEndResponse.of(game, snackGameRepository.ratePercentileOf(sessionId))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.snackgame.server.game.snackgame.service

import com.snackgame.server.game.snackgame.domain.SnackgameRepository
import com.snackgame.server.member.service.MemberWithdrawalOperation
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional

@Component
class SnackgameSessionWithdrawal(
private val snackgameRepository: SnackgameRepository
) : MemberWithdrawalOperation {

@Transactional(propagation = Propagation.MANDATORY)
override fun executeOn(memberId: Long) {
snackgameRepository.deleteAllByOwnerId(memberId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.snackgame.server.auth.token.dto.TokensDto
import com.snackgame.server.auth.token.support.OptionalGuest
import com.snackgame.server.auth.token.support.TokenToCookies
import com.snackgame.server.auth.token.support.TokensFromCookie
import com.snackgame.server.member.controller.dto.MemberDetailsResponse
import com.snackgame.server.member.service.dto.MemberDetailsResponse
import com.snackgame.server.member.controller.dto.NameRequest
import com.snackgame.server.member.controller.dto.OidcRequest
import com.snackgame.server.member.controller.dto.TokenResponse
Expand Down Expand Up @@ -43,7 +43,7 @@ class AuthController(

return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, *tokenToCookies.from(tokens))
.body(MemberDetailsResponse.of(guest))
.body(guest)
}

@Operation(summary = "일반 사용자 토큰 발급", description = "사용자의 이름으로 토큰을 발급한다")
Expand All @@ -54,7 +54,7 @@ class AuthController(

return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, *tokenToCookies.from(tokens))
.body(MemberDetailsResponse.of(member))
.body(member)
}

@Operation(
Expand Down Expand Up @@ -84,7 +84,7 @@ class AuthController(

return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, *tokenToCookies.from(tokens))
.body(MemberDetailsResponse.of(member))
.body(member)
}

@Operation(
Expand Down

This file was deleted.

Loading

0 comments on commit 07ff594

Please sign in to comment.