Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -15,7 +16,9 @@
import swyp.team5.greening.common.resolver.LogIn;
import swyp.team5.greening.petPlant.dto.request.CreateDailyRecordRequestDto;
import swyp.team5.greening.petPlant.dto.response.CreateDailyRecordResponseDto;
import swyp.team5.greening.petPlant.dto.response.FindDailyRecordResponseDto;
import swyp.team5.greening.petPlant.service.DailyRecordCommandService;
import swyp.team5.greening.petPlant.service.DailyRecordQueryService;

@Tag(name = "애완 식물 오늘의 기록 API")
@RestController
Expand All @@ -24,6 +27,7 @@
public class DailyRecordController {

private final DailyRecordCommandService dailyRecordCommandService;
private final DailyRecordQueryService dailyRecordQueryService;

@Operation(summary = "특정 애완 식물 오늘의 기록 작성 API")
@PostMapping("/{petPlantId}/daily-record")
Expand All @@ -34,7 +38,24 @@ public ApiResponseDto<CreateDailyRecordResponseDto> createDailyRecord(
@Validated @RequestBody CreateDailyRecordRequestDto requestDto
) {
return ApiResponseDto.of(
dailyRecordCommandService.createDailyRecord(userId, petPlantId, requestDto));
dailyRecordCommandService.createDailyRecord(
userId,
petPlantId,
requestDto
));
}

@Operation(summary = "특정 애완 식물 특정 오늘의 기록 조회 API")
@GetMapping("/daily-record/{dailyRecordId}")
@ResponseStatus(HttpStatus.OK)
public ApiResponseDto<FindDailyRecordResponseDto> getDailyRecord(
@LogIn Long userId,
@PathVariable Long dailyRecordId
) {
return ApiResponseDto.of(dailyRecordQueryService.findDailyRecord(
userId,
dailyRecordId
));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import jakarta.persistence.CascadeType;
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;
Expand Down Expand Up @@ -33,6 +35,10 @@ public class DailyRecord extends BaseTimeEntity {
@Column(name = "write_date")
private LocalDate writeDate;

@Enumerated(EnumType.STRING)
@Column(name = "state")
private DailyRecordState state;

@Column(name = "pet_plant_id")
private Long petPlantId;

Expand All @@ -43,10 +49,12 @@ public class DailyRecord extends BaseTimeEntity {
public DailyRecord(
String title,
LocalDate writeDate,
DailyRecordState state,
Long petPlantId
) {
this.title = title;
this.writeDate = writeDate;
this.state = state;
this.petPlantId = petPlantId;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package swyp.team5.greening.petPlant.domain.entity;

public enum DailyRecordState {

IN_PROGRESS,
DELETED

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import swyp.team5.greening.petPlant.domain.entity.DailyRecord;
import swyp.team5.greening.petPlant.dto.data.FindDailyRecordDto;

public interface DailyRecordQueryRepository {

Expand All @@ -11,4 +13,6 @@ List<DailyRecord> findByPetPlantAndWriteDate(
LocalDate startDate,
LocalDate endDate
);

Optional<FindDailyRecordDto> findDailyRecord(Long dailyRecordId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package swyp.team5.greening.petPlant.dto.data;

import swyp.team5.greening.petPlant.domain.entity.DailyRecord;
import swyp.team5.greening.petPlant.domain.entity.PetPlant;

public record FindDailyRecordDto(
DailyRecord dailyRecord,
PetPlant petPlant
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package swyp.team5.greening.petPlant.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import swyp.team5.greening.petPlant.domain.entity.DailyRecord;
import swyp.team5.greening.petPlant.domain.entity.DailyRecordContent;
import swyp.team5.greening.petPlant.dto.DailyRecordContentDto;

public record FindDailyRecordResponseDto(

String title,

@JsonFormat(pattern = "yyyy-MM-dd'T'hh:mm:ss")
LocalDateTime createdAt,

List<DailyRecordContentDto> content

) {

public static FindDailyRecordResponseDto of(DailyRecord dailyRecord) {

List<DailyRecordContent> dailyRecordContents = dailyRecord.getDailyRecordContents();

return new FindDailyRecordResponseDto(
dailyRecord.getTitle(),
dailyRecord.getCreatedAt(),
dailyRecordContents.stream()
.sorted(Comparator.comparing(DailyRecordContent::getSequence))
.map(content ->
new DailyRecordContentDto(content.getType().name(),
content.getContent()))
.toList()
);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ public enum PetPlantExceptionMessage implements ExceptionMessage {
NOT_FOUND_PET_PLANT("존재하지 않는 애완 식물입니다.", "404"),
BAD_REQUEST_PET_PLANT_WRITER("내가 등록한 애완 식물이 아닙니다.", "400"),

INVALID_DATE_ACCESS("해당 날짜에만 접근 가능합니다.", "400");
NOT_FOUND_DAILY_RECORD("해당 날짜의 기록이 존재하지 않습니다.", "404"),

INVALID_DATE_ACCESS("해당 날짜에만 접근 가능합니다.", "400");

private final String message;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import swyp.team5.greening.petPlant.domain.entity.DailyRecord;
import swyp.team5.greening.petPlant.domain.repository.DailyRecordQueryRepository;
import swyp.team5.greening.petPlant.dto.data.FindDailyRecordDto;

public interface DailyRecordJpaQueryRepository extends JpaRepository<DailyRecord, Long>,
DailyRecordQueryRepository {
Expand All @@ -18,6 +20,7 @@ public interface DailyRecordJpaQueryRepository extends JpaRepository<DailyRecord
WHERE dailyRecord.petPlantId = :petPlantId
AND dailyRecord.writeDate >= :startDate
AND dailyRecord.writeDate < :endDate
AND dailyRecord.state = 'IN_PROGRESS'
ORDER BY dailyRecord.writeDate asc
""")
List<DailyRecord> findByPetPlantAndWriteDate(
Expand All @@ -26,4 +29,16 @@ List<DailyRecord> findByPetPlantAndWriteDate(
@Param("endDate") LocalDate endDate
);

@Override
@Query("""
SELECT new swyp.team5.greening.petPlant.dto.data.FindDailyRecordDto(
dailyRecord, petPlant)
FROM DailyRecord dailyRecord
INNER JOIN PetPlant petPlant
ON petPlant.id = dailyRecord.petPlantId
WHERE dailyRecord.id = :dailyRecordId
AND dailyRecord.state = 'IN_PROGRESS'
""")
Optional<FindDailyRecordDto> findDailyRecord(@Param("dailyRecordId") Long dailyRecordId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import swyp.team5.greening.petPlant.domain.entity.DailyRecord;
import swyp.team5.greening.petPlant.domain.entity.DailyRecordContent;
import swyp.team5.greening.petPlant.domain.entity.DailyRecordContentType;
import swyp.team5.greening.petPlant.domain.entity.DailyRecordState;
import swyp.team5.greening.petPlant.domain.entity.PetPlant;
import swyp.team5.greening.petPlant.domain.entity.PetPlantState;
import swyp.team5.greening.petPlant.domain.repository.DailyRecordRepository;
Expand Down Expand Up @@ -59,6 +60,7 @@ public CreateDailyRecordResponseDto createDailyRecord(
DailyRecord dailyRecord = DailyRecord.builder()
.title(requestDto.title())
.writeDate(requestDto.today())
.state(DailyRecordState.IN_PROGRESS)
.petPlantId(petPlantId)
.build();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package swyp.team5.greening.petPlant.service;

import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import swyp.team5.greening.common.exception.GreeningGlobalException;
import swyp.team5.greening.petPlant.domain.entity.DailyRecord;
import swyp.team5.greening.petPlant.domain.entity.PetPlant;
import swyp.team5.greening.petPlant.domain.repository.DailyRecordQueryRepository;
import swyp.team5.greening.petPlant.dto.data.FindDailyRecordDto;
import swyp.team5.greening.petPlant.dto.response.FindDailyRecordResponseDto;
import swyp.team5.greening.petPlant.exception.PetPlantExceptionMessage;

@Service
@RequiredArgsConstructor
public class DailyRecordQueryService {

private final DailyRecordQueryRepository dailyRecordQueryRepository;

@Transactional
public FindDailyRecordResponseDto findDailyRecord(
Long userId,
Long dailyRecordId
) {
FindDailyRecordDto dailyRecordDto = dailyRecordQueryRepository.findDailyRecord(
dailyRecordId)
.orElseThrow(()
-> new GreeningGlobalException(PetPlantExceptionMessage.NOT_FOUND_DAILY_RECORD));

DailyRecord dailyRecord = dailyRecordDto.dailyRecord();
PetPlant petPlant = dailyRecordDto.petPlant();

if (!Objects.equals(petPlant.getUserId(), userId)) {
throw new GreeningGlobalException(PetPlantExceptionMessage.BAD_REQUEST_PET_PLANT_WRITER);
}

return FindDailyRecordResponseDto.of(dailyRecord);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package swyp.team5.greening.post.dto.response;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import swyp.team5.greening.post.domain.entity.Post;
import swyp.team5.greening.post.domain.entity.PostContent;
Expand Down Expand Up @@ -41,7 +42,9 @@ public static FindPostResponseDto of(
isLike,
isAuthor,
postContents.stream()
.map(content -> new PostContentDto(content.getType().name(), content.getContent()))
.sorted(Comparator.comparing(PostContent::getSequence))
.map(content ->
new PostContentDto(content.getType().name(), content.getContent()))
.toList()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public interface PostJpaQueryRepository extends JpaRepository<Post, Long>, PostQ
ON likes.userId = :userId
AND likes.postId = post.id
WHERE post.id = :postId
AND post.state = 'IN_PROGRESS'
""")
Optional<FindPostDto> findPost(
@Param("postId") Long postId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.ResultActions;
import swyp.team5.greening.common.exception.GreeningGlobalException;
import swyp.team5.greening.petPlant.domain.entity.DailyRecord;
import swyp.team5.greening.petPlant.domain.entity.DailyRecordContent;
import swyp.team5.greening.petPlant.domain.entity.DailyRecordContentType;
import swyp.team5.greening.petPlant.domain.entity.DailyRecordState;
import swyp.team5.greening.petPlant.domain.entity.PetPlant;
import swyp.team5.greening.petPlant.domain.entity.PetPlantState;
import swyp.team5.greening.petPlant.domain.repository.DailyRecordRepository;
Expand All @@ -26,7 +30,6 @@
import swyp.team5.greening.petPlant.dto.request.CreateDailyRecordRequestDto;
import swyp.team5.greening.petPlant.exception.PetPlantExceptionMessage;
import swyp.team5.greening.support.ApiTestSupport;
import swyp.team5.greening.user.domain.repository.UserRepository;

class DailyRecordControllerTest extends ApiTestSupport {

Expand All @@ -39,9 +42,6 @@ class DailyRecordControllerTest extends ApiTestSupport {
@Autowired
private DailyRecordRepository dailyRecordRepository;

@Autowired
private UserRepository userRepository;

@BeforeEach
void init() {
petPlantRepository.deleteAll();
Expand Down Expand Up @@ -161,4 +161,56 @@ void createDailyRecord3() throws Exception {
}
}

@Nested
@DisplayName("사용자는 애완 식물 1개에 대해 오늘의 기록을 1개 작성한 상태이다.")
class TestCase2 {

PetPlant petPlant;

DailyRecord dailyRecord;

List<DailyRecordContent> contents;

@BeforeEach
void setUp() {
petPlant = PetPlant.builder()
.name("이름")
.plantType("민들레")
.state(PetPlantState.IN_PROGRESS)
.userId(loginUser.getId())
.build();
petPlantRepository.save(petPlant);

dailyRecord = DailyRecord.builder()
.title("오늘의 일기 7/3")
.writeDate(LocalDate.of(2025, 7, 3))
.state(DailyRecordState.IN_PROGRESS)
.petPlantId(petPlant.getId())
.build();

contents = List.of(DailyRecordContent.builder()
.type(DailyRecordContentType.TEXT)
.content("3cm 컸다.")
.build());

dailyRecord.updateContent(contents);
dailyRecordRepository.save(dailyRecord);
}

@Test
@DisplayName("사용자는 자신이 작성한 오늘의 기록을 조회할 수 있다.")
void getDailyRecord1() throws Exception {
//when
ResultActions perform = mockMvc.perform(
get("/api/pet-plants/daily-record/{dailyRecord}", dailyRecord.getId())
.header(HttpHeaders.AUTHORIZATION, accessToken));

//then
perform.andExpect(status().isOk())
.andExpect(jsonPath("$.data.title").value(dailyRecord.getTitle()))
.andExpect(jsonPath("$.data.content.size()").value(1))
.andExpect(jsonPath("$.data.content[0].value").value(contents.get(0).getContent()));
}
}

}
Loading
Loading