-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ [Feature] 마신 음료에 대한 당 기록 기능을 구현했어요. (#50)
* feat: 마신 음료 당 기입 기능 구현 (#41) * test: 마신 음료 당 기입 관련 테스트 (#41) * chore: 공백 제거 (#41) * chore: 응답 status 변경 (#41) * chore: 노션 API 명세서에 작성된 내용에 맞추어 dto 필드명 변경 (#41) * refactor: 기록 단건 조회 시 Optional 로 감싸서 반환되도록 수정 - PR 리뷰 (#41)
- Loading branch information
1 parent
3fde119
commit abdc4d5
Showing
11 changed files
with
272 additions
and
4 deletions.
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42
oversweet-api/src/main/java/com/depromeet/oversweet/record/controller/RecordController.java
This file contains 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,42 @@ | ||
package com.depromeet.oversweet.record.controller; | ||
|
||
import com.depromeet.oversweet.record.dto.request.DrinkRecordSaveRequest; | ||
import com.depromeet.oversweet.record.dto.response.DrinkRecordSaveResponse; | ||
import com.depromeet.oversweet.record.service.DrinkRecordSaveService; | ||
import com.depromeet.oversweet.response.DataResponse; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@Tag(name = "기록", description = "마신 음료 당 기록 관련 API") | ||
@RestController | ||
@RequestMapping("/api/v1/record") | ||
@RequiredArgsConstructor | ||
public class RecordController { | ||
|
||
private final DrinkRecordSaveService drinkRecordSaveService; | ||
|
||
/** | ||
* 마신 음료 당 기록 | ||
* 추후 로그인 기능 구현 후, 로그인한 유저의 ID를 받아와야 함 (ex. @AuthenticationPrincipal User user) | ||
*/ | ||
@Operation(summary = "마신 음료 당 기록", description = "유저가 마신 음료의 당을 기록합니다.") | ||
@ApiResponses(@ApiResponse(responseCode = "201", description = "마신 음료 당 기록 성공")) | ||
@PostMapping("/drink") | ||
public ResponseEntity<DataResponse<DrinkRecordSaveResponse>> saveDrinkRecord( | ||
@RequestBody @Valid final DrinkRecordSaveRequest drinkRecordSaveRequest | ||
) { | ||
DrinkRecordSaveResponse response = drinkRecordSaveService.saveDrinkRecord(100L, drinkRecordSaveRequest); | ||
return ResponseEntity.ok().body(DataResponse.of(HttpStatus.CREATED, "마신 음료 당 기록 성공", response)); | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
...-api/src/main/java/com/depromeet/oversweet/record/dto/request/DrinkRecordSaveRequest.java
This file contains 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,23 @@ | ||
package com.depromeet.oversweet.record.dto.request; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import jakarta.validation.constraints.Min; | ||
import jakarta.validation.constraints.NotNull; | ||
import lombok.Builder; | ||
|
||
@Builder | ||
public record DrinkRecordSaveRequest( | ||
|
||
@NotNull | ||
@Schema(description = "음료 ID", example = "1") Long drinkId, | ||
|
||
@NotNull | ||
@Min(1) | ||
@Schema(description = "마신 잔의 수", example = "2") Integer count, | ||
|
||
@NotNull | ||
@Min(0) | ||
@Schema(description = "1잔 기준 최종 섭취 당 함량", example = "10") Integer intakeSugar | ||
|
||
) { | ||
} |
24 changes: 24 additions & 0 deletions
24
...pi/src/main/java/com/depromeet/oversweet/record/dto/response/DrinkRecordSaveResponse.java
This file contains 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,24 @@ | ||
package com.depromeet.oversweet.record.dto.response; | ||
|
||
import com.depromeet.oversweet.drink.dto.response.DrinkDailySugarTotalStatisticsInfo; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.Builder; | ||
|
||
@Builder | ||
public record DrinkRecordSaveResponse( | ||
|
||
@Schema(description = "지금 마신 음료 당", example = "10") int intakeSugar, | ||
|
||
@Schema(description = "하루 적정 당 섭취량", example = "24") int dailySugar, | ||
|
||
@Schema(description = "방금 기록한 당 성분까지 포함한, 오늘 먹은 총 당 섭취량", example = "20") int dailyTotalSugar, | ||
|
||
@Schema(description = "적정 당 섭취량을 초과 했는지 안했는지 여부", example = "false") boolean isExcess | ||
|
||
) { | ||
public static DrinkRecordSaveResponse of(int intakeSugar, DrinkDailySugarTotalStatisticsInfo info) { | ||
return new DrinkRecordSaveResponse( | ||
intakeSugar, info.dailySugar(), info.dailyTotalSugar(), info.isExcess() | ||
); | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
...weet-api/src/main/java/com/depromeet/oversweet/record/service/DrinkRecordSaveService.java
This file contains 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,57 @@ | ||
package com.depromeet.oversweet.record.service; | ||
|
||
import com.depromeet.oversweet.domain.drink.entity.DrinkEntity; | ||
import com.depromeet.oversweet.domain.drink.repository.FindDrinkRepository; | ||
import com.depromeet.oversweet.domain.member.entity.MemberEntity; | ||
import com.depromeet.oversweet.domain.member.repository.FindMemberRepository; | ||
import com.depromeet.oversweet.domain.record.entity.RecordEntity; | ||
import com.depromeet.oversweet.domain.record.repository.FindRecordsRepository; | ||
import com.depromeet.oversweet.domain.record.repository.SaveRecordRepository; | ||
import com.depromeet.oversweet.drink.dto.response.DrinkDailySugarTotalStatisticsInfo; | ||
import com.depromeet.oversweet.drink.vo.DrinkStatisticsTotalInfo; | ||
import com.depromeet.oversweet.drink.vo.LocalDateTimeInfo; | ||
import com.depromeet.oversweet.record.dto.request.DrinkRecordSaveRequest; | ||
import com.depromeet.oversweet.record.dto.response.DrinkRecordSaveResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class DrinkRecordSaveService { | ||
|
||
private final FindMemberRepository findMemberRepository; | ||
private final FindDrinkRepository findDrinkRepository; | ||
private final FindRecordsRepository findRecordsRepository; | ||
private final SaveRecordRepository saveRecordRepository; | ||
|
||
public DrinkRecordSaveResponse saveDrinkRecord(Long memberId, DrinkRecordSaveRequest drinkRecordSaveRequest) { | ||
|
||
final MemberEntity findMember = findMemberRepository.findMemberById(memberId); | ||
|
||
final DrinkEntity findDrink = findDrinkRepository.findDrinkById(drinkRecordSaveRequest.drinkId()); | ||
|
||
RecordEntity record = RecordEntity.builder() | ||
.member(findMember) | ||
.drink(findDrink) | ||
.count(drinkRecordSaveRequest.count()) | ||
.intakeSugar(drinkRecordSaveRequest.intakeSugar()) | ||
.build(); | ||
|
||
saveRecordRepository.saveRecord(record); | ||
|
||
// 오늘 (데일리 날짜 확인) 00:00 ~ 23:59 | ||
final LocalDateTimeInfo dateTimeInfo = LocalDateTimeInfo.getDailyDateTime(); | ||
|
||
// 해당 유저의 오늘(데일리) 섭취 음료 조회 Repository | ||
final List<RecordEntity> dailyRecords = findRecordsRepository.findRecordsByLocalDateTime(findMember.getId(), dateTimeInfo.startDateTime(), dateTimeInfo.endDateTime()); | ||
|
||
DrinkStatisticsTotalInfo drinkStatisticsTotalInfo = new DrinkStatisticsTotalInfo(dailyRecords); | ||
|
||
DrinkDailySugarTotalStatisticsInfo dailyTotalStatisticsInfo = drinkStatisticsTotalInfo.getDailyTotalStatisticsInfo(findMember.getDailySugar()); | ||
|
||
// 기록 관련 response 로 반환 | ||
return DrinkRecordSaveResponse.of(record.getIntakeSugar(), dailyTotalStatisticsInfo); | ||
} | ||
} |
This file contains 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 |
---|---|---|
|
@@ -107,6 +107,4 @@ public RecordEntity getSecondRecord() { | |
return secondRecordEntity; | ||
} | ||
|
||
|
||
|
||
} |
78 changes: 78 additions & 0 deletions
78
...-api/src/test/java/com/depromeet/oversweet/record/service/DrinkRecordSaveServiceTest.java
This file contains 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,78 @@ | ||
package com.depromeet.oversweet.record.service; | ||
|
||
import com.depromeet.oversweet.common.TestSetup; | ||
import com.depromeet.oversweet.domain.drink.entity.DrinkEntity; | ||
import com.depromeet.oversweet.domain.drink.repository.FindDrinkRepository; | ||
import com.depromeet.oversweet.domain.member.entity.MemberEntity; | ||
import com.depromeet.oversweet.domain.member.repository.FindMemberRepository; | ||
import com.depromeet.oversweet.domain.record.entity.RecordEntity; | ||
import com.depromeet.oversweet.domain.record.repository.FindRecordsRepository; | ||
import com.depromeet.oversweet.domain.record.repository.SaveRecordRepository; | ||
import com.depromeet.oversweet.record.dto.request.DrinkRecordSaveRequest; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.jupiter.MockitoSettings; | ||
|
||
import java.util.Optional; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.mockito.Mockito.when; | ||
|
||
@DisplayName("마신 음료 당 기록 테스트") | ||
@MockitoSettings | ||
class DrinkRecordSaveServiceTest { | ||
|
||
@Mock | ||
private FindMemberRepository findMemberRepository; | ||
@Mock | ||
private FindDrinkRepository findDrinkRepository; | ||
@Mock | ||
private FindRecordsRepository findRecordsRepository; | ||
@Mock | ||
private SaveRecordRepository saveRecordRepository; | ||
|
||
@InjectMocks | ||
DrinkRecordSaveService drinkRecordSaveService; | ||
|
||
private MemberEntity memberEntity; | ||
private DrinkEntity drinkEntity; | ||
private RecordEntity recordEntity; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
TestSetup testSetup = new TestSetup(); | ||
testSetup.setUp(); | ||
memberEntity = testSetup.getMember(); | ||
drinkEntity = testSetup.getFirstDrink(); | ||
recordEntity = testSetup.getFirstRecord(); | ||
} | ||
|
||
@Test | ||
@DisplayName("마신 음료 당 기록을 한다.") | ||
void saveDrinkRecordTest() { | ||
//given | ||
|
||
//when | ||
when(findMemberRepository.findMemberById(memberEntity.getId())).thenReturn(memberEntity); | ||
when(findDrinkRepository.findDrinkById(drinkEntity.getId())).thenReturn(drinkEntity); | ||
when(findRecordsRepository.findRecordById(recordEntity.getId())).thenReturn(Optional.ofNullable(recordEntity)); | ||
|
||
DrinkRecordSaveRequest saveRequest = DrinkRecordSaveRequest.builder() | ||
.drinkId(drinkEntity.getId()) | ||
.count(recordEntity.getCount()) | ||
.intakeSugar(recordEntity.getIntakeSugar()) | ||
.build(); | ||
|
||
drinkRecordSaveService.saveDrinkRecord(memberEntity.getId(), saveRequest); | ||
|
||
Optional<RecordEntity> findRecordOpt = findRecordsRepository.findRecordById(recordEntity.getId()); | ||
|
||
assertThat(findRecordOpt.isPresent()); | ||
assertEquals(recordEntity.getId(), findRecordOpt.get().getId()); | ||
} | ||
|
||
} |
This file contains 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 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 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
11 changes: 11 additions & 0 deletions
11
.../src/main/java/com/depromeet/oversweet/domain/record/repository/SaveRecordRepository.java
This file contains 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,11 @@ | ||
package com.depromeet.oversweet.domain.record.repository; | ||
|
||
import com.depromeet.oversweet.domain.record.entity.RecordEntity; | ||
|
||
/** | ||
* 유저가 마신 음료 당 기록 Interface | ||
*/ | ||
public interface SaveRecordRepository { | ||
|
||
void saveRecord(RecordEntity record); | ||
} |
22 changes: 22 additions & 0 deletions
22
.../main/java/com/depromeet/oversweet/domain/record/repository/SaveRecordRepositoryImpl.java
This file contains 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,22 @@ | ||
package com.depromeet.oversweet.domain.record.repository; | ||
|
||
import com.depromeet.oversweet.domain.record.entity.RecordEntity; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Repository; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
/** | ||
* 유저가 마신 음료 당 기록 구현체 | ||
*/ | ||
@Repository | ||
@RequiredArgsConstructor | ||
public class SaveRecordRepositoryImpl implements SaveRecordRepository { | ||
|
||
private final RecordJpaRepository recordJpaRepository; | ||
|
||
@Override | ||
@Transactional | ||
public void saveRecord(RecordEntity record) { | ||
recordJpaRepository.save(record); | ||
} | ||
} |