Skip to content

Commit e6b5fc6

Browse files
authored
Feat: 스터디룸 로직 보완 및 테스트 코드 작성 (#56) (#85)
* feat: dto 도입과 스터디룸 설정 외부화 * feat: 상태 검증, n+1 문제 해결, 동시성 제어 추가 * refactor: 스터디룸 레퍼지토리 쿼리dsl 타입으로 안정성 추가 * refactor: 스터디름 스웨거 어노테이션 추가 * Test: 지금까지 만들어왔던 테스트코드 정리 * Test: 테스트 룸 컨트롤러단에서 SecurityConfig 제외 * Test:룸 컨트롤러 webMvcTest제거, 단위테스트로 진행 * fix: 코드리뷰 받은 문서파일 제거
1 parent 1e1b690 commit e6b5fc6

23 files changed

+1971
-373
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dependencies {
2828
// Spring
2929
implementation("org.springframework.boot:spring-boot-starter-web")
3030
implementation("org.springframework.boot:spring-boot-starter-websocket")
31+
implementation("org.springframework.boot:spring-boot-starter-validation")
3132

3233
// Database & JPA
3334
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.back.domain.studyroom.config;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
import org.springframework.boot.context.properties.ConfigurationProperties;
6+
import org.springframework.stereotype.Component;
7+
8+
@Getter
9+
@Setter
10+
@Component
11+
@ConfigurationProperties(prefix = "studyroom")
12+
public class StudyRoomProperties {
13+
14+
private Heartbeat heartbeat = new Heartbeat();
15+
private Default defaultSettings = new Default();
16+
17+
@Getter
18+
@Setter
19+
public static class Heartbeat {
20+
private int timeoutMinutes = 5;
21+
}
22+
23+
@Getter
24+
@Setter
25+
public static class Default {
26+
private int maxParticipants = 10;
27+
private boolean allowCamera = true;
28+
private boolean allowAudio = true;
29+
private boolean allowScreenShare = true;
30+
}
31+
}

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

Lines changed: 165 additions & 211 deletions
Large diffs are not rendered by default.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import jakarta.validation.constraints.*;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
@Getter
9+
@NoArgsConstructor
10+
@AllArgsConstructor
11+
public class CreateRoomRequest {
12+
@NotBlank(message = "방 제목은 필수입니다")
13+
@Size(max = 100, message = "방 제목은 100자를 초과할 수 없습니다")
14+
private String title;
15+
16+
@Size(max = 500, message = "방 설명은 500자를 초과할 수 없습니다")
17+
private String description;
18+
19+
private Boolean isPrivate = false;
20+
21+
private String password;
22+
23+
@Min(value = 2, message = "최소 2명 이상이어야 합니다")
24+
@Max(value = 100, message = "최대 100명까지 가능합니다")
25+
private Integer maxParticipants = 10;
26+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
7+
@Getter
8+
@NoArgsConstructor
9+
@AllArgsConstructor
10+
public class JoinRoomRequest {
11+
private String password;
12+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import com.back.domain.studyroom.entity.RoomMember;
4+
import com.back.domain.studyroom.entity.RoomRole;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
8+
import java.time.LocalDateTime;
9+
10+
@Getter
11+
@Builder
12+
public class JoinRoomResponse {
13+
private Long roomId;
14+
private Long userId;
15+
private RoomRole role;
16+
private LocalDateTime joinedAt;
17+
18+
public static JoinRoomResponse from(RoomMember member) {
19+
return JoinRoomResponse.builder()
20+
.roomId(member.getRoom().getId())
21+
.userId(member.getUser().getId())
22+
.role(member.getRole())
23+
.joinedAt(member.getJoinedAt())
24+
.build();
25+
}
26+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import com.back.domain.studyroom.entity.Room;
4+
import com.back.domain.studyroom.entity.RoomRole;
5+
import com.back.domain.studyroom.entity.RoomStatus;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
9+
import java.time.LocalDateTime;
10+
11+
@Getter
12+
@Builder
13+
public class MyRoomResponse {
14+
private Long roomId;
15+
private String title;
16+
private String description;
17+
private int currentParticipants;
18+
private int maxParticipants;
19+
private RoomStatus status;
20+
private RoomRole myRole;
21+
private LocalDateTime createdAt;
22+
23+
public static MyRoomResponse of(Room room, RoomRole myRole) {
24+
return MyRoomResponse.builder()
25+
.roomId(room.getId())
26+
.title(room.getTitle())
27+
.description(room.getDescription() != null ? room.getDescription() : "")
28+
.currentParticipants(room.getCurrentParticipants())
29+
.maxParticipants(room.getMaxParticipants())
30+
.status(room.getStatus())
31+
.myRole(myRole)
32+
.createdAt(room.getCreatedAt())
33+
.build();
34+
}
35+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import com.back.domain.studyroom.entity.Room;
4+
import com.back.domain.studyroom.entity.RoomStatus;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
8+
import java.time.LocalDateTime;
9+
import java.util.List;
10+
11+
@Getter
12+
@Builder
13+
public class RoomDetailResponse {
14+
private Long roomId;
15+
private String title;
16+
private String description;
17+
private boolean isPrivate;
18+
private int maxParticipants;
19+
private int currentParticipants;
20+
private RoomStatus status;
21+
private boolean allowCamera;
22+
private boolean allowAudio;
23+
private boolean allowScreenShare;
24+
private String createdBy;
25+
private LocalDateTime createdAt;
26+
private List<RoomMemberResponse> members;
27+
28+
public static RoomDetailResponse of(Room room, List<RoomMemberResponse> members) {
29+
return RoomDetailResponse.builder()
30+
.roomId(room.getId())
31+
.title(room.getTitle())
32+
.description(room.getDescription() != null ? room.getDescription() : "")
33+
.isPrivate(room.isPrivate())
34+
.maxParticipants(room.getMaxParticipants())
35+
.currentParticipants(room.getCurrentParticipants())
36+
.status(room.getStatus())
37+
.allowCamera(room.isAllowCamera())
38+
.allowAudio(room.isAllowAudio())
39+
.allowScreenShare(room.isAllowScreenShare())
40+
.createdBy(room.getCreatedBy().getNickname())
41+
.createdAt(room.getCreatedAt())
42+
.members(members)
43+
.build();
44+
}
45+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import com.back.domain.studyroom.entity.RoomMember;
4+
import com.back.domain.studyroom.entity.RoomRole;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
8+
import java.time.LocalDateTime;
9+
10+
@Getter
11+
@Builder
12+
public class RoomMemberResponse {
13+
private Long userId;
14+
private String nickname;
15+
private RoomRole role;
16+
private boolean isOnline;
17+
private LocalDateTime joinedAt;
18+
private LocalDateTime lastActiveAt;
19+
20+
public static RoomMemberResponse from(RoomMember member) {
21+
return RoomMemberResponse.builder()
22+
.userId(member.getUser().getId())
23+
.nickname(member.getUser().getNickname())
24+
.role(member.getRole())
25+
.isOnline(member.isOnline())
26+
.joinedAt(member.getJoinedAt())
27+
.lastActiveAt(member.getLastActiveAt() != null ? member.getLastActiveAt() : member.getJoinedAt())
28+
.build();
29+
}
30+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.back.domain.studyroom.dto;
2+
3+
import com.back.domain.studyroom.entity.Room;
4+
import com.back.domain.studyroom.entity.RoomStatus;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
8+
import java.time.LocalDateTime;
9+
10+
@Getter
11+
@Builder
12+
public class RoomResponse {
13+
private Long roomId;
14+
private String title;
15+
private String description;
16+
private int currentParticipants;
17+
private int maxParticipants;
18+
private RoomStatus status;
19+
private String createdBy;
20+
private LocalDateTime createdAt;
21+
22+
public static RoomResponse from(Room room) {
23+
return RoomResponse.builder()
24+
.roomId(room.getId())
25+
.title(room.getTitle())
26+
.description(room.getDescription() != null ? room.getDescription() : "")
27+
.currentParticipants(room.getCurrentParticipants())
28+
.maxParticipants(room.getMaxParticipants())
29+
.status(room.getStatus())
30+
.createdBy(room.getCreatedBy().getNickname())
31+
.createdAt(room.getCreatedAt())
32+
.build();
33+
}
34+
}

0 commit comments

Comments
 (0)