diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java b/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java index ddc1694..b24130f 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/actionplan/controller/ActionPlanController.java @@ -23,7 +23,7 @@ public class ActionPlanController { private final ActionPlanService actionPlanService; - @PostMapping("seed/{seedId}/actionPlan") + @PostMapping("seed/{seedId}/actionplan") @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "ActionPlanPost",description = "액션 플랜 생성 API입니다.") public ApiResponse createActionPlan(@PathVariable("seedId")Long seedId, @Valid @RequestBody ActionPlanCreateRequestDto actionPlanCreateRequestDto) { @@ -31,14 +31,14 @@ public ApiResponse createActionPlan(@PathVariable("seedId")Long seedId, @Valid @ return ApiResponse.success(SuccessStatus.POST_ACTIONPLAN_SUCCESS.getStatusCode(), SuccessStatus.POST_ACTIONPLAN_SUCCESS.getMessage()); } - @GetMapping("seed/{seedId}/actionPlan") + @GetMapping("seed/{seedId}/actionplan") @ResponseStatus(HttpStatus.OK) @Operation(summary = "ActionPlanGet", description = "씨앗 별 액션 플랜 조회 API입니다.") public ApiResponse getActionPlan(@PathVariable Long seedId) { return ApiResponse.success(SuccessStatus.GET_SEED_ACTIONPLAN_SUCCESS, actionPlanService.getActionPlan(seedId)); } - @PatchMapping("actionPlan/{actionPlanId}") + @PatchMapping("actionplan/{actionPlanId}") @ResponseStatus(HttpStatus.OK) @Operation(summary = "ActionPlanPatch", description = "액션 플랜 내용을 수정하는 API입니다.") public ApiResponse updateActionPlan(@PathVariable Long actionPlanId, @Valid @RequestBody ActionPlanUpdateRequestDto actionPlanUpdateRequestDto) { @@ -46,7 +46,7 @@ public ApiResponse updateActionPlan(@PathVariable Long actionPlanId, @Valid @Req return ApiResponse.success(SuccessStatus.PATCH_ACTIONPLAN_SUCCESS.getStatusCode(), SuccessStatus.PATCH_ACTIONPLAN_SUCCESS.getMessage()); } - @DeleteMapping("actionPlan/{actionPlanId}") + @DeleteMapping("actionplan/{actionPlanId}") @ResponseStatus(HttpStatus.OK) @Operation(summary = "ActionPlanDelete", description = "액션 플랜을 삭제하는 API입니다.") public ApiResponse deleteActionPlan(@PathVariable Long actionPlanId) { @@ -54,7 +54,7 @@ public ApiResponse deleteActionPlan(@PathVariable Long actionPlanId) { return ApiResponse.success(SuccessStatus.DELETE_ACTIONPLAN_SUCCESS.getStatusCode(), SuccessStatus.DELETE_ACTIONPLAN_SUCCESS.getMessage()); } - @PatchMapping("actionPlan/{actionPlanId}/completion") + @PatchMapping("actionplan/{actionPlanId}/completion") @ResponseStatus(HttpStatus.OK) @Operation(summary = "ActionPlanComplete", description = "액션 플랜을 완료하는 API입니다.") public ApiResponse completeActionPlan(@PathVariable Long actionPlanId) { @@ -62,7 +62,7 @@ public ApiResponse completeActionPlan(@PathVariable Long actionPlanId) { return ApiResponse.success(SuccessStatus.COMPLETE_ACTIONPLAN_SUCCESS.getStatusCode(),SuccessStatus.COMPLETE_ACTIONPLAN_SUCCESS.getMessage()); } - @GetMapping("member/{memberId}/actionPlan/percent") + @GetMapping("member/{memberId}/actionplan/percent") @ResponseStatus(HttpStatus.OK) @Operation(summary = "ActionPlanPercent", description = "완료한 액션 플랜 퍼센트를 구하는 API입니다.") public ApiResponse getActionPlanPercent(@PathVariable Long memberId) { diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java b/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java index 7d567eb..3ce450c 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/member/domain/Member.java @@ -56,4 +56,9 @@ public Member(String nickname, String email, SocialPlatform socialPlatform, Bool public void incrementGatheredSsuk() { this.gatheredSsuk = (this.gatheredSsuk == null ? 0 : this.gatheredSsuk) + 1; } + + public void useSsuck() { + this.gatheredSsuk--; + this.usedSsuk++; + } } diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/review/controller/ReviewController.java b/growthookServer/src/main/java/com/example/growthookserver/api/review/controller/ReviewController.java new file mode 100644 index 0000000..52a9dcf --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/review/controller/ReviewController.java @@ -0,0 +1,34 @@ +package com.example.growthookserver.api.review.controller; + +import com.example.growthookserver.api.review.dto.request.ReviewCreateRequestDto; +import com.example.growthookserver.api.review.service.ReviewService; +import com.example.growthookserver.common.response.ApiResponse; +import com.example.growthookserver.common.response.SuccessStatus; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PathVariable; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("api/v1") +@Tag(name = "Review - 리뷰 관련 API", description = "Review API Document") +public class ReviewController { + + private final ReviewService reviewService; + @PostMapping("actionplan/{actionPlanId}/review") + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "ReviewPost", description = "리뷰 생성 API입니다.") + public ApiResponse createReview(@PathVariable("actionPlanId") Long actionPlanId, @Valid @RequestBody ReviewCreateRequestDto reviewCreateRequestDto) { + reviewService.createReview(actionPlanId, reviewCreateRequestDto); + return ApiResponse.success( + SuccessStatus.POST_REVIEW_SUCCESS.getStatusCode(), SuccessStatus.POST_REVIEW_SUCCESS.getMessage()); + } +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/review/dto/request/ReviewCreateRequestDto.java b/growthookServer/src/main/java/com/example/growthookserver/api/review/dto/request/ReviewCreateRequestDto.java new file mode 100644 index 0000000..ba4123d --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/review/dto/request/ReviewCreateRequestDto.java @@ -0,0 +1,17 @@ +package com.example.growthookserver.api.review.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class ReviewCreateRequestDto { + @NotBlank + @Size(max = 300) + private String content; +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/review/repository/ReviewRepository.java b/growthookServer/src/main/java/com/example/growthookserver/api/review/repository/ReviewRepository.java new file mode 100644 index 0000000..fb569e5 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/review/repository/ReviewRepository.java @@ -0,0 +1,8 @@ +package com.example.growthookserver.api.review.repository; + +import com.example.growthookserver.api.review.domain.Review; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReviewRepository extends JpaRepository { + +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/review/service/ReviewService.java b/growthookServer/src/main/java/com/example/growthookserver/api/review/service/ReviewService.java new file mode 100644 index 0000000..9744213 --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/review/service/ReviewService.java @@ -0,0 +1,10 @@ +package com.example.growthookserver.api.review.service; + +import com.example.growthookserver.api.review.dto.request.ReviewCreateRequestDto; + +public interface ReviewService{ + + //* 액션 플랜별 리뷰 작성 + void createReview(Long actionPlanId, ReviewCreateRequestDto reviewCreateRequestDto); + +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/review/service/ReviewServiceImpl.java b/growthookServer/src/main/java/com/example/growthookserver/api/review/service/ReviewServiceImpl.java new file mode 100644 index 0000000..0bda40d --- /dev/null +++ b/growthookServer/src/main/java/com/example/growthookserver/api/review/service/ReviewServiceImpl.java @@ -0,0 +1,32 @@ +package com.example.growthookserver.api.review.service; + +import com.example.growthookserver.api.actionplan.domain.ActionPlan; +import com.example.growthookserver.api.actionplan.repository.ActionPlanRepository; +import com.example.growthookserver.api.review.domain.Review; +import com.example.growthookserver.api.review.dto.request.ReviewCreateRequestDto; +import com.example.growthookserver.api.review.repository.ReviewRepository; +import com.example.growthookserver.api.seed.domain.Seed; +import com.example.growthookserver.api.seed.repository.SeedRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ReviewServiceImpl implements ReviewService { + + private final ReviewRepository reviewRepository; + private final ActionPlanRepository actionPlanRepository; + + @Override + @Transactional + public void createReview(Long actionPlanId, ReviewCreateRequestDto reviewCreateRequestDto) { + ActionPlan actionPlan = actionPlanRepository.findActionPlanByIdOrThrow(actionPlanId); + Review review = Review.builder() + .content(reviewCreateRequestDto.getContent()) + .actionPlan(actionPlan) + .build(); + reviewRepository.save(review); + } +} diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java b/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java index 00f9c58..0c4b4dc 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/seed/controller/SeedController.java @@ -94,4 +94,12 @@ public ApiResponse getSeedAlarm(@PathVariable Long memb return ApiResponse.success(SuccessStatus.GET_SEED_ALARM, seedService.getSeedAlarm(memberId)); } + @PatchMapping("seed/{seedId}/lock/status") + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "unlockSeed", description = "인사이트 잠금을 해제하는 API입니다.") + public ApiResponse unlockSeed(@PathVariable Long seedId) { + seedService.unlockSeed(seedId); + return ApiResponse.success(SuccessStatus.UNLOCK_SEED.getStatusCode(), SuccessStatus.UNLOCK_SEED.getMessage()); + } + } diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/seed/domain/Seed.java b/growthookServer/src/main/java/com/example/growthookserver/api/seed/domain/Seed.java index 5082f8a..b572498 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/seed/domain/Seed.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/seed/domain/Seed.java @@ -74,4 +74,6 @@ public void changeCave(Cave newCave) { } public void toggleScrapStatus() { this.isScraped = !this.isScraped; } + + public void unlockSeed() { this.isLocked = false; } } diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/Impl/SeedServiceImpl.java b/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/Impl/SeedServiceImpl.java index 0e68bf2..a5b8a2e 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/Impl/SeedServiceImpl.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/Impl/SeedServiceImpl.java @@ -4,6 +4,8 @@ import com.example.growthookserver.api.actionplan.repository.ActionPlanRepository; import com.example.growthookserver.api.cave.domain.Cave; import com.example.growthookserver.api.cave.repository.CaveRepository; +import com.example.growthookserver.api.member.domain.Member; +import com.example.growthookserver.api.member.repository.MemberRepository; import com.example.growthookserver.api.seed.domain.Seed; import com.example.growthookserver.api.seed.dto.request.SeedCreateRequestDto; import com.example.growthookserver.api.seed.dto.request.SeedMoveRequestDto; @@ -35,6 +37,7 @@ public class SeedServiceImpl implements SeedService { private final CaveRepository caveRepository; private final SeedRepository seedRepository; private final ActionPlanRepository actionPlanRepository; + private final MemberRepository memberRepository; @Override @Transactional @@ -118,6 +121,17 @@ public SeedAlarmGetResponseDto getSeedAlarm(Long memberId) { return SeedAlarmGetResponseDto.of(seedCount); } + @Override + @Transactional + public void unlockSeed(Long seedId) { + Seed seed = seedRepository.findSeedByIdOrThrow(seedId); + seed.unlockSeed(); + + Long memberId = seed.getMemberId(); + Member member = memberRepository.findMemberByIdOrThrow(memberId); + member.useSsuck(); + } + @Override @Transactional public void toggleSeedScrapStatus(Long seedId) { diff --git a/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/SeedService.java b/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/SeedService.java index 563a51e..d3458a8 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/SeedService.java +++ b/growthookServer/src/main/java/com/example/growthookserver/api/seed/service/SeedService.java @@ -40,4 +40,6 @@ public interface SeedService { //* 씨앗 알림 조회 SeedAlarmGetResponseDto getSeedAlarm(Long memberId); + //* 씨앗 잠금 해제 + void unlockSeed(Long seedId); } diff --git a/growthookServer/src/main/java/com/example/growthookserver/common/response/SuccessStatus.java b/growthookServer/src/main/java/com/example/growthookserver/common/response/SuccessStatus.java index 20c7627..ed1aa24 100644 --- a/growthookServer/src/main/java/com/example/growthookserver/common/response/SuccessStatus.java +++ b/growthookServer/src/main/java/com/example/growthookserver/common/response/SuccessStatus.java @@ -37,6 +37,7 @@ public enum SuccessStatus { GET_SEED_LIST(HttpStatus.OK, "전체 씨앗 리스트 조회 성공" ), TOGGLE_SEED_SCRAP_STATUS(HttpStatus.OK, "씨앗 스크랩 여부 토글 전환 성공"), GET_SEED_ALARM(HttpStatus.OK,"씨앗 알람 조회 성공"), + UNLOCK_SEED(HttpStatus.OK, "씨앗 잠금 해제 성공"), /** * actionplan @@ -49,6 +50,11 @@ public enum SuccessStatus { GET_FINISHED_ACTIONPLAN_PERCENT(HttpStatus.OK, "완료한 액션 플랜 퍼센트 조회 성공"), GET_DOING_ACTIONPLAN_SUCCESS(HttpStatus.OK, "진행 중인 액션 플랜 리스트 조회 성공"), GET_FINISHED_ACTIONPLAN_SUCCESS(HttpStatus.OK,"완료한 액션 플랜 리스트 조회 성공"), + + /** + * review + */ + POST_REVIEW_SUCCESS(HttpStatus.CREATED, "리뷰 생성 성공"), ; private final HttpStatus httpStatus;