Skip to content

Commit e9a1c5a

Browse files
loseminhonamgigun
andauthored
Refactor: 아바타 시스템 DB와 완전 분리 (#302) (#304)
* refactor: 스더티룸 권한에 대한 로직 개선 * fix: ci에서 통과 못한 테스트코드 수정 * fix:rest api와 웹소켓 중간 경로 통합 * fix:rest api와 웹소켓 중간 경로 통합 * fix: 에러 확인을 위한 통합테스트 추가, Room.create()메서드 수정 * refactor, feat : 조회 분할 * refactor: redis 로직 최적화 및 중복 검증 로직 제거 * fix: 에러 번호 수정 * feat: 스터디룸 방 비밀번호 변경 및 삭제 기능 구현 * fix:app-dev 제거 * feat: 웹소켓 기반 소극적 하트비트 * feat: 스터디룸 썸네일 기능 추가 및 webrtc 설정 변경에서 주석처리 * fix:소극적 하트비트 사용 주석처리 * Feat: 스터디 룸 내에 고양이 아바타 시스템과 프로필 이미지 url 연동 * fix: 기존 작성되어있던 test 코드 수정 * test: 아바타 테스트 코드 완료 * refactor: 프론트엔드 요청 사항에 따른 스터디룸 조회 마스킹 제거 * feat: 스터디룸 방 초대 코드 시스템 * Infra: main branch 로컬 환경과 운영 환경 동기화 * Infra: docker-compose 파일 수정 - Redis 버전 업그레이드 기존: 6.2 -> 변경: 7.0 * Fix: 백엔드 CD 파일 수정 - 자동화 시, 잘못된 도메인으로 호스트 ID 검증하는 오류 해결 * Infra: EC2 환경변수 수정 - 잘못 표기한 도메인 네임 변경 * Chore: CD 파일 수정 - Github Actions commandLine 인식 문제로 인해 set -Eeuo pipefail 줄바꿈 * Chore: 백엔드 CD 파일 수정 - 인스턴스 ID 체크 삭제 * Infra: 백엔드 CD 파일 수정 - .env 파일 추가시, $DOT_ENV_PROD -> $DOT_ENV 로 변경 * Infra: 도커 컴포즈 수정 - mysql 사용자 정보 변경 * Infra: 운영환경 설정 - application-prod.yml 과 application.yml 동기화 * Fix: SecurityConfig 수정 - H2 DB 허용 X * test,fix: 방 초대에 대한 테스트 코드 작성 및 에러 수정 * fix: 스터디룸 파일 업로드 맵핑 형식으로 변환 * fix: 병합충돌 제어 수정 * fix: 병합충돌 제어 * fix: 스터디 룸 내 프론트엔드 요구 사항 및 오류사항 수정 * feat: 방 즐겨찾기, 방 공지사항 구현 * fix: mockbean 수정 * fix: 테스트에서 빠진 비로그인 사용자 추가 * hotfix: 누락된 사용자 추방에 대한 컨트롤러 추가 * hotfix: VISITOR도 추방 가능하도록 수정 * fix: 누락된 테스트코드 추가 및 테스트코드 로직 수정 * refactor: 아바타 시스템 db와 분리 및 테스트 코드 수정 * fix: 턴서버 dev에 맞춤 --------- Co-authored-by: namgigun <[email protected]>
1 parent 9436ad8 commit e9a1c5a

18 files changed

+108
-1119
lines changed

src/main/java/com/back/domain/studyroom/controller/RoomAvatarController.java

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.back.domain.studyroom.controller;
22

3-
import com.back.domain.studyroom.dto.AvatarResponse;
43
import com.back.domain.studyroom.dto.UpdateAvatarRequest;
54
import com.back.domain.studyroom.service.AvatarService;
65
import com.back.global.common.dto.RsData;
@@ -13,16 +12,14 @@
1312
import io.swagger.v3.oas.annotations.tags.Tag;
1413
import jakarta.validation.Valid;
1514
import lombok.RequiredArgsConstructor;
16-
import org.springframework.http.HttpStatus;
1715
import org.springframework.http.ResponseEntity;
1816
import org.springframework.web.bind.annotation.*;
1917

20-
import java.util.List;
21-
2218
/**
2319
* 방 아바타 관리 API 컨트롤러
2420
* - JWT 인증 필수
25-
* - MEMBER 등급 이상만 아바타 변경 가능
21+
* - 아바타는 숫자(ID)로만 관리
22+
* - 프론트엔드에서 숫자에 맞는 이미지 매핑
2623
*/
2724
@RestController
2825
@RequestMapping("/api/rooms/{roomId}/avatars")
@@ -34,42 +31,19 @@ public class RoomAvatarController {
3431
private final AvatarService avatarService;
3532
private final CurrentUser currentUser;
3633

37-
/**
38-
* 사용 가능한 아바타 목록 조회
39-
*/
40-
@GetMapping
41-
@Operation(
42-
summary = "아바타 목록 조회",
43-
description = "선택 가능한 아바타 목록을 조회합니다. 고양이, 강아지 등 다양한 아바타를 제공합니다."
44-
)
45-
@ApiResponses({
46-
@ApiResponse(responseCode = "200", description = "조회 성공"),
47-
@ApiResponse(responseCode = "401", description = "인증 실패")
48-
})
49-
public ResponseEntity<RsData<List<AvatarResponse>>> getAvatars(
50-
@Parameter(description = "방 ID", required = true) @PathVariable Long roomId) {
51-
52-
List<AvatarResponse> avatars = avatarService.getAvailableAvatars();
53-
54-
return ResponseEntity.ok(
55-
RsData.success("아바타 목록 조회 완료", avatars)
56-
);
57-
}
58-
5934
/**
6035
* 내 아바타 변경 (모든 사용자 가능)
6136
*/
6237
@PutMapping("/me")
6338
@Operation(
6439
summary = "아바타 변경",
6540
description = "방에서 사용할 아바타를 변경합니다.\n\n" +
66-
"- VISITOR: Redis에만 저장 (퇴장 시 삭제, 재입장 시 랜덤 배정)\n" +
67-
"- MEMBER 이상: DB에 저장 (재입장 시에도 유지)"
41+
"- 프론트에서 원하는 숫자(avatarId)를 전송하면 그대로 저장됩니다.\n" +
42+
"- DB 검증 없이 Redis에만 저장됩니다.\n" +
43+
"- 모든 사용자(VISITOR 포함) 변경 가능합니다."
6844
)
6945
@ApiResponses({
7046
@ApiResponse(responseCode = "200", description = "변경 성공"),
71-
@ApiResponse(responseCode = "400", description = "잘못된 아바타 ID"),
72-
@ApiResponse(responseCode = "404", description = "존재하지 않는 방 또는 아바타"),
7347
@ApiResponse(responseCode = "401", description = "인증 실패")
7448
})
7549
public ResponseEntity<RsData<Void>> updateMyAvatar(

src/main/java/com/back/domain/studyroom/controller/RoomController.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public ResponseEntity<RsData<RoomResponse>> createRoom(
7777
@PostMapping("/{roomId}/join")
7878
@Operation(
7979
summary = "방 입장",
80-
description = "특정 스터디 룸에 입장합니다. 공개방은 바로 입장 가능하며, 비공개방은 비밀번호가 필요합니다."
80+
description = "특정 스터디 룸에 입장합니다. 공개방은 바로 입장 가능하며, 비공개방은 비밀번호가 필요합니다. 입장 시 랜덤 아바타(1~3)가 배정됩니다."
8181
)
8282
@ApiResponses({
8383
@ApiResponse(responseCode = "200", description = "방 입장 성공"),
@@ -96,8 +96,11 @@ public ResponseEntity<RsData<JoinRoomResponse>> joinRoom(
9696
password = request.getPassword();
9797
}
9898

99-
RoomMember member = roomService.joinRoom(roomId, password, currentUserId);
100-
JoinRoomResponse response = JoinRoomResponse.from(member);
99+
// 방 입장 + 아바타 ID 반환
100+
com.back.domain.studyroom.dto.JoinRoomWithAvatarResult result =
101+
roomService.joinRoomWithAvatar(roomId, password, currentUserId);
102+
103+
JoinRoomResponse response = JoinRoomResponse.of(result.getMember(), result.getAvatarId());
101104

102105
return ResponseEntity
103106
.status(HttpStatus.OK)

src/main/java/com/back/domain/studyroom/controller/RoomInvitePublicController.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class RoomInvitePublicController {
3131
private final RoomInviteService inviteService;
3232
private final RoomService roomService;
3333
private final CurrentUser currentUser;
34+
private final com.back.domain.studyroom.service.AvatarService avatarService;
3435

3536
@PostMapping("/{inviteCode}")
3637
@SecurityRequirement(name = "Bearer Authentication")
@@ -59,7 +60,11 @@ public ResponseEntity<RsData<JoinRoomResponse>> joinByInviteCode(
5960

6061
// 방 입장 권한 체크 (비밀번호 무시, Redis 등록 건너뜀)
6162
RoomMember member = roomService.joinRoom(room.getId(), null, userId, false);
62-
JoinRoomResponse response = JoinRoomResponse.from(member);
63+
64+
// 랜덤 아바타 ID 생성
65+
Long avatarId = avatarService.assignRandomAvatar();
66+
67+
JoinRoomResponse response = JoinRoomResponse.of(member, avatarId);
6368

6469
return ResponseEntity
6570
.status(HttpStatus.OK)

src/main/java/com/back/domain/studyroom/dto/AvatarResponse.java

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/main/java/com/back/domain/studyroom/dto/JoinRoomResponse.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ public class JoinRoomResponse {
1313
private Long roomId;
1414
private Long userId;
1515
private RoomRole role;
16+
private Long avatarId; // 부여받은 아바타 ID (숫자만)
1617
private LocalDateTime joinedAt;
1718

18-
public static JoinRoomResponse from(RoomMember member) {
19+
public static JoinRoomResponse of(RoomMember member, Long avatarId) {
1920
return JoinRoomResponse.builder()
2021
.roomId(member.getRoom().getId())
2122
.userId(member.getUser().getId())
2223
.role(member.getRole())
24+
.avatarId(avatarId)
2325
.joinedAt(member.getJoinedAt())
2426
.build();
2527
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import com.back.domain.studyroom.entity.RoomMember;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
7+
/**
8+
* 방 입장 결과 + 아바타 ID
9+
* 내부 전달용 DTO
10+
*/
11+
@Getter
12+
@AllArgsConstructor
13+
public class JoinRoomWithAvatarResult {
14+
private RoomMember member;
15+
private Long avatarId;
16+
}

src/main/java/com/back/domain/studyroom/dto/RoomMemberResponse.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ public class RoomMemberResponse {
1313
private Long userId;
1414
private String nickname;
1515
private String profileImageUrl;
16-
private Long avatarId;
17-
private String avatarImageUrl;
16+
private Long avatarId; // 아바타 ID (숫자만, 프론트에서 매핑)
1817
private RoomRole role;
1918
private LocalDateTime joinedAt;
2019
private LocalDateTime promotedAt;
@@ -36,15 +35,14 @@ public static RoomMemberResponse from(RoomMember member) {
3635
}
3736

3837
/**
39-
* 아바타 정보를 포함된 내용으로 생성
38+
* 아바타 ID 포함하여 생성
4039
*/
41-
public static RoomMemberResponse of(RoomMember member, Long avatarId, String avatarImageUrl) {
40+
public static RoomMemberResponse of(RoomMember member, Long avatarId) {
4241
return RoomMemberResponse.builder()
4342
.userId(member.getUser().getId())
4443
.nickname(member.getUser().getNickname())
4544
.profileImageUrl(member.getUser().getProfileImageUrl())
4645
.avatarId(avatarId)
47-
.avatarImageUrl(avatarImageUrl)
4846
.role(member.getRole())
4947
.joinedAt(member.getJoinedAt())
5048
.promotedAt(member.getPromotedAt())

src/main/java/com/back/domain/studyroom/entity/Avatar.java

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/main/java/com/back/domain/studyroom/entity/RoomMemberAvatar.java

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/main/java/com/back/domain/studyroom/repository/AvatarRepository.java

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)