Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/api-specs/battle-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
- `page` (기본값: `1`)
- `size` (기본값: `10`)
- `status` (선택)
- 항목(`BattleSimpleResponse`): `battleId`, `title`, `thumbnailUrl`, `status`, `publishAt`, `createdAt`, `difficulty`
- `difficulty`: 대상 수준 (`BEGINNER` 초급 / `INTERMEDIATE` 중급 / `ADVANCED` 고급). 새로 만든 배틀은 초급으로 저장되고, [클래스 설정 수정](./class-api.md#91-배틀-클래스-설정-수정)으로 바꾼다.

### 2.4 배틀 상세
- `GET /api/v1/admin/battles/{battleId}`
Expand Down
1 change: 1 addition & 0 deletions docs/api-specs/class-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,7 @@ AI가 주제 후보를 제안하면 운영자가 하나를 고르거나 직접

- 응답: `AdminBattleDetailResponse`. 끝에 `difficulty`, `category`, `classRecommendable`, `midVoteEnabled`가 추가됐다. 어드민 배틀 상세 조회에도 같은 필드가 내려간다.
- 추천 API는 이 설정이 켜진 배틀만 돌려준다. 그래서 운영에서 배틀마다 설정해야 추천 결과가 나온다.
- 수준은 기획 확정 전까지 임시로 초급이다. 수준이 비어 있던 기존 배틀은 SQL로 초급을 채웠고, 어드민이 새로 만드는 배틀도 초급으로 저장된다. 어드민 배틀 목록에도 `difficulty`가 내려간다.

| 상황 | 응답 |
|---|---|
Expand Down
1 change: 1 addition & 0 deletions docs/erd/class.puml
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ note bottom of battles
→ 에디터픽 → 참여자 수 → 최신 id 순, 최대 3개 (모자라면 채우지 않음)
difficulty·category·class_recommendable 는 어드민 PATCH /admin/battles/{id}/class-settings 로 설정
추천을 켜려면 difficulty·category 필수, 커스텀 배틀(creator_type USER)은 설정 불가
difficulty 는 임시로 초급 기본값 (#571: 기존 NULL → BEGINNER, 어드민 신규 생성도 BEGINNER)
end note

note bottom of classes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public BattleSimpleResponse toSimpleResponse(Battle battle) {
urlProvider.getImageUrl(FileCategory.BATTLE, battle.getThumbnailUrl()),
battle.getStatus() != null ? battle.getStatus().name() : "PENDING",
battle.getPublishAt(),
battle.getCreatedAt()
battle.getCreatedAt(),
battle.getDifficulty()
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.swyp.picke.domain.battle.dto.response;

import com.swyp.picke.domain.battle.enums.BattleDifficulty;
import java.time.LocalDateTime;

public record BattleSimpleResponse(
Expand All @@ -8,5 +9,6 @@ public record BattleSimpleResponse(
String thumbnailUrl,
String status,
LocalDateTime publishAt,
LocalDateTime createdAt
LocalDateTime createdAt,
BattleDifficulty difficulty
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.swyp.picke.domain.battle.entity.BattleOptionTag;
import com.swyp.picke.domain.battle.entity.BattleTag;
import com.swyp.picke.domain.battle.enums.BattleCreatorType;
import com.swyp.picke.domain.battle.enums.BattleDifficulty;
import com.swyp.picke.domain.battle.enums.BattleStatus;
import com.swyp.picke.domain.battle.util.BattleOptionDisplay;
import com.swyp.picke.domain.user.dto.response.UserBattleStatusResponse;
Expand Down Expand Up @@ -337,6 +338,8 @@ public AdminBattleDetailResponse createBattle(AdminBattleCreateRequest request,
request.audioDuration(),
request.status()
);
// 수준은 기획 확정 전까지 초급으로 두고, 어드민 상세에서 바꾼다 (#571)
battle.updateClassSettings(BattleDifficulty.BEGINNER, null, null, null);
battle = battleRepository.save(battle);

if (request.tagIds() != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- #571 수준이 비어 있는 배틀을 임시로 전부 초급으로 채운다 (어드민 상세에서 변경)
-- 멱등하게 작성되어 재실행해도 안전하다.
UPDATE battles SET difficulty = 'BEGINNER' WHERE difficulty IS NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- Rollback for V20261024_01__battles_difficulty_beginner.sql
-- 어떤 행을 채웠는지 따로 기록하지 않으므로, 어드민이 초급으로 직접 고른 배틀도 함께 비워진다.
UPDATE battles SET difficulty = NULL WHERE difficulty = 'BEGINNER' AND creator_type <> 'USER';
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.swyp.picke.domain.battle.entity.Battle;
import com.swyp.picke.domain.battle.enums.BattleDifficulty;
import com.swyp.picke.domain.battle.entity.BattleOption;
import com.swyp.picke.domain.battle.repository.BattleOptionRepository;
import com.swyp.picke.domain.battle.repository.BattleOptionTagRepository;
Expand Down Expand Up @@ -149,6 +150,7 @@ void createBattle_persistsAllMappedFields() throws Exception {
assertThat(savedBattle.getThumbnailUrl()).isEqualTo("images/battles/battle-thumb.png");
assertThat(savedBattle.getAudioDuration()).isEqualTo(95);
assertThat(savedBattle.getTargetDate()).isEqualTo(targetDate);
assertThat(savedBattle.getDifficulty()).isEqualTo(BattleDifficulty.BEGINNER);

assertThat(options).hasSize(2);
BattleOption optionA = options.stream().filter(option -> option.getDisplayOrder() == 1).findFirst().orElseThrow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@ void adminClassSettings() throws Exception {

JsonNode items = data(recommend(Map.of("difficulty", "ADVANCED", "categories", "역사"))).get("items");
assertThat(ids(items)).containsExactly(battle.getId());

JsonNode adminItems = data(mockMvc.perform(get("/api/v1/admin/battles")
.header("Authorization", "Bearer " + adminToken)
.param("size", "100"))).get("items");
JsonNode listed = null;
for (JsonNode item : adminItems) {
if (item.get("battleId").asLong() == battle.getId()) {
listed = item;
}
}
assertThat(listed).isNotNull();
assertThat(listed.get("difficulty").asText()).isEqualTo("ADVANCED");
}

@Test
Expand Down
Loading