Skip to content
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] 회원 데일리 루틴 삭제 #37

Merged
merged 10 commits into from
Jan 10, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ public ResponseEntity<Response> entityNotFoundException(EntityNotFoundException
log.error(exception.getMessage());
return ResponseEntity.status(NOT_FOUND).body(fail(exception.getMessage()));
}

@ExceptionHandler(IllegalStateException.class)
public ResponseEntity<Response> illegalStateException(IllegalStateException exception) {
log.error(exception.getMessage());
return ResponseEntity.status(BAD_REQUEST).body(fail(exception.getMessage()));
}
}
14 changes: 14 additions & 0 deletions src/main/java/com/soptie/server/member/message/ErrorMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.soptie.server.member.message;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public enum ErrorMessage {
INVALID_MEMBER("유효하지 않은 회원입니다."),
INACCESSIBLE_ROUTINE("해당 회원이 접근할 수 없는 루틴입니다."),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 회원이 접근할 수 없는 루틴이라는 이미지가 명확하게는 안 그려지는 듯한데 어떻게 생각하시나요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@csb9427 오호 그럴 수도 있겠네요! 그럼 "회원의 루틴이 아닙니다" 메세지는 좀 더 직관적일까요?? 그 외에 추천해주실 메세지가 있다면 추천 부탁드려요!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

회원의 루틴이 아닙니다 좋은 거 같아요!!

;

private final String meesage;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.soptie.server.member.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.soptie.server.member.entity.Member;

public interface MemberRepository extends JpaRepository<Member, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.soptie.server.memberRoutine.controller;

import static com.soptie.server.common.dto.Response.*;
import static com.soptie.server.memberRoutine.message.ResponseMessage.*;

import java.net.URI;
import java.nio.file.AccessDeniedException;
import java.security.Principal;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import com.soptie.server.common.dto.Response;
import com.soptie.server.memberRoutine.service.MemberDailyRoutineService;
import com.soptie.server.memberRoutine.dto.MemberDailyRoutineRequest;

import lombok.RequiredArgsConstructor;
import lombok.val;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/routines/daily/member")
public class MemberDailyRoutineController {

private final MemberDailyRoutineService memberDailyRoutineService;

@PostMapping
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 밑에 루틴 추가 pr이 있어서 합쳐서 보여지는 건가?

public ResponseEntity<Response> createMemberDailyRoutine(
Principal principal, @RequestBody MemberDailyRoutineRequest request) {
val memberId = Long.parseLong(principal.getName());
val response = memberDailyRoutineService.createMemberDailyRoutine(memberId, request);
return ResponseEntity
.created(getURI())
.body(success(SUCCESS_CREATE_ROUTINE.getMessage(), response));
}

private URI getURI() {
return ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/")
.buildAndExpand()
.toUri();
}

@DeleteMapping("/routine/{routineId}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"/routine/{routineId}" 말고 "/{routineId}"는 좀 그럴려나요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자원의 표현성으로 의논 완료!

public ResponseEntity<Response> deleteMemberDailyRoutine(Principal principal, @PathVariable Long routineId) {
val memberId = Long.parseLong(principal.getName());
memberDailyRoutineService.deleteMemberDailyRoutine(memberId, routineId);
return ResponseEntity.ok(success(SUCCESS_DELETE_ROUTINE.getMessage()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.soptie.server.memberRoutine.dto;

public record MemberDailyRoutineRequest(
Long routineId
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.soptie.server.memberRoutine.dto;

public record MemberDailyRoutineResponse(
long routineId
) {

public static MemberDailyRoutineResponse of(Long routineId) {
return new MemberDailyRoutineResponse(routineId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,15 @@ public class CompletedMemberDailyRoutine {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "routine_id")
private DailyRoutine routine;

public CompletedMemberDailyRoutine(MemberDailyRoutine routine) {
this.achieveCount = routine.getAchieveCount();
setMember(routine);
this.routine = routine.getRoutine();
}

private void setMember(MemberDailyRoutine routine) {
member.getDailyRoutines().remove(routine);
this.member = routine.getMember();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor
@Getter
public class MemberDailyRoutine {

@Id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.soptie.server.memberRoutine.message;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public enum ResponseMessage {
SUCCESS_CREATE_ROUTINE("데일리 루틴 추가 성공"),
SUCCESS_DELETE_ROUTINE("데일리 루틴 삭제 성공"),
;

private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.soptie.server.memberRoutine.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.soptie.server.memberRoutine.entity.daily.CompletedMemberDailyRoutine;

public interface CompletedMemberDailyRoutineRepository extends JpaRepository<CompletedMemberDailyRoutine, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.soptie.server.memberRoutine.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.soptie.server.memberRoutine.entity.daily.MemberDailyRoutine;

public interface MemberDailyRoutineRepository extends JpaRepository<MemberDailyRoutine, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.soptie.server.memberRoutine.service;

import com.soptie.server.memberRoutine.dto.MemberDailyRoutineRequest;
import com.soptie.server.memberRoutine.dto.MemberDailyRoutineResponse;

public interface MemberDailyRoutineService {
MemberDailyRoutineResponse createMemberDailyRoutine(long memberId, MemberDailyRoutineRequest request);
void deleteMemberDailyRoutine(long memberId, Long routineId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.soptie.server.memberRoutine.service;

import static com.soptie.server.member.message.ErrorMessage.*;
import static com.soptie.server.routine.message.ErrorMessage.*;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.soptie.server.member.entity.Member;
import com.soptie.server.member.repository.MemberRepository;
import com.soptie.server.memberRoutine.dto.MemberDailyRoutineRequest;
import com.soptie.server.memberRoutine.dto.MemberDailyRoutineResponse;
import com.soptie.server.memberRoutine.entity.daily.CompletedMemberDailyRoutine;
import com.soptie.server.memberRoutine.entity.daily.MemberDailyRoutine;
import com.soptie.server.memberRoutine.repository.CompletedMemberDailyRoutineRepository;
import com.soptie.server.memberRoutine.repository.MemberDailyRoutineRepository;
import com.soptie.server.routine.entity.daily.DailyRoutine;
import com.soptie.server.routine.repository.daily.routine.DailyRoutineRepository;

import jakarta.persistence.EntityNotFoundException;
import lombok.*;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberDailyRoutineServiceImpl implements MemberDailyRoutineService {

private final MemberDailyRoutineRepository memberDailyRoutineRepository;
private final MemberRepository memberRepository;
private final DailyRoutineRepository dailyRoutineRepository;
private final CompletedMemberDailyRoutineRepository completedMemberDailyRoutineRepository;

@Override
@Transactional
public MemberDailyRoutineResponse createMemberDailyRoutine(long memberId, MemberDailyRoutineRequest request) {
val member = findMember(memberId);
val routine = findRoutine(request.routineId());
val memberRoutine = new MemberDailyRoutine(member, routine);
val savedMemberRoutine = memberDailyRoutineRepository.save(memberRoutine);
return MemberDailyRoutineResponse.of(savedMemberRoutine.getId());
}

private DailyRoutine findRoutine(Long id) {
return dailyRoutineRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException(INVALID_ROUTINE.getMessage()));
}

@Override
@Transactional
public void deleteMemberDailyRoutine(long memberId, Long routineId) {
val member = findMember(memberId);
val routine = findMemberRoutine(routineId);
checkRoutineForMember(member, routine);
deleteMemberRoutine(routine);
}

private Member findMember(Long id) {
return memberRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException(INVALID_MEMBER.getMeesage()));
}

private MemberDailyRoutine findMemberRoutine(Long id) {
return memberDailyRoutineRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException(INVALID_ROUTINE.getMessage()));
}

private void checkRoutineForMember(Member member, MemberDailyRoutine routine) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

체크와 동시에 예외도 터뜨리고 있는데 이럴 시, 메서드명에 예외도 터뜨림을 알려줘야 할까요....??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

논의 완료!

if (!member.getDailyRoutines().contains(routine)) {
throw new IllegalStateException(INACCESSIBLE_ROUTINE.getMeesage());
}
}

private void deleteMemberRoutine(MemberDailyRoutine routine) {
moveCompletedRoutine(routine);
memberDailyRoutineRepository.delete(routine);
}

private void moveCompletedRoutine(MemberDailyRoutine routine) {
val completedRoutine = new CompletedMemberDailyRoutine(routine);
completedMemberDailyRoutineRepository.save(completedRoutine);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@Getter
public enum ErrorMessage {
INVALID_THEME("유효하지 않은 테마입니다."),
INVALID_ROUTINE("유효하지 않은 루틴입니다."),
;

private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class DollControllerTest extends BaseControllerTest {
@DisplayName("인형 이미지 조회 성공")
void success_getDollImage() throws Exception {
// given
DollType dollType = DollType.BEAR;
DollType dollType = DollType.BROWN;
DollImageResponse dollImage = DollFixture.createDollImageResponseDTO();
ResponseEntity<Response> response = ResponseEntity.ok(Response.success("인형 이미지 조회 성공", dollImage));

Expand Down
Loading