From e1e5eddebdc301cfd4ca0b81b2af88fb74cd3b82 Mon Sep 17 00:00:00 2001 From: ckkim817 Date: Sun, 14 Jul 2024 08:58:01 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[FEAT/#84]=20GoogleMeetLink=20DTO=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/appointment/dto/GoogleMeetLinkRequest.java | 6 ++++++ .../domain/appointment/dto/GoogleMeetLinkResponse.java | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkRequest.java create mode 100644 src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkResponse.java diff --git a/src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkRequest.java b/src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkRequest.java new file mode 100644 index 0000000..fec26ad --- /dev/null +++ b/src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkRequest.java @@ -0,0 +1,6 @@ +package org.sopt.seonyakServer.domain.appointment.dto; + +public record GoogleMeetLinkRequest( + Long appointmentId +) { +} diff --git a/src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkResponse.java b/src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkResponse.java new file mode 100644 index 0000000..608351b --- /dev/null +++ b/src/main/java/org/sopt/seonyakServer/domain/appointment/dto/GoogleMeetLinkResponse.java @@ -0,0 +1,9 @@ +package org.sopt.seonyakServer.domain.appointment.dto; + +public record GoogleMeetLinkResponse( + String googleMeetLink +) { + public static GoogleMeetLinkResponse of(final String googleMeetLink) { + return new GoogleMeetLinkResponse(googleMeetLink); + } +} From 111bcca117402e559cfebc18247c5a419fd929e4 Mon Sep 17 00:00:00 2001 From: ckkim817 Date: Sun, 14 Jul 2024 09:01:02 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[FEAT/#84]=20=EA=B5=AC=EA=B8=80=20=EB=AF=B8?= =?UTF-8?q?=ED=8A=B8=20=EB=A7=81=ED=81=AC=20=EA=B4=80=EB=A0=A8=20JPA=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/AppointmentRepository.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/org/sopt/seonyakServer/domain/appointment/repository/AppointmentRepository.java b/src/main/java/org/sopt/seonyakServer/domain/appointment/repository/AppointmentRepository.java index 2d361c2..991e35c 100644 --- a/src/main/java/org/sopt/seonyakServer/domain/appointment/repository/AppointmentRepository.java +++ b/src/main/java/org/sopt/seonyakServer/domain/appointment/repository/AppointmentRepository.java @@ -2,6 +2,23 @@ import org.sopt.seonyakServer.domain.appointment.model.Appointment; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface AppointmentRepository extends JpaRepository { + + @Query("SELECT a.googleMeetLink " + + "FROM Appointment a " + + "WHERE a.id = :appointmentId") + String findGoogleMeetLinkById(@Param("appointmentId") Long appointmentId); + + @Query("SELECT a.member.id " + + "FROM Appointment a " + + "WHERE a.id = :appointmentId") + Long findMemberIdById(@Param("appointmentId") Long appointmentId); + + @Query("SELECT a.senior.id " + + "FROM Appointment a " + + "WHERE a.id = :appointmentId") + Long findSeniorIdById(@Param("appointmentId") Long appointmentId); } From 676c72a1a31dfd372b8c5c681d5403146c219625 Mon Sep 17 00:00:00 2001 From: ckkim817 Date: Sun, 14 Jul 2024 09:01:53 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[FEAT/#84]=20=EA=B5=AC=EA=B8=80=20=EB=AF=B8?= =?UTF-8?q?=ED=8A=B8=20=ED=9A=8C=EC=9D=98=EC=8B=A4=20=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AppointmentService.java | 23 ++++++++++++++++++- .../global/auth/PrincipalHandler.java | 2 +- .../global/exception/enums/ErrorType.java | 7 ++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/sopt/seonyakServer/domain/appointment/service/AppointmentService.java b/src/main/java/org/sopt/seonyakServer/domain/appointment/service/AppointmentService.java index 4ccb05c..42a85a6 100644 --- a/src/main/java/org/sopt/seonyakServer/domain/appointment/service/AppointmentService.java +++ b/src/main/java/org/sopt/seonyakServer/domain/appointment/service/AppointmentService.java @@ -2,6 +2,8 @@ import lombok.RequiredArgsConstructor; import org.sopt.seonyakServer.domain.appointment.dto.AppointmentRequest; +import org.sopt.seonyakServer.domain.appointment.dto.GoogleMeetLinkRequest; +import org.sopt.seonyakServer.domain.appointment.dto.GoogleMeetLinkResponse; import org.sopt.seonyakServer.domain.appointment.model.Appointment; import org.sopt.seonyakServer.domain.appointment.model.AppointmentStatus; import org.sopt.seonyakServer.domain.appointment.repository.AppointmentRepository; @@ -41,4 +43,23 @@ public void postAppointment(AppointmentRequest appointmentRequest) { ); appointmentRepository.save(appointment); } -} \ No newline at end of file + + @Transactional(readOnly = true) + public GoogleMeetLinkResponse getGoogleMeetLink(GoogleMeetLinkRequest googleMeetLinkRequest) { + Long userId = memberRepository.findMemberByIdOrThrow(principalHandler.getUserIdFromPrincipal()).getId(); + Long memberId = appointmentRepository.findMemberIdById(googleMeetLinkRequest.appointmentId()); + Long seniorId = appointmentRepository.findSeniorIdById(googleMeetLinkRequest.appointmentId()); + + if (!userId.equals(memberId) && !userId.equals(seniorId)) { + throw new CustomException(ErrorType.NOT_MEMBERS_APPOINTMENT_ERROR); + } + + String googleMeetLink = appointmentRepository.findGoogleMeetLinkById(googleMeetLinkRequest.appointmentId()); + + if (googleMeetLink == null || googleMeetLink.isEmpty()) { + throw new CustomException(ErrorType.NOT_FOUND_GOOGLE_MEET_LINK_ERROR); + } + + return GoogleMeetLinkResponse.of(googleMeetLink); + } +} diff --git a/src/main/java/org/sopt/seonyakServer/global/auth/PrincipalHandler.java b/src/main/java/org/sopt/seonyakServer/global/auth/PrincipalHandler.java index 9d091ef..ab92b83 100644 --- a/src/main/java/org/sopt/seonyakServer/global/auth/PrincipalHandler.java +++ b/src/main/java/org/sopt/seonyakServer/global/auth/PrincipalHandler.java @@ -20,7 +20,7 @@ public void isPrincipalNull( final Object principal ) { if (principal.toString().equals(ANONYMOUS_USER)) { - throw new CustomException(ErrorType.EMPTY_PRINCIPLE_ERROR); + throw new CustomException(ErrorType.EMPTY_PRINCIPAL_ERROR); } } } \ No newline at end of file diff --git a/src/main/java/org/sopt/seonyakServer/global/exception/enums/ErrorType.java b/src/main/java/org/sopt/seonyakServer/global/exception/enums/ErrorType.java index b0c4c48..4ae158b 100644 --- a/src/main/java/org/sopt/seonyakServer/global/exception/enums/ErrorType.java +++ b/src/main/java/org/sopt/seonyakServer/global/exception/enums/ErrorType.java @@ -32,13 +32,15 @@ public enum ErrorType { JSON_TO_MAP_ERROR(HttpStatus.BAD_REQUEST, "40017", "JSON 문자열을 Map으로 변환하는 중 오류가 발생했습니다."), UNIV_CERT_REQUEST_ERROR(HttpStatus.BAD_REQUEST, "40018", "이미 인증이 완료 이메일입니다."), SAME_MEMBER_APPOINTMENT_ERROR(HttpStatus.BAD_REQUEST, "40019", "자기 자신에게는 약속을 신청할 수 없습니다."), + NOT_MEMBERS_APPOINTMENT_ERROR(HttpStatus.BAD_REQUEST, "40020", "해당 회원의 약속이 아닙니다"), + // S3 관련 오류 IMAGE_EXTENSION_ERROR(HttpStatus.BAD_REQUEST, "40051", "이미지 확장자는 jpg, png, webp만 가능합니다."), IMAGE_SIZE_ERROR(HttpStatus.BAD_REQUEST, "40052", "이미지 사이즈는 5MB를 넘을 수 없습니다."), // 인증 관련 오류 - EMPTY_PRINCIPLE_ERROR(HttpStatus.BAD_REQUEST, "40076", "Principle 객체가 없습니다. (null)"), + EMPTY_PRINCIPAL_ERROR(HttpStatus.BAD_REQUEST, "40076", "Principal 객체가 없습니다. (null)"), /** * 401 UNAUTHORIZED @@ -50,7 +52,7 @@ public enum ErrorType { INVALID_JWT_SIGNATURE(HttpStatus.UNAUTHORIZED, "40105", "잘못된 JWT 서명입니다."), UNKNOWN_JWT_ERROR(HttpStatus.UNAUTHORIZED, "40106", "알 수 없는 JWT 토큰 오류가 발생했습니다."), - INVALID_SOCIAL_ACCESS_TOKEN(HttpStatus.UNAUTHORIZED, "40107", "유효하지 않은 소셜 엑세스 토큰입니다."), + INVALID_SOCIAL_ACCESS_TOKEN(HttpStatus.UNAUTHORIZED, "40107", "유효하지 않은 소셜 액세스 토큰입니다."), EXPIRED_AUTHENTICATION_CODE(HttpStatus.UNAUTHORIZED, "40108", "인가 코드가 만료되었습니다."), UN_LOGIN_ERROR(HttpStatus.UNAUTHORIZED, "40109", "로그인 후 진행해주세요."), @@ -62,6 +64,7 @@ public enum ErrorType { NOT_FOUND_CREDENTIALS_JSON_ERROR(HttpStatus.NOT_FOUND, "40403", "구글미트 Credentials Json 파일을 찾을 수 없습니다."), NOT_FOUND_SENIOR_BY_MEMBER(HttpStatus.NOT_FOUND, "40404", "해당 ID를 가진 멤버와 매핑된 선배를 찾을 수 없습니다."), NOT_FOUND_SENIOR_ERROR(HttpStatus.NOT_FOUND, "40405", "존재하지 않는 선배입니다."), + NOT_FOUND_GOOGLE_MEET_LINK_ERROR(HttpStatus.NOT_FOUND, "40407", "구글 미트 링크가 존재하지 않는 약속입니다."), /** * 409 CONFLICT From 93dd0dd33401d29a50be04a5d97cfc34eab35656 Mon Sep 17 00:00:00 2001 From: ckkim817 Date: Sun, 14 Jul 2024 09:02:34 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[FEAT/#84]=20=EA=B5=AC=EA=B8=80=20=EB=AF=B8?= =?UTF-8?q?=ED=8A=B8=20=ED=9A=8C=EC=9D=98=EC=8B=A4=20=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AppointmentController.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/sopt/seonyakServer/domain/appointment/controller/AppointmentController.java b/src/main/java/org/sopt/seonyakServer/domain/appointment/controller/AppointmentController.java index dd0159f..4db90df 100644 --- a/src/main/java/org/sopt/seonyakServer/domain/appointment/controller/AppointmentController.java +++ b/src/main/java/org/sopt/seonyakServer/domain/appointment/controller/AppointmentController.java @@ -3,8 +3,11 @@ import lombok.RequiredArgsConstructor; import org.sopt.seonyakServer.domain.appointment.dto.AppointmentRequest; +import org.sopt.seonyakServer.domain.appointment.dto.GoogleMeetLinkRequest; +import org.sopt.seonyakServer.domain.appointment.dto.GoogleMeetLinkResponse; import org.sopt.seonyakServer.domain.appointment.service.AppointmentService; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -12,16 +15,23 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/v1/appoinment") +@RequestMapping("/api/v1") public class AppointmentController { private final AppointmentService appointmentService; - @PostMapping("") + @PostMapping("/appoinment") public ResponseEntity postAppointment( @RequestBody final AppointmentRequest appointmentRequest ) { appointmentService.postAppointment(appointmentRequest); return ResponseEntity.ok().build(); } + + @GetMapping("/google-meet") + public ResponseEntity getGoogleMeetLink( + @RequestBody final GoogleMeetLinkRequest googleMeetLinkRequest + ) { + return ResponseEntity.ok(appointmentService.getGoogleMeetLink(googleMeetLinkRequest)); + } }