-
Notifications
You must be signed in to change notification settings - Fork 0
[feat] 기록 생성 api 개발 #50
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
Merged
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
4f5a335
[feat] 기록 생성 관련 dto (#45)
buzz0331 405a5b2
[feat] 기록 생성 Usecase (#45)
buzz0331 983492e
[feat] 기록 생성 Controller (#45)
buzz0331 8088911
Merge branch 'develop' of https://github.com/THIP-TextHip/THIP-Server…
buzz0331 5aec75d
Merge branch 'develop' of https://github.com/THIP-TextHip/THIP-Server…
buzz0331 2fd757d
[feat] Record 도메인 규칙 선언 (#45)
buzz0331 475a13f
[feat] RecordCommandPort 정의 (#45)
buzz0331 7f9c6c9
[feat] Controller에서 필요한 dto 정의 (#45)
buzz0331 09e0327
[feat] 기록 생성 api 핸들러 추가 (#45)
buzz0331 9dde2d2
[feat] 기록 생성 서비스 구현 (#45)
buzz0331 7c70201
[feat] 기록 생성 관련 persistence 선언 (#45)
buzz0331 9e5d3e8
[feat] 기록 생성 관련 에러코드 추가 (#45)
buzz0331 9c2ff07
[test] Record 생성 api 통합 테스트 (#45)
buzz0331 02ae826
[test] Record 도메인 단위 테스트 (#45)
buzz0331 b16f767
[test] 모든 테스트에 클래스 단위 DisplayName 지정 (#45)
buzz0331 55a7afa
[test] 테스트 메서드 네이밍 수정 (#45)
buzz0331 36cbc0d
[feat] Room, UserRoom에 필요한 도메인 규칙 정의 (#45)
buzz0331 fb3ec7d
[feat] UserRoom Persistence port 정의 (#45)
buzz0331 b5e14ee
[feat] UserRoom 관련 쿼리 (#45)
buzz0331 7654186
[feat] UserRoomQueryPort 추가 (#45)
buzz0331 f244055
[feat] validateOverview 수정 (#45)
buzz0331 e5aca74
[feat] 기록 생성 api 로직 수정 (#45)
buzz0331 2e657bb
[teat] Record, UserRoom 도메인 단위 테스트 (#45)
buzz0331 ee10143
[teat] Record 통합 테스트 수정 (#45)
buzz0331 3e9f385
[teat] record, userroom 관련 필요한 에러코드 추가 (#45)
buzz0331 63e1675
[chore] VoteCreateService todo 추가 (#45)
buzz0331 5a3fdf7
[refactor] 에러 구문 백분율 처리 오류 제거 (#45)
buzz0331 dc9212e
[refactor] userpercentage 100 넘어갈 경우 100으로 통일 (#45)
buzz0331 05328fd
[refactor] 컨트롤러 핸들러 파라미터 불변성 보장 (#45)
buzz0331 a407341
Merge branch 'develop' of https://github.com/THIP-TextHip/THIP-Server…
buzz0331 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 19 additions & 1 deletion
20
src/main/java/konkuk/thip/record/adapter/in/web/RecordCommandController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,28 @@ | ||
| package konkuk.thip.record.adapter.in.web; | ||
|
|
||
| import jakarta.validation.Valid; | ||
| import konkuk.thip.common.dto.BaseResponse; | ||
| import konkuk.thip.common.security.annotation.UserId; | ||
| import konkuk.thip.record.adapter.in.web.request.RecordCreateRequest; | ||
| import konkuk.thip.record.adapter.in.web.response.RecordCreateResponse; | ||
| import konkuk.thip.record.application.port.in.RecordCreateUseCase; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| public class RecordCommandController { | ||
| private final RecordCreateUseCase recordCreateUseCase; | ||
|
|
||
| @PostMapping("/rooms/{roomId}/record") | ||
| public BaseResponse<RecordCreateResponse> createRecord( | ||
| @UserId final Long userId, | ||
| @PathVariable final Long roomId, | ||
| @Valid @RequestBody final RecordCreateRequest recordCreateRequest) { | ||
| return BaseResponse.ok( | ||
| RecordCreateResponse.of( | ||
| recordCreateUseCase.createRecord(recordCreateRequest.toCommand(roomId, userId)) | ||
| )); | ||
| } | ||
|
|
||
| } |
7 changes: 0 additions & 7 deletions
7
src/main/java/konkuk/thip/record/adapter/in/web/request/DummyRequest.java
This file was deleted.
Oops, something went wrong.
28 changes: 28 additions & 0 deletions
28
src/main/java/konkuk/thip/record/adapter/in/web/request/RecordCreateRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package konkuk.thip.record.adapter.in.web.request; | ||
|
|
||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.NotNull; | ||
| import jakarta.validation.constraints.Size; | ||
| import konkuk.thip.record.application.port.in.dto.RecordCreateCommand; | ||
|
|
||
| public record RecordCreateRequest ( | ||
| @NotNull(message = "page는 필수입니다.") | ||
| Integer page, | ||
|
|
||
| @NotNull(message = "isOverview(= 총평 여부)는 필수입니다.") | ||
| Boolean isOverview, | ||
|
|
||
| @NotBlank(message = "기록 내용은 필수입니다.") | ||
| @Size(max = 500, message = "기록 내용은 최대 500자 입니다.") | ||
| String content | ||
| ) { | ||
| public RecordCreateCommand toCommand(Long roomId, Long creatorId) { | ||
| return new RecordCreateCommand( | ||
| creatorId, | ||
| roomId, | ||
| page, | ||
| isOverview, | ||
| content | ||
| ); | ||
| } | ||
| } |
7 changes: 0 additions & 7 deletions
7
src/main/java/konkuk/thip/record/adapter/in/web/response/DummyResponse.java
This file was deleted.
Oops, something went wrong.
9 changes: 9 additions & 0 deletions
9
src/main/java/konkuk/thip/record/adapter/in/web/response/RecordCreateResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package konkuk.thip.record.adapter.in.web.response; | ||
|
|
||
| public record RecordCreateResponse( | ||
| Long recordId | ||
| ) { | ||
| public static RecordCreateResponse of(Long recordId) { | ||
| return new RecordCreateResponse(recordId); | ||
| } | ||
| } |
26 changes: 26 additions & 0 deletions
26
...main/java/konkuk/thip/record/adapter/out/persistence/RecordCommandPersistenceAdapter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,41 @@ | ||
| package konkuk.thip.record.adapter.out.persistence; | ||
|
|
||
| import konkuk.thip.common.exception.EntityNotFoundException; | ||
| import konkuk.thip.record.adapter.out.mapper.RecordMapper; | ||
| import konkuk.thip.record.application.port.out.RecordCommandPort; | ||
| import konkuk.thip.record.domain.Record; | ||
| import konkuk.thip.room.adapter.out.jpa.RoomJpaEntity; | ||
| import konkuk.thip.room.adapter.out.persistence.RoomJpaRepository; | ||
| import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; | ||
| import konkuk.thip.user.adapter.out.persistence.UserJpaRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Repository; | ||
|
|
||
| import static konkuk.thip.common.exception.code.ErrorCode.ROOM_NOT_FOUND; | ||
| import static konkuk.thip.common.exception.code.ErrorCode.USER_NOT_FOUND; | ||
|
|
||
| @Repository | ||
| @RequiredArgsConstructor | ||
| public class RecordCommandPersistenceAdapter implements RecordCommandPort { | ||
|
|
||
| private final RecordJpaRepository recordJpaRepository; | ||
| private final UserJpaRepository userJpaRepository; | ||
| private final RoomJpaRepository roomJpaRepository; | ||
| private final RecordMapper recordMapper; | ||
|
|
||
| @Override | ||
| public Long saveRecord(Record record) { | ||
| UserJpaEntity userJpaEntity = userJpaRepository.findById(record.getCreatorId()).orElseThrow( | ||
| () -> new EntityNotFoundException(USER_NOT_FOUND) | ||
| ); | ||
|
|
||
| RoomJpaEntity roomJpaEntity = roomJpaRepository.findById(record.getRoomId()).orElseThrow( | ||
| () -> new EntityNotFoundException(ROOM_NOT_FOUND) | ||
| ); | ||
|
|
||
| return recordJpaRepository.save( | ||
| recordMapper.toJpaEntity(record, userJpaEntity, roomJpaEntity) | ||
| ).getPostId(); | ||
| } | ||
|
|
||
| } |
5 changes: 0 additions & 5 deletions
5
src/main/java/konkuk/thip/record/application/port/in/DummyUseCase.java
This file was deleted.
Oops, something went wrong.
9 changes: 9 additions & 0 deletions
9
src/main/java/konkuk/thip/record/application/port/in/RecordCreateUseCase.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package konkuk.thip.record.application.port.in; | ||
|
|
||
| import konkuk.thip.record.application.port.in.dto.RecordCreateCommand; | ||
|
|
||
| public interface RecordCreateUseCase { | ||
|
|
||
| Long createRecord(RecordCreateCommand command); | ||
|
|
||
| } |
10 changes: 0 additions & 10 deletions
10
src/main/java/konkuk/thip/record/application/port/in/dto/DummyCommand.java
This file was deleted.
Oops, something went wrong.
15 changes: 15 additions & 0 deletions
15
src/main/java/konkuk/thip/record/application/port/in/dto/RecordCreateCommand.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package konkuk.thip.record.application.port.in.dto; | ||
|
|
||
| public record RecordCreateCommand( | ||
| Long userId, | ||
|
|
||
| Long roomId, | ||
|
|
||
| int page, | ||
|
|
||
| boolean isOverview, | ||
|
|
||
| String content | ||
| ) { | ||
|
|
||
| } |
4 changes: 4 additions & 0 deletions
4
src/main/java/konkuk/thip/record/application/port/out/RecordCommandPort.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,10 @@ | ||
| package konkuk.thip.record.application.port.out; | ||
|
|
||
|
|
||
| import konkuk.thip.record.domain.Record; | ||
|
|
||
| public interface RecordCommandPort { | ||
|
|
||
| Long saveRecord(Record record); | ||
|
|
||
| } |
98 changes: 98 additions & 0 deletions
98
src/main/java/konkuk/thip/record/application/service/RecordCreateService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| package konkuk.thip.record.application.service; | ||
|
|
||
| import jakarta.transaction.Transactional; | ||
| import konkuk.thip.book.application.port.out.BookCommandPort; | ||
| import konkuk.thip.book.domain.Book; | ||
| import konkuk.thip.common.exception.BusinessException; | ||
| import konkuk.thip.common.exception.InvalidStateException; | ||
| import konkuk.thip.record.application.port.in.RecordCreateUseCase; | ||
| import konkuk.thip.record.application.port.in.dto.RecordCreateCommand; | ||
| import konkuk.thip.record.application.port.out.RecordCommandPort; | ||
| import konkuk.thip.record.domain.Record; | ||
| import konkuk.thip.room.application.port.out.RoomCommandPort; | ||
| import konkuk.thip.room.domain.Room; | ||
| import konkuk.thip.user.application.port.out.UserRoomCommandPort; | ||
| import konkuk.thip.user.domain.UserRoom; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import static konkuk.thip.common.exception.code.ErrorCode.*; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class RecordCreateService implements RecordCreateUseCase { | ||
|
|
||
| private final RecordCommandPort recordCommandPort; | ||
| private final RoomCommandPort roomCommandPort; | ||
| private final BookCommandPort bookCommandPort; | ||
| private final UserRoomCommandPort userRoomCommandPort; | ||
|
|
||
| @Transactional | ||
| @Override | ||
| //todo updateRoomPercentage 스케줄러로 책임을 분리할지 논의 | ||
| public Long createRecord(RecordCreateCommand command) { | ||
| // 1. Record 생성 | ||
| Record record = Record.withoutId( | ||
| command.content(), | ||
| command.userId(), | ||
| command.page(), | ||
| command.isOverview(), | ||
| command.roomId() | ||
| ); | ||
|
|
||
| // 2. UserRoom, Room, Book 조회 | ||
| UserRoom userRoom = userRoomCommandPort.findByUserIdAndRoomId(command.userId(), command.roomId()); | ||
| Room room = roomCommandPort.findById(record.getRoomId()); | ||
| Book book = bookCommandPort.findById(room.getBookId()); | ||
|
|
||
| // 3. 유효성 검증 | ||
| validateRoom(room); | ||
| validateUserRoom(userRoom); | ||
| validateRecord(record, book); | ||
|
|
||
| // 4. UserRoom의 currentPage, userPercentage 업데이트 | ||
| updateRoomProgress(userRoom, record, book, room); | ||
|
|
||
| // 5. Record 저장 | ||
| return recordCommandPort.saveRecord(record); | ||
| } | ||
|
|
||
| private void updateRoomProgress(UserRoom userRoom, Record record, Book book, Room room) { | ||
| if(userRoom.updateUserProgress(record.getPage(), book.getPageCount())) { | ||
| // userPercentage가 업데이트되었으면 Room의 roomPercentage 업데이트 | ||
| List<UserRoom> userRoomList = userRoomCommandPort.findAllByRoomId(record.getRoomId()); | ||
| Double totalUserPercentage = userRoomList.stream() | ||
| .map(UserRoom::getUserPercentage) | ||
| .reduce(0.0, Double::sum); | ||
| room.updateRoomPercentage(totalUserPercentage / userRoomList.size()); | ||
| } | ||
| } | ||
|
|
||
| private void validateUserRoom(UserRoom userRoom) { | ||
| // UserRoom의 총평 작성 가능 여부 검증 | ||
| if (!userRoom.canWriteOverview()) { | ||
| String message = String.format( | ||
| "총평(isOverview)은 사용자 진행률이 80%% 이상일 때만 가능합니다. 현재 사용자 진행률 = %.2f%%", | ||
| userRoom.getUserPercentage() | ||
| ); | ||
| throw new InvalidStateException(RECORD_CANNOT_BE_OVERVIEW, new IllegalStateException(message)); | ||
| } | ||
| } | ||
|
|
||
| private void validateRoom(Room room) { | ||
| // 방이 만료되었는지 검증 | ||
| if (room.isExpired()) { | ||
| throw new BusinessException(RECORD_CANNOT_WRITE_IN_EXPIRED_ROOM); | ||
| } | ||
| } | ||
|
|
||
| private void validateRecord(Record record, Book book) { | ||
| // 페이지 유효성 검증 | ||
| record.validatePage(book.getPageCount()); | ||
|
|
||
| // 총평 유효성 검증 | ||
| record.validateOverview(book.getPageCount()); | ||
| } | ||
| } |
11 changes: 0 additions & 11 deletions
11
src/main/java/konkuk/thip/record/application/service/RecordService.java
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
LGTM 저도 투표 관련 validation 로직 참고해서 수정해보겠습니다!