From 724034205dd92ba25b54feebde1f74173eccc9aa Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 4 Jul 2025 19:35:15 +0900 Subject: [PATCH 1/6] =?UTF-8?q?refactor:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EA=B5=AC=EC=A1=B0=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applicationadmin/ApiAdminApplication.java | 37 ----------- application-config/build.gradle | 14 ---- application-user/build.gradle | 59 ----------------- .../applicationuser/ApiUserApplication.java | 40 ------------ build.gradle | 46 ++++--------- common/build.gradle | 10 --- domain-base/.gitattributes | 3 - domain-base/build.gradle | 29 --------- domain-bookmark/build.gradle | 32 --------- domain-menu/.gitattributes | 3 - domain-menu/gradle/wrapper/gradle-wrapper.jar | Bin 43764 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 -- domain-reservation/.gitignore | 37 ----------- domain-reservation/build.gradle | 32 --------- domain-store/.gitattributes | 3 - domain-store/.gitignore | 37 ----------- domain-store/build.gradle | 30 --------- .../gradle/wrapper/gradle-wrapper.jar | Bin 43764 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 -- domain-token/.gitattributes | 3 - domain-token/.gitignore | 37 ----------- domain-token/build.gradle | 31 --------- .../src/main/resources/application.properties | 1 - domain-user/.gitattributes | 3 - domain-user/.gitignore | 37 ----------- external-oauth/.gitignore | 37 ----------- external-oauth/build.gradle | 40 ------------ infra-aws/.gitattributes | 3 - infra-aws/.gitignore | 37 ----------- .../.gitattributes | 0 .../.gitignore | 0 .../build.gradle | 36 +++++------ .../java/com/nowait/ApiAdminApplication.java | 13 ++++ .../config/SwaggerConfig.java | 29 +++++++++ .../config/security/CorsConfig.java | 28 ++++++++ .../config/security}/SecurityConfig.java | 8 +-- .../exception/GlobalExceptionHandler.java | 16 ++--- .../menu/controller/MenuController.java | 0 .../menu/controller/MenuImageController.java | 0 .../menu/dto/MenuCreateRequest.java | 2 +- .../menu/dto/MenuCreateResponse.java | 2 +- .../menu/dto/MenuImageUploadResponse.java | 2 +- .../menu/dto/MenuReadDto.java | 2 +- .../menu/dto/MenuReadResponse.java | 0 .../menu/dto/MenuUpdateRequest.java | 0 .../menu/service/MenuImageService.java | 16 ++--- .../menu/service/MenuService.java | 12 ++-- .../order/controller/OrderController.java | 2 +- .../controller/ReservationController.java | 0 .../reservation/dto/CallGetResponseDto.java | 2 +- .../dto/ReservationGetResponseDto.java | 2 +- .../dto/ReservationStatusSummaryDto.java | 0 .../ReservationStatusUpdateRequestDto.java | 0 .../service/ReservationService.java | 6 +- .../RefreshTokenNotFoundException.java | 2 +- .../exception/ResourceNotFoundException.java | 2 +- .../exception/TokenBadRequestException.java | 4 +- .../exception/UnauthorizedException.java | 2 +- .../security}/jwt/JwtAuthorizationFilter.java | 4 +- .../security}/jwt/JwtUtil.java | 2 +- .../service/CustomUserDetailService.java | 8 +-- .../store/controller/StoreController.java | 0 .../controller/StoreImageController.java | 0 .../store/dto/StoreCreateRequest.java | 2 +- .../store/dto/StoreCreateResponse.java | 2 +- .../store/dto/StoreImageUploadResponse.java | 2 +- .../store/dto/StoreReadDto.java | 2 +- .../store/dto/StoreUpdateRequest.java | 0 .../store/service/StoreImageService.java | 17 +++-- .../store/service/StoreService.java | 0 .../store/service/StoreServiceImpl.java | 13 ++-- .../token/controller/TokenController.java | 2 +- .../token/dto/AuthenticationResponse.java | 0 .../token/dto/RefreshTokenRequest.java | 0 .../token/service/TokenService.java | 10 +-- .../user/controller/UserController.java | 0 .../user/dto/ManagerLoginRequestDto.java | 0 .../user/dto/ManagerLoginResponseDto.java | 2 +- .../user/dto/ManagerSignupRequestDto.java | 2 +- .../user/dto/ManagerSignupResponseDto.java | 2 +- .../user/dto/UserResponseDto.java | 0 .../user/serivce/UserService.java | 8 +-- .../.gitattributes | 0 .../.gitignore | 0 nowait-app-user-api/build.gradle | 61 ++++++++++++++++++ .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../java/com/nowait/ApiUserApplication.java | 15 +++++ .../controller/BookmarkController.java | 2 +- .../bookmark/dto/BookmarkCreateResponse.java | 2 +- .../bookmark/dto/BookmarkGetResponse.java | 2 +- .../bookmark/service/BookmarkService.java | 14 ++-- .../applicationuser/config/SwaggerConfig.java | 29 +++++++++ .../config/security}/CorsConfig.java | 2 +- .../config/security}/SecurityConfig.java | 12 ++-- .../exception/GlobalExceptionHandler.java | 23 +++---- .../menu/controller/MenuController.java | 0 .../menu/dto/MenuImageUploadResponse.java | 2 +- .../applicationuser/menu/dto/MenuReadDto.java | 2 +- .../menu/dto/MenuReadResponse.java | 0 .../menu/service/MenuService.java | 12 ++-- .../oauth}/dto/KaKaoResponse.java | 2 +- .../oauth}/dto/OAuth2Response.java | 2 +- .../oauth2/CustomOAuth2UserService.java | 12 ++-- .../oauth2/OAuth2LoginSuccessHandler.java | 13 ++-- .../order/controller/OrderController.java | 0 .../order/dto/CartItemDto.java | 0 .../order/dto/OrderCreateRequestDto.java | 0 .../order/dto/OrderCreateResponseDto.java | 2 +- .../dto/OrderItemListGetResponseDto.java | 3 +- .../order/dto/OrderItemResponseDTO.java | 0 .../order/service/OrderService.java | 22 +++---- .../controller/ReservationController.java | 2 +- .../dto/ReservationCreateRequestDto.java | 0 .../dto/ReservationCreateResponseDto.java | 0 .../service/ReservationService.java | 16 ++--- .../RefreshTokenNotFoundException.java | 2 +- .../exception/ResourceNotFoundException.java | 2 +- .../exception/TokenBadRequestException.java | 4 +- .../exception/UnauthorizedException.java | 2 +- .../security}/jwt/JwtAuthorizationFilter.java | 7 +- .../security}/jwt/JwtUtil.java | 2 +- .../service/CustomUserDetailService.java | 8 +-- .../store/controller/StoreController.java | 0 .../store/dto/StoreImageUploadResponse.java | 2 +- .../store/dto/StoreReadDto.java | 2 +- .../store/dto/StoreReadResponse.java | 0 .../store/service/StoreService.java | 0 .../store/service/StoreServiceImpl.java | 16 ++--- .../token/controller/TokenController.java | 2 +- .../token/dto/AuthenticationResponse.java | 0 .../token/dto/RefreshTokenRequest.java | 0 .../token/service/TokenService.java | 11 ++-- .../.gitattributes | 0 .../.gitignore | 0 nowait-common/build.gradle | 15 +++++ .../java/com/nowait/common/api/ApiError.java | 0 .../java/com/nowait/common/api/ApiResult.java | 0 .../java/com/nowait/common/api/ApiUtils.java | 0 .../nowait/common/enums/HttpStatusCode.java | 0 .../common/enums/ReservationStatus.java | 0 .../java/com/nowait/common/enums/Role.java | 3 +- .../com/nowait/common/enums/SocialType.java | 0 .../nowait/common/exception/ErrorMessage.java | 0 .../common/exception/ErrorResponse.java | 0 {common => nowait-domain}/.gitignore | 0 {domain-user => nowait-domain}/build.gradle | 13 +++- .../domain-admin-rdb}/.gitignore | 0 .../domain-admin-rdb}/build.gradle | 12 +++- .../domain-core-rdb}/.gitignore | 0 nowait-domain/domain-core-rdb/build.gradle | 47 ++++++++++++++ .../base/entity}/BaseTimeEntity.java | 2 +- .../domaincorerdb}/menu/entity/Menu.java | 5 +- .../domaincorerdb}/menu/entity/MenuImage.java | 4 +- .../exception/MenuImageEmptyException.java | 2 +- .../exception/MenuImageNotFoundException.java | 2 +- .../menu/exception/MenuNotFoundException.java | 2 +- .../exception/MenuParamEmptyException.java | 2 +- .../menu/repository/MenuImageRepository.java | 6 +- .../menu/repository/MenuRepository.java | 4 +- .../order/entity/OrderItem.java | 6 +- .../order/entity/UserOrder.java | 6 +- .../DepositorNameTooLongException.java | 2 +- .../exception/DuplicateOrderException.java | 2 +- .../exception/OrderItemsEmptyException.java | 2 +- .../OrderParameterEmptyException.java | 2 +- .../order/repository/OrderItemRepository.java | 4 +- .../order/repository/OrderRepository.java | 5 +- .../reservation/entity/Reservation.java | 6 +- .../ReservationNotFoundException.java | 2 +- .../repository/ReservationRepository.java | 6 +- .../domaincorerdb}/store/entity/Store.java | 5 +- .../store/entity/StoreImage.java | 4 +- .../exception/StoreImageEmptyException.java | 2 +- .../StoreImageNotFoundException.java | 2 +- .../exception/StoreKeywordEmptyException.java | 2 +- .../exception/StoreNotFoundException.java | 2 +- .../exception/StoreParamEmptyException.java | 2 +- .../repository/StoreImageRepository.java | 6 +- .../store/repository/StoreRepository.java | 5 +- .../domaincorerdb}/token/entity/Token.java | 7 +- .../token/exception/BusinessException.java | 2 +- .../token/repository/TokenRepository.java | 6 +- .../user/entity/MemberDetails.java | 2 +- .../domaincorerdb}/user/entity/User.java | 2 +- .../user/exception/UserNotFoundException.java | 2 +- .../user/repository/UserRepository.java | 6 +- .../domain-user-rdb}/.gitignore | 0 .../domain-user-rdb}/build.gradle | 19 ++++-- .../bookmark/entity/Bookmark.java | 8 +-- .../BookmarkOwnerMismatchException.java | 2 +- .../exception/DuplicateBookmarkException.java | 2 +- .../repository/BookmarkRepository.java | 8 +-- .../oauth}/dto/CustomOAuth2User.java | 4 +- {common => nowait-infra}/.gitattributes | 0 {domain-order => nowait-infra}/.gitignore | 0 {infra-aws => nowait-infra}/build.gradle | 12 +++- .../nowait/infraaws/aws}/s3/S3Service.java | 2 +- .../nowait/infraaws}/config/AsyncConfig.java | 2 +- .../nowait/infraaws/config/AwsS3Config.java | 0 security-admin/.gitattributes | 3 - security-admin/.gitignore | 37 ----------- security-admin/build.gradle | 38 ----------- security-front/.gitignore | 37 ----------- security-front/build.gradle | 41 ------------ settings.gradle | 24 ++----- 206 files changed, 585 insertions(+), 1106 deletions(-) delete mode 100644 application-admin/src/main/java/com/nowait/applicationadmin/ApiAdminApplication.java delete mode 100644 application-config/build.gradle delete mode 100644 application-user/build.gradle delete mode 100644 application-user/src/main/java/com/nowait/applicationuser/ApiUserApplication.java delete mode 100644 common/build.gradle delete mode 100644 domain-base/.gitattributes delete mode 100644 domain-base/build.gradle delete mode 100644 domain-bookmark/build.gradle delete mode 100644 domain-menu/.gitattributes delete mode 100644 domain-menu/gradle/wrapper/gradle-wrapper.jar delete mode 100644 domain-menu/gradle/wrapper/gradle-wrapper.properties delete mode 100644 domain-reservation/.gitignore delete mode 100644 domain-reservation/build.gradle delete mode 100644 domain-store/.gitattributes delete mode 100644 domain-store/.gitignore delete mode 100644 domain-store/build.gradle delete mode 100644 domain-store/gradle/wrapper/gradle-wrapper.jar delete mode 100644 domain-store/gradle/wrapper/gradle-wrapper.properties delete mode 100644 domain-token/.gitattributes delete mode 100644 domain-token/.gitignore delete mode 100644 domain-token/build.gradle delete mode 100644 domain-token/src/main/resources/application.properties delete mode 100644 domain-user/.gitattributes delete mode 100644 domain-user/.gitignore delete mode 100644 external-oauth/.gitignore delete mode 100644 external-oauth/build.gradle delete mode 100644 infra-aws/.gitattributes delete mode 100644 infra-aws/.gitignore rename {application-admin => nowait-app-admin-api}/.gitattributes (100%) rename {application-admin => nowait-app-admin-api}/.gitignore (100%) rename {application-admin => nowait-app-admin-api}/build.gradle (57%) create mode 100644 nowait-app-admin-api/src/main/java/com/nowait/ApiAdminApplication.java create mode 100644 nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/config/SwaggerConfig.java create mode 100644 nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/config/security/CorsConfig.java rename {security-admin/src/main/java/com/nowait/adminsecurity/auth/config => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/config/security}/SecurityConfig.java (91%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/exception/GlobalExceptionHandler.java (90%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/controller/MenuController.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/controller/MenuImageController.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/dto/MenuCreateRequest.java (92%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/dto/MenuCreateResponse.java (94%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/dto/MenuImageUploadResponse.java (88%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/dto/MenuReadDto.java (94%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/dto/MenuReadResponse.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/dto/MenuUpdateRequest.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/service/MenuImageService.java (74%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/menu/service/MenuService.java (89%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/order/controller/OrderController.java (92%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/reservation/controller/ReservationController.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/reservation/dto/CallGetResponseDto.java (91%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/reservation/dto/ReservationGetResponseDto.java (92%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/reservation/dto/ReservationStatusSummaryDto.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/reservation/dto/ReservationStatusUpdateRequestDto.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java (90%) rename {security-admin/src/main/java/com/nowait/adminsecurity => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/security}/exception/RefreshTokenNotFoundException.java (80%) rename {security-front/src/main/java/com/nowait/frontsecurity => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/security}/exception/ResourceNotFoundException.java (87%) rename {security-admin/src/main/java/com/nowait/adminsecurity => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/security}/exception/TokenBadRequestException.java (63%) rename {security-admin/src/main/java/com/nowait/adminsecurity => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/security}/exception/UnauthorizedException.java (89%) rename {security-admin/src/main/java/com/nowait/adminsecurity/auth => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/security}/jwt/JwtAuthorizationFilter.java (94%) rename {security-admin/src/main/java/com/nowait/adminsecurity/auth => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/security}/jwt/JwtUtil.java (97%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/security}/service/CustomUserDetailService.java (78%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/controller/StoreController.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/controller/StoreImageController.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateRequest.java (92%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/dto/StoreCreateResponse.java (94%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/dto/StoreImageUploadResponse.java (87%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/dto/StoreReadDto.java (94%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/dto/StoreUpdateRequest.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/service/StoreImageService.java (81%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/service/StoreService.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/store/service/StoreServiceImpl.java (88%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/token/controller/TokenController.java (97%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/token/dto/AuthenticationResponse.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/token/dto/RefreshTokenRequest.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/token/service/TokenService.java (86%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/user/controller/UserController.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/user/dto/ManagerLoginRequestDto.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/user/dto/ManagerLoginResponseDto.java (95%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/user/dto/ManagerSignupRequestDto.java (96%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/user/dto/ManagerSignupResponseDto.java (94%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/user/dto/UserResponseDto.java (100%) rename {application-admin => nowait-app-admin-api}/src/main/java/com/nowait/applicationadmin/user/serivce/UserService.java (92%) rename {application-config => nowait-app-user-api}/.gitattributes (100%) rename {application-user => nowait-app-user-api}/.gitignore (100%) create mode 100644 nowait-app-user-api/build.gradle rename {application-user => nowait-app-user-api}/gradle/wrapper/gradle-wrapper.jar (100%) rename {application-user => nowait-app-user-api}/gradle/wrapper/gradle-wrapper.properties (100%) create mode 100644 nowait-app-user-api/src/main/java/com/nowait/ApiUserApplication.java rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/bookmark/controller/BookmarkController.java (97%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/bookmark/dto/BookmarkCreateResponse.java (90%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/bookmark/dto/BookmarkGetResponse.java (89%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/bookmark/service/BookmarkService.java (86%) create mode 100644 nowait-app-user-api/src/main/java/com/nowait/applicationuser/config/SwaggerConfig.java rename {application-config/src/main/java/com/nowait/config/config => nowait-app-user-api/src/main/java/com/nowait/applicationuser/config/security}/CorsConfig.java (96%) rename {security-front/src/main/java/com/nowait/frontsecurity/auth/config => nowait-app-user-api/src/main/java/com/nowait/applicationuser/config/security}/SecurityConfig.java (89%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/exception/GlobalExceptionHandler.java (89%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/menu/controller/MenuController.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/menu/dto/MenuImageUploadResponse.java (88%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/menu/dto/MenuReadDto.java (94%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/menu/dto/MenuReadResponse.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/menu/service/MenuService.java (82%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-app-user-api/src/main/java/com/nowait/applicationuser/oauth}/dto/KaKaoResponse.java (95%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-app-user-api/src/main/java/com/nowait/applicationuser/oauth}/dto/OAuth2Response.java (90%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-app-user-api/src/main/java/com/nowait/applicationuser/oauth}/oauth2/CustomOAuth2UserService.java (86%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-app-user-api/src/main/java/com/nowait/applicationuser/oauth}/oauth2/OAuth2LoginSuccessHandler.java (89%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/order/controller/OrderController.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/order/dto/CartItemDto.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/order/dto/OrderCreateRequestDto.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/order/dto/OrderCreateResponseDto.java (94%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/order/dto/OrderItemListGetResponseDto.java (92%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/order/dto/OrderItemResponseDTO.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/order/service/OrderService.java (87%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/reservation/controller/ReservationController.java (96%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/reservation/dto/ReservationCreateRequestDto.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/reservation/dto/ReservationCreateResponseDto.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java (76%) rename {security-front/src/main/java/com/nowait/frontsecurity => nowait-app-user-api/src/main/java/com/nowait/applicationuser/security}/exception/RefreshTokenNotFoundException.java (80%) rename {security-admin/src/main/java/com/nowait/adminsecurity => nowait-app-user-api/src/main/java/com/nowait/applicationuser/security}/exception/ResourceNotFoundException.java (87%) rename {security-front/src/main/java/com/nowait/frontsecurity => nowait-app-user-api/src/main/java/com/nowait/applicationuser/security}/exception/TokenBadRequestException.java (63%) rename {security-front/src/main/java/com/nowait/frontsecurity => nowait-app-user-api/src/main/java/com/nowait/applicationuser/security}/exception/UnauthorizedException.java (89%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-app-user-api/src/main/java/com/nowait/applicationuser/security}/jwt/JwtAuthorizationFilter.java (95%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-app-user-api/src/main/java/com/nowait/applicationuser/security}/jwt/JwtUtil.java (97%) rename {security-admin/src/main/java/com/nowait/adminsecurity/auth => nowait-app-user-api/src/main/java/com/nowait/applicationuser/security}/service/CustomUserDetailService.java (78%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/store/dto/StoreImageUploadResponse.java (87%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/store/dto/StoreReadDto.java (94%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/store/dto/StoreReadResponse.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/store/service/StoreService.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java (88%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/token/controller/TokenController.java (97%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/token/dto/AuthenticationResponse.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/token/dto/RefreshTokenRequest.java (100%) rename {application-user => nowait-app-user-api}/src/main/java/com/nowait/applicationuser/token/service/TokenService.java (86%) rename {application-user => nowait-common}/.gitattributes (100%) rename {application-config => nowait-common}/.gitignore (100%) create mode 100644 nowait-common/build.gradle rename {common => nowait-common}/src/main/java/com/nowait/common/api/ApiError.java (100%) rename {common => nowait-common}/src/main/java/com/nowait/common/api/ApiResult.java (100%) rename {common => nowait-common}/src/main/java/com/nowait/common/api/ApiUtils.java (100%) rename {common => nowait-common}/src/main/java/com/nowait/common/enums/HttpStatusCode.java (100%) rename {common => nowait-common}/src/main/java/com/nowait/common/enums/ReservationStatus.java (100%) rename {common => nowait-common}/src/main/java/com/nowait/common/enums/Role.java (91%) rename {common => nowait-common}/src/main/java/com/nowait/common/enums/SocialType.java (100%) rename {common => nowait-common}/src/main/java/com/nowait/common/exception/ErrorMessage.java (100%) rename {common => nowait-common}/src/main/java/com/nowait/common/exception/ErrorResponse.java (100%) rename {common => nowait-domain}/.gitignore (100%) rename {domain-user => nowait-domain}/build.gradle (90%) rename {domain-base => nowait-domain/domain-admin-rdb}/.gitignore (100%) rename {domain-menu => nowait-domain/domain-admin-rdb}/build.gradle (77%) rename {domain-bookmark => nowait-domain/domain-core-rdb}/.gitignore (100%) create mode 100644 nowait-domain/domain-core-rdb/build.gradle rename {domain-base/src/main/java/com/nowait/base => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/base/entity}/BaseTimeEntity.java (95%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/entity/Menu.java (94%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/entity/MenuImage.java (89%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/exception/MenuImageEmptyException.java (81%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/exception/MenuImageNotFoundException.java (81%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/exception/MenuNotFoundException.java (80%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/exception/MenuParamEmptyException.java (81%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/repository/MenuImageRepository.java (63%) rename {domain-menu/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/menu/repository/MenuRepository.java (81%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/entity/OrderItem.java (84%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/entity/UserOrder.java (89%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/exception/DepositorNameTooLongException.java (82%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/exception/DuplicateOrderException.java (80%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/exception/OrderItemsEmptyException.java (80%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/exception/OrderParameterEmptyException.java (81%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/repository/OrderItemRepository.java (65%) rename {domain-order/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/order/repository/OrderRepository.java (80%) rename {domain-reservation/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/reservation/entity/Reservation.java (90%) rename {domain-reservation/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/reservation/exception/ReservationNotFoundException.java (80%) rename {domain-reservation/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/reservation/repository/ReservationRepository.java (57%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/entity/Store.java (94%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/entity/StoreImage.java (89%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/exception/StoreImageEmptyException.java (80%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/exception/StoreImageNotFoundException.java (81%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/exception/StoreKeywordEmptyException.java (81%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/exception/StoreNotFoundException.java (80%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/exception/StoreParamEmptyException.java (81%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/repository/StoreImageRepository.java (63%) rename {domain-store/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/store/repository/StoreRepository.java (85%) rename {domain-token/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/token/entity/Token.java (89%) rename {domain-token/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/token/exception/BusinessException.java (87%) rename {domain-token/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/token/repository/TokenRepository.java (56%) rename {domain-user/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/user/entity/MemberDetails.java (96%) rename {domain-user/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/user/entity/User.java (97%) rename {domain-user/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/user/exception/UserNotFoundException.java (80%) rename {domain-user/src/main/java/com/nowait => nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb}/user/repository/UserRepository.java (61%) rename {domain-menu => nowait-domain/domain-user-rdb}/.gitignore (100%) rename {domain-order => nowait-domain/domain-user-rdb}/build.gradle (58%) rename {domain-bookmark/src/main/java/com/nowait => nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb}/bookmark/entity/Bookmark.java (84%) rename {domain-bookmark/src/main/java/com/nowait => nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb}/bookmark/exception/BookmarkOwnerMismatchException.java (80%) rename {domain-bookmark/src/main/java/com/nowait => nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb}/bookmark/exception/DuplicateBookmarkException.java (80%) rename {domain-bookmark/src/main/java/com/nowait => nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb}/bookmark/repository/BookmarkRepository.java (61%) rename {external-oauth/src/main/java/com/nowait/externaloauth => nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/oauth}/dto/CustomOAuth2User.java (92%) rename {common => nowait-infra}/.gitattributes (100%) rename {domain-order => nowait-infra}/.gitignore (100%) rename {infra-aws => nowait-infra}/build.gradle (93%) rename {infra-aws/src/main/java/com/nowait/infraaws => nowait-infra/src/main/java/com/nowait/infraaws/aws}/s3/S3Service.java (98%) rename {application-config/src/main/java/com/nowait/config => nowait-infra/src/main/java/com/nowait/infraaws}/config/AsyncConfig.java (94%) rename {infra-aws => nowait-infra}/src/main/java/com/nowait/infraaws/config/AwsS3Config.java (100%) delete mode 100644 security-admin/.gitattributes delete mode 100644 security-admin/.gitignore delete mode 100644 security-admin/build.gradle delete mode 100644 security-front/.gitignore delete mode 100644 security-front/build.gradle diff --git a/application-admin/src/main/java/com/nowait/applicationadmin/ApiAdminApplication.java b/application-admin/src/main/java/com/nowait/applicationadmin/ApiAdminApplication.java deleted file mode 100644 index 0e8b5c2f..00000000 --- a/application-admin/src/main/java/com/nowait/applicationadmin/ApiAdminApplication.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.nowait.applicationadmin; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; - -@EnableJpaAuditing -@SpringBootApplication(scanBasePackages = { - "com.nowait.applicationadmin", - "com.nowait.infraaws", - "com.nowait.adminsecurity", - "com.nowait.config", - "com.nowait.reservation" -}) -@EntityScan(basePackages = { - "com.nowait.menu.entity", - "com.nowait.store.entity", - "com.nowait.token.entity", - "com.nowait.user.entity", - "com.nowait.reservation.entity", - "com.nowait.order.entity" -}) -@EnableJpaRepositories(basePackages = { - "com.nowait.menu.repository", - "com.nowait.user.repository", - "com.nowait.store.repository", - "com.nowait.token.repository", - "com.nowait.order.repository", - "com.nowait.reservation.repository" -}) -public class ApiAdminApplication { - public static void main(String[] args) { - org.springframework.boot.SpringApplication.run(ApiAdminApplication.class, args); - } -} - diff --git a/application-config/build.gradle b/application-config/build.gradle deleted file mode 100644 index a6b89a70..00000000 --- a/application-config/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - id 'java-library' -} - -group = 'org.example' -version = '0.0.1-SNAPSHOT' - -repositories { - mavenCentral() -} - -dependencies { - api 'org.springframework.boot:spring-boot-starter-web' -} diff --git a/application-user/build.gradle b/application-user/build.gradle deleted file mode 100644 index cfa67b69..00000000 --- a/application-user/build.gradle +++ /dev/null @@ -1,59 +0,0 @@ -plugins { - id 'org.springframework.boot' version '3.5.0' - id 'io.spring.dependency-management' version '1.1.7' - id 'java' -} - -group = 'com.nowaiting' -version = '0.0.1-SNAPSHOT' - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } -} - -repositories { - mavenCentral() -} - -dependencies { - implementation project(':domain-user') // 도메인 계층 의존성 - implementation project(':domain-menu') // 메뉴 관련 도메인 - implementation project(':domain-base') // 시간 관련 도메인 - implementation project(':domain-store') // 주점 관련 도메인 - implementation project(':domain-token') // 토큰 관련 도메인 - implementation project(':domain-bookmark') // 북마크 관련 도메인 - implementation project(':domain-order') // 주문 관련 도메인 - implementation project(':domain-reservation') // 예약 관련 도메인 - implementation project(':infra-aws') // 사용자 관련 도메인 - implementation project(':security-front') // 사용자 관련 도메인 - implementation project(':external-oauth') // 외부 OAuth 관련 도메인 - implementation project(':application-config') - - // Spring Boot Starter - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-validation' - - // SPRING SECURITY - implementation 'org.springframework.boot:spring-boot-starter-security' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - - // DB - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - runtimeOnly 'com.mysql:mysql-connector-j' - - // SWAGGER - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' - - // 기타 필요 라이브러리 (예: Lombok) - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - - testImplementation 'org.springframework.boot:spring-boot-starter-test' -} - -test { - useJUnitPlatform() -} diff --git a/application-user/src/main/java/com/nowait/applicationuser/ApiUserApplication.java b/application-user/src/main/java/com/nowait/applicationuser/ApiUserApplication.java deleted file mode 100644 index fcfb659f..00000000 --- a/application-user/src/main/java/com/nowait/applicationuser/ApiUserApplication.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.nowait.applicationuser; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; - -@EnableJpaAuditing -@SpringBootApplication(scanBasePackages = { - "com.nowait.applicationuser", - "com.nowait.frontsecurity", - "com.nowait.externaloauth", - "com.nowait.config" -}) -@EntityScan(basePackages = { - "com.nowait.menu.entity", - "com.nowait.store.entity", - "com.nowait.token.entity", - "com.nowait.user.entity", - "com.nowait.bookmark.entity", - "com.nowait.reservation.entity", - "com.nowait.order.entity" -}) -@EnableJpaRepositories(basePackages = { - "com.nowait.menu.repository", - "com.nowait.user.repository", - "com.nowait.store.repository", - "com.nowait.token.repository", - "com.nowait.bookmark.repository", - "com.nowait.order.repository", - "com.nowait.reservation.repository" -}) -public class ApiUserApplication { - - public static void main(String[] args) { - SpringApplication.run(ApiUserApplication.class, args); - } - -} diff --git a/build.gradle b/build.gradle index 791934ae..03ccdb50 100644 --- a/build.gradle +++ b/build.gradle @@ -1,46 +1,30 @@ plugins { - id 'org.springframework.boot' version '3.5.0' apply false - id 'io.spring.dependency-management' version '1.1.7' apply false + id 'org.springframework.boot' version '3.5.0' + id 'io.spring.dependency-management' version '1.1.7' } -group = 'com.nowaiting' +group = 'com.nowait' version = '0.0.1-SNAPSHOT' repositories { mavenCentral() } +allprojects { + group = 'com.nowait' + version = '0.0.1-SNAPSHOT' +} + subprojects { - apply plugin: 'java' - apply plugin: 'org.springframework.boot' - apply plugin: 'io.spring.dependency-management' - - group = rootProject.group - version = rootProject.version - - // 실행 모듈만 따로 정의 - def applicationModules = ['application-admin', 'application-user'] - - if (applicationModules.contains(project.name)) { - // 실제 Service 실행 모듈 - apply plugin: 'org.springframework.boot' - bootJar { enabled = true } - jar { enabled = false } - } else { - // 라이브러리/설정/도메인 전용 모듈 - bootJar { enabled = false } - jar { enabled = true } - } + apply plugin: "java" + apply plugin: 'java-library' + apply plugin: "io.spring.dependency-management" + apply plugin: "org.springframework.boot" repositories { mavenCentral() } - java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } - } dependencyManagement { imports { @@ -48,12 +32,6 @@ subprojects { } } - if (project.name != 'common') { - dependencies { - implementation project(':common') - } - } - test { useJUnitPlatform() } diff --git a/common/build.gradle b/common/build.gradle deleted file mode 100644 index 44e9a75f..00000000 --- a/common/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -jar { - enabled = true -} -bootJar { - enabled = false -} - - -dependencies { -} diff --git a/domain-base/.gitattributes b/domain-base/.gitattributes deleted file mode 100644 index 8af972cd..00000000 --- a/domain-base/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -/gradlew text eol=lf -*.bat text eol=crlf -*.jar binary diff --git a/domain-base/build.gradle b/domain-base/build.gradle deleted file mode 100644 index 6ae34bc8..00000000 --- a/domain-base/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -plugins { - id 'java-library' -} - -group = 'com.nowaiting' -version = rootProject.version - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } -} - -repositories { - mavenCentral() -} - -dependencies { - // JPA Auditing 및 @MappedSuperclass 를 위한 - api 'org.springframework.boot:spring-boot-starter-data-jpa' - // JPA API - api 'jakarta.persistence:jakarta.persistence-api:3.1.0' - // Lombok - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - // Jackson - api 'com.fasterxml.jackson.core:jackson-databind:2.15.2' // Jackson 핵심 - api 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2' -} diff --git a/domain-bookmark/build.gradle b/domain-bookmark/build.gradle deleted file mode 100644 index 82ebe024..00000000 --- a/domain-bookmark/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'java-library' -} - -group = 'com.nowaiting' -version = rootProject.version - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } -} - -repositories { - mavenCentral() -} - -dependencies { - implementation project(':common') - implementation project(':domain-base') - implementation project(':domain-user') - implementation project(':domain-store') - - api 'org.springframework.boot:spring-boot-starter-data-jpa' - api 'jakarta.persistence:jakarta.persistence-api:3.1.0' - - compileOnly 'org.projectlombok:lombok:1.18.26' - annotationProcessor 'org.projectlombok:lombok:1.18.26' - - testImplementation 'org.junit.jupiter:junit-jupiter' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' -} diff --git a/domain-menu/.gitattributes b/domain-menu/.gitattributes deleted file mode 100644 index 8af972cd..00000000 --- a/domain-menu/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -/gradlew text eol=lf -*.bat text eol=crlf -*.jar binary diff --git a/domain-menu/gradle/wrapper/gradle-wrapper.jar b/domain-menu/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 1b33c55baabb587c669f562ae36f953de2481846..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43764 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 { diff --git a/domain-menu/src/main/java/com/nowait/menu/repository/MenuRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/menu/repository/MenuRepository.java similarity index 81% rename from domain-menu/src/main/java/com/nowait/menu/repository/MenuRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/menu/repository/MenuRepository.java index fbe2282b..80f07c95 100644 --- a/domain-menu/src/main/java/com/nowait/menu/repository/MenuRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/menu/repository/MenuRepository.java @@ -1,4 +1,4 @@ -package com.nowait.menu.repository; +package com.nowait.domaincorerdb.menu.repository; import java.util.List; import java.util.Optional; @@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.nowait.menu.entity.Menu; +import com.nowait.domaincorerdb.menu.entity.Menu; @Repository public interface MenuRepository extends JpaRepository { diff --git a/domain-order/src/main/java/com/nowait/order/entity/OrderItem.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/OrderItem.java similarity index 84% rename from domain-order/src/main/java/com/nowait/order/entity/OrderItem.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/OrderItem.java index a979933a..e23f943c 100644 --- a/domain-order/src/main/java/com/nowait/order/entity/OrderItem.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/OrderItem.java @@ -1,7 +1,7 @@ -package com.nowait.order.entity; +package com.nowait.domaincorerdb.order.entity; -import com.nowait.menu.entity.Menu; -import com.nowait.base.BaseTimeEntity; +import com.nowait.domaincorerdb.base.entity.BaseTimeEntity; +import com.nowait.domaincorerdb.menu.entity.Menu; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/domain-order/src/main/java/com/nowait/order/entity/UserOrder.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/UserOrder.java similarity index 89% rename from domain-order/src/main/java/com/nowait/order/entity/UserOrder.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/UserOrder.java index 06909f2c..3f2ae656 100644 --- a/domain-order/src/main/java/com/nowait/order/entity/UserOrder.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/UserOrder.java @@ -1,10 +1,10 @@ -package com.nowait.order.entity; +package com.nowait.domaincorerdb.order.entity; import java.util.ArrayList; import java.util.List; -import com.nowait.store.entity.Store; -import com.nowait.base.BaseTimeEntity; +import com.nowait.domaincorerdb.base.entity.BaseTimeEntity; +import com.nowait.domaincorerdb.store.entity.Store; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; diff --git a/domain-order/src/main/java/com/nowait/order/exception/DepositorNameTooLongException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/DepositorNameTooLongException.java similarity index 82% rename from domain-order/src/main/java/com/nowait/order/exception/DepositorNameTooLongException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/DepositorNameTooLongException.java index b5da206e..2767804f 100644 --- a/domain-order/src/main/java/com/nowait/order/exception/DepositorNameTooLongException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/DepositorNameTooLongException.java @@ -1,4 +1,4 @@ -package com.nowait.order.exception; +package com.nowait.domaincorerdb.order.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-order/src/main/java/com/nowait/order/exception/DuplicateOrderException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/DuplicateOrderException.java similarity index 80% rename from domain-order/src/main/java/com/nowait/order/exception/DuplicateOrderException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/DuplicateOrderException.java index aee663cd..c9311def 100644 --- a/domain-order/src/main/java/com/nowait/order/exception/DuplicateOrderException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/DuplicateOrderException.java @@ -1,4 +1,4 @@ -package com.nowait.order.exception; +package com.nowait.domaincorerdb.order.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-order/src/main/java/com/nowait/order/exception/OrderItemsEmptyException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/OrderItemsEmptyException.java similarity index 80% rename from domain-order/src/main/java/com/nowait/order/exception/OrderItemsEmptyException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/OrderItemsEmptyException.java index 416e101f..e3f6f730 100644 --- a/domain-order/src/main/java/com/nowait/order/exception/OrderItemsEmptyException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/OrderItemsEmptyException.java @@ -1,4 +1,4 @@ -package com.nowait.order.exception; +package com.nowait.domaincorerdb.order.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-order/src/main/java/com/nowait/order/exception/OrderParameterEmptyException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/OrderParameterEmptyException.java similarity index 81% rename from domain-order/src/main/java/com/nowait/order/exception/OrderParameterEmptyException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/OrderParameterEmptyException.java index 197814c4..b50ccece 100644 --- a/domain-order/src/main/java/com/nowait/order/exception/OrderParameterEmptyException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/exception/OrderParameterEmptyException.java @@ -1,4 +1,4 @@ -package com.nowait.order.exception; +package com.nowait.domaincorerdb.order.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-order/src/main/java/com/nowait/order/repository/OrderItemRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderItemRepository.java similarity index 65% rename from domain-order/src/main/java/com/nowait/order/repository/OrderItemRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderItemRepository.java index 7544e3d0..b7cbc6cf 100644 --- a/domain-order/src/main/java/com/nowait/order/repository/OrderItemRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderItemRepository.java @@ -1,9 +1,9 @@ -package com.nowait.order.repository; +package com.nowait.domaincorerdb.order.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.nowait.order.entity.OrderItem; +import com.nowait.domaincorerdb.order.entity.OrderItem; @Repository public interface OrderItemRepository extends JpaRepository { diff --git a/domain-order/src/main/java/com/nowait/order/repository/OrderRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderRepository.java similarity index 80% rename from domain-order/src/main/java/com/nowait/order/repository/OrderRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderRepository.java index e41b80de..b07c96dd 100644 --- a/domain-order/src/main/java/com/nowait/order/repository/OrderRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/repository/OrderRepository.java @@ -1,4 +1,4 @@ -package com.nowait.order.repository; +package com.nowait.domaincorerdb.order.repository; import java.time.LocalDateTime; import java.util.List; @@ -6,8 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.nowait.order.entity.UserOrder; - +import com.nowait.domaincorerdb.order.entity.UserOrder; @Repository public interface OrderRepository extends JpaRepository { boolean existsBySignatureAndCreatedAtAfter(String signature, LocalDateTime createdAt); diff --git a/domain-reservation/src/main/java/com/nowait/reservation/entity/Reservation.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/entity/Reservation.java similarity index 90% rename from domain-reservation/src/main/java/com/nowait/reservation/entity/Reservation.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/entity/Reservation.java index 67463687..219f002d 100644 --- a/domain-reservation/src/main/java/com/nowait/reservation/entity/Reservation.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/entity/Reservation.java @@ -1,10 +1,10 @@ -package com.nowait.reservation.entity; +package com.nowait.domaincorerdb.reservation.entity; import java.time.LocalDateTime; -import com.nowait.store.entity.Store; import com.nowait.common.enums.ReservationStatus; -import com.nowait.user.entity.User; +import com.nowait.domaincorerdb.store.entity.Store; +import com.nowait.domaincorerdb.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/domain-reservation/src/main/java/com/nowait/reservation/exception/ReservationNotFoundException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/exception/ReservationNotFoundException.java similarity index 80% rename from domain-reservation/src/main/java/com/nowait/reservation/exception/ReservationNotFoundException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/exception/ReservationNotFoundException.java index 3f65976f..4ce91721 100644 --- a/domain-reservation/src/main/java/com/nowait/reservation/exception/ReservationNotFoundException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/exception/ReservationNotFoundException.java @@ -1,4 +1,4 @@ -package com.nowait.reservation.exception; +package com.nowait.domaincorerdb.reservation.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-reservation/src/main/java/com/nowait/reservation/repository/ReservationRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/repository/ReservationRepository.java similarity index 57% rename from domain-reservation/src/main/java/com/nowait/reservation/repository/ReservationRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/repository/ReservationRepository.java index e564ff78..874469c8 100644 --- a/domain-reservation/src/main/java/com/nowait/reservation/repository/ReservationRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/repository/ReservationRepository.java @@ -1,11 +1,13 @@ -package com.nowait.reservation.repository; +package com.nowait.domaincorerdb.reservation.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; -import com.nowait.reservation.entity.Reservation; +import com.nowait.domaincorerdb.reservation.entity.Reservation; +@Repository public interface ReservationRepository extends JpaRepository { List findAllByStore_StoreIdOrderByRequestedAtAsc(Long storeId); } diff --git a/domain-store/src/main/java/com/nowait/store/entity/Store.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/Store.java similarity index 94% rename from domain-store/src/main/java/com/nowait/store/entity/Store.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/Store.java index c1458feb..08175e48 100644 --- a/domain-store/src/main/java/com/nowait/store/entity/Store.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/Store.java @@ -1,8 +1,8 @@ -package com.nowait.store.entity; +package com.nowait.domaincorerdb.store.entity; import java.time.LocalDateTime; -import com.nowait.base.BaseTimeEntity; +import com.nowait.domaincorerdb.base.entity.BaseTimeEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -12,7 +12,6 @@ import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; diff --git a/domain-store/src/main/java/com/nowait/store/entity/StoreImage.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/StoreImage.java similarity index 89% rename from domain-store/src/main/java/com/nowait/store/entity/StoreImage.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/StoreImage.java index d657bd7b..e8c5d270 100644 --- a/domain-store/src/main/java/com/nowait/store/entity/StoreImage.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/entity/StoreImage.java @@ -1,6 +1,6 @@ -package com.nowait.store.entity; +package com.nowait.domaincorerdb.store.entity; -import com.nowait.base.BaseTimeEntity; +import com.nowait.domaincorerdb.base.entity.BaseTimeEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/domain-store/src/main/java/com/nowait/store/exception/StoreImageEmptyException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreImageEmptyException.java similarity index 80% rename from domain-store/src/main/java/com/nowait/store/exception/StoreImageEmptyException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreImageEmptyException.java index 0f65bb1e..174cb8d0 100644 --- a/domain-store/src/main/java/com/nowait/store/exception/StoreImageEmptyException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreImageEmptyException.java @@ -1,4 +1,4 @@ -package com.nowait.store.exception; +package com.nowait.domaincorerdb.store.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-store/src/main/java/com/nowait/store/exception/StoreImageNotFoundException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreImageNotFoundException.java similarity index 81% rename from domain-store/src/main/java/com/nowait/store/exception/StoreImageNotFoundException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreImageNotFoundException.java index aff9e0c0..f1b49fd1 100644 --- a/domain-store/src/main/java/com/nowait/store/exception/StoreImageNotFoundException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreImageNotFoundException.java @@ -1,4 +1,4 @@ -package com.nowait.store.exception; +package com.nowait.domaincorerdb.store.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-store/src/main/java/com/nowait/store/exception/StoreKeywordEmptyException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreKeywordEmptyException.java similarity index 81% rename from domain-store/src/main/java/com/nowait/store/exception/StoreKeywordEmptyException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreKeywordEmptyException.java index 2b1fecc7..e69ad30b 100644 --- a/domain-store/src/main/java/com/nowait/store/exception/StoreKeywordEmptyException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreKeywordEmptyException.java @@ -1,4 +1,4 @@ -package com.nowait.store.exception; +package com.nowait.domaincorerdb.store.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-store/src/main/java/com/nowait/store/exception/StoreNotFoundException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreNotFoundException.java similarity index 80% rename from domain-store/src/main/java/com/nowait/store/exception/StoreNotFoundException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreNotFoundException.java index 15d485db..ded420e0 100644 --- a/domain-store/src/main/java/com/nowait/store/exception/StoreNotFoundException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreNotFoundException.java @@ -1,4 +1,4 @@ -package com.nowait.store.exception; +package com.nowait.domaincorerdb.store.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-store/src/main/java/com/nowait/store/exception/StoreParamEmptyException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreParamEmptyException.java similarity index 81% rename from domain-store/src/main/java/com/nowait/store/exception/StoreParamEmptyException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreParamEmptyException.java index 5dc0bf13..c33bc1bb 100644 --- a/domain-store/src/main/java/com/nowait/store/exception/StoreParamEmptyException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/exception/StoreParamEmptyException.java @@ -1,4 +1,4 @@ -package com.nowait.store.exception; +package com.nowait.domaincorerdb.store.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-store/src/main/java/com/nowait/store/repository/StoreImageRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreImageRepository.java similarity index 63% rename from domain-store/src/main/java/com/nowait/store/repository/StoreImageRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreImageRepository.java index 0617122e..80448ab8 100644 --- a/domain-store/src/main/java/com/nowait/store/repository/StoreImageRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreImageRepository.java @@ -1,12 +1,12 @@ -package com.nowait.store.repository; +package com.nowait.domaincorerdb.store.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.nowait.store.entity.Store; -import com.nowait.store.entity.StoreImage; +import com.nowait.domaincorerdb.store.entity.Store; +import com.nowait.domaincorerdb.store.entity.StoreImage; @Repository public interface StoreImageRepository extends JpaRepository { diff --git a/domain-store/src/main/java/com/nowait/store/repository/StoreRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreRepository.java similarity index 85% rename from domain-store/src/main/java/com/nowait/store/repository/StoreRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreRepository.java index a0d04ffb..efeec3ca 100644 --- a/domain-store/src/main/java/com/nowait/store/repository/StoreRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/store/repository/StoreRepository.java @@ -1,4 +1,5 @@ -package com.nowait.store.repository; +package com.nowait.domaincorerdb.store.repository; + import java.util.List; import java.util.Optional; @@ -8,7 +9,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.nowait.store.entity.Store; +import com.nowait.domaincorerdb.store.entity.Store; @Repository public interface StoreRepository extends JpaRepository { diff --git a/domain-token/src/main/java/com/nowait/token/entity/Token.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/entity/Token.java similarity index 89% rename from domain-token/src/main/java/com/nowait/token/entity/Token.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/entity/Token.java index 16311bfa..14378dd6 100644 --- a/domain-token/src/main/java/com/nowait/token/entity/Token.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/entity/Token.java @@ -1,8 +1,8 @@ -package com.nowait.token.entity; +package com.nowait.domaincorerdb.token.entity; import java.time.LocalDateTime; -import com.nowait.user.entity.User; +import com.nowait.domaincorerdb.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -23,7 +23,8 @@ @Table(name = "token") @Getter public class Token { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long tokenId; @ManyToOne(fetch = FetchType.LAZY) diff --git a/domain-token/src/main/java/com/nowait/token/exception/BusinessException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/exception/BusinessException.java similarity index 87% rename from domain-token/src/main/java/com/nowait/token/exception/BusinessException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/exception/BusinessException.java index b9df2243..86886330 100644 --- a/domain-token/src/main/java/com/nowait/token/exception/BusinessException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/exception/BusinessException.java @@ -1,4 +1,4 @@ -package com.nowait.token.exception; +package com.nowait.domaincorerdb.token.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-token/src/main/java/com/nowait/token/repository/TokenRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/repository/TokenRepository.java similarity index 56% rename from domain-token/src/main/java/com/nowait/token/repository/TokenRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/repository/TokenRepository.java index 53d49d76..ab74bc46 100644 --- a/domain-token/src/main/java/com/nowait/token/repository/TokenRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/token/repository/TokenRepository.java @@ -1,11 +1,13 @@ -package com.nowait.token.repository; +package com.nowait.domaincorerdb.token.repository; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; -import com.nowait.token.entity.Token; +import com.nowait.domaincorerdb.token.entity.Token; +@Repository public interface TokenRepository extends JpaRepository { Optional findByUserId(Long userId); } diff --git a/domain-user/src/main/java/com/nowait/user/entity/MemberDetails.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/entity/MemberDetails.java similarity index 96% rename from domain-user/src/main/java/com/nowait/user/entity/MemberDetails.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/entity/MemberDetails.java index 247b5ae8..f9bc7b3f 100644 --- a/domain-user/src/main/java/com/nowait/user/entity/MemberDetails.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/entity/MemberDetails.java @@ -1,4 +1,4 @@ -package com.nowait.user.entity; +package com.nowait.domaincorerdb.user.entity; import java.util.Collection; import java.util.List; diff --git a/domain-user/src/main/java/com/nowait/user/entity/User.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/entity/User.java similarity index 97% rename from domain-user/src/main/java/com/nowait/user/entity/User.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/entity/User.java index 71e68ecb..0bb965f4 100644 --- a/domain-user/src/main/java/com/nowait/user/entity/User.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/entity/User.java @@ -1,4 +1,4 @@ -package com.nowait.user.entity; +package com.nowait.domaincorerdb.user.entity; import org.springframework.security.crypto.password.PasswordEncoder; diff --git a/domain-user/src/main/java/com/nowait/user/exception/UserNotFoundException.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/exception/UserNotFoundException.java similarity index 80% rename from domain-user/src/main/java/com/nowait/user/exception/UserNotFoundException.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/exception/UserNotFoundException.java index 74788aa9..aef89ab3 100644 --- a/domain-user/src/main/java/com/nowait/user/exception/UserNotFoundException.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/exception/UserNotFoundException.java @@ -1,4 +1,4 @@ -package com.nowait.user.exception; +package com.nowait.domaincorerdb.user.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-user/src/main/java/com/nowait/user/repository/UserRepository.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/repository/UserRepository.java similarity index 61% rename from domain-user/src/main/java/com/nowait/user/repository/UserRepository.java rename to nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/repository/UserRepository.java index 331264a3..b22b9fc9 100644 --- a/domain-user/src/main/java/com/nowait/user/repository/UserRepository.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/user/repository/UserRepository.java @@ -1,11 +1,13 @@ -package com.nowait.user.repository; +package com.nowait.domaincorerdb.user.repository; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; -import com.nowait.user.entity.User; +import com.nowait.domaincorerdb.user.entity.User; +@Repository public interface UserRepository extends JpaRepository { Optional findByEmail(String email); Optional findByNickname(String nickName); diff --git a/domain-menu/.gitignore b/nowait-domain/domain-user-rdb/.gitignore similarity index 100% rename from domain-menu/.gitignore rename to nowait-domain/domain-user-rdb/.gitignore diff --git a/domain-order/build.gradle b/nowait-domain/domain-user-rdb/build.gradle similarity index 58% rename from domain-order/build.gradle rename to nowait-domain/domain-user-rdb/build.gradle index 263db1df..09aa35f3 100644 --- a/domain-order/build.gradle +++ b/nowait-domain/domain-user-rdb/build.gradle @@ -2,6 +2,14 @@ plugins { id 'java-library' } +jar { + enabled = true +} +bootJar { + enabled = false +} + + group = 'com.nowaiting' version = rootProject.version @@ -16,14 +24,17 @@ repositories { } dependencies { - implementation project(':common') - implementation project(':domain-base') - implementation project(':domain-store') - implementation project(':domain-menu') + implementation project(':nowait-common') + implementation project(':nowait-domain:domain-core-rdb') api 'org.springframework.boot:spring-boot-starter-data-jpa' api 'jakarta.persistence:jakarta.persistence-api:3.1.0' + // OAuth + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' + implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0' + compileOnly 'org.projectlombok:lombok:1.18.26' annotationProcessor 'org.projectlombok:lombok:1.18.26' diff --git a/domain-bookmark/src/main/java/com/nowait/bookmark/entity/Bookmark.java b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/entity/Bookmark.java similarity index 84% rename from domain-bookmark/src/main/java/com/nowait/bookmark/entity/Bookmark.java rename to nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/entity/Bookmark.java index d1808277..1f5b3fa2 100644 --- a/domain-bookmark/src/main/java/com/nowait/bookmark/entity/Bookmark.java +++ b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/entity/Bookmark.java @@ -1,8 +1,8 @@ -package com.nowait.bookmark.entity; +package com.nowait.domainuserrdb.bookmark.entity; -import com.nowait.store.entity.Store; -import com.nowait.base.BaseTimeEntity; -import com.nowait.user.entity.User; +import com.nowait.domaincorerdb.base.entity.BaseTimeEntity; +import com.nowait.domaincorerdb.store.entity.Store; +import com.nowait.domaincorerdb.user.entity.User; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/domain-bookmark/src/main/java/com/nowait/bookmark/exception/BookmarkOwnerMismatchException.java b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/exception/BookmarkOwnerMismatchException.java similarity index 80% rename from domain-bookmark/src/main/java/com/nowait/bookmark/exception/BookmarkOwnerMismatchException.java rename to nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/exception/BookmarkOwnerMismatchException.java index dcb2549a..0f7cdd9f 100644 --- a/domain-bookmark/src/main/java/com/nowait/bookmark/exception/BookmarkOwnerMismatchException.java +++ b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/exception/BookmarkOwnerMismatchException.java @@ -1,4 +1,4 @@ -package com.nowait.bookmark.exception; +package com.nowait.domainuserrdb.bookmark.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-bookmark/src/main/java/com/nowait/bookmark/exception/DuplicateBookmarkException.java b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/exception/DuplicateBookmarkException.java similarity index 80% rename from domain-bookmark/src/main/java/com/nowait/bookmark/exception/DuplicateBookmarkException.java rename to nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/exception/DuplicateBookmarkException.java index d18b4371..7b9ef268 100644 --- a/domain-bookmark/src/main/java/com/nowait/bookmark/exception/DuplicateBookmarkException.java +++ b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/exception/DuplicateBookmarkException.java @@ -1,4 +1,4 @@ -package com.nowait.bookmark.exception; +package com.nowait.domainuserrdb.bookmark.exception; import com.nowait.common.exception.ErrorMessage; diff --git a/domain-bookmark/src/main/java/com/nowait/bookmark/repository/BookmarkRepository.java b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/repository/BookmarkRepository.java similarity index 61% rename from domain-bookmark/src/main/java/com/nowait/bookmark/repository/BookmarkRepository.java rename to nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/repository/BookmarkRepository.java index e5a2a10d..69526299 100644 --- a/domain-bookmark/src/main/java/com/nowait/bookmark/repository/BookmarkRepository.java +++ b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/bookmark/repository/BookmarkRepository.java @@ -1,13 +1,13 @@ -package com.nowait.bookmark.repository; +package com.nowait.domainuserrdb.bookmark.repository; import java.util.Collection; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import com.nowait.store.entity.Store; -import com.nowait.bookmark.entity.Bookmark; -import com.nowait.user.entity.User; +import com.nowait.domaincorerdb.store.entity.Store; +import com.nowait.domaincorerdb.user.entity.User; +import com.nowait.domainuserrdb.bookmark.entity.Bookmark; @Repository public interface BookmarkRepository extends JpaRepository { diff --git a/external-oauth/src/main/java/com/nowait/externaloauth/dto/CustomOAuth2User.java b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/oauth/dto/CustomOAuth2User.java similarity index 92% rename from external-oauth/src/main/java/com/nowait/externaloauth/dto/CustomOAuth2User.java rename to nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/oauth/dto/CustomOAuth2User.java index 41a5b1b1..f163bca7 100644 --- a/external-oauth/src/main/java/com/nowait/externaloauth/dto/CustomOAuth2User.java +++ b/nowait-domain/domain-user-rdb/src/main/java/com/nowait/domainuserrdb/oauth/dto/CustomOAuth2User.java @@ -1,4 +1,4 @@ -package com.nowait.externaloauth.dto; +package com.nowait.domainuserrdb.oauth.dto; import java.util.ArrayList; import java.util.Collection; @@ -7,7 +7,7 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.core.user.OAuth2User; -import com.nowait.user.entity.User; +import com.nowait.domaincorerdb.user.entity.User; import lombok.RequiredArgsConstructor; diff --git a/common/.gitattributes b/nowait-infra/.gitattributes similarity index 100% rename from common/.gitattributes rename to nowait-infra/.gitattributes diff --git a/domain-order/.gitignore b/nowait-infra/.gitignore similarity index 100% rename from domain-order/.gitignore rename to nowait-infra/.gitignore diff --git a/infra-aws/build.gradle b/nowait-infra/build.gradle similarity index 93% rename from infra-aws/build.gradle rename to nowait-infra/build.gradle index c4a109cf..aa478c84 100644 --- a/infra-aws/build.gradle +++ b/nowait-infra/build.gradle @@ -2,6 +2,14 @@ plugins { id 'java' } +jar { + enabled = true +} +bootJar { + enabled = false +} + + group = 'com.nowaiting' version = rootProject.version @@ -19,13 +27,13 @@ dependencies { // Multipart File Upload // 추후 분리 필요 implementation 'org.springframework.boot:spring-boot-starter-web' + // 비동기 실행 + implementation 'org.springframework.boot:spring-boot-starter-aop' // S3 implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' // Resilience4j implementation 'io.github.resilience4j:resilience4j-spring-boot3:2.2.0' implementation 'io.github.resilience4j:resilience4j-bulkhead:2.3.0' - // 비동기 실행 - implementation 'org.springframework.boot:spring-boot-starter-aop' // lombok compileOnly 'org.projectlombok:lombok:1.18.30' annotationProcessor 'org.projectlombok:lombok:1.18.30' diff --git a/infra-aws/src/main/java/com/nowait/infraaws/s3/S3Service.java b/nowait-infra/src/main/java/com/nowait/infraaws/aws/s3/S3Service.java similarity index 98% rename from infra-aws/src/main/java/com/nowait/infraaws/s3/S3Service.java rename to nowait-infra/src/main/java/com/nowait/infraaws/aws/s3/S3Service.java index a2c586fc..18416c32 100644 --- a/infra-aws/src/main/java/com/nowait/infraaws/s3/S3Service.java +++ b/nowait-infra/src/main/java/com/nowait/infraaws/aws/s3/S3Service.java @@ -1,4 +1,4 @@ -package com.nowait.infraaws.s3; +package com.nowait.infraaws.aws.s3; import java.io.InputStream; import java.util.UUID; diff --git a/application-config/src/main/java/com/nowait/config/config/AsyncConfig.java b/nowait-infra/src/main/java/com/nowait/infraaws/config/AsyncConfig.java similarity index 94% rename from application-config/src/main/java/com/nowait/config/config/AsyncConfig.java rename to nowait-infra/src/main/java/com/nowait/infraaws/config/AsyncConfig.java index 0d63871f..78ea0dbe 100644 --- a/application-config/src/main/java/com/nowait/config/config/AsyncConfig.java +++ b/nowait-infra/src/main/java/com/nowait/infraaws/config/AsyncConfig.java @@ -1,4 +1,4 @@ -package com.nowait.config.config; +package com.nowait.infraaws.config; import java.util.concurrent.Executor; diff --git a/infra-aws/src/main/java/com/nowait/infraaws/config/AwsS3Config.java b/nowait-infra/src/main/java/com/nowait/infraaws/config/AwsS3Config.java similarity index 100% rename from infra-aws/src/main/java/com/nowait/infraaws/config/AwsS3Config.java rename to nowait-infra/src/main/java/com/nowait/infraaws/config/AwsS3Config.java diff --git a/security-admin/.gitattributes b/security-admin/.gitattributes deleted file mode 100644 index 8af972cd..00000000 --- a/security-admin/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -/gradlew text eol=lf -*.bat text eol=crlf -*.jar binary diff --git a/security-admin/.gitignore b/security-admin/.gitignore deleted file mode 100644 index c2065bc2..00000000 --- a/security-admin/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/security-admin/build.gradle b/security-admin/build.gradle deleted file mode 100644 index 9c9de646..00000000 --- a/security-admin/build.gradle +++ /dev/null @@ -1,38 +0,0 @@ -plugins { - id 'java-library' -} - -group = 'com.nowaiting' -version = rootProject.version - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } -} - -repositories { - mavenCentral() -} - -dependencies { - implementation project(':common') - implementation project(':domain-user') - implementation project(':domain-base') - implementation project(':domain-token') - implementation project(':application-config') - // SPRING SECURITY - api 'org.springframework.boot:spring-boot-starter-security' - api 'org.springframework.boot:spring-boot-starter-test' - // Lombok (optional) - compileOnly 'org.projectlombok:lombok:1.18.26' - annotationProcessor 'org.projectlombok:lombok:1.18.26' - // jwt - implementation 'io.jsonwebtoken:jjwt-api:0.12.3' - implementation 'io.jsonwebtoken:jjwt-impl:0.12.3' - implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3' - implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0' - implementation 'com.auth0:java-jwt:4.4.0' - // SWAGGER - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' -} diff --git a/security-front/.gitignore b/security-front/.gitignore deleted file mode 100644 index c2065bc2..00000000 --- a/security-front/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/security-front/build.gradle b/security-front/build.gradle deleted file mode 100644 index 6201e438..00000000 --- a/security-front/build.gradle +++ /dev/null @@ -1,41 +0,0 @@ -plugins { - id 'java-library' -} - -group = 'com.nowaiting' -version = rootProject.version - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } -} - -repositories { - mavenCentral() -} - -dependencies { - implementation project(':common') - implementation project(':domain-user') - implementation project(':domain-base') - implementation project(':domain-token') - implementation project(':external-oauth') - implementation project(':application-config') - // SPRING SECURITY - api 'org.springframework.boot:spring-boot-starter-security' - api 'org.springframework.boot:spring-boot-starter-test' - // Lombok (optional) - compileOnly 'org.projectlombok:lombok:1.18.26' - annotationProcessor 'org.projectlombok:lombok:1.18.26' - // jwt - implementation 'io.jsonwebtoken:jjwt-api:0.12.3' - implementation 'io.jsonwebtoken:jjwt-impl:0.12.3' - implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3' - // OAUTH2 - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' - implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0' - // SWAGGER - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' -} diff --git a/settings.gradle b/settings.gradle index 4984deb9..24f20718 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,19 +1,9 @@ rootProject.name = 'nowait' -include 'common' -include 'domain-base' -include 'domain-user' -include 'domain-menu' -include 'domain-store' -include 'domain-token' -include 'domain-bookmark' -include 'domain-order' -include 'domain-reservation' -include 'security-admin' -include 'security-front' -include 'external-oauth' -include 'infra-aws' -include 'application-config' -include 'application-user' -include 'application-admin' - +include 'nowait-app-user-api' +include 'nowait-app-admin-api' +include 'nowait-common' +include 'nowait-domain:domain-core-rdb' +include 'nowait-domain:domain-admin-rdb' +include 'nowait-domain:domain-user-rdb' +include 'nowait-infra' From ca8b1405f7104e34101d60c48345fae5eafb6752 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 4 Jul 2025 22:02:45 +0900 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EA=B5=AC=EC=A1=B0=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-admin.yml | 21 ++++++++++----------- .github/workflows/deploy-user.yml | 21 ++++++++++----------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/.github/workflows/deploy-admin.yml b/.github/workflows/deploy-admin.yml index 5d28a479..39de4768 100644 --- a/.github/workflows/deploy-admin.yml +++ b/.github/workflows/deploy-admin.yml @@ -5,12 +5,11 @@ on: branches: - develop paths: - - 'application-admin/**' - - 'application-config/**' - - 'common/**' - - 'domain-*/**' - - 'security-admin/**' - - 'infra-aws/**' + - 'nowait-app-admin-api/**' + - 'nowait-common/**' + - 'nowait-domain/domain-core-rdb/**' + - 'nowait-domain/domain-admin-rdb/**' + - 'nowait-infra/**' - 'build.gradle' - 'settings.gradle' - 'gradle/**' @@ -41,14 +40,14 @@ jobs: - name: Set YML run: | - mkdir -p application-admin/src/main/resources + mkdir -p nowait-app-admin-api/src/main/resources echo "${{ secrets.APPLICATION_DEV_ADMIN_YML }}" \ | base64 --decode \ - > application-admin/src/main/resources/application-admin.yml - find application-admin/src + > nowait-app-admin-api/src/main/resources/application-admin.yml + find nowait-app-admin-api/src - name: Build Admin JAR - run: ./gradlew clean :application-admin:bootJar -x test + run: ./gradlew clean :nowait-app-admin-api:bootJar -x test - name: Prepare deployment package run: | @@ -56,7 +55,7 @@ jobs: mkdir -p deploy/scripts cp scripts/start-admin.sh scripts/stop-admin.sh deploy/scripts/ cp appspec-admin.yml deploy/appspec.yml - cp application-admin/build/libs/application-admin-*.jar deploy/application-admin.jar + cp nowait-app-admin-api/build/libs/nowait-app-admin-api-*.jar deploy/nowait-app-admin-api.jar cd deploy zip -r ../NoWait-admin-${GITHUB_SHA}.zip . cd .. diff --git a/.github/workflows/deploy-user.yml b/.github/workflows/deploy-user.yml index f5162197..70f31909 100644 --- a/.github/workflows/deploy-user.yml +++ b/.github/workflows/deploy-user.yml @@ -5,12 +5,11 @@ on: branches: - develop paths: - - 'application-user/**' - - 'application-config/**' - - 'common/**' - - 'domain-*/**' - - 'security-front/**' - - 'external-oauth/**' + - 'nowait-app-user-api/**' + - 'nowait-common/**' + - 'nowait-domain/domain-core-rdb/**' + - 'nowait-domain/domain-user-rdb/**' + - 'nowait-infra/**' - 'build.gradle' - 'settings.gradle' - 'gradle/**' @@ -41,14 +40,14 @@ jobs: - name: Set YML run: | - mkdir -p application-user/src/main/resources + mkdir -p nowait-app-user-api/src/main/resources echo "${{ secrets.APPLICATION_DEV_USER_YML }}" \ | base64 --decode \ - > application-user/src/main/resources/application-user.yml - find application-user/src + > nowait-app-user-api/src/main/resources/nowait-app-user-api.yml + find nowait-app-user-api/src - name: Build User JAR - run: ./gradlew clean :application-user:bootJar -x test + run: ./gradlew clean :nowait-app-user-api:bootJar -x test - name: Prepare deployment package run: | @@ -56,7 +55,7 @@ jobs: mkdir -p deploy/scripts cp scripts/start-user.sh scripts/stop-user.sh deploy/scripts/ cp appspec-user.yml deploy/appspec.yml - cp application-user/build/libs/application-user-*.jar deploy/application-user.jar + cp nowait-app-user-api/build/libs/nowait-app-user-api-*.jar deploy/nowait-app-user-api.jar cd deploy zip -r ../NoWait-user-${GITHUB_SHA}.zip . cd .. From 48cc4fcbcdffec91c1b5c8e253bba7f2896188f0 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 4 Jul 2025 22:37:44 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EA=B5=AC=EC=A1=B0=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-admin.yml | 16 ++++++++-------- .github/workflows/deploy-user.yml | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/deploy-admin.yml b/.github/workflows/deploy-admin.yml index 39de4768..5c9889c2 100644 --- a/.github/workflows/deploy-admin.yml +++ b/.github/workflows/deploy-admin.yml @@ -5,14 +5,14 @@ on: branches: - develop paths: - - 'nowait-app-admin-api/**' - - 'nowait-common/**' - - 'nowait-domain/domain-core-rdb/**' - - 'nowait-domain/domain-admin-rdb/**' - - 'nowait-infra/**' - - 'build.gradle' - - 'settings.gradle' - - 'gradle/**' + - 'nowait-app-admin-api/**' + - 'nowait-common/**' + - 'nowait-domain/domain-core-rdb/**' + - 'nowait-domain/domain-admin-rdb/**' + - 'nowait-infra/**' + - 'build.gradle' + - 'settings.gradle' + - 'gradle/**' env: PROJECT_NAME: NoWait diff --git a/.github/workflows/deploy-user.yml b/.github/workflows/deploy-user.yml index 70f31909..67b2f28f 100644 --- a/.github/workflows/deploy-user.yml +++ b/.github/workflows/deploy-user.yml @@ -5,14 +5,14 @@ on: branches: - develop paths: - - 'nowait-app-user-api/**' - - 'nowait-common/**' - - 'nowait-domain/domain-core-rdb/**' - - 'nowait-domain/domain-user-rdb/**' - - 'nowait-infra/**' - - 'build.gradle' - - 'settings.gradle' - - 'gradle/**' + - 'nowait-app-user-api/**' + - 'nowait-common/**' + - 'nowait-domain/domain-core-rdb/**' + - 'nowait-domain/domain-user-rdb/**' + - 'nowait-infra/**' + - 'build.gradle' + - 'settings.gradle' + - 'gradle/**' env: PROJECT_NAME: NoWait From 28ba7b8fb7f576b77f690f9bc0f5f585d8ea0eb6 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 4 Jul 2025 22:38:12 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat(order):=20=EA=B4=80=EB=A6=AC=EC=9E=90?= =?UTF-8?q?=20Order=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/controller/OrderController.java | 2 +- .../order/dto/OrderResponseDto.java | 31 ++++++++++++++++ .../dto/OrderStatusUpdateRequestDto.java | 16 +++++++++ .../dto/OrderStatusUpdateResponseDto.java | 17 +++++++++ .../order/service/OrderService.java | 36 +++++++++++++++++++ .../order/service/OrderService.java | 1 + .../order/entity/OrderStatus.java | 2 +- 7 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java create mode 100644 nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java create mode 100644 nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java create mode 100644 nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/controller/OrderController.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/controller/OrderController.java index 775306e8..dfc03619 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/controller/OrderController.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/controller/OrderController.java @@ -25,7 +25,7 @@ @Tag(name = "Order API", description = "주문 API") @RestController -@RequestMapping("admin/orders") +@RequestMapping("/admin/orders") @RequiredArgsConstructor public class OrderController { diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java new file mode 100644 index 00000000..f5e93610 --- /dev/null +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java @@ -0,0 +1,31 @@ +package com.nowait.applicationadmin.order.dto; + +import java.time.LocalDateTime; + +import com.nowait.domaincorerdb.order.entity.OrderStatus; +import com.nowait.domaincorerdb.order.entity.UserOrder; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class OrderResponseDto { + private Long id; + private Long tableId; + private String depositorName; + private Integer totalPrice; + private OrderStatus status; + private LocalDateTime createdAt; + + public static OrderResponseDto fromEntity(UserOrder userOrder) { + return OrderResponseDto.builder() + .id(userOrder.getId()) + .tableId(userOrder.getTableId()) + .depositorName(userOrder.getDepositorName()) + .totalPrice(userOrder.getTotalPrice()) + .status(userOrder.getStatus()) + .createdAt(userOrder.getCreatedAt()) + .build(); + } +} diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java new file mode 100644 index 00000000..a28f0434 --- /dev/null +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java @@ -0,0 +1,16 @@ +package com.nowait.applicationadmin.order.dto; + +import com.nowait.domaincorerdb.order.entity.OrderStatus; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class OrderStatusUpdateRequestDto { + @Schema(description = "주문 상태", example = "WAITING_FOR_PAYMENT", allowableValues = {"WAITING_FOR_PAYMENT", "COOKING", "COOKED"}) + @NotNull(message = "주문상태는 필수입니다") + private final OrderStatus orderStatus; +} diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java new file mode 100644 index 00000000..dfcec919 --- /dev/null +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java @@ -0,0 +1,17 @@ +package com.nowait.applicationadmin.order.dto; + +import com.nowait.domaincorerdb.order.entity.OrderStatus; +import com.nowait.domaincorerdb.order.entity.UserOrder; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class OrderStatusUpdateResponseDto { + private final OrderStatus orderStatus; + + public static OrderStatusUpdateResponseDto fromEntity(UserOrder userOrder) { + return new OrderStatusUpdateResponseDto(userOrder.getStatus()); + } +} diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java new file mode 100644 index 00000000..41418531 --- /dev/null +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java @@ -0,0 +1,36 @@ +package com.nowait.applicationadmin.order.service; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.nowait.applicationadmin.order.dto.OrderResponseDto; +import com.nowait.applicationadmin.order.dto.OrderStatusUpdateResponseDto; +import com.nowait.domaincorerdb.order.entity.OrderStatus; +import com.nowait.domaincorerdb.order.entity.UserOrder; +import com.nowait.domaincorerdb.order.repository.OrderRepository; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class OrderService { + private final OrderRepository orderRepository; + + @Transactional(readOnly = true) + public List findAllOrders(Long storeId) { + return orderRepository.findAllByStore_StoreId(storeId).stream() + .map(OrderResponseDto::fromEntity) + .collect(Collectors.toList()); + } + + @Transactional + public OrderStatusUpdateResponseDto updateOrderStatus(Long orderId, OrderStatus newStatus) { + UserOrder userOrder = orderRepository.findById(orderId) + .orElseThrow(() -> new IllegalArgumentException("Order not found with id: " + orderId)); + userOrder.updateStatus(newStatus); + return OrderStatusUpdateResponseDto.fromEntity(userOrder); + } +} diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java index a3f59ebf..1f0ed53c 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java @@ -18,6 +18,7 @@ import com.nowait.domaincorerdb.menu.entity.Menu; import com.nowait.domaincorerdb.menu.repository.MenuRepository; import com.nowait.domaincorerdb.order.entity.OrderItem; +import com.nowait.domaincorerdb.order.entity.OrderStatus; import com.nowait.domaincorerdb.order.entity.UserOrder; import com.nowait.domaincorerdb.order.exception.DuplicateOrderException; import com.nowait.domaincorerdb.order.exception.OrderItemsEmptyException; diff --git a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/OrderStatus.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/OrderStatus.java index 7a111111..98b50744 100644 --- a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/OrderStatus.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/order/entity/OrderStatus.java @@ -1,4 +1,4 @@ -package com.nowait.order.entity; +package com.nowait.domaincorerdb.order.entity; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; From 012c9f699b4b669ff1afbecd53c7d02bcd35d42b Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 4 Jul 2025 22:38:33 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/dto/OrderResponseDto.java | 33 ----------- .../dto/OrderStatusUpdateRequestDto.java | 16 ------ .../dto/OrderStatusUpdateResponseDto.java | 17 ------ .../order/service/OrderService.java | 37 ------------ application-config/build.gradle | 0 .../applicationconfig/config/AsyncConfig.java | 21 ------- .../applicationconfig/config/CorsConfig.java | 28 --------- .../nowait/config/config/SwaggerConfig.java | 30 ---------- build.gradle | 4 +- .../com/example/domaintoken/entity/Token.java | 54 ------------------ .../exception/BusinessException.java | 16 ------ .../repository/TokenRepository.java | 11 ---- .../infrastorage/config/AwsS3Config.java | 33 ----------- .../example/infrastorage/s3/S3Service.java | 57 ------------------- nowait-app-admin-api/build.gradle | 9 ++- nowait-app-user-api/build.gradle | 7 +-- nowait-common/build.gradle | 3 - nowait-domain/build.gradle | 6 +- nowait-domain/domain-admin-rdb/build.gradle | 3 - nowait-domain/domain-core-rdb/build.gradle | 7 +-- nowait-domain/domain-user-rdb/build.gradle | 6 +- nowait-infra/build.gradle | 3 - 22 files changed, 18 insertions(+), 383 deletions(-) delete mode 100644 application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java delete mode 100644 application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java delete mode 100644 application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java delete mode 100644 application-admin/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java delete mode 100644 application-config/build.gradle delete mode 100644 application-config/src/main/java/com/example/applicationconfig/config/AsyncConfig.java delete mode 100644 application-config/src/main/java/com/example/applicationconfig/config/CorsConfig.java delete mode 100644 application-config/src/main/java/com/nowait/config/config/SwaggerConfig.java delete mode 100644 domain-token/src/main/java/com/example/domaintoken/entity/Token.java delete mode 100644 domain-token/src/main/java/com/example/domaintoken/exception/BusinessException.java delete mode 100644 domain-token/src/main/java/com/example/domaintoken/repository/TokenRepository.java delete mode 100644 infra-aws/src/main/java/com/example/infrastorage/config/AwsS3Config.java delete mode 100644 infra-aws/src/main/java/com/example/infrastorage/s3/S3Service.java diff --git a/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java b/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java deleted file mode 100644 index afb2a079..00000000 --- a/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderResponseDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.nowait.applicationadmin.order.dto; - -import java.time.LocalDateTime; - -import com.nowait.applicationadmin.reservation.dto.ReservationGetResponseDto; -import com.nowait.order.entity.UserOrder; -import com.nowait.order.entity.OrderStatus; -import com.nowait.reservation.entity.Reservation; - -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class OrderResponseDto { - private Long id; - private Long tableId; - private String depositorName; - private Integer totalPrice; - private OrderStatus status; - private LocalDateTime createdAt; - - public static OrderResponseDto fromEntity(UserOrder userOrder) { - return OrderResponseDto.builder() - .id(userOrder.getId()) - .tableId(userOrder.getTableId()) - .depositorName(userOrder.getDepositorName()) - .totalPrice(userOrder.getTotalPrice()) - .status(userOrder.getStatus()) - .createdAt(userOrder.getCreatedAt()) - .build(); - } -} diff --git a/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java b/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java deleted file mode 100644 index a8a78442..00000000 --- a/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateRequestDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.nowait.applicationadmin.order.dto; - -import com.nowait.order.entity.OrderStatus; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public class OrderStatusUpdateRequestDto { - @Schema(description = "주문 상태", example = "WAITING_FOR_PAYMENT", allowableValues = {"WAITING_FOR_PAYMENT", "COOKING", "COOKED"}) - @NotNull(message = "주문상태는 필수입니다") - private final OrderStatus orderStatus; -} diff --git a/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java b/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java deleted file mode 100644 index 63de5b53..00000000 --- a/application-admin/src/main/java/com/nowait/applicationadmin/order/dto/OrderStatusUpdateResponseDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.nowait.applicationadmin.order.dto; - -import com.nowait.order.entity.OrderStatus; -import com.nowait.order.entity.UserOrder; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public class OrderStatusUpdateResponseDto { - private final OrderStatus orderStatus; - - public static OrderStatusUpdateResponseDto fromEntity(UserOrder userOrder) { - return new OrderStatusUpdateResponseDto(userOrder.getStatus()); - } -} diff --git a/application-admin/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java b/application-admin/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java deleted file mode 100644 index c06986cf..00000000 --- a/application-admin/src/main/java/com/nowait/applicationadmin/order/service/OrderService.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.nowait.applicationadmin.order.service; - -import java.util.List; -import java.util.stream.Collectors; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.nowait.applicationadmin.order.dto.OrderResponseDto; -import com.nowait.applicationadmin.order.dto.OrderStatusUpdateResponseDto; -import com.nowait.order.entity.OrderStatus; -import com.nowait.order.entity.UserOrder; -import com.nowait.order.repository.OrderRepository; - -import lombok.RequiredArgsConstructor; - -@Service -@RequiredArgsConstructor -public class OrderService { - - private final OrderRepository orderRepository; - - @Transactional(readOnly = true) - public List findAllOrders(Long storeId) { - return orderRepository.findAllByStore_StoreId(storeId).stream() - .map(OrderResponseDto::fromEntity) - .collect(Collectors.toList()); - } - - @Transactional - public OrderStatusUpdateResponseDto updateOrderStatus(Long orderId, OrderStatus newStatus) { - UserOrder userOrder = orderRepository.findById(orderId) - .orElseThrow(() -> new IllegalArgumentException("Order not found with id: " + orderId)); - userOrder.updateStatus(newStatus); - return OrderStatusUpdateResponseDto.fromEntity(userOrder); - } -} diff --git a/application-config/build.gradle b/application-config/build.gradle deleted file mode 100644 index e69de29b..00000000 diff --git a/application-config/src/main/java/com/example/applicationconfig/config/AsyncConfig.java b/application-config/src/main/java/com/example/applicationconfig/config/AsyncConfig.java deleted file mode 100644 index 9c839fbb..00000000 --- a/application-config/src/main/java/com/example/applicationconfig/config/AsyncConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.example.applicationconfig.config; - -import java.util.concurrent.Executor; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; - -@Configuration -public class AsyncConfig { - @Bean(name = "s3UploadExecutor") - public Executor s3UploadExecutor() { - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setCorePoolSize(5); - executor.setMaxPoolSize(10); - executor.setQueueCapacity(100); - executor.setThreadNamePrefix("S3Upload-"); - executor.initialize(); - return executor; - } -} diff --git a/application-config/src/main/java/com/example/applicationconfig/config/CorsConfig.java b/application-config/src/main/java/com/example/applicationconfig/config/CorsConfig.java deleted file mode 100644 index d8615194..00000000 --- a/application-config/src/main/java/com/example/applicationconfig/config/CorsConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.applicationconfig.config; - -import java.util.List; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.CorsConfigurationSource; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; - -@Configuration -public class CorsConfig { - @Bean - public CorsConfigurationSource corsConfigurationSource() { - CorsConfiguration config = new CorsConfiguration(); - - config.setAllowCredentials(true); // 쿠키나 인증헤더 자격증명 허용 - config.setAllowedOrigins(List.of("http://localhost:3000")); // 허용할 출처 설정 - config.setAllowedMethods(List.of("GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS")); // 메서드 허용 - config.setAllowedHeaders(List.of("*")); //클라이언트가 보낼 수 있는 헤더 - config.setExposedHeaders(List.of("Authorization")); //클라이언트(브라우저)가 접근할 수 있는 헤더 지정 - // config.setAllowCredentials(true); // 쿠키 포함 허용 - - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/**", config); //** 뜻은 모든 URL 경로에 적용한다는 의미 - return source; - } -} diff --git a/application-config/src/main/java/com/nowait/config/config/SwaggerConfig.java b/application-config/src/main/java/com/nowait/config/config/SwaggerConfig.java deleted file mode 100644 index 7c6454c0..00000000 --- a/application-config/src/main/java/com/nowait/config/config/SwaggerConfig.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.nowait.config.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.info.Info; -import io.swagger.v3.oas.models.security.SecurityRequirement; -import io.swagger.v3.oas.models.security.SecurityScheme; - -@Configuration -public class SwaggerConfig { - - @Bean - public OpenAPI openAPI() { - return new OpenAPI() - .addSecurityItem(new SecurityRequirement().addList("JWT")) - .components(new Components() - .addSecuritySchemes("JWT", new SecurityScheme() - .name("Authorization") - .type(SecurityScheme.Type.HTTP) - .scheme("bearer") - .bearerFormat("JWT") - .in(SecurityScheme.In.HEADER))) - .info(new Info().title("NOWAIT API") - .description("NOWAIT API Specification") - .version("v0.0.1")); - } -} diff --git a/build.gradle b/build.gradle index 03ccdb50..94b2c6d6 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,9 @@ subprojects { apply plugin: "java" apply plugin: 'java-library' apply plugin: "io.spring.dependency-management" - apply plugin: "org.springframework.boot" + if (project.name.startsWith('nowait-app-')) { + apply plugin: "org.springframework.boot" + } repositories { mavenCentral() diff --git a/domain-token/src/main/java/com/example/domaintoken/entity/Token.java b/domain-token/src/main/java/com/example/domaintoken/entity/Token.java deleted file mode 100644 index 3bd47167..00000000 --- a/domain-token/src/main/java/com/example/domaintoken/entity/Token.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.example.domaintoken.entity; - -import java.time.LocalDateTime; - -import com.nowait.user.entity.User; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "token") -@Getter -public class Token { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long tokenId; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id", nullable = false) - private User user; - - @Column - private String refreshToken; - - private LocalDateTime expiredDate; - - @Builder - public Token(User user, String refreshToken, LocalDateTime expiredDate) { - this.user = user; - this.refreshToken = refreshToken; - this.expiredDate = expiredDate; - } - - // static method로 객체를 생성 - 생성 의도 파악 쉬웁 - public static Token toEntity(User user, String refreshToken, LocalDateTime expiredDate){ - return Token.builder() - .user(user) - .refreshToken(refreshToken) - .expiredDate(expiredDate) - .build(); - } - -} diff --git a/domain-token/src/main/java/com/example/domaintoken/exception/BusinessException.java b/domain-token/src/main/java/com/example/domaintoken/exception/BusinessException.java deleted file mode 100644 index 7fe9c748..00000000 --- a/domain-token/src/main/java/com/example/domaintoken/exception/BusinessException.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.domaintoken.exception; - -import com.nowait.common.exception.ErrorMessage; - -public abstract class BusinessException extends RuntimeException { - private final ErrorMessage errorMessage; - - protected BusinessException(ErrorMessage errorMessage) { - super(errorMessage.getMessage()); - this.errorMessage = errorMessage; - } - - public String getCode() { - return errorMessage.getCode(); - } -} diff --git a/domain-token/src/main/java/com/example/domaintoken/repository/TokenRepository.java b/domain-token/src/main/java/com/example/domaintoken/repository/TokenRepository.java deleted file mode 100644 index d813fd09..00000000 --- a/domain-token/src/main/java/com/example/domaintoken/repository/TokenRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.domaintoken.repository; - -import java.util.Optional; - -import org.springframework.data.jpa.repository.JpaRepository; - -import com.example.domaintoken.entity.Token; - -public interface TokenRepository extends JpaRepository { - Optional findByUserId(Long userId); -} diff --git a/infra-aws/src/main/java/com/example/infrastorage/config/AwsS3Config.java b/infra-aws/src/main/java/com/example/infrastorage/config/AwsS3Config.java deleted file mode 100644 index 4eda87c2..00000000 --- a/infra-aws/src/main/java/com/example/infrastorage/config/AwsS3Config.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.example.infrastorage.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.AmazonS3ClientBuilder; - -@Configuration -public class AwsS3Config { - - @Value("${cloud.aws.credentials.access-key}") - private String accessKey; - - @Value("${cloud.aws.credentials.secret-key}") - private String secretKey; - - @Value("${cloud.aws.region.static}") - private String region; - - @Bean - public AmazonS3Client amazonS3Client() { - BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); - return (AmazonS3Client)AmazonS3ClientBuilder.standard() - .withRegion(region) - .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) - .build(); - } - -} diff --git a/infra-aws/src/main/java/com/example/infrastorage/s3/S3Service.java b/infra-aws/src/main/java/com/example/infrastorage/s3/S3Service.java deleted file mode 100644 index 20d9abf0..00000000 --- a/infra-aws/src/main/java/com/example/infrastorage/s3/S3Service.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.example.infrastorage.s3; - -import java.io.InputStream; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.ObjectMetadata; - -import io.github.resilience4j.bulkhead.annotation.Bulkhead; -import lombok.RequiredArgsConstructor; - -@Service -@RequiredArgsConstructor -public class S3Service { - private final AmazonS3Client amazonS3Client; - - @Value("${cloud.aws.s3.bucket}") - private String bucket; - - public record S3UploadResult(String key, String url) { - } - - @Bulkhead(name = "s3UploadBulkhead", type = Bulkhead.Type.THREADPOOL) - @Async("s3UploadExecutor") - public CompletableFuture upload(String type, Long refId, MultipartFile file) { // TODO MultipartFile 분리 필요 (Spring에 의존하면 안 됨) - try (InputStream inputStream = file.getInputStream()) { - String key = createFileKey(type, refId, file.getOriginalFilename()); - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentLength(file.getSize()); - - amazonS3Client.putObject(bucket, key, inputStream, metadata); - String url = amazonS3Client.getUrl(bucket, key).toString(); - - return CompletableFuture.completedFuture(new S3UploadResult(key, url)); - } catch (Exception e) { - throw new RuntimeException("S3 업로드 실패", e); - } - } - - public void delete(String filename) { - try { - amazonS3Client.deleteObject(bucket, filename); - } catch (Exception e) { - throw new RuntimeException("S3 파일 삭제 실패", e); - } - } - - private String createFileKey(String type, Long refId, String filename) { - return type + "/" + refId + "/" + UUID.randomUUID() + "-" + filename; - } -} diff --git a/nowait-app-admin-api/build.gradle b/nowait-app-admin-api/build.gradle index 11db36d5..f6f6a509 100644 --- a/nowait-app-admin-api/build.gradle +++ b/nowait-app-admin-api/build.gradle @@ -2,12 +2,12 @@ plugins { id 'java' } -bootJar { - enabled = true -} jar { enabled = false } +bootJar { + enabled = true +} group = 'com.nowait' version = '0.0.1-SNAPSHOT' @@ -16,10 +16,9 @@ repositories { mavenCentral() } -// api-admin에서 사용하는 도메인, 인프라 모듈만 추가 dependencies { implementation project(':nowait-common') - implementation project(':nowait-infra') // aws 관련 도메인 + implementation project(':nowait-infra') implementation project(':nowait-domain:domain-admin-rdb') implementation project(':nowait-domain:domain-core-rdb') diff --git a/nowait-app-user-api/build.gradle b/nowait-app-user-api/build.gradle index 47adf831..6e3a1302 100644 --- a/nowait-app-user-api/build.gradle +++ b/nowait-app-user-api/build.gradle @@ -2,12 +2,12 @@ plugins { id 'java' } -bootJar { - enabled = true -} jar { enabled = false } +bootJar { + enabled = true +} group = 'com.nowait' version = '0.0.1-SNAPSHOT' @@ -30,7 +30,6 @@ dependencies { // SPRING SECURITY implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.boot:spring-boot-starter-test' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' // jwt implementation 'io.jsonwebtoken:jjwt-api:0.12.3' diff --git a/nowait-common/build.gradle b/nowait-common/build.gradle index 41106356..c2f76e1b 100644 --- a/nowait-common/build.gradle +++ b/nowait-common/build.gradle @@ -1,9 +1,6 @@ jar { enabled = true } -bootJar { - enabled = false -} java { toolchain { diff --git a/nowait-domain/build.gradle b/nowait-domain/build.gradle index ebc5b4ae..9ce9a13f 100644 --- a/nowait-domain/build.gradle +++ b/nowait-domain/build.gradle @@ -5,9 +5,6 @@ plugins { jar { enabled = true } -bootJar { - enabled = false -} group = 'com.nowaiting' @@ -32,10 +29,11 @@ dependencies { api 'jakarta.persistence:jakarta.persistence-api:3.1.0' // SPRING SECURITY api 'org.springframework.boot:spring-boot-starter-security' - api 'org.springframework.boot:spring-boot-starter-test' // Lombok (optional) compileOnly 'org.projectlombok:lombok:1.18.26' annotationProcessor 'org.projectlombok:lombok:1.18.26' + // SWAGGER + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' // Test testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/nowait-domain/domain-admin-rdb/build.gradle b/nowait-domain/domain-admin-rdb/build.gradle index 48aa299a..6b1b69c7 100644 --- a/nowait-domain/domain-admin-rdb/build.gradle +++ b/nowait-domain/domain-admin-rdb/build.gradle @@ -5,9 +5,6 @@ plugins { jar { enabled = true } -bootJar { - enabled = false -} group = 'com.nowaiting' diff --git a/nowait-domain/domain-core-rdb/build.gradle b/nowait-domain/domain-core-rdb/build.gradle index 7ea55f16..01bc023b 100644 --- a/nowait-domain/domain-core-rdb/build.gradle +++ b/nowait-domain/domain-core-rdb/build.gradle @@ -5,9 +5,6 @@ plugins { jar { enabled = true } -bootJar { - enabled = false -} group = 'com.nowait' @@ -32,9 +29,11 @@ dependencies { // SPRING SECURITY implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.boot:spring-boot-starter-test' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-validation' + // SWAGGER + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + compileOnly 'org.projectlombok:lombok:1.18.26' annotationProcessor 'org.projectlombok:lombok:1.18.26' diff --git a/nowait-domain/domain-user-rdb/build.gradle b/nowait-domain/domain-user-rdb/build.gradle index 09aa35f3..5a14ae53 100644 --- a/nowait-domain/domain-user-rdb/build.gradle +++ b/nowait-domain/domain-user-rdb/build.gradle @@ -5,9 +5,6 @@ plugins { jar { enabled = true } -bootJar { - enabled = false -} group = 'com.nowaiting' @@ -35,6 +32,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0' + // SWAGGER + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + compileOnly 'org.projectlombok:lombok:1.18.26' annotationProcessor 'org.projectlombok:lombok:1.18.26' diff --git a/nowait-infra/build.gradle b/nowait-infra/build.gradle index aa478c84..5cbc1f17 100644 --- a/nowait-infra/build.gradle +++ b/nowait-infra/build.gradle @@ -5,9 +5,6 @@ plugins { jar { enabled = true } -bootJar { - enabled = false -} group = 'com.nowaiting' From 2615a2bacafa598a980d23fae1df97f64c9f8735 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 4 Jul 2025 22:42:08 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nowait-domain/domain-admin-rdb/build.gradle | 2 +- .../com/nowait/auth/config/CorsConfig.java | 28 ----- .../nowait/auth/config/SecurityConfig.java | 93 --------------- .../com/nowait/auth/dto/CustomOAuth2User.java | 55 --------- .../com/nowait/auth/dto/KaKaoResponse.java | 40 ------- .../com/nowait/auth/dto/OAuth2Response.java | 19 --- .../auth/jwt/JwtAuthorizationFilter.java | 98 ---------------- .../java/com/nowait/auth/jwt/JwtUtil.java | 76 ------------ .../auth/oauth2/CustomOAuth2UserService.java | 70 ------------ .../oauth2/OAuth2LoginSuccessHandler.java | 80 ------------- .../auth/service/CustomUserDetailService.java | 30 ----- .../nowait/exception/BusinessException.java | 14 --- .../com/nowait/exception/ErrorMessage.java | 22 ---- .../com/nowait/exception/ErrorResponse.java | 26 ----- .../exception/GlobalExceptionHandler.java | 108 ------------------ .../RefreshTokenNotFoundException.java | 9 -- .../exception/ResourceNotFoundException.java | 14 --- .../exception/TokenBadRequestException.java | 8 -- .../exception/UnauthorizedException.java | 19 --- 19 files changed, 1 insertion(+), 810 deletions(-) delete mode 100644 security-front/src/main/java/com/nowait/auth/config/CorsConfig.java delete mode 100644 security-front/src/main/java/com/nowait/auth/config/SecurityConfig.java delete mode 100644 security-front/src/main/java/com/nowait/auth/dto/CustomOAuth2User.java delete mode 100644 security-front/src/main/java/com/nowait/auth/dto/KaKaoResponse.java delete mode 100644 security-front/src/main/java/com/nowait/auth/dto/OAuth2Response.java delete mode 100644 security-front/src/main/java/com/nowait/auth/jwt/JwtAuthorizationFilter.java delete mode 100644 security-front/src/main/java/com/nowait/auth/jwt/JwtUtil.java delete mode 100644 security-front/src/main/java/com/nowait/auth/oauth2/CustomOAuth2UserService.java delete mode 100644 security-front/src/main/java/com/nowait/auth/oauth2/OAuth2LoginSuccessHandler.java delete mode 100644 security-front/src/main/java/com/nowait/auth/service/CustomUserDetailService.java delete mode 100644 security-front/src/main/java/com/nowait/exception/BusinessException.java delete mode 100644 security-front/src/main/java/com/nowait/exception/ErrorMessage.java delete mode 100644 security-front/src/main/java/com/nowait/exception/ErrorResponse.java delete mode 100644 security-front/src/main/java/com/nowait/exception/GlobalExceptionHandler.java delete mode 100644 security-front/src/main/java/com/nowait/exception/RefreshTokenNotFoundException.java delete mode 100644 security-front/src/main/java/com/nowait/exception/ResourceNotFoundException.java delete mode 100644 security-front/src/main/java/com/nowait/exception/TokenBadRequestException.java delete mode 100644 security-front/src/main/java/com/nowait/exception/UnauthorizedException.java diff --git a/nowait-domain/domain-admin-rdb/build.gradle b/nowait-domain/domain-admin-rdb/build.gradle index 6b1b69c7..bf111954 100644 --- a/nowait-domain/domain-admin-rdb/build.gradle +++ b/nowait-domain/domain-admin-rdb/build.gradle @@ -7,7 +7,7 @@ jar { } -group = 'com.nowaiting' +group = 'com.nowait' version = rootProject.version java { diff --git a/security-front/src/main/java/com/nowait/auth/config/CorsConfig.java b/security-front/src/main/java/com/nowait/auth/config/CorsConfig.java deleted file mode 100644 index 34b293b5..00000000 --- a/security-front/src/main/java/com/nowait/auth/config/CorsConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.nowait.auth.config; - -import java.util.List; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.CorsConfigurationSource; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; - -@Configuration -public class CorsConfig { - @Bean - public CorsConfigurationSource corsConfigurationSource() { - CorsConfiguration config = new CorsConfiguration(); - - config.setAllowCredentials(true); // 쿠키나 인증헤더 자격증명 허용 - config.setAllowedOrigins(List.of("http://localhost:3000", "http://localhost:8083")); // 허용할 출처 설정 - config.setAllowedMethods(List.of("GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS")); // 메서드 허용 - config.setAllowedHeaders(List.of("*")); //클라이언트가 보낼 수 있는 헤더 - config.setExposedHeaders(List.of("Authorization")); //클라이언트(브라우저)가 접근할 수 있는 헤더 지정 - // config.setAllowCredentials(true); // 쿠키 포함 허용 - - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/**", config); //** 뜻은 모든 URL 경로에 적용한다는 의미 - return source; - } -} diff --git a/security-front/src/main/java/com/nowait/auth/config/SecurityConfig.java b/security-front/src/main/java/com/nowait/auth/config/SecurityConfig.java deleted file mode 100644 index c4ebb970..00000000 --- a/security-front/src/main/java/com/nowait/auth/config/SecurityConfig.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.nowait.auth.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.web.cors.CorsConfigurationSource; - -import com.nowait.auth.jwt.JwtAuthorizationFilter; -import com.nowait.auth.jwt.JwtUtil; -import com.nowait.auth.oauth2.CustomOAuth2UserService; -import com.nowait.auth.oauth2.OAuth2LoginSuccessHandler; -import com.nowait.auth.service.CustomUserDetailService; - -import lombok.RequiredArgsConstructor; - -@Configuration -@EnableWebSecurity // security 활성화 어노테이션 -@RequiredArgsConstructor -public class SecurityConfig { - private final CustomOAuth2UserService customOAuth2UserService; - private final OAuth2LoginSuccessHandler OAuth2LoginSuccessHandler; - private final JwtUtil jwtUtil; - private final CustomUserDetailService userDetailsService; - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - // CSRF 방어 기능 비활성화 (jwt 토큰을 사용할 것이기에 필요없음) - .csrf(AbstractHttpConfigurer::disable) - // 시큐리티 폼 로그인 비활성화 - .formLogin(AbstractHttpConfigurer::disable) - // HTTP Basic 인증 비활성화 - .httpBasic(AbstractHttpConfigurer::disable) - // oauth2 로그인 - // - userInfoEndPoint에서 사용자 정보 불러오고, - // - successHandler에서 로그인 성공 시 JWT 생성 및 반환로직 - .oauth2Login(oauth2 -> - oauth2.userInfoEndpoint(userInfoEndpoint -> - userInfoEndpoint.userService(customOAuth2UserService) - ).successHandler(OAuth2LoginSuccessHandler) - ) - // 세션 사용하지 않음 - .sessionManagement(session -> - session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) - ) - .authorizeHttpRequests(auth -> auth - .requestMatchers( - "/oauth2/authorization/kakao", // 카카오 로그인 요청 - "/login/oauth2/code/**", // 카카오 인증 콜백 - "/api/refresh-token", // refresh token (토큰 갱신) - "/orders/**", // 주문 관련 API - "/v1/menus/**", - "/v1/stores/**", - "/api/users/signup", - "/api/users/login", - "/swagger-ui/**", - "/v3/api-docs/**", - "/v3/api-docs.json", - "/api-docs/**", - "/swagger-resources/**", - "/webjars/**", - "/demo-ui.html" - ) - .permitAll() - .anyRequest().authenticated() // 그외 요청은 허가된 사람만 인가 - ) - // JWTFiler - .addFilterBefore(new JwtAuthorizationFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class); - - return http.build(); - } - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - @Bean - public AuthenticationProvider authenticationProvider() { - DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); - authenticationProvider.setUserDetailsService(userDetailsService); - authenticationProvider.setPasswordEncoder(passwordEncoder()); - return authenticationProvider; - } - -} diff --git a/security-front/src/main/java/com/nowait/auth/dto/CustomOAuth2User.java b/security-front/src/main/java/com/nowait/auth/dto/CustomOAuth2User.java deleted file mode 100644 index 61432393..00000000 --- a/security-front/src/main/java/com/nowait/auth/dto/CustomOAuth2User.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.nowait.auth.dto; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; - -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.oauth2.core.user.OAuth2User; - -import com.nowait.user.entity.User; - -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class CustomOAuth2User implements OAuth2User { - private final User user; - - @Override - public Map getAttributes() { - return Map.of("email", user.getEmail(), "nickname", user.getNickname()); - } - - // 사용자가 가지는 권한 설정 - @Override - public Collection getAuthorities() { - Collection authorities = new ArrayList<>(); - - authorities.add(new GrantedAuthority() { - @Override - public String getAuthority() { - return user.getRole().getName(); // 유저의 권한 리턴 - } - }); - - return authorities; - } - - @Override - public String getName() { - return user.getEmail(); - } - - public User getUser() { - return user; - } - - public Long getUserId() { - return user.getId(); - } - - public String getNickname() { - return user.getNickname(); - } - -} diff --git a/security-front/src/main/java/com/nowait/auth/dto/KaKaoResponse.java b/security-front/src/main/java/com/nowait/auth/dto/KaKaoResponse.java deleted file mode 100644 index e745bd26..00000000 --- a/security-front/src/main/java/com/nowait/auth/dto/KaKaoResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.nowait.auth.dto; - -import java.util.Map; - -import lombok.RequiredArgsConstructor; - -// 카카오 OAuth2 응답에서 필요한 정보를 추출하는 역할 -@RequiredArgsConstructor -public class KaKaoResponse implements OAuth2Response { - private final Map attributes; - - @Override - public String getProvider() { - return "kakao"; - } - - @Override - public String getProviderId() { - return attributes.get("id").toString(); - } - - @Override - public String getEmail() { - Map kakaoAccount = (Map)attributes.get("kakao_account"); - return kakaoAccount.get("email").toString(); - } - - @Override - public String getNickName() { - Map properties = (Map)attributes.get("properties"); - return properties.get("nickname").toString(); - } - - @Override - public String getProfileImage() { - Map properties = (Map)attributes.get("properties"); - return properties.get("profile_image").toString(); - } - -} diff --git a/security-front/src/main/java/com/nowait/auth/dto/OAuth2Response.java b/security-front/src/main/java/com/nowait/auth/dto/OAuth2Response.java deleted file mode 100644 index de987480..00000000 --- a/security-front/src/main/java/com/nowait/auth/dto/OAuth2Response.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.nowait.auth.dto; - -public interface OAuth2Response { - // 제공자 (ex. naver, kakao) - String getProvider(); - - // 제공자에서 발급해주는 아이디 (번호) - String getProviderId(); - - // 아래 이메일, 닉네임, 프로필이미지는 내가 카카오 developers에서 발급받겠다고 신청한 정보들이다 - // 이메일 - String getEmail(); - - // 닉네임 - String getNickName(); - - // 프로필이미지 - String getProfileImage(); -} diff --git a/security-front/src/main/java/com/nowait/auth/jwt/JwtAuthorizationFilter.java b/security-front/src/main/java/com/nowait/auth/jwt/JwtAuthorizationFilter.java deleted file mode 100644 index dcbbd985..00000000 --- a/security-front/src/main/java/com/nowait/auth/jwt/JwtAuthorizationFilter.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.nowait.auth.jwt; - -import java.io.IOException; - -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.OncePerRequestFilter; - -import com.nowait.auth.dto.CustomOAuth2User; -import com.nowait.common.enums.Role; -import com.nowait.common.enums.SocialType; -import com.nowait.user.entity.User; - -import io.jsonwebtoken.ExpiredJwtException; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -// JWT 검증 필터 -// 1. 헤더에서 accessToken 추출, 2. 토큰 검증, 3. 유효하면 사용자정보를 SecurityContextHolder에 세팅 -// 그러면, 이후 컨트롤러에서 @AuthenticationPrincipal에서 저장했던 사용자 정보를 꺼내쓸 수 있음 -@RequiredArgsConstructor -@Slf4j -public class JwtAuthorizationFilter extends OncePerRequestFilter { - private final JwtUtil jwtUtil; - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - String header = request.getHeader("Authorization"); - - // 인증헤더 Bearer가 없다면, 다음 필터로 넘김 - if (header == null || !header.startsWith("Bearer ")) { - filterChain.doFilter(request, response); - - log.debug("JwtAuthorizationFilter: Authorization 헤더가 없거나 Bearer 토큰 형식이 아님. JWT 인증 필터를 건너뜁니다. [header={}] ", header); - return; - } - - log.info("header :: {}, header.substring(7) :: {}", header, header.substring(7)); - String accessToken = header.substring(7); - - // 토큰 만료 여부 확인, 만료 시 다음 필터로 넘기지 않음 - try { - jwtUtil.isExpired(accessToken); - } catch (ExpiredJwtException e) { - - // response status code + msg - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - response.getWriter().print("access token expired"); - - log.warn("JwtAuthorizationFilter: 만료된 AccessToken입니다. 토큰 인증 거부, URI: {}", request.getRequestURI()); - return; - } - - // 토큰이 accessToken 종류인지 확인 - String tokenCategory = jwtUtil.getTokenCategory(accessToken); - - if (!tokenCategory.equals("accessToken")) { - //response status code - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - response.getWriter().print("invalid access token"); - - log.warn("JwtAuthorizationFilter: 잘못된 토큰 유형(accessToken 아님)으로 인증 요청. URI: {}, tokenCategory: {}", request.getRequestURI(), tokenCategory); - return; - } - - // userId와 role 값 추출 - Long userId = jwtUtil.getUserId(accessToken); - String roleString = jwtUtil.getRole(accessToken); - if (userId == null || roleString == null) { - log.warn("JwtAuthorizationFilter: JWT에서 userId 또는 role 추출 실패. 토큰: {}", accessToken); - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - response.getWriter().print("invalid token"); - return; - } - User user = User.createUserWithId(userId, "sampleEmail", "sampleNickname", "sampleProfileImg" - , SocialType.KAKAO, Role.fromString(roleString)); - - CustomOAuth2User customOAuth2User = new CustomOAuth2User(user); - - // 스프링 시큐리티 인증 토큰 생성 - UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken( - customOAuth2User, null, customOAuth2User.getAuthorities()); - - // 생성한 인증 정보를 SecurityContext에 설정 - SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); - - log.info("JwtAuthorizationFilter: 인증 성공. userId={}, role={}, URI={}", userId, roleString, request.getRequestURI()); - - filterChain.doFilter(request, response); - - } - -} diff --git a/security-front/src/main/java/com/nowait/auth/jwt/JwtUtil.java b/security-front/src/main/java/com/nowait/auth/jwt/JwtUtil.java deleted file mode 100644 index fd0620e9..00000000 --- a/security-front/src/main/java/com/nowait/auth/jwt/JwtUtil.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.nowait.auth.jwt; - -import java.nio.charset.StandardCharsets; -import java.util.Date; - -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import io.jsonwebtoken.Jwts; - -@Component -public class JwtUtil { - private final SecretKey secretKey; - - // 시크릿 키를 암호화하여, 키 생성 - public JwtUtil(@Value("${jwt.secret}") String secret) { - this.secretKey = new SecretKeySpec( - secret.getBytes(StandardCharsets.UTF_8), - Jwts.SIG.HS256.key().build().getAlgorithm() - ); - } - - public String createAccessToken(String tokenCategory, Long userId, String role, Long expiredMs) { - return Jwts.builder() - .claim("tokenCategory", tokenCategory) // accessToken - .claim("userId", userId) - .claim("role", role) - .issuedAt(new Date(System.currentTimeMillis())) - .expiration(new Date(System.currentTimeMillis() + expiredMs)) - .signWith(secretKey) - .compact(); - } - - public String createRefreshToken(String tokenCategory, Long userId, Long expiredMs) { - return Jwts.builder() - .claim("tokenCategory", tokenCategory) // refreshToken - .claim("userId", userId) - .issuedAt(new Date(System.currentTimeMillis())) - .expiration(new Date(System.currentTimeMillis() + expiredMs)) - .signWith(secretKey) - .compact(); - } - - public String getTokenCategory(String token) { - return Jwts.parser().verifyWith(secretKey).build() - .parseClaimsJws(token) - .getBody() - .get("tokenCategory", String.class); - } - - public String getRole(String token) { - return Jwts.parser().verifyWith(secretKey).build() - .parseClaimsJws(token) - .getBody() - .get("role", String.class); - } - - public Long getUserId(String token) { - return Jwts.parser().verifyWith(secretKey).build() - .parseClaimsJws(token) - .getBody() - .get("userId", Long.class); - } - - public Boolean isExpired(String token) { - return Jwts.parser().verifyWith(secretKey).build() - .parseSignedClaims(token) - .getPayload() - .getExpiration() - .before(new Date()); - } - -} diff --git a/security-front/src/main/java/com/nowait/auth/oauth2/CustomOAuth2UserService.java b/security-front/src/main/java/com/nowait/auth/oauth2/CustomOAuth2UserService.java deleted file mode 100644 index b51577f7..00000000 --- a/security-front/src/main/java/com/nowait/auth/oauth2/CustomOAuth2UserService.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.nowait.auth.oauth2; - -import java.util.Optional; - -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.stereotype.Service; - -import com.nowait.auth.dto.CustomOAuth2User; -import com.nowait.auth.dto.KaKaoResponse; -import com.nowait.auth.dto.OAuth2Response; -import com.nowait.common.enums.Role; -import com.nowait.common.enums.SocialType; -import com.nowait.user.entity.User; -import com.nowait.user.repository.UserRepository; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -// OAuth2 제공자(카카오)로부터 제공받은 사용자 정보를, 우리 서비스에 맞게 가공, 변환 -@Service -@RequiredArgsConstructor -@Slf4j -public class CustomOAuth2UserService extends DefaultOAuth2UserService { - private final UserRepository userRepository; - - @Override - public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { - OAuth2User oAuth2User = super.loadUser(userRequest); - - log.info("CustomOAuth2UserService :: {}", oAuth2User); - log.info("oAuthUser.getAttributes :: {}", oAuth2User.getAttributes()); - - String registrationId = userRequest.getClientRegistration().getRegistrationId(); - OAuth2Response oAuth2Response = null; - - if (registrationId.equals("kakao")) { - oAuth2Response = new KaKaoResponse(oAuth2User.getAttributes()); - } else { - throw new OAuth2AuthenticationException("지원하지 않는 OAuth2 Provider 입니다."); - } - - // DB에 유저가 있는지 판단 - Optional foundUser = userRepository.findByEmail(oAuth2Response.getEmail()); - - // DB에 유저 없으면 - 회원가입 - if (foundUser.isEmpty()) { - - User user = User.builder() - .email(oAuth2Response.getEmail()) - .nickname(oAuth2Response.getNickName()) - .profileImage(oAuth2Response.getProfileImage()) - .socialType(SocialType.KAKAO) - .role(Role.USER) // 일반 유저 설정 - .build(); - - userRepository.save(user); - - return new CustomOAuth2User(user); - } else { - // DB에 유저 존재하면 - 로그인 진행 (이때 로그인 처리는 안하고, OAuth2LoginSuccessHandler에서 담당함) - User user = foundUser.get(); - - return new CustomOAuth2User(user); - } - } - -} diff --git a/security-front/src/main/java/com/nowait/auth/oauth2/OAuth2LoginSuccessHandler.java b/security-front/src/main/java/com/nowait/auth/oauth2/OAuth2LoginSuccessHandler.java deleted file mode 100644 index 9364e1cc..00000000 --- a/security-front/src/main/java/com/nowait/auth/oauth2/OAuth2LoginSuccessHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.nowait.auth.oauth2; - -import java.io.IOException; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; - -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; -import org.springframework.stereotype.Component; - -import com.example.domaintoken.entity.Token; -import com.example.domaintoken.repository.TokenRepository; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.nowait.auth.dto.CustomOAuth2User; -import com.nowait.auth.jwt.JwtUtil; -import com.nowait.user.entity.User; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -// 카카오 로그인 성공 시, 콜백 핸들러 -// 1. JWT 토큰 발급 -// - 이때, JWT payload는 보안상 최소한의 정보(userId, role)만 담겠다 -// 2. refreshToken만 DB에 저장 -// 3. JSON 응답으로, accessToken과 refreshToken 을 반환해준다. -@Component -@RequiredArgsConstructor -@Slf4j -public class OAuth2LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { - private final JwtUtil jwtUtil; - private final TokenRepository tokenRepository; - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) throws IOException { - - // 1. CustomOAuth2UserService에서 설정한 OAuth2User 정보 가져오기 - CustomOAuth2User customUserDetails = (CustomOAuth2User)authentication.getPrincipal(); - - User user = customUserDetails.getUser(); - Long userId = customUserDetails.getUserId(); - String email = customUserDetails.getName(); - - Collection authorities = authentication.getAuthorities(); - Iterator iterator = authorities.iterator(); - GrantedAuthority auth = iterator.next(); - - String role = auth.getAuthority(); - - log.info("user, userId, email, role :: {} {} {} {}", user, userId, email, role); - - // 2. 1)의 사용자 정보를 담아, accessToken과 refreshToken 발행 - String accessToken = jwtUtil.createAccessToken("accessToken", userId, role, 60 * 60 * 1000L); // 유효기간 1시간 - String refreshToken = jwtUtil.createRefreshToken("refreshToken", userId, - 30 * 24 * 60 * 60 * 1000L); // 유효기간 30일 - - // 3. refreshToken을 DB에 저장 - Token refreshTokenEntity = Token.toEntity(user, refreshToken, LocalDateTime.now().plusDays(30)); - tokenRepository.save(refreshTokenEntity); - - // 4. JSON 응답으로, accessToken과 refreshToken 을 반환해준다. - response.setContentType("application/json"); - response.setCharacterEncoding("utf-8"); - - ObjectMapper objectMapper = new ObjectMapper(); // 객체 -> json 문자열로 변환 - String body = objectMapper.writeValueAsString( - Map.of( - "accessToken", accessToken, - "refreshToken", refreshToken - ) - ); - response.getWriter().write(body); - } - -} diff --git a/security-front/src/main/java/com/nowait/auth/service/CustomUserDetailService.java b/security-front/src/main/java/com/nowait/auth/service/CustomUserDetailService.java deleted file mode 100644 index 4476c9c4..00000000 --- a/security-front/src/main/java/com/nowait/auth/service/CustomUserDetailService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.nowait.auth.service; - -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Component; - -import com.nowait.user.entity.MemberDetails; -import com.nowait.user.entity.User; -import com.nowait.user.repository.UserRepository; - -import lombok.RequiredArgsConstructor; - -@Component -@RequiredArgsConstructor -public class CustomUserDetailService implements UserDetailsService { - - private final UserRepository userRepository; - - @Override - public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { - User user = userRepository.findByEmail(email).orElseThrow(); - return MemberDetails.create(user); - } - - public UserDetails loadUserById(Long id) throws UsernameNotFoundException { - User member = userRepository.findById(id).orElseThrow(); - return MemberDetails.create(member); - } -} diff --git a/security-front/src/main/java/com/nowait/exception/BusinessException.java b/security-front/src/main/java/com/nowait/exception/BusinessException.java deleted file mode 100644 index 60eec165..00000000 --- a/security-front/src/main/java/com/nowait/exception/BusinessException.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.nowait.exception; - -public abstract class BusinessException extends RuntimeException { - private final ErrorMessage errorMessage; - - protected BusinessException(ErrorMessage errorMessage) { - super(errorMessage.getMessage()); - this.errorMessage = errorMessage; - } - - public String getCode() { - return errorMessage.getCode(); - } -} diff --git a/security-front/src/main/java/com/nowait/exception/ErrorMessage.java b/security-front/src/main/java/com/nowait/exception/ErrorMessage.java deleted file mode 100644 index c365a92e..00000000 --- a/security-front/src/main/java/com/nowait/exception/ErrorMessage.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.nowait.exception; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public enum ErrorMessage { - // global - INVALID_INPUT_VALUE("입력값이 올바르지 않습니다.", "global001"), - - // auth - UNAUTHORIZED("권한이 없습니다", "auth001"), - - // token - REFRESH_TOKEN_NOT_FOUND("기존 리프레시 토큰을 찾을 수 없습니다.", "token001"), - DOES_NOT_MATCH_REFRESH_TOKEN("기존 리프레시 토큰이 일치하지 않습니다.", "token002"); - - private final String message; - private final String code; - -} diff --git a/security-front/src/main/java/com/nowait/exception/ErrorResponse.java b/security-front/src/main/java/com/nowait/exception/ErrorResponse.java deleted file mode 100644 index a15935e8..00000000 --- a/security-front/src/main/java/com/nowait/exception/ErrorResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.nowait.exception; - -import java.util.HashMap; -import java.util.Map; - -import lombok.Getter; - -@Getter -public class ErrorResponse { - private final String message; - private final String code; - private final Map errors; - - public ErrorResponse(String message, String code) { - this.message = message; - this.code = code; - errors = new HashMap<>(); - } - - public ErrorResponse(String message, String code, Map errors) { - this.message = message; - this.code = code; - this.errors = errors; - } - -} diff --git a/security-front/src/main/java/com/nowait/exception/GlobalExceptionHandler.java b/security-front/src/main/java/com/nowait/exception/GlobalExceptionHandler.java deleted file mode 100644 index b9f7c1e2..00000000 --- a/security-front/src/main/java/com/nowait/exception/GlobalExceptionHandler.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.nowait.exception; - -import static com.nowait.exception.ErrorMessage.*; -import static org.springframework.http.HttpStatus.*; -import static org.springframework.http.HttpStatus.UNAUTHORIZED; - -import java.util.Map; -import java.util.stream.Collectors; - -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.MissingRequestValueException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestControllerAdvice; -import org.springframework.web.multipart.MultipartException; - -import io.swagger.v3.oas.annotations.Hidden; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Hidden -@RestControllerAdvice -public class GlobalExceptionHandler { - - // OAUTH 인증 실패 에러처리 메서드 - @ResponseStatus(value = BAD_REQUEST) - @ExceptionHandler(OAuth2AuthenticationException.class) - public ErrorResponse handlerOAuth2AuthenticationException(OAuth2AuthenticationException e) { - log.error("handleOAuth2AuthenticationException", e); - - return new ErrorResponse("OAuth 인증 실패 : " + e.getMessage(), INVALID_INPUT_VALUE.getCode()); - } - - @ResponseStatus(value = BAD_REQUEST) - @ExceptionHandler(BusinessException.class) - public ErrorResponse handleBusinessException(BusinessException e) { - log.error("handleBusinessException", e); - return new ErrorResponse(e.getMessage(), e.getCode()); - } - - @ResponseStatus(value = BAD_REQUEST) - @ExceptionHandler(MethodArgumentNotValidException.class) - public ErrorResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { - log.error("handleMethodArgumentNotValidException", e); - Map errors = getErrors(e); - return new ErrorResponse(INVALID_INPUT_VALUE.getMessage(), INVALID_INPUT_VALUE.getCode(), errors); - } - - @ResponseStatus(value = BAD_REQUEST) - @ExceptionHandler(HttpMessageNotReadableException.class) - public ErrorResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { - log.error("handleHttpMessageNotReadableException", e); - return new ErrorResponse(INVALID_INPUT_VALUE.getMessage(), INVALID_INPUT_VALUE.getCode()); - } - - @ResponseStatus(value = BAD_REQUEST) - @ExceptionHandler(IllegalArgumentException.class) - public ErrorResponse handleIllegalArgumentException(IllegalArgumentException e) { - log.error("handleIllegalArgumentException", e); - return new ErrorResponse(e.getMessage(), INVALID_INPUT_VALUE.getCode()); - } - - @ResponseStatus(value = BAD_REQUEST) - @ExceptionHandler(MissingRequestValueException.class) - public ErrorResponse handleMissingRequestValueException(MissingRequestValueException e) { - log.error("handleMissingRequestValueExceptionException", e); - return new ErrorResponse(INVALID_INPUT_VALUE.getMessage(), INVALID_INPUT_VALUE.getCode()); - } - - @ResponseStatus(value = UNAUTHORIZED) - @ExceptionHandler(UnauthorizedException.class) - public ErrorResponse handleUnauthorizedException(UnauthorizedException e) { - log.error("handleUnauthorizedExceptionException", e); - return new ErrorResponse(e.getMessage(), e.getCode()); - } - - @ResponseStatus(value = NOT_FOUND) - @ExceptionHandler(ResourceNotFoundException.class) - public ErrorResponse handleResourceNotFoundException(ResourceNotFoundException e) { - log.error("handleResourceNotFoundExceptionException", e); - return new ErrorResponse(e.getMessage(), e.getCode()); - } - - @ResponseStatus(value = BAD_REQUEST) - @ExceptionHandler(MultipartException.class) - public ErrorResponse handleMultipartException(MultipartException e) { - log.error("handleMultipartException", e); - return new ErrorResponse(e.getMessage(), INVALID_INPUT_VALUE.getCode()); - } - - - private static Map getErrors(MethodArgumentNotValidException e) { - return e.getBindingResult() - .getAllErrors() - .stream() - .filter(ObjectError.class::isInstance) - .collect(Collectors.toMap( - error -> error instanceof FieldError ? ((FieldError)error).getField() : error.getObjectName(), - ObjectError::getDefaultMessage, - (msg1, msg2) -> msg1 + ";" + msg2 - )); - } - -} diff --git a/security-front/src/main/java/com/nowait/exception/RefreshTokenNotFoundException.java b/security-front/src/main/java/com/nowait/exception/RefreshTokenNotFoundException.java deleted file mode 100644 index 5365ef52..00000000 --- a/security-front/src/main/java/com/nowait/exception/RefreshTokenNotFoundException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.nowait.exception; - -public class RefreshTokenNotFoundException extends ResourceNotFoundException { - - public RefreshTokenNotFoundException() { - super(ErrorMessage.REFRESH_TOKEN_NOT_FOUND); - } - -} diff --git a/security-front/src/main/java/com/nowait/exception/ResourceNotFoundException.java b/security-front/src/main/java/com/nowait/exception/ResourceNotFoundException.java deleted file mode 100644 index ae4e4b7b..00000000 --- a/security-front/src/main/java/com/nowait/exception/ResourceNotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.nowait.exception; - -public abstract class ResourceNotFoundException extends RuntimeException { - private final ErrorMessage errorMessage; - - protected ResourceNotFoundException(ErrorMessage errorMessage) { - super(errorMessage.getMessage()); - this.errorMessage = errorMessage; - } - - public String getCode() { - return errorMessage.getCode(); - } -} diff --git a/security-front/src/main/java/com/nowait/exception/TokenBadRequestException.java b/security-front/src/main/java/com/nowait/exception/TokenBadRequestException.java deleted file mode 100644 index 504852ee..00000000 --- a/security-front/src/main/java/com/nowait/exception/TokenBadRequestException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.nowait.exception; - -public class TokenBadRequestException extends BusinessException { - public TokenBadRequestException() { - super(ErrorMessage.DOES_NOT_MATCH_REFRESH_TOKEN); - } - -} diff --git a/security-front/src/main/java/com/nowait/exception/UnauthorizedException.java b/security-front/src/main/java/com/nowait/exception/UnauthorizedException.java deleted file mode 100644 index 65a8fd0a..00000000 --- a/security-front/src/main/java/com/nowait/exception/UnauthorizedException.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.nowait.exception; - -public class UnauthorizedException extends RuntimeException { - private final ErrorMessage errorMessage; - - public UnauthorizedException() { - super(ErrorMessage.UNAUTHORIZED.getMessage()); - this.errorMessage = ErrorMessage.UNAUTHORIZED; - } - - public UnauthorizedException(ErrorMessage errorMessage) { - super(errorMessage.getMessage()); - this.errorMessage = errorMessage; - } - - public String getCode() { - return errorMessage.getCode(); - } -}