-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 방 생성, 수정 기능 구현 #20
Changes from 13 commits
034ee6e
bb3add1
ece1678
b067abb
00558f6
20cc332
25d0044
2dd7c1a
7b8ff99
86b2b53
051d56e
a35ce88
c299ac3
a0bacae
b2fddfb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package com.moabam.api.application; | ||
|
||
import static com.moabam.global.error.model.ErrorMessage.*; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.moabam.api.domain.entity.Participant; | ||
import com.moabam.api.domain.entity.Room; | ||
import com.moabam.api.domain.entity.Routine; | ||
import com.moabam.api.domain.repository.ParticipantRepository; | ||
import com.moabam.api.domain.repository.RoomRepository; | ||
import com.moabam.api.domain.repository.RoutineRepository; | ||
import com.moabam.api.dto.CreateRoomRequest; | ||
import com.moabam.api.dto.ModifyRoomRequest; | ||
import com.moabam.api.dto.RoomMapper; | ||
import com.moabam.global.error.exception.ForbiddenException; | ||
import com.moabam.global.error.exception.NotFoundException; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class RoomService { | ||
|
||
private final RoomRepository roomRepository; | ||
private final RoutineRepository routineRepository; | ||
private final ParticipantRepository participantRepository; | ||
|
||
@Transactional | ||
public void createRoom(Long memberId, CreateRoomRequest createRoomRequest) { | ||
Room room = RoomMapper.toRoomEntity(createRoomRequest); | ||
List<Routine> routines = RoomMapper.toRoutineEntity(room, createRoomRequest.routines()); | ||
Participant participant = Participant.builder() | ||
.room(room) | ||
.memberId(memberId) | ||
.build(); | ||
participant.enableManager(); | ||
|
||
roomRepository.save(room); | ||
routineRepository.saveAll(routines); | ||
participantRepository.save(participant); | ||
} | ||
|
||
@Transactional | ||
public void modifyRoom(Long memberId, Long roomId, ModifyRoomRequest modifyRoomRequest) { | ||
// TODO: 추후에 별도 메서드로 뺄듯 | ||
Participant participant = participantRepository.findParticipantByRoomIdAndMemberId(roomId, memberId) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Q: 추후에 �별도 메서드로 뺀다는 것이 JPA를 사용안하고 직접 쿼리를 짜는 걸로 이해하면 될까요?! 아니라면, 조회에 대한 쿼리는 되도록 JPA를 안쓰고 네이티브 쿼리나 QueryDSL 사용을 권장합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 저건 나중에 반복적으로 쓰이면 private으로 뺄수도 있다고 일단 남겼습니다! |
||
.orElseThrow(() -> new NotFoundException(PARTICIPANT_NOT_FOUND)); | ||
|
||
if (!participant.isManager()) { | ||
throw new ForbiddenException(ROOM_MODIFY_UNAUTHORIZED_REQUEST); | ||
} | ||
|
||
Room room = roomRepository.findById(roomId).orElseThrow(() -> new NotFoundException(ROOM_NOT_FOUND)); | ||
room.changeTitle(modifyRoomRequest.title()); | ||
room.changePassword(modifyRoomRequest.password()); | ||
room.changeCertifyTime(modifyRoomRequest.certifyTime()); | ||
room.changeMaxCount(modifyRoomRequest.maxUserCount()); | ||
Comment on lines
+60
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A: 저도 항상 이게 고민인데, 하나의 메서드에서 여러 파라미터를 받아 해결할 지? 아니면 재윤, 영명님이 하신 것처럼 분리할 지? 고민입니다! 분리한 이유가 있다면 무엇인가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 엔티티까지 들어가지 않고 여기서 어떤 정보들이 변하는지 확인이 가능해서 분리해보았습니다! |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.moabam.api.domain.entity; | ||
|
||
import static java.util.Objects.*; | ||
|
||
import com.moabam.global.common.entity.BaseTimeEntity; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.Table; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Getter | ||
@Table(name = "certification") | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Certification extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "routine_id", nullable = false, updatable = false) | ||
private Routine routine; | ||
|
||
@Column(name = "member_id", nullable = false, updatable = false) | ||
private Long memberId; | ||
|
||
@Column(name = "image", nullable = false) | ||
private String image; | ||
|
||
@Builder | ||
private Certification(Routine routine, Long memberId, String image) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. id도 같이 넣어야 하는걸로 알고 있습니다! |
||
this.routine = requireNonNull(routine); | ||
this.memberId = requireNonNull(memberId); | ||
this.image = requireNonNull(image); | ||
} | ||
|
||
public void changeImage(String image) { | ||
this.image = image; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.moabam.api.domain.entity; | ||
|
||
import static java.util.Objects.*; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import org.hibernate.annotations.SQLDelete; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.Table; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Getter | ||
@Table(name = "participant") | ||
@SQLDelete(sql = "UPDATE participants SET deleted_at = CURRENT_TIMESTAMP where id = ?") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. participants -> participant 아닌가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 헉 큰일날뻔 감사합니다 >.< |
||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Participant { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "room_id", updatable = false, nullable = false) | ||
private Room room; | ||
|
||
@Column(name = "member_id", updatable = false, nullable = false) | ||
private Long memberId; | ||
|
||
@Column(name = "is_manager") | ||
private boolean isManager; | ||
|
||
@Column(name = "certify_count") | ||
private int certifyCount; | ||
|
||
@Column(name = "deleted_at") | ||
private LocalDateTime deletedAt; | ||
|
||
@Builder | ||
private Participant(Room room, Long memberId) { | ||
this.room = requireNonNull(room); | ||
this.memberId = requireNonNull(memberId); | ||
this.isManager = false; | ||
this.certifyCount = 0; | ||
} | ||
|
||
public void disableManager() { | ||
this.isManager = false; | ||
} | ||
|
||
public void enableManager() { | ||
this.isManager = true; | ||
} | ||
|
||
public void updateCertifyCount() { | ||
this.certifyCount += 1; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package com.moabam.api.domain.entity; | ||
|
||
import static com.moabam.api.domain.entity.enums.RoomType.*; | ||
import static com.moabam.global.error.model.ErrorMessage.*; | ||
import static java.util.Objects.*; | ||
|
||
import org.hibernate.annotations.ColumnDefault; | ||
|
||
import com.moabam.api.domain.entity.enums.RoomType; | ||
import com.moabam.global.common.entity.BaseTimeEntity; | ||
import com.moabam.global.error.exception.BadRequestException; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Table; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@Getter | ||
@Table(name = "room") | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Room extends BaseTimeEntity { | ||
|
||
private static final String ROOM_LEVEL_0_IMAGE = "'temptemp'"; | ||
private static final String ROOM_LEVEL_10_IMAGE = "'temp'"; | ||
private static final String ROOM_LEVEL_20_IMAGE = "'tempp'"; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C: 저희 컨벤션은 모두 붙이는 걸로 알고 있습니다! |
||
private static final int MORNING_START_TIME = 4; | ||
private static final int MORNING_END_TIME = 10; | ||
private static final int NIGHT_START_TIME = 20; | ||
private static final int NIGHT_END_TIME = 2; | ||
private static final int CLOCK_ZERO = 0; | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "id") | ||
private Long id; | ||
|
||
// TODO: 한글 10자도 맞나? | ||
@Column(name = "title", nullable = false, length = 30) | ||
private String title; | ||
Comment on lines
+46
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Q: 저도 궁금하네요! 공유 부탁드립니다! ㅋㄱㅋㄱ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문자수 관련인가요? 저번에 찾아봤을 때 mysql이 버전이 업데이트 되면서 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ㅋㅋㅋㅋ 일단은 영어는 1바이트, 한글은 3바이트라 30으로 설정해두었슴다 |
||
|
||
@Column(name = "password", length = 8) | ||
private String password; | ||
|
||
@Column(name = "level", nullable = false) | ||
private int level; | ||
|
||
@Enumerated(value = EnumType.STRING) | ||
@Column(name = "type") | ||
private RoomType roomType; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Q: 컬럼명과 필드명을 다르게 한 이유가 있을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 헉 실수 |
||
|
||
@Column(name = "certify_time", nullable = false) | ||
private int certifyTime; | ||
|
||
@Column(name = "current_user_count", nullable = false) | ||
private int currentUserCount; | ||
|
||
@Column(name = "max_user_count", nullable = false) | ||
private int maxUserCount; | ||
|
||
// TODO: 한글 길이 고려 | ||
@Column(name = "announcement", length = 255) | ||
private String announcement; | ||
|
||
@ColumnDefault(ROOM_LEVEL_0_IMAGE) | ||
@Column(name = "room_image", length = 500) | ||
private String roomImage; | ||
|
||
@Builder | ||
private Room(String title, String password, RoomType roomType, int certifyTime, int maxUserCount) { | ||
this.title = requireNonNull(title); | ||
this.password = password; | ||
this.level = 0; | ||
this.roomType = requireNonNull(roomType); | ||
this.certifyTime = validateCertifyTime(roomType, certifyTime); | ||
this.currentUserCount = 1; | ||
this.maxUserCount = maxUserCount; | ||
this.roomImage = ROOM_LEVEL_0_IMAGE; | ||
} | ||
|
||
public void levelUp() { | ||
this.level += 1; | ||
} | ||
|
||
public void changeAnnouncement(String announcement) { | ||
this.announcement = announcement; | ||
} | ||
|
||
public void changeTitle(String title) { | ||
this.title = title; | ||
} | ||
|
||
public void changePassword(String password) { | ||
this.password = password; | ||
} | ||
|
||
public void changeMaxCount(int maxUserCount) { | ||
if (maxUserCount < this.currentUserCount) { | ||
throw new BadRequestException(ROOM_MAX_USER_COUNT_MODIFY_FAIL); | ||
} | ||
|
||
this.maxUserCount = maxUserCount; | ||
} | ||
|
||
public void upgradeRoomImage(String roomImage) { | ||
this.roomImage = roomImage; | ||
} | ||
|
||
public void changeCertifyTime(int certifyTime) { | ||
this.certifyTime = validateCertifyTime(this.roomType, certifyTime); | ||
} | ||
|
||
private int validateCertifyTime(RoomType roomType, int certifyTime) { | ||
if (roomType.equals(MORNING) && (certifyTime < MORNING_START_TIME || certifyTime > MORNING_END_TIME)) { | ||
throw new BadRequestException(INVALID_REQUEST_FIELD); | ||
} | ||
|
||
if (roomType.equals(NIGHT) | ||
&& ((certifyTime < NIGHT_START_TIME && certifyTime > NIGHT_END_TIME) || certifyTime < CLOCK_ZERO)) { | ||
throw new BadRequestException(INVALID_REQUEST_FIELD); | ||
} | ||
|
||
return certifyTime; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C: 저희 컨벤션은
return
을 제외한 모두 붙여쓰는 것으로 알고 있습니다!