From df70cf3f9a0670f8185d36ff3bc8a7c64e93c340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A0=95=EB=B9=88?= Date: Mon, 13 Apr 2026 01:36:18 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20=EB=B0=B0=ED=8B=80=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=EC=97=90=EC=84=9C=20CANCELED=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=ED=95=84=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/rival/battle/BattleJpaRepository.java | 2 +- .../rival/battle/service/FindAllBattleInfoService.java | 7 ------- .../battle/service/FindAllBattleInfoServiceTest.java | 10 ---------- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java b/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java index a900c73d5..11ff9cbd7 100644 --- a/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java +++ b/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java @@ -48,7 +48,7 @@ AND b.id NOT IN ( FROM battles b LEFT JOIN rivals r ON b.fk_rival_id = r.id WHERE (r.fk_first_user_id = :userId OR r.fk_second_user_id = :userId) - AND b.battle_status NOT IN ('REJECTED', 'PENDING') + AND b.battle_status NOT IN ('REJECTED', 'PENDING', 'CANCELED') """, nativeQuery = true) List findByUserIdWithOutRejected(@Param("userId") Long userId); diff --git a/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java b/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java index 04e70834c..e4a2a742d 100644 --- a/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java +++ b/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java @@ -36,8 +36,6 @@ public class FindAllBattleInfoService implements FindAllBattleInfoUseCase { private static final String RESULT_LOSING = "LOSING"; private static final String RESULT_DRAWING = "DRAWING"; private static final String RESULT_NOT_STARTED = "NOT_STARTED"; - private static final String RESULT_CANCELED = "CANCELED"; - private static final String RESULT_PENDING = "PENDING"; private final BattleRepositoryPort battleRepositoryPort; private final BattleFinishService battleFinishService; @@ -220,11 +218,6 @@ private String determineResult( return RESULT_NOT_STARTED; } - // 취소된 배틀 - if (status == BattleStatus.CANCELED) { - return RESULT_CANCELED; - } - throw new IllegalStateException("Unexpected battle status: " + status); } diff --git a/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java b/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java index e8016a8b7..dfeb65af3 100644 --- a/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java +++ b/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java @@ -157,16 +157,6 @@ void execute_returnsNotStarted_whenNotStarted() { assertThat(result.battles().get(0).result()).isEqualTo("NOT_STARTED"); } - @Test - @DisplayName("CANCELED 배틀은 CANCELED를 반환한다") - void execute_returnsCanceled_whenCanceled() { - stubCommonDependencies(List.of(battle(BattleStatus.CANCELED, null))); - - FindAllBattleInfoData.Result result = findAllBattleInfoService.execute(command()); - - assertThat(result.battles().get(0).result()).isEqualTo("CANCELED"); - } - @Test @DisplayName("상대방 rankTier가 NONE이면 expTier를 tier로 반환한다") void execute_returnsEnemyTierAsExpTier_whenRankTierIsNone() { From 1b5765d631903554899a88f0a23e10cd6a233742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A0=95=EB=B9=88?= Date: Mon, 13 Apr 2026 01:44:50 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20=EB=B0=B0=ED=8B=80=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20=EC=A6=89=EC=8B=9C=20=EC=8B=9C=EC=9E=91=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?NOT=5FSTARTED=20=EC=83=81=ED=83=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rival/battle/BattleJpaRepository.java | 14 ---- .../battle/BattlePersistenceAdapter.java | 8 -- .../controller/BattleControllerDocument.java | 2 +- .../battle/data/FindAllBattleInfoData.java | 2 +- .../battle/port/out/BattleRepositoryPort.java | 1 - .../battle/service/BattleFinishService.java | 78 +++++++++---------- .../service/FindAllBattleInfoService.java | 6 -- .../rival/battle/enums/BattleStatus.java | 1 - .../service/BattleFinishServiceTest.java | 50 ------------ .../service/FindAllBattleInfoServiceTest.java | 10 --- 10 files changed, 38 insertions(+), 134 deletions(-) diff --git a/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java b/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java index 11ff9cbd7..637ac2928 100644 --- a/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java +++ b/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattleJpaRepository.java @@ -115,20 +115,6 @@ AND b.end_at < NOW() """, nativeQuery = true) List findExpiredInProgressBattles(); - /** - * 종료 시각이 지났으나 아직 NOT_STARTED 상태인 배틀 조회 → CANCELED 처리 (스케줄러용) - * soft-delete된 라이벌(fk_rival_id IS NULL)은 제외 - */ - @Query(value = """ - SELECT b.* - FROM battles b - WHERE b.battle_status = 'NOT_STARTED' - AND b.fk_rival_id IS NOT NULL - AND b.end_at IS NOT NULL - AND b.end_at < NOW() - """, nativeQuery = true) - List findExpiredNotStartedBattles(); - /** * 유저 관련 PENDING 상태 배틀 신청 목록 조회 */ diff --git a/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattlePersistenceAdapter.java b/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattlePersistenceAdapter.java index 047ad7ca2..0b74edbb2 100644 --- a/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattlePersistenceAdapter.java +++ b/src/main/java/com/process/clash/adapter/persistence/rival/battle/BattlePersistenceAdapter.java @@ -107,14 +107,6 @@ public List findExpiredInProgressBattles() { .toList(); } - @Override - public List findExpiredNotStartedBattles() { - return battleJpaRepository.findExpiredNotStartedBattles() - .stream() - .map(battleJpaMapper::toDomain) - .toList(); - } - @Override public List findPendingBattlesByUserId(Long userId) { return battleJpaRepository.findPendingBattlesByUserId(userId) diff --git a/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/controller/BattleControllerDocument.java b/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/controller/BattleControllerDocument.java index 3fe245d1a..0aa3e6dfa 100644 --- a/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/controller/BattleControllerDocument.java +++ b/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/controller/BattleControllerDocument.java @@ -47,7 +47,7 @@ com.process.clash.adapter.web.common.ApiResponse applyBattle( ApplyBattleDto.Request request ); - @Operation(summary = "배틀 승인", description = "신청받은 배틀을 승인합니다. 승인 후 배틀은 NOT_STARTED 상태가 되며, 시작일 KST 06시에 자동으로 IN_PROGRESS로 전환됩니다.") + @Operation(summary = "배틀 승인", description = "신청받은 배틀을 승인합니다. 승인 즉시 배틀이 IN_PROGRESS 상태로 시작됩니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "승인 성공", content = @Content( diff --git a/src/main/java/com/process/clash/application/compete/rival/battle/data/FindAllBattleInfoData.java b/src/main/java/com/process/clash/application/compete/rival/battle/data/FindAllBattleInfoData.java index 0c29e244b..25d571c1d 100644 --- a/src/main/java/com/process/clash/application/compete/rival/battle/data/FindAllBattleInfoData.java +++ b/src/main/java/com/process/clash/application/compete/rival/battle/data/FindAllBattleInfoData.java @@ -29,7 +29,7 @@ public record BattleInfo( Long id, Enemy enemy, LocalDate expireDate, - String result // WON, LOST, DRAWN, WINNING, LOSING, DRAWING, NOT_STARTED, CANCELED, PENDING + String result // WON, LOST, DRAWN, WINNING, LOSING, DRAWING ) { public static BattleInfo of(Long id, Enemy enemy, LocalDate expireDate, String result) { return new BattleInfo(id, enemy, expireDate, result); diff --git a/src/main/java/com/process/clash/application/compete/rival/battle/port/out/BattleRepositoryPort.java b/src/main/java/com/process/clash/application/compete/rival/battle/port/out/BattleRepositoryPort.java index e4088c6f4..327025000 100644 --- a/src/main/java/com/process/clash/application/compete/rival/battle/port/out/BattleRepositoryPort.java +++ b/src/main/java/com/process/clash/application/compete/rival/battle/port/out/BattleRepositoryPort.java @@ -19,6 +19,5 @@ public interface BattleRepositoryPort { void rejectAllActiveBattlesByUserId(Long userId); void rejectAllActiveBattlesByRivalId(Long rivalId); List findExpiredInProgressBattles(); - List findExpiredNotStartedBattles(); List findPendingBattlesByUserId(Long userId); } \ No newline at end of file diff --git a/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java b/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java index 3f12355dc..983adeed5 100644 --- a/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java +++ b/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java @@ -32,56 +32,50 @@ public class BattleFinishService { public void finishExpiredBattles() { List expiredInProgress = battleRepositoryPort.findExpiredInProgressBattles(); - List expiredNotStarted = battleRepositoryPort.findExpiredNotStartedBattles(); - List battlesToUpdate = new ArrayList<>(); - - if (!expiredInProgress.isEmpty()) { - // 라이벌 일괄 조회 - Set rivalIds = expiredInProgress.stream() - .map(Battle::rivalId) - .collect(Collectors.toSet()); - Map rivalMap = rivalRepositoryPort.findByIdIn(rivalIds).stream() - .collect(Collectors.toMap(Rival::id, r -> r)); - - // 유저별 배틀 그룹화 후 평균 exp 일괄 조회 - Map> battlesByUserId = new HashMap<>(); - for (Battle battle : expiredInProgress) { - Rival rival = rivalMap.get(battle.rivalId()); - if (rival == null) continue; - battlesByUserId.computeIfAbsent(rival.firstUserId(), k -> new ArrayList<>()).add(battle); - battlesByUserId.computeIfAbsent(rival.secondUserId(), k -> new ArrayList<>()).add(battle); - } + if (expiredInProgress.isEmpty()) { + return; + } - Map> avgExpByUserAndBattle = new HashMap<>(); - for (Map.Entry> entry : battlesByUserId.entrySet()) { - avgExpByUserAndBattle.put( - entry.getKey(), - userExpHistoryRepositoryPort.findAverageExpForBattles(entry.getKey(), entry.getValue()) - ); - } + List battlesToUpdate = new ArrayList<>(); - for (Battle battle : expiredInProgress) { - try { - Rival rival = Optional.ofNullable(rivalMap.get(battle.rivalId())) - .orElseThrow(() -> new IllegalStateException("Rival not found. rivalId=" + battle.rivalId())); - Long winnerId = determineWinner(battle.id(), rival.firstUserId(), rival.secondUserId(), avgExpByUserAndBattle); - battlesToUpdate.add(battle.finishWithWinner(winnerId)); - } catch (Exception e) { - log.error("배틀 종료 처리 중 오류 발생. battleId={}", battle.id(), e); - } - } + // 라이벌 일괄 조회 + Set rivalIds = expiredInProgress.stream() + .map(Battle::rivalId) + .collect(Collectors.toSet()); + Map rivalMap = rivalRepositoryPort.findByIdIn(rivalIds).stream() + .collect(Collectors.toMap(Rival::id, r -> r)); + + // 유저별 배틀 그룹화 후 평균 exp 일괄 조회 + Map> battlesByUserId = new HashMap<>(); + for (Battle battle : expiredInProgress) { + Rival rival = rivalMap.get(battle.rivalId()); + if (rival == null) continue; + battlesByUserId.computeIfAbsent(rival.firstUserId(), k -> new ArrayList<>()).add(battle); + battlesByUserId.computeIfAbsent(rival.secondUserId(), k -> new ArrayList<>()).add(battle); } - expiredNotStarted.stream() - .map(Battle::cancel) - .forEach(battlesToUpdate::add); + Map> avgExpByUserAndBattle = new HashMap<>(); + for (Map.Entry> entry : battlesByUserId.entrySet()) { + avgExpByUserAndBattle.put( + entry.getKey(), + userExpHistoryRepositoryPort.findAverageExpForBattles(entry.getKey(), entry.getValue()) + ); + } - if (!battlesToUpdate.isEmpty()) { - battleRepositoryPort.saveAll(battlesToUpdate); + for (Battle battle : expiredInProgress) { + try { + Rival rival = Optional.ofNullable(rivalMap.get(battle.rivalId())) + .orElseThrow(() -> new IllegalStateException("Rival not found. rivalId=" + battle.rivalId())); + Long winnerId = determineWinner(battle.id(), rival.firstUserId(), rival.secondUserId(), avgExpByUserAndBattle); + battlesToUpdate.add(battle.finishWithWinner(winnerId)); + } catch (Exception e) { + log.error("배틀 종료 처리 중 오류 발생. battleId={}", battle.id(), e); + } } - log.info("Expired battles processed. done={}, canceled={}", expiredInProgress.size(), expiredNotStarted.size()); + battleRepositoryPort.saveAll(battlesToUpdate); + log.info("Expired battles processed. done={}", expiredInProgress.size()); } /** diff --git a/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java b/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java index e4a2a742d..423b1aae9 100644 --- a/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java +++ b/src/main/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoService.java @@ -35,7 +35,6 @@ public class FindAllBattleInfoService implements FindAllBattleInfoUseCase { private static final String RESULT_WINNING = "WINNING"; private static final String RESULT_LOSING = "LOSING"; private static final String RESULT_DRAWING = "DRAWING"; - private static final String RESULT_NOT_STARTED = "NOT_STARTED"; private final BattleRepositoryPort battleRepositoryPort; private final BattleFinishService battleFinishService; @@ -213,11 +212,6 @@ private String determineResult( } } - // 시작 전 배틀 - if (status == BattleStatus.NOT_STARTED) { - return RESULT_NOT_STARTED; - } - throw new IllegalStateException("Unexpected battle status: " + status); } diff --git a/src/main/java/com/process/clash/domain/rival/battle/enums/BattleStatus.java b/src/main/java/com/process/clash/domain/rival/battle/enums/BattleStatus.java index 200c2a757..838ea5ba5 100644 --- a/src/main/java/com/process/clash/domain/rival/battle/enums/BattleStatus.java +++ b/src/main/java/com/process/clash/domain/rival/battle/enums/BattleStatus.java @@ -2,7 +2,6 @@ public enum BattleStatus { IN_PROGRESS, - NOT_STARTED, PENDING, DONE, REJECTED, diff --git a/src/test/java/com/process/clash/application/compete/rival/battle/service/BattleFinishServiceTest.java b/src/test/java/com/process/clash/application/compete/rival/battle/service/BattleFinishServiceTest.java index cc115989f..df9e326aa 100644 --- a/src/test/java/com/process/clash/application/compete/rival/battle/service/BattleFinishServiceTest.java +++ b/src/test/java/com/process/clash/application/compete/rival/battle/service/BattleFinishServiceTest.java @@ -65,7 +65,6 @@ void finishExpiredBattles_transitionsInProgressToDone() { RivalLinkingStatus.ACCEPTED, FIRST_USER_ID, SECOND_USER_ID); when(battleRepositoryPort.findExpiredInProgressBattles()).thenReturn(List.of(inProgressBattle)); - when(battleRepositoryPort.findExpiredNotStartedBattles()).thenReturn(List.of()); when(rivalRepositoryPort.findByIdIn(Set.of(RIVAL_ID))).thenReturn(List.of(rival)); when(userExpHistoryRepositoryPort.findAverageExpForBattles(eq(FIRST_USER_ID), anyList())) .thenReturn(Map.of(1L, 10.0)); @@ -79,59 +78,10 @@ void finishExpiredBattles_transitionsInProgressToDone() { assertThat(captor.getValue()).allMatch(b -> b.battleStatus() == BattleStatus.DONE); } - @Test - @DisplayName("종료 시각이 지난 NOT_STARTED 배틀을 CANCELED로 전환한다") - void finishExpiredBattles_transitionsNotStartedToCanceled() { - Instant startedAt = Instant.now().minus(8, ChronoUnit.DAYS); - Instant endAt = Instant.now().minus(1, ChronoUnit.DAYS); - Battle notStartedBattle = new Battle(2L, Instant.now(), Instant.now(), - startedAt, endAt, 7, BattleStatus.NOT_STARTED, null, RIVAL_ID, FIRST_USER_ID); - - when(battleRepositoryPort.findExpiredInProgressBattles()).thenReturn(List.of()); - when(battleRepositoryPort.findExpiredNotStartedBattles()).thenReturn(List.of(notStartedBattle)); - - battleFinishService.finishExpiredBattles(); - - ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); - verify(battleRepositoryPort).saveAll(captor.capture()); - assertThat(captor.getValue()).allMatch(b -> b.battleStatus() == BattleStatus.CANCELED); - } - - @Test - @DisplayName("IN_PROGRESS와 NOT_STARTED 만료 배틀을 한 번의 saveAll로 처리한다") - void finishExpiredBattles_savesAllInSingleCall() { - Instant startedAt = Instant.now().minus(8, ChronoUnit.DAYS); - Instant endAt = Instant.now().minus(1, ChronoUnit.DAYS); - Battle inProgressBattle = new Battle(1L, Instant.now(), Instant.now(), - startedAt, endAt, 7, BattleStatus.IN_PROGRESS, null, RIVAL_ID, FIRST_USER_ID); - Battle notStartedBattle = new Battle(2L, Instant.now(), Instant.now(), - startedAt, endAt, 7, BattleStatus.NOT_STARTED, null, RIVAL_ID, FIRST_USER_ID); - - Rival rival = new Rival(RIVAL_ID, Instant.now(), Instant.now(), - RivalLinkingStatus.ACCEPTED, FIRST_USER_ID, SECOND_USER_ID); - - when(battleRepositoryPort.findExpiredInProgressBattles()).thenReturn(List.of(inProgressBattle)); - when(battleRepositoryPort.findExpiredNotStartedBattles()).thenReturn(List.of(notStartedBattle)); - when(rivalRepositoryPort.findByIdIn(Set.of(RIVAL_ID))).thenReturn(List.of(rival)); - when(userExpHistoryRepositoryPort.findAverageExpForBattles(eq(FIRST_USER_ID), anyList())) - .thenReturn(Map.of(1L, 10.0)); - when(userExpHistoryRepositoryPort.findAverageExpForBattles(eq(SECOND_USER_ID), anyList())) - .thenReturn(Map.of(1L, 5.0)); - - battleFinishService.finishExpiredBattles(); - - ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); - verify(battleRepositoryPort).saveAll(captor.capture()); - assertThat(captor.getValue()).hasSize(2) - .anyMatch(b -> b.battleStatus() == BattleStatus.DONE) - .anyMatch(b -> b.battleStatus() == BattleStatus.CANCELED); - } - @Test @DisplayName("종료할 배틀이 없으면 saveAll을 호출하지 않는다") void finishExpiredBattles_doesNotCallSaveAll_whenNoBattlesToProcess() { when(battleRepositoryPort.findExpiredInProgressBattles()).thenReturn(List.of()); - when(battleRepositoryPort.findExpiredNotStartedBattles()).thenReturn(List.of()); battleFinishService.finishExpiredBattles(); diff --git a/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java b/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java index dfeb65af3..98e666b92 100644 --- a/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java +++ b/src/test/java/com/process/clash/application/compete/rival/battle/service/FindAllBattleInfoServiceTest.java @@ -147,16 +147,6 @@ void execute_returnsDrawing_whenInProgressAndTied() { assertThat(result.battles().get(0).result()).isEqualTo("DRAWING"); } - @Test - @DisplayName("NOT_STARTED 배틀은 NOT_STARTED를 반환한다") - void execute_returnsNotStarted_whenNotStarted() { - stubCommonDependencies(List.of(battle(BattleStatus.NOT_STARTED, null))); - - FindAllBattleInfoData.Result result = findAllBattleInfoService.execute(command()); - - assertThat(result.battles().get(0).result()).isEqualTo("NOT_STARTED"); - } - @Test @DisplayName("상대방 rankTier가 NONE이면 expTier를 tier로 반환한다") void execute_returnsEnemyTierAsExpTier_whenRankTierIsNone() { From b75e769c88b8bbe6846081d99f3759d6a0bb56e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A0=95=EB=B9=88?= Date: Mon, 13 Apr 2026 01:48:30 +0900 Subject: [PATCH 3/4] =?UTF-8?q?docs:=20=EC=A3=BC=EC=84=9D=EC=97=90=20NOT?= =?UTF-8?q?=5FSTARTED=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../battle/docs/response/FindAllBattleInfoResponseDocument.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/response/FindAllBattleInfoResponseDocument.java b/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/response/FindAllBattleInfoResponseDocument.java index eb207a78b..f414a5cd9 100644 --- a/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/response/FindAllBattleInfoResponseDocument.java +++ b/src/main/java/com/process/clash/adapter/web/compete/rival/battle/docs/response/FindAllBattleInfoResponseDocument.java @@ -34,7 +34,7 @@ public static class BattleInfoDoc { public LocalDate expireDate; @Schema(description = "결과", example = "WON") - public String result; // WON, LOST, DRAWN, WINNING, LOSING, DRAWING, NOT_STARTED, CANCELED, PENDING + public String result; // WON, LOST, DRAWN, WINNING, LOSING, DRAWING } public static class EnemyDoc { From ba907d2a56cd3b6b914dca990727cca3a6cf134c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EC=A0=95=EB=B9=88?= Date: Mon, 13 Apr 2026 01:57:43 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20NOT=5FSTARTED=20=EC=9E=94?= =?UTF-8?q?=EC=A1=B4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=95=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compete/rival/battle/service/BattleFinishService.java | 6 ++++-- .../db/migration/V33__cancel_not_started_battles.sql | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/db/migration/V33__cancel_not_started_battles.sql diff --git a/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java b/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java index 983adeed5..13e4d94d4 100644 --- a/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java +++ b/src/main/java/com/process/clash/application/compete/rival/battle/service/BattleFinishService.java @@ -74,8 +74,10 @@ public void finishExpiredBattles() { } } - battleRepositoryPort.saveAll(battlesToUpdate); - log.info("Expired battles processed. done={}", expiredInProgress.size()); + if (!battlesToUpdate.isEmpty()) { + battleRepositoryPort.saveAll(battlesToUpdate); + } + log.info("Expired battles processed. done={}", battlesToUpdate.size()); } /** diff --git a/src/main/resources/db/migration/V33__cancel_not_started_battles.sql b/src/main/resources/db/migration/V33__cancel_not_started_battles.sql new file mode 100644 index 000000000..97d20829e --- /dev/null +++ b/src/main/resources/db/migration/V33__cancel_not_started_battles.sql @@ -0,0 +1,5 @@ +-- 배틀 승인 즉시 IN_PROGRESS로 시작되도록 변경함에 따라 +-- 기존에 남아 있는 NOT_STARTED 상태 배틀을 CANCELED로 일괄 전환 +UPDATE battles +SET battle_status = 'CANCELED' +WHERE battle_status = 'NOT_STARTED'; \ No newline at end of file