-
Notifications
You must be signed in to change notification settings - Fork 0
예약 관련 API 구현 #13
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
Merged
Merged
예약 관련 API 구현 #13
Changes from all commits
Commits
Show all changes
93 commits
Select commit
Hold shift + click to select a range
d871d1e
chore: ``format_sql`` 프로퍼티 추가
snowykte0426 4ded58a
add: Booking Application Port 및 Place Persistence Port 추가
snowykte0426 ee9414b
add: ``BookingApplicationAdapter`` 선언
snowykte0426 5b9ae36
update: QueryDSL 기반 Custom Repository명 변경
snowykte0426 2b69792
add: ``Place`` 관련 API Response DTO 정의
snowykte0426 e3bdeff
add: ``Booking`` Repository 선언 및 정의
snowykte0426 9b6dadc
add: ``Place`` Repository 구현
snowykte0426 f4445f7
add: 예약 가능한 장소 조회 Use Case 구현
snowykte0426 32fccd2
add: Place 영속 계층 Adapter 선언 맟 정의
snowykte0426 23facd4
update: TimeSlot Domain에서 복합 키 구현을 위한 Record 정의
snowykte0426 48f1163
update: 실제 RDB 스키마와 동일하도록 변경
snowykte0426 c486189
update: Entity 변경에 따른 Mapper 클래스 수정
snowykte0426 b93c7e5
update: ``GET /api/v1/bookings/available`` 구현
snowykte0426 b74ba19
update: ``Booking`` 엔드포인트 변경
snowykte0426 1b9d997
update: ``GET /api/v1/booking/information`` 엔드포인트 정의
snowykte0426 e3f8058
update: ``BookingApplicationAdapter`` 클래스에 UseCase 클래스 연결
snowykte0426 0547ba4
add: ``BookingMapper`` 클래스에 ``toReponse`` 메서드 추가
snowykte0426 11b459f
update: 불필요 어노테이션 제거
snowykte0426 b6112ce
update: ``president`` 필드 추가
snowykte0426 da45910
add: ``FindBookingByDateAndTimeAndPlaceUseCase`` 클래스 선언
snowykte0426 f009fff
add: 예약 정보 조회 쿼리 메서드 구현
snowykte0426 fa08218
add: ``Booking`` 영속성 계층 Port,Adapter 구현
snowykte0426 da518e9
update: ``FindBookingByDAteAndTimeAndPlaceUseCase`` 구현
snowykte0426 b0595cd
update: ``placeType`` 파라미터 nullable
snowykte0426 c899c9e
fix: RDB 테이블과 Entity 동기화
snowykte0426 90eef65
add: ``CreateBookingUseCase`` 클래스 구현
snowykte0426 7d9197a
add: 예약 생성 API 실행 시 발생 가능 예외 상황 정의
snowykte0426 7a67585
add: 예약 생성 API 실행 시 발생 가능 예외 클래스 정의
snowykte0426 7f68719
add: ``save`` 메서드 추가
snowykte0426 c5f7ff8
update: ``createBooking`` 메서드 구현
snowykte0426 42677f6
add: 여러 사용자 조회 쿼리 메서드 추가
snowykte0426 df17223
add: 예약 생성 API Request DTO 정의
snowykte0426 376a2dd
add: 장소명을 활용한 장소 정보 쿼리 메서드 추가
snowykte0426 9f15d49
add: 장소 미조회 시 예외 클래스 추가
snowykte0426 1244937
add: 장소명을 활용한 장소 정보 조회 메서드 추가
snowykte0426 2d8fbd1
fix: Entity와 Domain 동기화
snowykte0426 2e8bca6
add: ``TimeSlot`` Persistence 계층 구성
snowykte0426 57a6005
update: ``@Setter`` 어노테이션 제거
snowykte0426 7ccd125
update: Web Request,Request 구분 제거 및 엔드포인트 검증 강화
snowykte0426 e874dd5
add: Cache 관련 프로퍼티 추가
snowykte0426 d718797
add: ``CacheConfig`` 설정 클래스 구현
snowykte0426 15b664e
add: ``findAll`` 메서드 진입점 추가
snowykte0426 db185b1
delete: 미사용 메서드 제거
snowykte0426 9277295
update: 예외 클래스명 수정 및 예외 적용 범위 확대
snowykte0426 fe23637
update: 캐시를 활용한 성능 향상 전략 적용
snowykte0426 68642b0
add: ``Java Caffeine`` 라이브러리 및 Spring Cache Starter 추가
snowykte0426 db72ca2
delete: 미사용 예외 클래스 제거
snowykte0426 45dea30
add: 예약 인원 초과 예외 추가
snowykte0426 3bb7f85
update: 예약 인원 최대치 검사 로직 추가
snowykte0426 2f21141
update: 미사용 의존성 제거
snowykte0426 abc7887
test: 예약 생성,예약 검색 Use Case 클래스 단위 테스트 작성
snowykte0426 4004d58
test: 예약 가능한 장소 조회 Use Case 클래스 테스트 코드 추가
snowykte0426 8d1ba97
Merge branch 'develop' of https://github.com/Team-Ampersand/Groom-Ser…
snowykte0426 2908844
update: 코드 재사용을 위한 Recode명 수정 및 요구사항의 변화에 따른 검증 어노테이션 제거
snowykte0426 91d1883
update: 임시 Mock 제거 및 실제 기능 구현
snowykte0426 ee899a5
add: 예약 대표자가 아닌 사용자의 요청 시 발행될 예외 추가
snowykte0426 1fefa79
update: 인증/인가 엔드포인트를 제외한 모든 엔드포인트에 접근 권한 설정
snowykte0426 890503d
add: 예약 리소스 조회 및 존재 여부 확인 메서드 추가
snowykte0426 17924bf
update: Deprecated 된 메서드 사용 중지
snowykte0426 3722765
update: ``Security Context Holder``에 권한 정보 저장 추가
snowykte0426 d801fb8
add: 예약 수정 API 구현
snowykte0426 d9afdba
update: 토큰 발행 시 권한 정보 포함하도록 수정
snowykte0426 b2f87ca
update: 유효하지 않은 예약 수정 시 예외 추가
snowykte0426 e6ef27a
fix: 올바르지 않은 메서드 적용 수정
snowykte0426 11a4732
add: 비관적 락 적용 ``SELETE`` 메서드 추가
snowykte0426 1f49f8c
add: 예약 삭제 비즈니스 로직 추가
snowykte0426 73601f3
add: 예약 삭제 비즈니스 로직 구현
snowykte0426 270c3c0
add: 예약 삭제 엔드포인트 구현
snowykte0426 14c9560
update: ``updateBooking`` 메서드의 반환 타입을 Void로 변경
snowykte0426 4758692
fix: 예약 삭제 로직에서 대표자 이메일 확인 조건 수정
snowykte0426 43d4533
add: Booking 미존재 시 방어 코드 추가
snowykte0426 4351345
update: 미사용 의존성 DI 제거
snowykte0426 b5265f6
test: 예약 수정,삭제 로직 테스트 코드 작성
snowykte0426 d0550f9
test: 실제 로직에 맞게 테스트 코드 적용
snowykte0426 8afd3ad
update: 루트 경로에 대한 접근 권한을 허용
snowykte0426 cf4a344
update: 상태 확인 엔드포인트 변경
snowykte0426 3ec3ae5
update: 수정된 헬스 체크 경로에 대한 curl 명령어 수정
snowykte0426 514d708
update: ``CreateBookingUseCase``에 비관적 락 적용
snowykte0426 aa7dbff
test: 비관적 락 적용에 따른 메서드 변경 적용
snowykte0426 d5dcdd8
update: ``findMemberByEmail`` 메서드에 ``Optional`` 적용
snowykte0426 4ec7711
update: 메서드 이름을 Java 네이밍 규칙에 맞게 수정
snowykte0426 521775c
update: ``FindBookingByDateAndTimeAndPlaceUseCase``에서 ``BookingPersis…
snowykte0426 1164ef3
update: QueryDSL 구현을 Adapter로 이전
snowykte0426 db80837
update: QueryDSL 구현을 Adapter로 이전
snowykte0426 f5be9c2
update: ``Booking`` 테이블에 인덱스 적용
snowykte0426 95b0ec7
fix: 사용자 정보 객체 반환 시 비밀번호 노출 문제 해결
snowykte0426 8ff4892
fix: 예약이 불가능한 시간대이기 때문에 예약이 존재하지 않는 장소를 예약 가능한 장소로 반환하던 문제 수정
snowykte0426 6d8e231
update: 올바르지 않았던 패키지명 수정
snowykte0426 65383e2
update: ``AuthService`` 메서드 분리
snowykte0426 8ae38b9
update: ``GetBookingResponse``에 예약 ID 추가
snowykte0426 a70d313
add: 오래된 Booking 데이터 삭제 스케쥴러 구현
snowykte0426 74f1d19
test: 오래된 예약 삭제 Use Case 클래스 테스트 코드 작성
snowykte0426 c0bff35
test: Use Case 테스트 클래스의 DisplayName 수정
snowykte0426 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,19 @@ | ||
| package com.ampersand.groom.domain.auth.application.service; | ||
|
|
||
| import com.ampersand.groom.domain.auth.application.port.AuthPort; | ||
| import com.ampersand.groom.domain.auth.expection.*; | ||
| import com.ampersand.groom.domain.auth.domain.JwtToken; | ||
| import com.ampersand.groom.domain.auth.exception.*; | ||
| import com.ampersand.groom.domain.auth.presentation.data.request.SignupRequest; | ||
| import com.ampersand.groom.domain.member.domain.constant.MemberRole; | ||
| import com.ampersand.groom.domain.member.persistence.entity.MemberJpaEntity; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.security.crypto.password.PasswordEncoder; | ||
| import org.springframework.stereotype.Service; | ||
|
|
||
| import java.time.Instant; | ||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
|
|
@@ -27,74 +30,95 @@ public class AuthService { | |
| private long refreshTokenExpiration; | ||
|
|
||
| public JwtToken signIn(String email, String password) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 로그인이라는 메서드 내에서 로직이 너무 많은 책임을 가지고있음. 비밀번호, 유저 접근 권한, 토큰 생성등 다양한 기능들은 코드만 보고는 읽기가 어려워보임. private으로 몇군데 분리를 시켜놓고 도메인 행위가 잘 나타났으면 좋겠음
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| MemberJpaEntity user = findUserByEmail(email); | ||
| validateUserStatus(user); | ||
| validatePassword(password, user.getPassword()); | ||
| return generateJwtToken(email, user.getRole()); | ||
| } | ||
|
|
||
| MemberJpaEntity user = authPort.findMembersByCriteria(email) | ||
| .orElseThrow(()->new UserNotFoundException()); | ||
| public JwtToken refreshToken(String refreshToken) { | ||
| validateRefreshToken(refreshToken); | ||
| String email = jwtService.getEmailFromToken(refreshToken); | ||
| validateToken(email, refreshToken); | ||
| MemberJpaEntity user = findUserByEmail(email); | ||
| return generateJwtToken(email, user.getRole()); | ||
| } | ||
|
|
||
| if(!user.getIsAvailable()) { | ||
| public void signup(SignupRequest request) { | ||
| checkUserExists(request.getEmail()); | ||
| MemberJpaEntity newUser = createNewUser(request, calculateGenerationFromEmail(request.getEmail())); | ||
| authPort.save(newUser); | ||
| } | ||
|
|
||
| private MemberJpaEntity findUserByEmail(String email) { | ||
| return authPort.findMembersByCriteria(email) | ||
| .orElseThrow(UserNotFoundException::new); | ||
| } | ||
|
|
||
| private void validateUserStatus(MemberJpaEntity user) { | ||
| if (!user.getIsAvailable()) { | ||
| throw new UserForbiddenException(); | ||
| } | ||
| } | ||
|
|
||
| if (!passwordEncoder.matches(password, user.getPassword())) { | ||
| private void validatePassword(String rawPassword, String encodedPassword) { | ||
| if (!passwordEncoder.matches(rawPassword, encodedPassword)) { | ||
| throw new PasswordInvalidException(); | ||
| } | ||
| } | ||
|
|
||
| String accessToken = jwtService.createAccessToken(email); | ||
| String refreshToken = jwtService.createRefreshToken(email); | ||
|
|
||
| private JwtToken generateJwtToken(String email, MemberRole role) { | ||
| String accessToken = jwtService.createAccessToken(email, role); | ||
| String refreshToken = jwtService.createRefreshToken(email, role); | ||
| return JwtToken.builder() | ||
| .accessToken(accessToken) | ||
| .refreshToken(refreshToken) | ||
| .accessTokenExpiration(Instant.now().plusMillis(accessTokenExpiration)) | ||
| .refreshTokenExpiration(Instant.now().plusMillis(refreshTokenExpiration)) | ||
| .role(user.getRole()) | ||
| .role(role) | ||
| .build(); | ||
| } | ||
|
|
||
| public JwtToken refreshToken(String refreshToken) { | ||
| private void validateRefreshToken(String refreshToken) { | ||
| if (refreshToken == null || refreshToken.isEmpty()) { | ||
| throw new RefreshTokenRequestFormatInvalidException(); | ||
| } | ||
| } | ||
|
|
||
| String email = jwtService.getEmailFromToken(refreshToken); | ||
| boolean isTokenValid = jwtService.refreshToken(email, refreshToken); | ||
| if (!isTokenValid) { | ||
| throw new RefreshTokenExpiredOrInvalidException(); | ||
| } | ||
|
|
||
| if (!jwtService.validateToken(refreshToken)) { | ||
| private void validateToken(String email, String refreshToken) { | ||
| if (!jwtService.refreshToken(email, refreshToken) || !jwtService.validateToken(refreshToken)) { | ||
| throw new RefreshTokenExpiredOrInvalidException(); | ||
| } | ||
|
|
||
| MemberJpaEntity user = authPort.findMembersByCriteria(email) | ||
| .orElseThrow(()->new UserNotFoundException()); | ||
|
|
||
| String newAccessToken = jwtService.createAccessToken(email); | ||
| String newRefreshToken = jwtService.createRefreshToken(email); | ||
|
|
||
| return JwtToken.builder() | ||
| .accessToken(newAccessToken) | ||
| .refreshToken(newRefreshToken) | ||
| .accessTokenExpiration(Instant.now().plusMillis(accessTokenExpiration)) | ||
| .refreshTokenExpiration(Instant.now().plusMillis(refreshTokenExpiration)) | ||
| .role(user.getRole()) | ||
| .build(); | ||
| } | ||
|
|
||
| public void signup(SignupRequest request) { | ||
| authPort.findMembersByCriteria(request.getEmail()) | ||
| .ifPresent(emailVerification -> { | ||
| private void checkUserExists(String email) { | ||
| authPort.findMembersByCriteria(email) | ||
| .ifPresent(user -> { | ||
| throw new UserExistException(); | ||
| }); | ||
| } | ||
|
|
||
| private int calculateGenerationFromEmail(String email) { | ||
| try { | ||
| Matcher matcher = Pattern.compile("\\d{2}").matcher(email); | ||
| if (!matcher.find()) { | ||
| throw new EmailFormatInvalidException(); | ||
| } | ||
| int admissionYear = Integer.parseInt(matcher.group()) + 2000; | ||
| return (admissionYear - 2017) + 1; | ||
| } catch (NumberFormatException e) { | ||
| throw new EmailFormatInvalidException(); | ||
| } | ||
| } | ||
|
|
||
| MemberJpaEntity newUser = MemberJpaEntity.builder() | ||
| private MemberJpaEntity createNewUser(SignupRequest request, int generation) { | ||
| return MemberJpaEntity.builder() | ||
| .name(request.getName()) | ||
| .email(request.getEmail()) | ||
| .password(passwordEncoder.encode(request.getPassword())) | ||
| .generation(1) | ||
| .generation(generation) | ||
| .isAvailable(true) | ||
| .role(MemberRole.ROLE_STUDENT) | ||
| .build(); | ||
|
|
||
| authPort.save(newUser); | ||
| } | ||
| } | ||
| } | ||
2 changes: 1 addition & 1 deletion
2
...in/java/com/ampersand/groom/domain/auth/application/service/CustomUserDetailsService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
...in/java/com/ampersand/groom/domain/auth/application/service/EmailVerificationService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...xpection/EmailFormatInvalidException.java → ...xception/EmailFormatInvalidException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ection/EmailOrPasswordEmptyException.java → ...eption/EmailOrPasswordEmptyException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...h/expection/PasswordInvalidException.java → ...h/exception/PasswordInvalidException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...efreshTokenExpiredOrInvalidException.java → ...efreshTokenExpiredOrInvalidException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...shTokenRequestFormatInvalidException.java → ...shTokenRequestFormatInvalidException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...in/auth/expection/UserExistException.java → ...in/auth/exception/UserExistException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...uth/expection/UserForbiddenException.java → ...uth/exception/UserForbiddenException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...auth/expection/UserNotFoundException.java → ...auth/exception/UserNotFoundException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...icationCodeExpiredOrInvalidException.java → ...icationCodeExpiredOrInvalidException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...rificationCodeFormatInvalidException.java → ...rificationCodeFormatInvalidException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
캐시 버저닝에 관한 고민을 해보고 어떻게 버저닝을 할건지에 대한 고민을 나중에라도 해보면 좋겠음.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재는 단순히 TTL로 2시간만 설정되어 있는데
더 공부해보고 고민해보도록 하겠습니다
감사합니다❤️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런거 생각해보세요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 조언 감사합니다