Skip to content

Commit

Permalink
Feat: 보호자용 마이페이지와 관련된 로직 구현 (#31)
Browse files Browse the repository at this point in the history
* feat : SeniorRepository 인터페이스 추가

* feat : GuardService 클래스 추가

* feat : SeniorNotFoundException 클래스 추가

* feat : GuardControllerAdvice 클래스 추가

* feat : GuardController에 있는 api 구현

* feat : updateMember 메소드 추가

* feat : mapToResponse 메소드, updateSenior 메소드 추가 및 getter 추가

* feat : SeniorTest 클래스 추가
Senior 엔티티에 대한 테스트 코드

* feat : SeniorRepositoryTest 클래스 추가
SeniorRepository에 대한 테스트 코드

* refactor : basePackage 추가

* feat : findByIsSinitto 메소드 추가
모든 보호자 불러오는데 사용

* refactor : Transactional 어노테이션 추가 및 업데이트 시 save 메소드 제거

* refactor : responseEntity 리턴하도록 변경

* refactor : 주석 제거
  • Loading branch information
2iedo authored Oct 1, 2024
1 parent ef29c1d commit 4b476ce
Show file tree
Hide file tree
Showing 10 changed files with 343 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.example.sinitto.guard.controller;

import com.example.sinitto.common.annotation.MemberId;
import com.example.sinitto.guard.dto.GuardRequest;
import com.example.sinitto.guard.dto.GuardResponse;
import com.example.sinitto.guard.dto.SeniorRequest;
import com.example.sinitto.guard.dto.SeniorResponse;
import com.example.sinitto.guard.service.GuardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
Expand All @@ -14,71 +16,71 @@

@RestController
@RequestMapping("/api/guards")
@Tag(name = "[미구현]마이페이지 - 보호자용", description = "보호자와 시니어 관련 마이페이지 API")
@Tag(name = "마이페이지 - 보호자용", description = "보호자와 시니어 관련 마이페이지 API")
public class GuardController {
private final GuardService guardService;

public GuardController(GuardService guardService){
this.guardService = guardService;
}
@Operation(summary = "연결된 모든 시니어 정보 조회", description = "보호자가 등록한 모든 시니어의 정보를 요청합니다.")
@GetMapping("/senior")
public ResponseEntity<List<SeniorResponse>> getAllSeniors() {
// 임시 응답
return ResponseEntity.ok(new ArrayList<>());
public ResponseEntity<List<SeniorResponse>> getAllSeniors(@MemberId Long memberId) {
return ResponseEntity.ok(guardService.readSeniors(memberId));
}

@Operation(summary = "연결된 특정 시니어 정보 조회", description = "보호자가 등록한 특정 시니어의 정보를 요청합니다.")
@GetMapping("/senior/{seniorId}")
public ResponseEntity<SeniorResponse> getSenior(@PathVariable Long seniorId) {
// 임시 응답
return ResponseEntity.ok(new SeniorResponse(null, null, null));
public ResponseEntity<SeniorResponse> getSenior(@MemberId Long memberId, @PathVariable Long seniorId) {
return ResponseEntity.ok(guardService.readOneSenior(memberId, seniorId));
}

@Operation(summary = "시니어 정보 수정", description = "시니어의 정보를 수정합니다.")
@PutMapping("/senior/{seniorId}")
public ResponseEntity<String> updateSenior(@PathVariable Long seniorId, @RequestBody SeniorRequest request) {
// 임시 응답
public ResponseEntity<String> updateSenior(@MemberId Long memberId, @PathVariable Long seniorId, @RequestBody SeniorRequest seniorRequest) {
guardService.updateSenior(memberId, seniorId, seniorRequest);
return ResponseEntity.ok("시니어 정보가 수정되었습니다.");
}

@Operation(summary = "시니어 추가", description = "보호자가 새로운 시니어를 등록합니다.")
@PostMapping("/senior")
public ResponseEntity<String> createSenior(@RequestBody SeniorRequest request) {
// 임시 응답
public ResponseEntity<String> createSenior(@MemberId Long memberId, @RequestBody SeniorRequest seniorRequest) {
guardService.createSenior(memberId, seniorRequest);
return ResponseEntity.ok("새로운 시니어가 등록되었습니다.");
}

@Operation(summary = "시니어 삭제", description = "보호자가 시니어를 등록 해제합니다.")
@DeleteMapping("/senior/{seniorId}")
public ResponseEntity<String> deleteSenior(@PathVariable Long seniorId) {
// 임시 응답
public ResponseEntity<String> deleteSenior(@MemberId Long memberId, @PathVariable Long seniorId) {
guardService.deleteSenior(memberId, seniorId);
return ResponseEntity.ok("시니어가 삭제되었습니다.");
}

@Operation(summary = "보호자 본인 정보 조회", description = "보호자의 본인 정보를 조회합니다.")
@GetMapping
public ResponseEntity<GuardResponse> getGuardInfo() {
// 임시 응답
return ResponseEntity.ok(new GuardResponse(null, null, null));
public ResponseEntity<GuardResponse> getGuardInfo(@MemberId Long memberId) {
return ResponseEntity.ok(guardService.readGuard(memberId));
}

@Operation(summary = "보호자 본인 정보 수정", description = "보호자의 본인 정보를 수정합니다.")
@PutMapping
public ResponseEntity<String> updateGuardInfo(@RequestBody GuardRequest request) {
// 임시 응답
public ResponseEntity<String> updateGuardInfo(@MemberId Long memberId, @RequestBody GuardRequest guardRequest) {
guardService.updateGuard(memberId, guardRequest);
return ResponseEntity.ok("보호자 정보가 수정되었습니다.");
}

//PASS
// 현재는 jwt 안의 id를 삭제하게 구현했는데, 나중에 관리자 계정 만들면 특정 id 지정해서 삭제하게 수정해야할 듯합니다.
@Operation(summary = "보호자 삭제", description = "관리자용 API입니다.")
@DeleteMapping
public ResponseEntity<String> deleteGuard() {
// 임시 응답
public ResponseEntity<String> deleteGuard(@MemberId Long memberId) {
guardService.deleteGuard(memberId);
return ResponseEntity.ok("보호자가 삭제되었습니다.");
}

@Operation(summary = "모든 보호자 조회", description = "관리자용 API입니다.")
@GetMapping("/all")
public ResponseEntity<List<GuardResponse>> getAllGuards() {
// 임시 응답
return ResponseEntity.ok(new ArrayList<>());
public ResponseEntity<List<GuardResponse>> getAllGuards(@MemberId Long memberId) {
return ResponseEntity.ok(guardService.readAllGuards());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.sinitto.guard.controller;

import com.example.sinitto.guard.exception.SeniorNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.net.URI;

@RestControllerAdvice(basePackages = "com.example.sinitto.guard")
public class GuardControllerAdvice {
@ExceptionHandler(SeniorNotFoundException.class)
public ResponseEntity<ProblemDetail> handleSeniorNotFoundException(SeniorNotFoundException e){
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage());
problemDetail.setType(URI.create("/error/senior-not-found"));
problemDetail.setTitle("Senior Not Found");

return ResponseEntity.status(HttpStatus.NOT_FOUND).body(problemDetail);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.sinitto.guard.exception;

public class SeniorNotFoundException extends RuntimeException {
public SeniorNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.sinitto.guard.repository;

import com.example.sinitto.member.entity.Senior;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface SeniorRepository extends JpaRepository<Senior, Long> {
List<Senior> findByMemberId(Long memberId);
Optional<Senior> findByIdAndMemberId(Long Id, Long memberId);
}
108 changes: 108 additions & 0 deletions src/main/java/com/example/sinitto/guard/service/GuardService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.example.sinitto.guard.service;

import com.example.sinitto.guard.dto.GuardRequest;
import com.example.sinitto.guard.dto.GuardResponse;
import com.example.sinitto.guard.dto.SeniorRequest;
import com.example.sinitto.guard.dto.SeniorResponse;
import com.example.sinitto.guard.exception.SeniorNotFoundException;
import com.example.sinitto.guard.repository.SeniorRepository;
import com.example.sinitto.member.entity.Member;
import com.example.sinitto.member.entity.Senior;
import com.example.sinitto.member.repository.MemberRepository;
import org.springframework.stereotype.Service;
import com.example.sinitto.member.exception.MemberNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class GuardService {
private final MemberRepository memberRepository;
private final SeniorRepository seniorRepository;

public GuardService(MemberRepository memberRepository, SeniorRepository seniorRepository){
this.memberRepository = memberRepository;
this.seniorRepository = seniorRepository;
}

@Transactional
public GuardResponse readGuard(Long memberId){
Member member = memberRepository.findById(memberId).orElseThrow(
() -> new MemberNotFoundException("이메일에 해당하는 멤버를 찾을 수 없습니다.")
);

return new GuardResponse(member.getName(), member.getEmail(), member.getPhoneNumber());
}

@Transactional
public void updateGuard(Long memberId, GuardRequest guardRequest){
Member member = memberRepository.findById(memberId).orElseThrow(
() -> new MemberNotFoundException("이메일에 해당하는 멤버를 찾을 수 없습니다.")
);

member.updateMember(guardRequest.name(), guardRequest.email(), guardRequest.phoneNumber());
}

@Transactional
public void deleteGuard(Long memberId){
Member member = memberRepository.findById(memberId).orElseThrow(
() -> new MemberNotFoundException("이메일에 해당하는 멤버를 찾을 수 없습니다.")
);

memberRepository.delete(member);
}

@Transactional
public void createSenior(Long memberId, SeniorRequest seniorRequest){
Member member = memberRepository.findById(memberId).orElseThrow(
() -> new MemberNotFoundException("이메일에 해당하는 멤버를 찾을 수 없습니다.")
);

Senior senior = new Senior(seniorRequest.seniorName(), seniorRequest.seniorPhoneNumber(), member);

seniorRepository.save(senior);
}

@Transactional
public List<SeniorResponse> readSeniors(Long memberId){
List<Senior> senior = seniorRepository.findByMemberId(memberId);

return senior.stream().map(Senior::mapToResponse).toList();
}

@Transactional
public SeniorResponse readOneSenior(Long memberId, Long seniorId){
Senior senior = seniorRepository.findByIdAndMemberId(seniorId, memberId).orElseThrow(
() -> new SeniorNotFoundException("이메일에 해당하는 시니어를 찾을 수 없습니다.")
);

return new SeniorResponse(senior.getId(), senior.getName(), senior.getPhoneNumber());
}

@Transactional
public void updateSenior(Long memberId, Long seniorId, SeniorRequest seniorRequest){
Senior senior = seniorRepository.findByIdAndMemberId(seniorId, memberId).orElseThrow(
() -> new SeniorNotFoundException("이메일에 해당하는 시니어를 찾을 수 없습니다.")
);

senior.updateSenior(seniorRequest.seniorName(), seniorRequest.seniorPhoneNumber());
}

@Transactional
public void deleteSenior(Long memberId, Long seniorId){
Senior senior = seniorRepository.findByIdAndMemberId(seniorId, memberId).orElseThrow(
() -> new SeniorNotFoundException("이메일에 해당하는 시니어를 찾을 수 없습니다.")
);

seniorRepository.delete(senior);
}

@Transactional
public List<GuardResponse> readAllGuards(){
List<Member> members = memberRepository.findByIsSinitto(false);

return members.stream()
.map(m -> new GuardResponse(m.getName(), m.getEmail(), m.getPhoneNumber()))
.toList();
}
}
7 changes: 7 additions & 0 deletions src/main/java/com/example/sinitto/member/entity/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ public Member(String name, String phoneNumber, String email, boolean isSinitto)
protected Member() {
}

public void updateMember(String name, String email, String phoneNumber){
this.name = name;
this.email = email;
this.phoneNumber = phoneNumber;
}

public Long getId() {
return id;
}
Expand All @@ -51,3 +57,4 @@ public String getEmail() {
return email;
}
}

31 changes: 31 additions & 0 deletions src/main/java/com/example/sinitto/member/entity/Senior.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.sinitto.member.entity;

import com.example.sinitto.guard.dto.SeniorResponse;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import org.hibernate.annotations.OnDelete;
Expand All @@ -21,4 +22,34 @@ public class Senior {
@OnDelete(action = OnDeleteAction.CASCADE)
private Member member;

public Senior(String name, String phoneNumber, Member member){
this.name = name;
this.phoneNumber = phoneNumber;
this.member = member;
}

public void updateSenior(String name, String phoneNumber){
this.name = name;
this.phoneNumber = phoneNumber;
}

public SeniorResponse mapToResponse(){
return new SeniorResponse(this.id, this.name, this.phoneNumber);
}

public Long getId() {
return id;
}

public String getName() {
return name;
}

public String getPhoneNumber() {
return phoneNumber;
}

public Member getMember() {
return member;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {

Optional<Member> findByEmail(String email);

boolean existsByEmail(String email);
}
List<Member> findByIsSinitto(boolean isSinitto);
}
52 changes: 52 additions & 0 deletions src/test/java/com/example/sinitto/guard/entity/SeniorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.example.sinitto.guard.entity;

import com.example.sinitto.guard.dto.SeniorResponse;
import com.example.sinitto.member.entity.Member;
import com.example.sinitto.member.entity.Senior;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

public class SeniorTest {
private Member member;
private Senior senior;

@BeforeEach
void setup(){
member = new Member(
"test",
"01012345678",
"test@test.com",
true
);
senior = new Senior("testSenior", "01000000000", member);
}

@Test
@DisplayName("Senior 엔티티 생성자 테스트")
void counstructorTest(){
assertThat(senior.getId()).isNull();
assertThat(senior.getName()).isEqualTo("testSenior");
assertThat(senior.getPhoneNumber()).isEqualTo("01000000000");
assertThat(senior.getMember()).isEqualTo(member);
}

@Test
@DisplayName("updateSenior 메소드 테스트")
void updateSeniorTest(){
senior.updateSenior("updateSenior", "01011111111");
assertThat(senior.getName()).isEqualTo("updateSenior");
assertThat(senior.getPhoneNumber()).isEqualTo("01011111111");
}

@Test
@DisplayName("mapToResponse 메소드 테스트")
void mapToResponseTest(){
SeniorResponse response = senior.mapToResponse();
assertThat(response.seniorId()).isNull();
assertThat(response.seniorName()).isEqualTo(senior.getName());
assertThat(response.seniorPhoneNumber()).isEqualTo(senior.getPhoneNumber());
}
}
Loading

0 comments on commit 4b476ce

Please sign in to comment.