From d1f608cec5305fbbfc07cda58c6e373ad46a7ad9 Mon Sep 17 00:00:00 2001 From: parksey Date: Tue, 16 Apr 2024 17:02:46 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=93=88=20=EC=9E=AC?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 + build.gradle | 69 ++-- gradle.properties | 12 + jtoon-core/README.md | 13 + jtoon-core/core-api/build.gradle | 83 +++++ .../core-api}/src/docs/asciidoc/index.adoc | 0 .../core-api}/src/docs/asciidoc/payment.adoc | 0 .../java/shop/jtoon/JToonApplication.java | 0 .../global/aop/ApiInformationAspect.java | 7 +- .../shop/jtoon/global}/config/JpaConfig.java | 2 +- .../global/config/PasswordEncoderConfig.java | 0 .../jtoon/global}/entity/BaseTimeEntity.java | 2 +- .../shop/jtoon/global}/util/DynamicQuery.java | 2 +- .../jtoon/internal}/config/RedisConfig.java | 2 +- .../repository/StringRedisRepository.java | 5 +- .../internal}/service/RedisTokenService.java | 4 +- .../member/application/EmailService.java | 3 +- .../member/application/MemberService.java | 27 +- .../shop/jtoon/member}/dto/MemberDto.java | 8 +- .../jtoon/member}/dto/OAuthAttributes.java | 5 +- .../jtoon/member}/dto/OAuthSignUpDto.java | 11 +- .../shop/jtoon/member}/entity/Gender.java | 2 +- .../shop/jtoon/member}/entity/LoginType.java | 2 +- .../shop/jtoon/member}/entity/Member.java | 3 +- .../jtoon/member}/entity/MemberStatus.java | 2 +- .../java/shop/jtoon/member}/entity/Role.java | 2 +- .../member/presentation/MemberController.java | 0 .../member}/repository/MemberRepository.java | 7 +- .../jtoon/member/request/LocalSignUpReq.java | 8 +- .../application/MemberCookieService.java | 11 +- .../application/PaymentInfoService.java | 19 +- .../payment/application/PaymentService.java | 13 +- .../jtoon/payment}/entity/CookieItem.java | 2 +- .../jtoon/payment}/entity/MemberCookie.java | 4 +- .../jtoon/payment}/entity/PaymentInfo.java | 24 +- .../presentation/PaymentController.java | 17 +- .../repository/MemberCookieRepository.java | 9 +- .../repository/PaymentInfoRepository.java | 4 +- .../PaymentInfoSearchRepository.java | 18 +- .../shop/jtoon/payment/request/CancelReq.java | 4 +- .../jtoon/payment/request/ConditionReq.java | 4 +- .../jtoon/payment/request/PaymentReq.java | 17 +- .../jtoon/payment/response/PaymentRes.java | 6 +- .../service/PaymentInfoDomainService.java | 11 +- .../AuthenticationServiceImpl.java | 5 +- .../security/application/JwtServiceImpl.java | 7 +- .../security/application/OAuth2Service.java | 11 +- .../application/RefreshTokenServiceImpl.java | 2 +- .../security/presentation/AuthController.java | 0 .../shop/jtoon/security/request/LoginReq.java | 0 .../webtoon/application/EpisodeService.java | 20 +- .../webtoon/application/WebtoonService.java | 45 ++- .../webtoon}/entity/DayOfWeekWebtoon.java | 5 +- .../shop/jtoon/webtoon}/entity/Episode.java | 3 +- .../jtoon/webtoon}/entity/GenreWebtoon.java | 10 +- .../webtoon}/entity/PurchasedEpisode.java | 4 +- .../shop/jtoon/webtoon}/entity/Webtoon.java | 6 +- .../jtoon/webtoon}/entity/enums/AgeLimit.java | 2 +- .../webtoon}/entity/enums/DayOfWeek.java | 2 +- .../jtoon/webtoon}/entity/enums/Genre.java | 2 +- .../presentation/WebtoonController.java | 12 +- .../DayOfWeekWebtoonRepository.java | 6 +- .../repository/EpisodeRepository.java | 6 +- .../repository/EpisodeSearchRepository.java | 10 +- .../repository/GenreWebtoonRepository.java | 6 +- .../PurchasedEpisodeRepository.java | 4 +- .../repository/WebtoonRepository.java | 4 +- .../repository/WebtoonSearchRepository.java | 15 +- .../webtoon/request/CreateEpisodeReq.java | 4 +- .../webtoon/request/CreateWebtoonReq.java | 14 +- .../jtoon/webtoon/request/GetEpisodesReq.java | 0 .../jtoon/webtoon/request/GetWebtoonsReq.java | 2 +- .../jtoon/webtoon}/response/AuthorRes.java | 4 +- .../webtoon}/response/EpisodeInfoRes.java | 4 +- .../webtoon}/response/EpisodeItemRes.java | 4 +- .../jtoon/webtoon}/response/EpisodeRes.java | 6 +- .../jtoon/webtoon}/response/GenreRes.java | 6 +- .../webtoon}/response/WebtoonInfoRes.java | 6 +- .../webtoon}/response/WebtoonItemRes.java | 4 +- .../jtoon/webtoon}/response/WebtoonRes.java | 8 +- .../src/main/resources/application.yml | 0 jtoon-core/core-api/src/main/resources/config | 1 + .../src/main/resources}/docs/index.html | 0 .../src/main/resources}/docs/payment.html | 0 .../src/test/resources/application-test.yml | 0 .../core-api}/src/test/resources/test.png | Bin jtoon-internal/README.md | 9 + .../core-web/build.gradle | 3 + .../shop/jtoon/annotation/CurrentUser.java | 0 .../shop/jtoon/config/SecurityConfig.java | 0 .../java/shop/jtoon/config/WebConfig.java | 0 .../error/handler/GlobalExceptionHandler.java | 0 .../shop/jtoon/error/model/ErrorResponse.java | 0 .../security/filter/AuthenticationFilter.java | 0 .../handler/OAuth2FailureHandler.java | 0 .../handler/OAuth2SuccessHandler.java | 0 .../service/AuthenticationService.java | 0 .../service/AuthorizationService.java | 0 .../service/CustomOAuth2UserService.java | 0 .../jtoon/security/service/JwtService.java | 0 .../security/service/RefreshTokenService.java | 0 .../shop/jtoon/security/util/TokenCookie.java | 0 .../security/SecurityApplicationTest.java | 0 .../filter/AuthenticationFilterTest.java | 0 .../iamport-client/build.gradle | 1 + .../java/shop/jtoon/config/IamportConfig.java | 0 .../shop/jtoon/service/IamportService.java | 0 .../jtoon/IamportClientApplicationTest.java | 0 .../jtoon/service/IamportServiceTest.java | 0 .../s3-client/build.gradle | 3 + .../main/java/shop/jtoon/common/FileName.java | 0 .../java/shop/jtoon/common/ImageType.java | 0 .../java/shop/jtoon/dto/UploadImageDto.java | 0 .../java/shop/jtoon/service/S3Service.java | 0 .../main/java/shop/jtoon/util/S3Manager.java | 0 .../smtp-client/build.gradle | 3 + .../shop/jtoon/application/SmtpService.java | 0 .../src/main/java/shop/jtoon/entity/Mail.java | 0 .../java/shop/jtoon/SmtpApplicationTest.java | 0 .../jtoon/application/SmtpServiceTest.java | 0 jtoon-support/README.md | 19 + .../logging}/build.gradle | 0 .../main/resources/logback/logback-dev.xml | 39 ++ .../main/resources/logback/logback-local.xml | 24 ++ .../logging/src/main/resources/logging.yml | 7 + jtoon-support/monitoring/build.gradle | 0 jtoon-system/README.md | 7 + jtoon-system/build.gradle | 0 .../jtoon/exception/DuplicatedException.java | 0 .../jtoon/exception/ForbiddenException.java | 0 .../jtoon/exception/IamportException.java | 0 .../exception/InvalidRequestException.java | 0 .../jtoon/exception/NotFoundException.java | 0 .../exception/UnauthorizedException.java | 0 .../shop/jtoon/type/CustomPageRequest.java | 0 .../java/shop/jtoon/type/ErrorStatus.java | 0 .../src/main/java/shop/jtoon/util/RegExp.java | 0 .../shop/jtoon/util/SecurityConstant.java | 0 module-application/README.md | 15 - module-application/app-api/Dockerfile | 9 - module-application/app-api/build.gradle | 77 ---- .../shop/jtoon/config/WithCurrentUser.java | 34 -- .../shop/jtoon/factory/MemberFactory.java | 49 --- .../shop/jtoon/factory/PaymentFactory.java | 80 ---- .../jtoon/factory/PaymentSnippetFactory.java | 39 -- .../shop/jtoon/factory/WebtoonFactory.java | 98 ----- .../application/MemberCookieServiceTest.java | 118 ------ .../application/PaymentInfoServiceTest.java | 134 ------- .../application/PaymentServiceTest.java | 107 ------ .../presentation/PaymentControllerTest.java | 348 ------------------ .../AuthenticationServiceTest.java | 70 ---- .../application/JwtServiceImplTest.java | 86 ----- .../application/EpisodeServiceTest.java | 203 ---------- .../application/WebtoonServiceTest.java | 203 ---------- module-application/build.gradle | 18 - module-core/README.md | 15 - module-domain/README.md | 26 -- module-domain/build.gradle | 47 --- module-domain/domain-jpa/build.gradle | 13 - module-domain/domain-member/build.gradle | 18 - .../jtoon/MemberDomainApplicationTest.java | 7 - .../repository/MemberRepositoryTest.java | 170 --------- module-domain/domain-payment/build.gradle | 15 - .../jtoon/DomainPaymentApplicationTest.java | 7 - .../shop/jtoon/factory/CreatorFactory.java | 32 -- .../PaymentInfoSearchRepositoryTest.java | 124 ------- .../service/PaymentInfoDomainServiceTest.java | 49 --- module-domain/domain-redis/build.gradle | 15 - module-domain/domain-webtoon/build.gradle | 12 - module-internal/README.md | 21 -- module-internal/build.gradle | 31 -- settings.gradle | 31 +- 172 files changed, 558 insertions(+), 2575 deletions(-) create mode 100644 .gitmodules create mode 100644 gradle.properties create mode 100644 jtoon-core/README.md create mode 100644 jtoon-core/core-api/build.gradle rename {module-application/app-api => jtoon-core/core-api}/src/docs/asciidoc/index.adoc (100%) rename {module-application/app-api => jtoon-core/core-api}/src/docs/asciidoc/payment.adoc (100%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/JToonApplication.java (100%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/global/aop/ApiInformationAspect.java (99%) rename {module-domain/domain-jpa/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/global}/config/JpaConfig.java (94%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/global/config/PasswordEncoderConfig.java (100%) rename {module-domain/domain-jpa/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/global}/entity/BaseTimeEntity.java (95%) rename {module-domain/domain-jpa/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/global}/util/DynamicQuery.java (96%) rename {module-domain/domain-redis/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/internal}/config/RedisConfig.java (97%) rename {module-domain/domain-redis/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/internal}/repository/StringRedisRepository.java (95%) rename {module-domain/domain-redis/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/internal}/service/RedisTokenService.java (89%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/member/application/EmailService.java (99%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/member/application/MemberService.java (93%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/dto/MemberDto.java (75%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/dto/OAuthAttributes.java (96%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/dto/OAuthSignUpDto.java (71%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/entity/Gender.java (96%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/entity/LoginType.java (96%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/entity/Member.java (97%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/entity/MemberStatus.java (83%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/entity/Role.java (81%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/member/presentation/MemberController.java (100%) rename {module-domain/domain-member/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/member}/repository/MemberRepository.java (72%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java (84%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/application/MemberCookieService.java (87%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java (87%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/application/PaymentService.java (96%) rename {module-domain/domain-payment/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/payment}/entity/CookieItem.java (97%) rename {module-domain/domain-payment/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/payment}/entity/MemberCookie.java (93%) rename {module-domain/domain-payment/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/payment}/entity/PaymentInfo.java (78%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/presentation/PaymentController.java (79%) rename {module-domain/domain-payment/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/payment}/repository/MemberCookieRepository.java (70%) rename {module-domain/domain-payment/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/payment}/repository/PaymentInfoRepository.java (78%) rename {module-domain/domain-payment/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/payment}/repository/PaymentInfoSearchRepository.java (71%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/request/CancelReq.java (100%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/request/ConditionReq.java (100%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/request/PaymentReq.java (68%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/payment/response/PaymentRes.java (93%) rename {module-domain/domain-payment/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/payment}/service/PaymentInfoDomainService.java (90%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java (95%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/security/application/JwtServiceImpl.java (99%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/security/application/OAuth2Service.java (94%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java (94%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/security/presentation/AuthController.java (100%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/security/request/LoginReq.java (100%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java (87%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java (77%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/DayOfWeekWebtoon.java (92%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/Episode.java (96%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/GenreWebtoon.java (87%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/PurchasedEpisode.java (91%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/Webtoon.java (93%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/enums/AgeLimit.java (86%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/enums/DayOfWeek.java (84%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/entity/enums/Genre.java (91%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/webtoon/presentation/WebtoonController.java (90%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/repository/DayOfWeekWebtoonRepository.java (64%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/repository/EpisodeRepository.java (61%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/repository/EpisodeSearchRepository.java (75%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/repository/GenreWebtoonRepository.java (64%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/repository/PurchasedEpisodeRepository.java (63%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/repository/WebtoonRepository.java (68%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/repository/WebtoonSearchRepository.java (67%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java (93%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java (82%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java (100%) rename {module-application/app-api => jtoon-core/core-api}/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java (73%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/AuthorRes.java (75%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/EpisodeInfoRes.java (74%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/EpisodeItemRes.java (86%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/EpisodeRes.java (86%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/GenreRes.java (67%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/WebtoonInfoRes.java (84%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/WebtoonItemRes.java (85%) rename {module-domain/domain-webtoon/src/main/java/shop/jtoon => jtoon-core/core-api/src/main/java/shop/jtoon/webtoon}/response/WebtoonRes.java (81%) rename {module-application/app-api => jtoon-core/core-api}/src/main/resources/application.yml (100%) create mode 160000 jtoon-core/core-api/src/main/resources/config rename {module-application/app-api/src/main/resources/static => jtoon-core/core-api/src/main/resources}/docs/index.html (100%) rename {module-application/app-api/src/main/resources/static => jtoon-core/core-api/src/main/resources}/docs/payment.html (100%) rename {module-application/app-api => jtoon-core/core-api}/src/test/resources/application-test.yml (100%) rename {module-application/app-api => jtoon-core/core-api}/src/test/resources/test.png (100%) create mode 100644 jtoon-internal/README.md rename {module-internal => jtoon-internal}/core-web/build.gradle (92%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/annotation/CurrentUser.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/config/SecurityConfig.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/config/WebConfig.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/error/model/ErrorResponse.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/filter/AuthenticationFilter.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/handler/OAuth2FailureHandler.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/handler/OAuth2SuccessHandler.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/service/AuthenticationService.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/service/AuthorizationService.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/service/CustomOAuth2UserService.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/service/JwtService.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/service/RefreshTokenService.java (100%) rename {module-internal => jtoon-internal}/core-web/src/main/java/shop/jtoon/security/util/TokenCookie.java (100%) rename {module-internal => jtoon-internal}/core-web/src/test/java/shop/jtoon/security/SecurityApplicationTest.java (100%) rename {module-internal => jtoon-internal}/core-web/src/test/java/shop/jtoon/security/filter/AuthenticationFilterTest.java (100%) rename {module-internal => jtoon-internal}/iamport-client/build.gradle (89%) rename {module-internal => jtoon-internal}/iamport-client/src/main/java/shop/jtoon/config/IamportConfig.java (100%) rename {module-internal => jtoon-internal}/iamport-client/src/main/java/shop/jtoon/service/IamportService.java (100%) rename {module-internal => jtoon-internal}/iamport-client/src/test/java/shop/jtoon/IamportClientApplicationTest.java (100%) rename {module-internal => jtoon-internal}/iamport-client/src/test/java/shop/jtoon/service/IamportServiceTest.java (100%) rename {module-internal => jtoon-internal}/s3-client/build.gradle (84%) rename {module-internal => jtoon-internal}/s3-client/src/main/java/shop/jtoon/common/FileName.java (100%) rename {module-internal => jtoon-internal}/s3-client/src/main/java/shop/jtoon/common/ImageType.java (100%) rename {module-internal => jtoon-internal}/s3-client/src/main/java/shop/jtoon/dto/UploadImageDto.java (100%) rename {module-internal => jtoon-internal}/s3-client/src/main/java/shop/jtoon/service/S3Service.java (100%) rename {module-internal => jtoon-internal}/s3-client/src/main/java/shop/jtoon/util/S3Manager.java (100%) rename {module-internal => jtoon-internal}/smtp-client/build.gradle (86%) rename {module-internal => jtoon-internal}/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java (100%) rename {module-internal => jtoon-internal}/smtp-client/src/main/java/shop/jtoon/entity/Mail.java (100%) rename {module-internal => jtoon-internal}/smtp-client/src/test/java/shop/jtoon/SmtpApplicationTest.java (100%) rename {module-internal => jtoon-internal}/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java (100%) create mode 100644 jtoon-support/README.md rename {module-core => jtoon-support/logging}/build.gradle (100%) create mode 100644 jtoon-support/logging/src/main/resources/logback/logback-dev.xml create mode 100644 jtoon-support/logging/src/main/resources/logback/logback-local.xml create mode 100644 jtoon-support/logging/src/main/resources/logging.yml create mode 100644 jtoon-support/monitoring/build.gradle create mode 100644 jtoon-system/README.md create mode 100644 jtoon-system/build.gradle rename {module-core => jtoon-system}/src/main/java/shop/jtoon/exception/DuplicatedException.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/exception/ForbiddenException.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/exception/IamportException.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/exception/InvalidRequestException.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/exception/NotFoundException.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/exception/UnauthorizedException.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/type/CustomPageRequest.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/type/ErrorStatus.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/util/RegExp.java (100%) rename {module-core => jtoon-system}/src/main/java/shop/jtoon/util/SecurityConstant.java (100%) delete mode 100644 module-application/README.md delete mode 100644 module-application/app-api/Dockerfile delete mode 100644 module-application/app-api/build.gradle delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/config/WithCurrentUser.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/factory/MemberFactory.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/factory/PaymentFactory.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/factory/PaymentSnippetFactory.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/factory/WebtoonFactory.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/payment/application/MemberCookieServiceTest.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentInfoServiceTest.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentServiceTest.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/payment/presentation/PaymentControllerTest.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/security/application/AuthenticationServiceTest.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/security/application/JwtServiceImplTest.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/webtoon/application/EpisodeServiceTest.java delete mode 100644 module-application/app-api/src/test/java/shop/jtoon/webtoon/application/WebtoonServiceTest.java delete mode 100644 module-application/build.gradle delete mode 100644 module-core/README.md delete mode 100644 module-domain/README.md delete mode 100644 module-domain/build.gradle delete mode 100644 module-domain/domain-jpa/build.gradle delete mode 100644 module-domain/domain-member/build.gradle delete mode 100644 module-domain/domain-member/src/test/java/shop/jtoon/MemberDomainApplicationTest.java delete mode 100644 module-domain/domain-member/src/test/java/shop/jtoon/repository/MemberRepositoryTest.java delete mode 100644 module-domain/domain-payment/build.gradle delete mode 100644 module-domain/domain-payment/src/test/java/shop/jtoon/DomainPaymentApplicationTest.java delete mode 100644 module-domain/domain-payment/src/test/java/shop/jtoon/factory/CreatorFactory.java delete mode 100644 module-domain/domain-payment/src/test/java/shop/jtoon/repository/PaymentInfoSearchRepositoryTest.java delete mode 100644 module-domain/domain-payment/src/test/java/shop/jtoon/service/PaymentInfoDomainServiceTest.java delete mode 100644 module-domain/domain-redis/build.gradle delete mode 100644 module-domain/domain-webtoon/build.gradle delete mode 100644 module-internal/README.md delete mode 100644 module-internal/build.gradle diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f8956e9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "jtoon-core/core-api/src/main/resources/config"] + path = jtoon-core/core-api/src/main/resources/config + url = https://github.com/BE-04-JTOON/private-env.git diff --git a/build.gradle b/build.gradle index a3be76e..ead039d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,56 +1,51 @@ -buildscript { - ext { - springBootVersion = '3.1.2' - } - - repositories { - mavenCentral() - } - - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") - classpath "io.spring.gradle:dependency-management-plugin:1.1.2" - } +plugins { + id 'java' + id "java-library" + id 'org.springframework.boot' apply false + id 'io.spring.dependency-management' apply false } -subprojects { - group 'shop.jtoon' - version '0.0.1-SNAPSHOT' +java.sourceCompatibility = javaVersion - apply plugin: 'java-library' - apply plugin: 'idea' - apply plugin: 'org.springframework.boot' - apply plugin: 'io.spring.dependency-management' +applicationVersion=project['applicationVersion'] +projectGroup=project['projectGroup'] +javaVersion=project['javaVersion'] + +allprojects { + group = projectGroup + version = applicationVersion - sourceCompatibility = 17 + apply plugin: "java" + apply plugin: "java-library" repositories { mavenCentral() maven { url 'https://jitpack.io' } } +} + +subprojects { + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' dependencies { + // Lombok compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' - } - test { - useJUnitPlatform() + // Test + testImplementation 'org.springframework.boot:spring-boot-starter-test' } -} -project(':module-application') { - bootJar.enabled = false -} - -project(':module-domain') { - bootJar.enabled = false -} + tasks.getByName('bootJar') { + enabled = false + } -project(':module-internal') { - bootJar.enabled = false + tasks.getByName("jar") { + enabled = false + } } -project(':module-core') { - bootJar.enabled = false -} +tasks.named('test') { + useJUnitPlatform() +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..9ee1350 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,12 @@ +# Project dependency versions +applicationVersion=0.0.1 +javaVersion=17 + +# Project Configs +projectGroup=org.example + + +# Spring dependency versions +springBootVersion=3.2.4 +springDependencyManagementVersion=1.1.4 +springCloudDependenciesVersion=2023.0.1 \ No newline at end of file diff --git a/jtoon-core/README.md b/jtoon-core/README.md new file mode 100644 index 0000000..427f306 --- /dev/null +++ b/jtoon-core/README.md @@ -0,0 +1,13 @@ +# JToon Core + +Jtoon 서비스의 해결하고자하는 도메인에 대한 모듈 + +## 계층별 지키고자 하는 조건 +(layered 기반) + +- Presentation Layer : 외부 의존성이 높은 영역, Controller, dto 존재 +- Domain Layer(Service) : 해결하고자 하는 문제인 도메인에 집중하고자 하는 layer +- Repository Layer : 상세 구현 로직이 다양한 자원에 접근할 수 있는 기능을 제공하는 레이어 + +## Include +- `core-api`: 전체 도메인 로직에 대한 모듈만 존재 \ No newline at end of file diff --git a/jtoon-core/core-api/build.gradle b/jtoon-core/core-api/build.gradle new file mode 100644 index 0000000..9a30f58 --- /dev/null +++ b/jtoon-core/core-api/build.gradle @@ -0,0 +1,83 @@ +tasks.getByName('bootJar') { + enabled = true +} + +tasks.getByName("jar") { + enabled = false +} + +def generatedDir = "src/main/generated" + +sourceSets { + main { + java { + srcDirs = ['src/main/java'] + } + + resources { + srcDir "${project.projectDir}/src/main/java" + } + } +} + +clean { + delete file(generatedDir) +} + +dependencies { + + implementation project(":jtoon-system") + implementation project(":jtoon-internal:core-web") + implementation project(":jtoon-internal:iamport-client") + implementation project(":jtoon-internal:s3-client") + implementation project(":jtoon-internal:smtp-client") + + implementation project(":jtoon-support:logging") + implementation project(":jtoon-support:monitoring") + + implementation project(":jtoon-system") + // Redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + + // Web + implementation 'org.springframework.boot:spring-boot-starter-web' + + // Bean Validation + implementation 'org.springframework.boot:spring-boot-starter-validation' + + // JPA + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + // AOP + implementation 'org.springframework.boot:spring-boot-starter-aop' + + // H2 + implementation 'com.h2database:h2' + + // Test + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + // Security + implementation 'org.springframework.boot:spring-boot-starter-security' + testImplementation 'org.springframework.security:spring-security-test' + + // OAuth2 + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + + // JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + + // RestDocs + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + + // MySQL + implementation 'com.mysql:mysql-connector-j:8.0.33' + + // Querydsl + api 'com.querydsl:querydsl-jpa:5.0.0:jakarta' + annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' + annotationProcessor 'jakarta.annotation:jakarta.annotation-api' + annotationProcessor 'jakarta.persistence:jakarta.persistence-api' +} diff --git a/module-application/app-api/src/docs/asciidoc/index.adoc b/jtoon-core/core-api/src/docs/asciidoc/index.adoc similarity index 100% rename from module-application/app-api/src/docs/asciidoc/index.adoc rename to jtoon-core/core-api/src/docs/asciidoc/index.adoc diff --git a/module-application/app-api/src/docs/asciidoc/payment.adoc b/jtoon-core/core-api/src/docs/asciidoc/payment.adoc similarity index 100% rename from module-application/app-api/src/docs/asciidoc/payment.adoc rename to jtoon-core/core-api/src/docs/asciidoc/payment.adoc diff --git a/module-application/app-api/src/main/java/shop/jtoon/JToonApplication.java b/jtoon-core/core-api/src/main/java/shop/jtoon/JToonApplication.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/JToonApplication.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/JToonApplication.java diff --git a/module-application/app-api/src/main/java/shop/jtoon/global/aop/ApiInformationAspect.java b/jtoon-core/core-api/src/main/java/shop/jtoon/global/aop/ApiInformationAspect.java similarity index 99% rename from module-application/app-api/src/main/java/shop/jtoon/global/aop/ApiInformationAspect.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/global/aop/ApiInformationAspect.java index 00910cd..1bbeb69 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/global/aop/ApiInformationAspect.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/global/aop/ApiInformationAspect.java @@ -1,6 +1,8 @@ package shop.jtoon.global.aop; -import lombok.extern.slf4j.Slf4j; +import java.lang.reflect.Method; +import java.util.Arrays; + import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; @@ -10,8 +12,7 @@ import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; -import java.lang.reflect.Method; -import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; @Slf4j @Aspect diff --git a/module-domain/domain-jpa/src/main/java/shop/jtoon/config/JpaConfig.java b/jtoon-core/core-api/src/main/java/shop/jtoon/global/config/JpaConfig.java similarity index 94% rename from module-domain/domain-jpa/src/main/java/shop/jtoon/config/JpaConfig.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/global/config/JpaConfig.java index ebc4476..a044afe 100644 --- a/module-domain/domain-jpa/src/main/java/shop/jtoon/config/JpaConfig.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/global/config/JpaConfig.java @@ -1,4 +1,4 @@ -package shop.jtoon.config; +package shop.jtoon.global.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/module-application/app-api/src/main/java/shop/jtoon/global/config/PasswordEncoderConfig.java b/jtoon-core/core-api/src/main/java/shop/jtoon/global/config/PasswordEncoderConfig.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/global/config/PasswordEncoderConfig.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/global/config/PasswordEncoderConfig.java diff --git a/module-domain/domain-jpa/src/main/java/shop/jtoon/entity/BaseTimeEntity.java b/jtoon-core/core-api/src/main/java/shop/jtoon/global/entity/BaseTimeEntity.java similarity index 95% rename from module-domain/domain-jpa/src/main/java/shop/jtoon/entity/BaseTimeEntity.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/global/entity/BaseTimeEntity.java index 8b4895b..981936f 100644 --- a/module-domain/domain-jpa/src/main/java/shop/jtoon/entity/BaseTimeEntity.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/global/entity/BaseTimeEntity.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.global.entity; import java.time.LocalDateTime; diff --git a/module-domain/domain-jpa/src/main/java/shop/jtoon/util/DynamicQuery.java b/jtoon-core/core-api/src/main/java/shop/jtoon/global/util/DynamicQuery.java similarity index 96% rename from module-domain/domain-jpa/src/main/java/shop/jtoon/util/DynamicQuery.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/global/util/DynamicQuery.java index cb530a2..5211e9b 100644 --- a/module-domain/domain-jpa/src/main/java/shop/jtoon/util/DynamicQuery.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/global/util/DynamicQuery.java @@ -1,4 +1,4 @@ -package shop.jtoon.util; +package shop.jtoon.global.util; import java.util.List; import java.util.Objects; diff --git a/module-domain/domain-redis/src/main/java/shop/jtoon/config/RedisConfig.java b/jtoon-core/core-api/src/main/java/shop/jtoon/internal/config/RedisConfig.java similarity index 97% rename from module-domain/domain-redis/src/main/java/shop/jtoon/config/RedisConfig.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/internal/config/RedisConfig.java index 5aa5a80..abf480a 100644 --- a/module-domain/domain-redis/src/main/java/shop/jtoon/config/RedisConfig.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/internal/config/RedisConfig.java @@ -1,4 +1,4 @@ -package shop.jtoon.config; +package shop.jtoon.internal.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/module-domain/domain-redis/src/main/java/shop/jtoon/repository/StringRedisRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/internal/repository/StringRedisRepository.java similarity index 95% rename from module-domain/domain-redis/src/main/java/shop/jtoon/repository/StringRedisRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/internal/repository/StringRedisRepository.java index ac602b3..f7a8f97 100644 --- a/module-domain/domain-redis/src/main/java/shop/jtoon/repository/StringRedisRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/internal/repository/StringRedisRepository.java @@ -1,11 +1,12 @@ -package shop.jtoon.repository; +package shop.jtoon.internal.repository; import static shop.jtoon.util.SecurityConstant.*; +import java.util.concurrent.TimeUnit; + import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Repository; -import java.util.concurrent.TimeUnit; import lombok.RequiredArgsConstructor; @Repository diff --git a/module-domain/domain-redis/src/main/java/shop/jtoon/service/RedisTokenService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/internal/service/RedisTokenService.java similarity index 89% rename from module-domain/domain-redis/src/main/java/shop/jtoon/service/RedisTokenService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/internal/service/RedisTokenService.java index 33b9042..c2b8393 100644 --- a/module-domain/domain-redis/src/main/java/shop/jtoon/service/RedisTokenService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/internal/service/RedisTokenService.java @@ -1,10 +1,10 @@ -package shop.jtoon.service; +package shop.jtoon.internal.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; -import shop.jtoon.repository.StringRedisRepository; +import shop.jtoon.internal.repository.StringRedisRepository; @Service @RequiredArgsConstructor diff --git a/module-application/app-api/src/main/java/shop/jtoon/member/application/EmailService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/EmailService.java similarity index 99% rename from module-application/app-api/src/main/java/shop/jtoon/member/application/EmailService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/application/EmailService.java index 65709b8..71512b7 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/member/application/EmailService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/EmailService.java @@ -1,9 +1,10 @@ package shop.jtoon.member.application; +import java.util.UUID; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.UUID; import lombok.RequiredArgsConstructor; import shop.jtoon.application.SmtpService; import shop.jtoon.entity.Mail; diff --git a/module-application/app-api/src/main/java/shop/jtoon/member/application/MemberService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/MemberService.java similarity index 93% rename from module-application/app-api/src/main/java/shop/jtoon/member/application/MemberService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/application/MemberService.java index c41177d..6bf1a38 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/member/application/MemberService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/MemberService.java @@ -1,29 +1,32 @@ package shop.jtoon.member.application; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; +import static shop.jtoon.type.ErrorStatus.*; +import static shop.jtoon.util.SecurityConstant.*; + +import java.util.Optional; + import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import shop.jtoon.dto.MemberDto; -import shop.jtoon.dto.OAuthSignUpDto; -import shop.jtoon.entity.LoginType; -import shop.jtoon.entity.Member; + +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; + import shop.jtoon.exception.DuplicatedException; import shop.jtoon.exception.InvalidRequestException; import shop.jtoon.exception.NotFoundException; +import shop.jtoon.member.dto.MemberDto; +import shop.jtoon.member.dto.OAuthSignUpDto; +import shop.jtoon.member.entity.LoginType; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.repository.MemberRepository; import shop.jtoon.member.request.LocalSignUpReq; -import shop.jtoon.repository.MemberRepository; + import shop.jtoon.security.request.LoginReq; import shop.jtoon.security.service.JwtService; import shop.jtoon.security.service.RefreshTokenService; import shop.jtoon.security.util.TokenCookie; -import java.util.Optional; - -import static shop.jtoon.type.ErrorStatus.*; -import static shop.jtoon.util.SecurityConstant.*; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/dto/MemberDto.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/MemberDto.java similarity index 75% rename from module-domain/domain-member/src/main/java/shop/jtoon/dto/MemberDto.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/MemberDto.java index 7ddf941..1e1c308 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/dto/MemberDto.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/MemberDto.java @@ -1,9 +1,9 @@ -package shop.jtoon.dto; +package shop.jtoon.member.dto; import lombok.Builder; -import shop.jtoon.entity.Gender; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Role; +import shop.jtoon.member.entity.Gender; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.entity.Role; @Builder public record MemberDto( diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/dto/OAuthAttributes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthAttributes.java similarity index 96% rename from module-domain/domain-member/src/main/java/shop/jtoon/dto/OAuthAttributes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthAttributes.java index b81d363..5375f01 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/dto/OAuthAttributes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthAttributes.java @@ -1,13 +1,14 @@ -package shop.jtoon.dto; +package shop.jtoon.member.dto; import static shop.jtoon.type.ErrorStatus.*; import java.util.Map; import java.util.UUID; + import lombok.AccessLevel; import lombok.Builder; -import shop.jtoon.entity.LoginType; import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.member.entity.LoginType; @Builder(access = AccessLevel.PRIVATE) public record OAuthAttributes( diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/dto/OAuthSignUpDto.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthSignUpDto.java similarity index 71% rename from module-domain/domain-member/src/main/java/shop/jtoon/dto/OAuthSignUpDto.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthSignUpDto.java index 94a77a2..c31429f 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/dto/OAuthSignUpDto.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthSignUpDto.java @@ -1,10 +1,11 @@ -package shop.jtoon.dto; +package shop.jtoon.member.dto; import lombok.Builder; -import shop.jtoon.entity.Gender; -import shop.jtoon.entity.LoginType; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Role; + +import shop.jtoon.member.entity.Gender; +import shop.jtoon.member.entity.LoginType; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.entity.Role; @Builder public record OAuthSignUpDto( diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/entity/Gender.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Gender.java similarity index 96% rename from module-domain/domain-member/src/main/java/shop/jtoon/entity/Gender.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Gender.java index 3daf22c..5448881 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/entity/Gender.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Gender.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.member.entity; import java.util.Arrays; import java.util.Collections; diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/entity/LoginType.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/LoginType.java similarity index 96% rename from module-domain/domain-member/src/main/java/shop/jtoon/entity/LoginType.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/LoginType.java index 66b8456..ba01968 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/entity/LoginType.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/LoginType.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.member.entity; import java.util.Arrays; import java.util.Collections; diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/entity/Member.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Member.java similarity index 97% rename from module-domain/domain-member/src/main/java/shop/jtoon/entity/Member.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Member.java index 2889468..2e0fc97 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/entity/Member.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Member.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.member.entity; import static java.util.Objects.*; import static shop.jtoon.util.RegExp.*; @@ -19,6 +19,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import shop.jtoon.global.entity.BaseTimeEntity; import shop.jtoon.type.ErrorStatus; @Entity diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/entity/MemberStatus.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/MemberStatus.java similarity index 83% rename from module-domain/domain-member/src/main/java/shop/jtoon/entity/MemberStatus.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/MemberStatus.java index 386b8b2..79e5673 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/entity/MemberStatus.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/MemberStatus.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.member.entity; import lombok.AccessLevel; import lombok.AllArgsConstructor; diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/entity/Role.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Role.java similarity index 81% rename from module-domain/domain-member/src/main/java/shop/jtoon/entity/Role.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Role.java index c23d1be..eec8ff5 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/entity/Role.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Role.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.member.entity; import lombok.AccessLevel; import lombok.AllArgsConstructor; diff --git a/module-application/app-api/src/main/java/shop/jtoon/member/presentation/MemberController.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/MemberController.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/member/presentation/MemberController.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/MemberController.java diff --git a/module-domain/domain-member/src/main/java/shop/jtoon/repository/MemberRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/repository/MemberRepository.java similarity index 72% rename from module-domain/domain-member/src/main/java/shop/jtoon/repository/MemberRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/repository/MemberRepository.java index 3eec032..5ff8b1e 100644 --- a/module-domain/domain-member/src/main/java/shop/jtoon/repository/MemberRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/repository/MemberRepository.java @@ -1,9 +1,10 @@ -package shop.jtoon.repository; +package shop.jtoon.member.repository; + +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; -import shop.jtoon.entity.Member; +import shop.jtoon.member.entity.Member; public interface MemberRepository extends JpaRepository { Optional findByEmail(String email); diff --git a/module-application/app-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java similarity index 84% rename from module-application/app-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java index e7d5ae1..94b2959 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java @@ -6,10 +6,10 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; -import shop.jtoon.entity.Gender; -import shop.jtoon.entity.LoginType; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Role; +import shop.jtoon.member.entity.Gender; +import shop.jtoon.member.entity.LoginType; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.entity.Role; public record LocalSignUpReq( @Pattern(regexp = EMAIL_PATTERN) String email, diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java similarity index 87% rename from module-application/app-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java index c4333ed..36df6fe 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java @@ -1,13 +1,14 @@ package shop.jtoon.payment.application; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import shop.jtoon.entity.CookieItem; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.MemberCookie; + +import lombok.RequiredArgsConstructor; import shop.jtoon.exception.NotFoundException; -import shop.jtoon.repository.MemberCookieRepository; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.entity.CookieItem; +import shop.jtoon.payment.entity.MemberCookie; +import shop.jtoon.payment.repository.MemberCookieRepository; import shop.jtoon.type.ErrorStatus; @Service diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java similarity index 87% rename from module-application/app-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java index 8bac33a..2ff8365 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java @@ -1,19 +1,22 @@ package shop.jtoon.payment.application; -import lombok.RequiredArgsConstructor; +import java.util.List; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PaymentInfo; + +import lombok.RequiredArgsConstructor; + import shop.jtoon.exception.DuplicatedException; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.entity.PaymentInfo; +import shop.jtoon.payment.repository.PaymentInfoRepository; +import shop.jtoon.payment.repository.PaymentInfoSearchRepository; import shop.jtoon.payment.request.PaymentReq; import shop.jtoon.payment.response.PaymentRes; -import shop.jtoon.repository.PaymentInfoRepository; -import shop.jtoon.repository.PaymentInfoSearchRepository; -import shop.jtoon.service.PaymentInfoDomainService; -import shop.jtoon.type.ErrorStatus; -import java.util.List; +import shop.jtoon.payment.service.PaymentInfoDomainService; +import shop.jtoon.type.ErrorStatus; @Service @RequiredArgsConstructor diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/application/PaymentService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentService.java similarity index 96% rename from module-application/app-api/src/main/java/shop/jtoon/payment/application/PaymentService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentService.java index 2e68bc6..0ad3e34 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/application/PaymentService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentService.java @@ -1,20 +1,21 @@ package shop.jtoon.payment.application; -import lombok.RequiredArgsConstructor; +import java.math.BigDecimal; +import java.util.List; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import shop.jtoon.dto.MemberDto; -import shop.jtoon.entity.Member; + +import lombok.RequiredArgsConstructor; import shop.jtoon.member.application.MemberService; +import shop.jtoon.member.dto.MemberDto; +import shop.jtoon.member.entity.Member; import shop.jtoon.payment.request.CancelReq; import shop.jtoon.payment.request.ConditionReq; import shop.jtoon.payment.request.PaymentReq; import shop.jtoon.payment.response.PaymentRes; import shop.jtoon.service.IamportService; -import java.math.BigDecimal; -import java.util.List; - @Service @RequiredArgsConstructor @Transactional(readOnly = true) diff --git a/module-domain/domain-payment/src/main/java/shop/jtoon/entity/CookieItem.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/CookieItem.java similarity index 97% rename from module-domain/domain-payment/src/main/java/shop/jtoon/entity/CookieItem.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/CookieItem.java index 2260be8..29e5897 100644 --- a/module-domain/domain-payment/src/main/java/shop/jtoon/entity/CookieItem.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/CookieItem.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.payment.entity; import java.math.BigDecimal; import java.util.Arrays; diff --git a/module-domain/domain-payment/src/main/java/shop/jtoon/entity/MemberCookie.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/MemberCookie.java similarity index 93% rename from module-domain/domain-payment/src/main/java/shop/jtoon/entity/MemberCookie.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/MemberCookie.java index 1a46698..f5903f7 100644 --- a/module-domain/domain-payment/src/main/java/shop/jtoon/entity/MemberCookie.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/MemberCookie.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.payment.entity; import static java.util.Objects.*; import static shop.jtoon.type.ErrorStatus.*; @@ -17,6 +17,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.member.entity.Member; @Entity @Getter diff --git a/module-domain/domain-payment/src/main/java/shop/jtoon/entity/PaymentInfo.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java similarity index 78% rename from module-domain/domain-payment/src/main/java/shop/jtoon/entity/PaymentInfo.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java index 1cde93e..155c0f4 100644 --- a/module-domain/domain-payment/src/main/java/shop/jtoon/entity/PaymentInfo.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java @@ -1,16 +1,28 @@ -package shop.jtoon.entity; +package shop.jtoon.payment.entity; -import jakarta.persistence.*; +import static java.util.Objects.*; + +import java.math.BigDecimal; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +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; +import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.member.entity.Member; import shop.jtoon.type.ErrorStatus; -import java.math.BigDecimal; - -import static java.util.Objects.requireNonNull; - @Getter @Entity @Table(name = "payments_info") diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/presentation/PaymentController.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/presentation/PaymentController.java similarity index 79% rename from module-application/app-api/src/main/java/shop/jtoon/payment/presentation/PaymentController.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/presentation/PaymentController.java index e261440..9a3413d 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/presentation/PaymentController.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/presentation/PaymentController.java @@ -1,20 +1,25 @@ package shop.jtoon.payment.presentation; +import java.math.BigDecimal; +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; import shop.jtoon.annotation.CurrentUser; -import shop.jtoon.dto.MemberDto; +import shop.jtoon.member.dto.MemberDto; import shop.jtoon.payment.application.PaymentService; import shop.jtoon.payment.request.CancelReq; import shop.jtoon.payment.request.ConditionReq; import shop.jtoon.payment.request.PaymentReq; import shop.jtoon.payment.response.PaymentRes; -import java.math.BigDecimal; -import java.util.List; - @RestController @RequiredArgsConstructor @RequestMapping("/payments") diff --git a/module-domain/domain-payment/src/main/java/shop/jtoon/repository/MemberCookieRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java similarity index 70% rename from module-domain/domain-payment/src/main/java/shop/jtoon/repository/MemberCookieRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java index 57b836a..48bc13c 100644 --- a/module-domain/domain-payment/src/main/java/shop/jtoon/repository/MemberCookieRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java @@ -1,11 +1,12 @@ -package shop.jtoon.repository; +package shop.jtoon.payment.repository; + +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.MemberCookie; -import java.util.Optional; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.entity.MemberCookie; @Repository public interface MemberCookieRepository extends JpaRepository { diff --git a/module-domain/domain-payment/src/main/java/shop/jtoon/repository/PaymentInfoRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java similarity index 78% rename from module-domain/domain-payment/src/main/java/shop/jtoon/repository/PaymentInfoRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java index 75227f5..848171a 100644 --- a/module-domain/domain-payment/src/main/java/shop/jtoon/repository/PaymentInfoRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java @@ -1,9 +1,9 @@ -package shop.jtoon.repository; +package shop.jtoon.payment.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import shop.jtoon.entity.PaymentInfo; +import shop.jtoon.payment.entity.PaymentInfo; @Repository public interface PaymentInfoRepository extends JpaRepository { diff --git a/module-domain/domain-payment/src/main/java/shop/jtoon/repository/PaymentInfoSearchRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java similarity index 71% rename from module-domain/domain-payment/src/main/java/shop/jtoon/repository/PaymentInfoSearchRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java index 223a20d..5a94564 100644 --- a/module-domain/domain-payment/src/main/java/shop/jtoon/repository/PaymentInfoSearchRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java @@ -1,21 +1,23 @@ -package shop.jtoon.repository; +package shop.jtoon.payment.repository; +import static shop.jtoon.member.entity.QMember.*; +import static shop.jtoon.payment.entity.QPaymentInfo.*; + +import java.util.List; -import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; -import shop.jtoon.entity.PaymentInfo; -import shop.jtoon.util.DynamicQuery; -import java.util.List; +import com.querydsl.jpa.impl.JPAQueryFactory; -import static shop.jtoon.entity.QMember.*; -import static shop.jtoon.entity.QPaymentInfo.*; +import lombok.RequiredArgsConstructor; +import shop.jtoon.global.util.DynamicQuery; +import shop.jtoon.payment.entity.PaymentInfo; @Repository @RequiredArgsConstructor public class PaymentInfoSearchRepository { private final JPAQueryFactory queryFactory; + private final PaymentInfoRepository paymentInfoRepository; public List searchByMerchantsUidAndEmail(List merchantsUid, String email) { return queryFactory.selectFrom(paymentInfo) diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/request/CancelReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/CancelReq.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/payment/request/CancelReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/CancelReq.java index 51325cb..c3cccbe 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/request/CancelReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/CancelReq.java @@ -1,13 +1,13 @@ package shop.jtoon.payment.request; +import java.math.BigDecimal; + import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Builder; -import java.math.BigDecimal; - @Builder public record CancelReq( @NotBlank String impUid, diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/request/ConditionReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/ConditionReq.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/payment/request/ConditionReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/ConditionReq.java index 012acf4..f5e02cd 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/request/ConditionReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/ConditionReq.java @@ -1,9 +1,9 @@ package shop.jtoon.payment.request; -import lombok.Builder; - import java.util.List; +import lombok.Builder; + @Builder public record ConditionReq( List merchantsUid diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java similarity index 68% rename from module-application/app-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java index b84dea1..ab196ba 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java @@ -1,15 +1,18 @@ package shop.jtoon.payment.request; -import jakarta.validation.constraints.*; -import lombok.Builder; -import shop.jtoon.entity.CookieItem; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PaymentInfo; +import static shop.jtoon.util.RegExp.*; import java.math.BigDecimal; -import static shop.jtoon.util.RegExp.EMAIL_PATTERN; -import static shop.jtoon.util.RegExp.PHONE_PATTERN; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import lombok.Builder; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.entity.CookieItem; +import shop.jtoon.payment.entity.PaymentInfo; @Builder public record PaymentReq( diff --git a/module-application/app-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java similarity index 93% rename from module-application/app-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java index bf4d696..63d77fc 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java @@ -1,11 +1,11 @@ package shop.jtoon.payment.response; -import lombok.Builder; -import shop.jtoon.entity.PaymentInfo; - import java.math.BigDecimal; import java.time.LocalDateTime; +import lombok.Builder; +import shop.jtoon.payment.entity.PaymentInfo; + @Builder public record PaymentRes( String itemName, diff --git a/module-domain/domain-payment/src/main/java/shop/jtoon/service/PaymentInfoDomainService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/service/PaymentInfoDomainService.java similarity index 90% rename from module-domain/domain-payment/src/main/java/shop/jtoon/service/PaymentInfoDomainService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/payment/service/PaymentInfoDomainService.java index 37679a6..bcf92ed 100644 --- a/module-domain/domain-payment/src/main/java/shop/jtoon/service/PaymentInfoDomainService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/service/PaymentInfoDomainService.java @@ -1,14 +1,15 @@ -package shop.jtoon.service; +package shop.jtoon.payment.service; + +import java.math.BigDecimal; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import shop.jtoon.entity.CookieItem; + +import lombok.RequiredArgsConstructor; import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.payment.entity.CookieItem; import shop.jtoon.type.ErrorStatus; -import java.math.BigDecimal; - @Service @RequiredArgsConstructor @Transactional(readOnly = true) diff --git a/module-application/app-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java similarity index 95% rename from module-application/app-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java index b516af0..b671837 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java @@ -2,15 +2,16 @@ import static shop.jtoon.util.SecurityConstant.*; +import java.util.List; + import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Service; -import java.util.List; import lombok.RequiredArgsConstructor; -import shop.jtoon.dto.MemberDto; import shop.jtoon.member.application.MemberService; +import shop.jtoon.member.dto.MemberDto; import shop.jtoon.security.service.AuthenticationService; @Service diff --git a/module-application/app-api/src/main/java/shop/jtoon/security/application/JwtServiceImpl.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/JwtServiceImpl.java similarity index 99% rename from module-application/app-api/src/main/java/shop/jtoon/security/application/JwtServiceImpl.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/security/application/JwtServiceImpl.java index eb2c786..bc347eb 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/security/application/JwtServiceImpl.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/JwtServiceImpl.java @@ -2,6 +2,10 @@ import static shop.jtoon.type.ErrorStatus.*; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.util.Date; + import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -10,9 +14,6 @@ import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import jakarta.annotation.PostConstruct; -import java.nio.charset.StandardCharsets; -import java.security.Key; -import java.util.Date; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import shop.jtoon.exception.UnauthorizedException; diff --git a/module-application/app-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java similarity index 94% rename from module-application/app-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java index 7da9608..28446ad 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java @@ -1,5 +1,8 @@ package shop.jtoon.security.application; +import java.util.Collections; +import java.util.Map; + import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; @@ -10,14 +13,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.Collections; -import java.util.Map; import lombok.RequiredArgsConstructor; -import shop.jtoon.dto.OAuthAttributes; -import shop.jtoon.entity.LoginType; -import shop.jtoon.entity.Member; import shop.jtoon.exception.DuplicatedException; import shop.jtoon.member.application.MemberService; +import shop.jtoon.member.dto.OAuthAttributes; +import shop.jtoon.member.entity.LoginType; +import shop.jtoon.member.entity.Member; import shop.jtoon.security.service.CustomOAuth2UserService; import shop.jtoon.type.ErrorStatus; diff --git a/module-application/app-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java similarity index 94% rename from module-application/app-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java index 217f11d..334424d 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java @@ -3,8 +3,8 @@ import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; +import shop.jtoon.internal.service.RedisTokenService; import shop.jtoon.security.service.RefreshTokenService; -import shop.jtoon.service.RedisTokenService; @Service @RequiredArgsConstructor diff --git a/module-application/app-api/src/main/java/shop/jtoon/security/presentation/AuthController.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/presentation/AuthController.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/security/presentation/AuthController.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/security/presentation/AuthController.java diff --git a/module-application/app-api/src/main/java/shop/jtoon/security/request/LoginReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/request/LoginReq.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/security/request/LoginReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/security/request/LoginReq.java diff --git a/module-application/app-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java similarity index 87% rename from module-application/app-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java index 11d5f62..485e439 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java @@ -11,23 +11,25 @@ import lombok.RequiredArgsConstructor; import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.entity.Episode; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PurchasedEpisode; -import shop.jtoon.entity.Webtoon; + import shop.jtoon.exception.DuplicatedException; import shop.jtoon.exception.InvalidRequestException; import shop.jtoon.exception.NotFoundException; import shop.jtoon.member.application.MemberService; +import shop.jtoon.member.entity.Member; import shop.jtoon.payment.application.MemberCookieService; -import shop.jtoon.repository.EpisodeRepository; -import shop.jtoon.repository.EpisodeSearchRepository; -import shop.jtoon.repository.PurchasedEpisodeRepository; -import shop.jtoon.response.EpisodeInfoRes; -import shop.jtoon.response.EpisodeItemRes; + import shop.jtoon.service.S3Service; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.PurchasedEpisode; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.repository.EpisodeRepository; +import shop.jtoon.webtoon.repository.EpisodeSearchRepository; +import shop.jtoon.webtoon.repository.PurchasedEpisodeRepository; import shop.jtoon.webtoon.request.CreateEpisodeReq; import shop.jtoon.webtoon.request.GetEpisodesReq; +import shop.jtoon.webtoon.response.EpisodeInfoRes; +import shop.jtoon.webtoon.response.EpisodeItemRes; @Service @Transactional(readOnly = true) diff --git a/module-application/app-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java similarity index 77% rename from module-application/app-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java index 229b81b..806b7fb 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java @@ -4,33 +4,36 @@ import static shop.jtoon.common.ImageType.*; import static shop.jtoon.type.ErrorStatus.*; +import java.util.List; +import java.util.Map; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import java.util.List; -import java.util.Map; import lombok.RequiredArgsConstructor; import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.entity.DayOfWeekWebtoon; -import shop.jtoon.entity.GenreWebtoon; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Webtoon; -import shop.jtoon.entity.enums.DayOfWeek; + import shop.jtoon.exception.DuplicatedException; import shop.jtoon.exception.InvalidRequestException; import shop.jtoon.exception.NotFoundException; import shop.jtoon.member.application.MemberService; -import shop.jtoon.repository.DayOfWeekWebtoonRepository; -import shop.jtoon.repository.GenreWebtoonRepository; -import shop.jtoon.repository.WebtoonRepository; -import shop.jtoon.repository.WebtoonSearchRepository; -import shop.jtoon.response.GenreRes; -import shop.jtoon.response.WebtoonInfoRes; -import shop.jtoon.response.WebtoonItemRes; + +import shop.jtoon.member.entity.Member; import shop.jtoon.service.S3Service; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; +import shop.jtoon.webtoon.repository.DayOfWeekWebtoonRepository; +import shop.jtoon.webtoon.repository.GenreWebtoonRepository; +import shop.jtoon.webtoon.repository.WebtoonRepository; +import shop.jtoon.webtoon.repository.WebtoonSearchRepository; import shop.jtoon.webtoon.request.CreateWebtoonReq; import shop.jtoon.webtoon.request.GetWebtoonsReq; +import shop.jtoon.webtoon.response.GenreRes; +import shop.jtoon.webtoon.response.WebtoonInfoRes; +import shop.jtoon.webtoon.response.WebtoonItemRes; @Service @Transactional(readOnly = true) @@ -67,10 +70,8 @@ public void createWebtoon(Long memberId, MultipartFile thumbnailImage, CreateWeb public Map> getWebtoons(GetWebtoonsReq request) { return webtoonSearchRepository.findWebtoons(request.day(), request.keyword()) .stream() - .collect(groupingBy( - DayOfWeekWebtoon::getDayOfWeek, - mapping(dayOfWeekWebtoon -> WebtoonItemRes.from(dayOfWeekWebtoon.getWebtoon()), toList()) - )); + .collect(groupingBy(DayOfWeekWebtoon::getDayOfWeek, + mapping(dayOfWeekWebtoon -> WebtoonItemRes.from(dayOfWeekWebtoon.getWebtoon()), toList()))); } public WebtoonInfoRes getWebtoon(Long webtoonId) { @@ -82,8 +83,7 @@ public WebtoonInfoRes getWebtoon(Long webtoonId) { } public Webtoon getWebtoonById(Long webtoonId) { - return webtoonRepository.findById(webtoonId) - .orElseThrow(() -> new NotFoundException(WEBTOON_NOT_FOUND)); + return webtoonRepository.findById(webtoonId).orElseThrow(() -> new NotFoundException(WEBTOON_NOT_FOUND)); } private List getDayOfWeeks(Webtoon webtoon) { @@ -94,10 +94,7 @@ private List getDayOfWeeks(Webtoon webtoon) { } private List getGenres(Webtoon webtoon) { - return genreWebtoonRepository.findByWebtoon(webtoon) - .stream() - .map(GenreRes::from) - .toList(); + return genreWebtoonRepository.findByWebtoon(webtoon).stream().map(GenreRes::from).toList(); } private void validateDuplicateTitle(String title) { diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/DayOfWeekWebtoon.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java similarity index 92% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/DayOfWeekWebtoon.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java index b7ff7c3..3c0eefb 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/DayOfWeekWebtoon.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.webtoon.entity; import static java.util.Objects.*; import static shop.jtoon.type.ErrorStatus.*; @@ -18,7 +18,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.entity.enums.DayOfWeek; +import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; @Entity @Getter diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/Episode.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Episode.java similarity index 96% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/Episode.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Episode.java index dcedc21..bc0f12b 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/Episode.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Episode.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.webtoon.entity; import static java.util.Objects.*; import static shop.jtoon.type.ErrorStatus.*; @@ -22,6 +22,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.global.entity.BaseTimeEntity; @Entity @Getter diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/GenreWebtoon.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java similarity index 87% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/GenreWebtoon.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java index 6a58be2..ecee740 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/GenreWebtoon.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.webtoon.entity; import static java.util.Objects.*; import static shop.jtoon.type.ErrorStatus.*; @@ -18,7 +18,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.entity.enums.Genre; +import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.webtoon.entity.enums.Genre; @Entity @Getter @@ -46,9 +47,6 @@ private GenreWebtoon(Genre genre, Webtoon webtoon) { } public static GenreWebtoon create(Genre genre, Webtoon webtoon) { - return GenreWebtoon.builder() - .genre(genre) - .webtoon(webtoon) - .build(); + return GenreWebtoon.builder().genre(genre).webtoon(webtoon).build(); } } diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/PurchasedEpisode.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java similarity index 91% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/PurchasedEpisode.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java index c33739d..17b6cb2 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/PurchasedEpisode.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.webtoon.entity; import static java.util.Objects.*; import static shop.jtoon.type.ErrorStatus.*; @@ -16,6 +16,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.member.entity.Member; @Entity @Getter diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/Webtoon.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java similarity index 93% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/Webtoon.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java index 9b5f79f..b59bccb 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/Webtoon.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.webtoon.entity; import static java.util.Objects.*; import static shop.jtoon.type.ErrorStatus.*; @@ -16,8 +16,10 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.entity.enums.AgeLimit; import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.member.entity.Member; +import shop.jtoon.webtoon.entity.enums.AgeLimit; @Entity @Getter diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/AgeLimit.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java similarity index 86% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/AgeLimit.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java index 6549ffd..3b82cd3 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/AgeLimit.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity.enums; +package shop.jtoon.webtoon.entity.enums; import lombok.AccessLevel; import lombok.Getter; diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/DayOfWeek.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java similarity index 84% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/DayOfWeek.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java index 15e3c23..57c54e3 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/DayOfWeek.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity.enums; +package shop.jtoon.webtoon.entity.enums; import lombok.AccessLevel; import lombok.Getter; diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/Genre.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java similarity index 91% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/Genre.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java index 2084a95..ae1be69 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/entity/enums/Genre.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity.enums; +package shop.jtoon.webtoon.entity.enums; import lombok.AccessLevel; import lombok.Getter; diff --git a/module-application/app-api/src/main/java/shop/jtoon/webtoon/presentation/WebtoonController.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/presentation/WebtoonController.java similarity index 90% rename from module-application/app-api/src/main/java/shop/jtoon/webtoon/presentation/WebtoonController.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/presentation/WebtoonController.java index 69255f3..d5e1028 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/webtoon/presentation/WebtoonController.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/presentation/WebtoonController.java @@ -16,18 +16,18 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import shop.jtoon.annotation.CurrentUser; -import shop.jtoon.dto.MemberDto; -import shop.jtoon.entity.enums.DayOfWeek; -import shop.jtoon.response.EpisodeInfoRes; -import shop.jtoon.response.EpisodeItemRes; -import shop.jtoon.response.WebtoonInfoRes; -import shop.jtoon.response.WebtoonItemRes; +import shop.jtoon.member.dto.MemberDto; import shop.jtoon.webtoon.application.EpisodeService; import shop.jtoon.webtoon.application.WebtoonService; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; import shop.jtoon.webtoon.request.CreateEpisodeReq; import shop.jtoon.webtoon.request.CreateWebtoonReq; import shop.jtoon.webtoon.request.GetEpisodesReq; import shop.jtoon.webtoon.request.GetWebtoonsReq; +import shop.jtoon.webtoon.response.EpisodeInfoRes; +import shop.jtoon.webtoon.response.EpisodeItemRes; +import shop.jtoon.webtoon.response.WebtoonInfoRes; +import shop.jtoon.webtoon.response.WebtoonItemRes; @RestController @RequiredArgsConstructor diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/DayOfWeekWebtoonRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java similarity index 64% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/DayOfWeekWebtoonRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java index bb3ce2c..32fcbef 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/DayOfWeekWebtoonRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java @@ -1,11 +1,11 @@ -package shop.jtoon.repository; +package shop.jtoon.webtoon.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import shop.jtoon.entity.DayOfWeekWebtoon; -import shop.jtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; public interface DayOfWeekWebtoonRepository extends JpaRepository { diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/EpisodeRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java similarity index 61% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/EpisodeRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java index c9e57c6..610e244 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/EpisodeRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java @@ -1,9 +1,9 @@ -package shop.jtoon.repository; +package shop.jtoon.webtoon.repository; import org.springframework.data.jpa.repository.JpaRepository; -import shop.jtoon.entity.Episode; -import shop.jtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Webtoon; public interface EpisodeRepository extends JpaRepository { diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/EpisodeSearchRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java similarity index 75% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/EpisodeSearchRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java index 4ac6372..79a75f2 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/EpisodeSearchRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java @@ -1,6 +1,8 @@ -package shop.jtoon.repository; +package shop.jtoon.webtoon.repository; -import static shop.jtoon.entity.QEpisode.*; + + +import static shop.jtoon.webtoon.entity.QEpisode.*; import java.util.List; @@ -9,8 +11,8 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; -import shop.jtoon.entity.Episode; -import shop.jtoon.util.DynamicQuery; +import shop.jtoon.global.util.DynamicQuery; +import shop.jtoon.webtoon.entity.Episode; @Repository @RequiredArgsConstructor diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/GenreWebtoonRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java similarity index 64% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/GenreWebtoonRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java index d4bfd13..1a6b736 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/GenreWebtoonRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java @@ -1,11 +1,11 @@ -package shop.jtoon.repository; +package shop.jtoon.webtoon.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import shop.jtoon.entity.GenreWebtoon; -import shop.jtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; public interface GenreWebtoonRepository extends JpaRepository { diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/PurchasedEpisodeRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java similarity index 63% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/PurchasedEpisodeRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java index 3424161..275d007 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/PurchasedEpisodeRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java @@ -1,8 +1,8 @@ -package shop.jtoon.repository; +package shop.jtoon.webtoon.repository; import org.springframework.data.jpa.repository.JpaRepository; -import shop.jtoon.entity.PurchasedEpisode; +import shop.jtoon.webtoon.entity.PurchasedEpisode; public interface PurchasedEpisodeRepository extends JpaRepository { } diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/WebtoonRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java similarity index 68% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/WebtoonRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java index a71e340..4a480d7 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/WebtoonRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java @@ -1,8 +1,8 @@ -package shop.jtoon.repository; +package shop.jtoon.webtoon.repository; import org.springframework.data.jpa.repository.JpaRepository; -import shop.jtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.Webtoon; public interface WebtoonRepository extends JpaRepository { diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/WebtoonSearchRepository.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java similarity index 67% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/WebtoonSearchRepository.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java index 077b17e..6bac138 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/repository/WebtoonSearchRepository.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java @@ -1,8 +1,8 @@ -package shop.jtoon.repository; +package shop.jtoon.webtoon.repository; -import static shop.jtoon.entity.QDayOfWeekWebtoon.*; -import static shop.jtoon.entity.QMember.*; -import static shop.jtoon.entity.QWebtoon.*; +import static shop.jtoon.member.entity.QMember.*; +import static shop.jtoon.webtoon.entity.QDayOfWeekWebtoon.*; +import static shop.jtoon.webtoon.entity.QWebtoon.*; import java.util.List; @@ -12,15 +12,16 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; -import shop.jtoon.entity.DayOfWeekWebtoon; -import shop.jtoon.entity.enums.DayOfWeek; -import shop.jtoon.util.DynamicQuery; +import shop.jtoon.global.util.DynamicQuery; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; @Repository @RequiredArgsConstructor public class WebtoonSearchRepository { private final JPAQueryFactory jpaQueryFactory; + private final DayOfWeekWebtoonRepository dayOfWeekWebtoonRepository; public List findWebtoons(DayOfWeek dayOfWeek, String keyword) { return jpaQueryFactory.selectFrom(dayOfWeekWebtoon) diff --git a/module-application/app-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java similarity index 93% rename from module-application/app-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java index 7ff77de..a935d35 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java @@ -12,8 +12,8 @@ import shop.jtoon.common.FileName; import shop.jtoon.common.ImageType; import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.entity.Episode; -import shop.jtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Webtoon; @Builder public record CreateEpisodeReq( diff --git a/module-application/app-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java similarity index 82% rename from module-application/app-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java index 7e720d3..d80cd6e 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java @@ -12,13 +12,13 @@ import shop.jtoon.common.FileName; import shop.jtoon.common.ImageType; import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.entity.DayOfWeekWebtoon; -import shop.jtoon.entity.GenreWebtoon; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Webtoon; -import shop.jtoon.entity.enums.AgeLimit; -import shop.jtoon.entity.enums.DayOfWeek; -import shop.jtoon.entity.enums.Genre; +import shop.jtoon.member.entity.Member; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.AgeLimit; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; +import shop.jtoon.webtoon.entity.enums.Genre; @Builder public record CreateWebtoonReq( diff --git a/module-application/app-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java similarity index 100% rename from module-application/app-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java diff --git a/module-application/app-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java similarity index 73% rename from module-application/app-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java index 68c4b53..6158178 100644 --- a/module-application/app-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java @@ -1,7 +1,7 @@ package shop.jtoon.webtoon.request; import lombok.Builder; -import shop.jtoon.entity.enums.DayOfWeek; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; @Builder public record GetWebtoonsReq( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/AuthorRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/AuthorRes.java similarity index 75% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/AuthorRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/AuthorRes.java index e76b429..0fb1bfa 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/AuthorRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/AuthorRes.java @@ -1,7 +1,7 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import lombok.Builder; -import shop.jtoon.entity.Member; +import shop.jtoon.member.entity.Member; @Builder public record AuthorRes( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeInfoRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeInfoRes.java similarity index 74% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeInfoRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeInfoRes.java index 675f966..d47159f 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeInfoRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeInfoRes.java @@ -1,7 +1,7 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import lombok.Builder; -import shop.jtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Episode; @Builder public record EpisodeInfoRes( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeItemRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeItemRes.java similarity index 86% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeItemRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeItemRes.java index 0453fa2..4aa984c 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeItemRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeItemRes.java @@ -1,9 +1,9 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import java.time.format.DateTimeFormatter; import lombok.Builder; -import shop.jtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Episode; @Builder public record EpisodeItemRes( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeRes.java similarity index 86% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeRes.java index 9144d43..a551c87 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/EpisodeRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeRes.java @@ -1,10 +1,10 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import java.time.LocalDateTime; import lombok.Builder; -import shop.jtoon.entity.Episode; -import shop.jtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Webtoon; @Builder public record EpisodeRes( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/GenreRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/GenreRes.java similarity index 67% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/GenreRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/GenreRes.java index cbb8c1a..a5d1e75 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/GenreRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/GenreRes.java @@ -1,8 +1,8 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import lombok.Builder; -import shop.jtoon.entity.GenreWebtoon; -import shop.jtoon.entity.enums.Genre; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.enums.Genre; @Builder public record GenreRes( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonInfoRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonInfoRes.java similarity index 84% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonInfoRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonInfoRes.java index b72b46d..ef4a588 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonInfoRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonInfoRes.java @@ -1,10 +1,10 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import java.util.List; import lombok.Builder; -import shop.jtoon.entity.Webtoon; -import shop.jtoon.entity.enums.AgeLimit; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.AgeLimit; @Builder public record WebtoonInfoRes( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonItemRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonItemRes.java similarity index 85% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonItemRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonItemRes.java index fc078d9..9badfbb 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonItemRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonItemRes.java @@ -1,7 +1,7 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import lombok.Builder; -import shop.jtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.Webtoon; @Builder public record WebtoonItemRes( diff --git a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonRes.java similarity index 81% rename from module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonRes.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonRes.java index c41a3b2..39831db 100644 --- a/module-domain/domain-webtoon/src/main/java/shop/jtoon/response/WebtoonRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonRes.java @@ -1,11 +1,11 @@ -package shop.jtoon.response; +package shop.jtoon.webtoon.response; import java.time.LocalDateTime; import lombok.Builder; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Webtoon; -import shop.jtoon.entity.enums.AgeLimit; +import shop.jtoon.member.entity.Member; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.AgeLimit; @Builder public record WebtoonRes( diff --git a/module-application/app-api/src/main/resources/application.yml b/jtoon-core/core-api/src/main/resources/application.yml similarity index 100% rename from module-application/app-api/src/main/resources/application.yml rename to jtoon-core/core-api/src/main/resources/application.yml diff --git a/jtoon-core/core-api/src/main/resources/config b/jtoon-core/core-api/src/main/resources/config new file mode 160000 index 0000000..4992fd4 --- /dev/null +++ b/jtoon-core/core-api/src/main/resources/config @@ -0,0 +1 @@ +Subproject commit 4992fd48cf255fa80e7ee2834563f6695cc8365a diff --git a/module-application/app-api/src/main/resources/static/docs/index.html b/jtoon-core/core-api/src/main/resources/docs/index.html similarity index 100% rename from module-application/app-api/src/main/resources/static/docs/index.html rename to jtoon-core/core-api/src/main/resources/docs/index.html diff --git a/module-application/app-api/src/main/resources/static/docs/payment.html b/jtoon-core/core-api/src/main/resources/docs/payment.html similarity index 100% rename from module-application/app-api/src/main/resources/static/docs/payment.html rename to jtoon-core/core-api/src/main/resources/docs/payment.html diff --git a/module-application/app-api/src/test/resources/application-test.yml b/jtoon-core/core-api/src/test/resources/application-test.yml similarity index 100% rename from module-application/app-api/src/test/resources/application-test.yml rename to jtoon-core/core-api/src/test/resources/application-test.yml diff --git a/module-application/app-api/src/test/resources/test.png b/jtoon-core/core-api/src/test/resources/test.png similarity index 100% rename from module-application/app-api/src/test/resources/test.png rename to jtoon-core/core-api/src/test/resources/test.png diff --git a/jtoon-internal/README.md b/jtoon-internal/README.md new file mode 100644 index 0000000..81d4322 --- /dev/null +++ b/jtoon-internal/README.md @@ -0,0 +1,9 @@ +# Jtoon internal + +외부 시스템과 통신을 위한 모듈의 집함 + +## 종류 +- `core-web`: 모안 모듈 추후 Gateway로 분리할 수 있음 +- `iamport-client`: 결제관련 모듈 +- `s3-client`: AWS의 s3 통신을 위한 모듈 +- `smtp-client`: smtp 요청을 위한 모듈 \ No newline at end of file diff --git a/module-internal/core-web/build.gradle b/jtoon-internal/core-web/build.gradle similarity index 92% rename from module-internal/core-web/build.gradle rename to jtoon-internal/core-web/build.gradle index 25e23ff..8237d0d 100644 --- a/module-internal/core-web/build.gradle +++ b/jtoon-internal/core-web/build.gradle @@ -1,4 +1,7 @@ dependencies { + + implementation project(':jtoon-system') + // Web implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/module-internal/core-web/src/main/java/shop/jtoon/annotation/CurrentUser.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/annotation/CurrentUser.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/annotation/CurrentUser.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/annotation/CurrentUser.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/config/SecurityConfig.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/config/SecurityConfig.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/config/SecurityConfig.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/config/SecurityConfig.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/config/WebConfig.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/config/WebConfig.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/config/WebConfig.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/config/WebConfig.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/error/model/ErrorResponse.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/error/model/ErrorResponse.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/error/model/ErrorResponse.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/error/model/ErrorResponse.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/filter/AuthenticationFilter.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/filter/AuthenticationFilter.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/filter/AuthenticationFilter.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/filter/AuthenticationFilter.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2FailureHandler.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2FailureHandler.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2FailureHandler.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2FailureHandler.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2SuccessHandler.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2SuccessHandler.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2SuccessHandler.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/handler/OAuth2SuccessHandler.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/service/AuthenticationService.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/AuthenticationService.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/service/AuthenticationService.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/AuthenticationService.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/service/AuthorizationService.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/AuthorizationService.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/service/AuthorizationService.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/AuthorizationService.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/service/CustomOAuth2UserService.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/CustomOAuth2UserService.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/service/CustomOAuth2UserService.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/CustomOAuth2UserService.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/service/JwtService.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/JwtService.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/service/JwtService.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/JwtService.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/service/RefreshTokenService.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/RefreshTokenService.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/service/RefreshTokenService.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/service/RefreshTokenService.java diff --git a/module-internal/core-web/src/main/java/shop/jtoon/security/util/TokenCookie.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/security/util/TokenCookie.java similarity index 100% rename from module-internal/core-web/src/main/java/shop/jtoon/security/util/TokenCookie.java rename to jtoon-internal/core-web/src/main/java/shop/jtoon/security/util/TokenCookie.java diff --git a/module-internal/core-web/src/test/java/shop/jtoon/security/SecurityApplicationTest.java b/jtoon-internal/core-web/src/test/java/shop/jtoon/security/SecurityApplicationTest.java similarity index 100% rename from module-internal/core-web/src/test/java/shop/jtoon/security/SecurityApplicationTest.java rename to jtoon-internal/core-web/src/test/java/shop/jtoon/security/SecurityApplicationTest.java diff --git a/module-internal/core-web/src/test/java/shop/jtoon/security/filter/AuthenticationFilterTest.java b/jtoon-internal/core-web/src/test/java/shop/jtoon/security/filter/AuthenticationFilterTest.java similarity index 100% rename from module-internal/core-web/src/test/java/shop/jtoon/security/filter/AuthenticationFilterTest.java rename to jtoon-internal/core-web/src/test/java/shop/jtoon/security/filter/AuthenticationFilterTest.java diff --git a/module-internal/iamport-client/build.gradle b/jtoon-internal/iamport-client/build.gradle similarity index 89% rename from module-internal/iamport-client/build.gradle rename to jtoon-internal/iamport-client/build.gradle index c5fba35..2c1bbaa 100644 --- a/module-internal/iamport-client/build.gradle +++ b/jtoon-internal/iamport-client/build.gradle @@ -1,4 +1,5 @@ dependencies { + implementation project(':jtoon-system') // JPA implementation 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/module-internal/iamport-client/src/main/java/shop/jtoon/config/IamportConfig.java b/jtoon-internal/iamport-client/src/main/java/shop/jtoon/config/IamportConfig.java similarity index 100% rename from module-internal/iamport-client/src/main/java/shop/jtoon/config/IamportConfig.java rename to jtoon-internal/iamport-client/src/main/java/shop/jtoon/config/IamportConfig.java diff --git a/module-internal/iamport-client/src/main/java/shop/jtoon/service/IamportService.java b/jtoon-internal/iamport-client/src/main/java/shop/jtoon/service/IamportService.java similarity index 100% rename from module-internal/iamport-client/src/main/java/shop/jtoon/service/IamportService.java rename to jtoon-internal/iamport-client/src/main/java/shop/jtoon/service/IamportService.java diff --git a/module-internal/iamport-client/src/test/java/shop/jtoon/IamportClientApplicationTest.java b/jtoon-internal/iamport-client/src/test/java/shop/jtoon/IamportClientApplicationTest.java similarity index 100% rename from module-internal/iamport-client/src/test/java/shop/jtoon/IamportClientApplicationTest.java rename to jtoon-internal/iamport-client/src/test/java/shop/jtoon/IamportClientApplicationTest.java diff --git a/module-internal/iamport-client/src/test/java/shop/jtoon/service/IamportServiceTest.java b/jtoon-internal/iamport-client/src/test/java/shop/jtoon/service/IamportServiceTest.java similarity index 100% rename from module-internal/iamport-client/src/test/java/shop/jtoon/service/IamportServiceTest.java rename to jtoon-internal/iamport-client/src/test/java/shop/jtoon/service/IamportServiceTest.java diff --git a/module-internal/s3-client/build.gradle b/jtoon-internal/s3-client/build.gradle similarity index 84% rename from module-internal/s3-client/build.gradle rename to jtoon-internal/s3-client/build.gradle index dac3873..d756664 100644 --- a/module-internal/s3-client/build.gradle +++ b/jtoon-internal/s3-client/build.gradle @@ -1,4 +1,7 @@ dependencies { + + implementation project(':jtoon-system') + // S3 implementation 'org.springframework.boot:spring-boot-starter-web' implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.2") diff --git a/module-internal/s3-client/src/main/java/shop/jtoon/common/FileName.java b/jtoon-internal/s3-client/src/main/java/shop/jtoon/common/FileName.java similarity index 100% rename from module-internal/s3-client/src/main/java/shop/jtoon/common/FileName.java rename to jtoon-internal/s3-client/src/main/java/shop/jtoon/common/FileName.java diff --git a/module-internal/s3-client/src/main/java/shop/jtoon/common/ImageType.java b/jtoon-internal/s3-client/src/main/java/shop/jtoon/common/ImageType.java similarity index 100% rename from module-internal/s3-client/src/main/java/shop/jtoon/common/ImageType.java rename to jtoon-internal/s3-client/src/main/java/shop/jtoon/common/ImageType.java diff --git a/module-internal/s3-client/src/main/java/shop/jtoon/dto/UploadImageDto.java b/jtoon-internal/s3-client/src/main/java/shop/jtoon/dto/UploadImageDto.java similarity index 100% rename from module-internal/s3-client/src/main/java/shop/jtoon/dto/UploadImageDto.java rename to jtoon-internal/s3-client/src/main/java/shop/jtoon/dto/UploadImageDto.java diff --git a/module-internal/s3-client/src/main/java/shop/jtoon/service/S3Service.java b/jtoon-internal/s3-client/src/main/java/shop/jtoon/service/S3Service.java similarity index 100% rename from module-internal/s3-client/src/main/java/shop/jtoon/service/S3Service.java rename to jtoon-internal/s3-client/src/main/java/shop/jtoon/service/S3Service.java diff --git a/module-internal/s3-client/src/main/java/shop/jtoon/util/S3Manager.java b/jtoon-internal/s3-client/src/main/java/shop/jtoon/util/S3Manager.java similarity index 100% rename from module-internal/s3-client/src/main/java/shop/jtoon/util/S3Manager.java rename to jtoon-internal/s3-client/src/main/java/shop/jtoon/util/S3Manager.java diff --git a/module-internal/smtp-client/build.gradle b/jtoon-internal/smtp-client/build.gradle similarity index 86% rename from module-internal/smtp-client/build.gradle rename to jtoon-internal/smtp-client/build.gradle index 4ca5877..0de8cd2 100644 --- a/module-internal/smtp-client/build.gradle +++ b/jtoon-internal/smtp-client/build.gradle @@ -1,4 +1,7 @@ dependencies { + + implementation project(':jtoon-system') + // Bean Validation implementation 'org.springframework.boot:spring-boot-starter-validation' diff --git a/module-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java similarity index 100% rename from module-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java rename to jtoon-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java diff --git a/module-internal/smtp-client/src/main/java/shop/jtoon/entity/Mail.java b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/entity/Mail.java similarity index 100% rename from module-internal/smtp-client/src/main/java/shop/jtoon/entity/Mail.java rename to jtoon-internal/smtp-client/src/main/java/shop/jtoon/entity/Mail.java diff --git a/module-internal/smtp-client/src/test/java/shop/jtoon/SmtpApplicationTest.java b/jtoon-internal/smtp-client/src/test/java/shop/jtoon/SmtpApplicationTest.java similarity index 100% rename from module-internal/smtp-client/src/test/java/shop/jtoon/SmtpApplicationTest.java rename to jtoon-internal/smtp-client/src/test/java/shop/jtoon/SmtpApplicationTest.java diff --git a/module-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java b/jtoon-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java similarity index 100% rename from module-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java rename to jtoon-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java diff --git a/jtoon-support/README.md b/jtoon-support/README.md new file mode 100644 index 0000000..03b521f --- /dev/null +++ b/jtoon-support/README.md @@ -0,0 +1,19 @@ +# Jtoon Support + +Jtoon 서포트 모듈 + +## 분류 이유 + +`MSA전환시 MS로 분리가 되게 되는데 모니터링, 로깅같은 기능은 공통으로 필요하기 때문에 분리` + +## 종류 + +### Logging +로깅 모듈 + + + +### Monitoring +모니터링 모듈 + +`Spring Actuator`, `Prometeus`, `Grafana`로 구성 diff --git a/module-core/build.gradle b/jtoon-support/logging/build.gradle similarity index 100% rename from module-core/build.gradle rename to jtoon-support/logging/build.gradle diff --git a/jtoon-support/logging/src/main/resources/logback/logback-dev.xml b/jtoon-support/logging/src/main/resources/logback/logback-dev.xml new file mode 100644 index 0000000..1a9803c --- /dev/null +++ b/jtoon-support/logging/src/main/resources/logback/logback-dev.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + ${LOGS_ABSOLUTE_PATH}/tyleLog.log + + ${FILE_LOG_PATTERN} + + + ${LOGS_ABSOLUTE_PATH}/tyleLog.%d{yyyy-MM-dd}.log + 10 + 1GB + + + + + + + + + + + + + + diff --git a/jtoon-support/logging/src/main/resources/logback/logback-local.xml b/jtoon-support/logging/src/main/resources/logback/logback-local.xml new file mode 100644 index 0000000..b3d6268 --- /dev/null +++ b/jtoon-support/logging/src/main/resources/logback/logback-local.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf8 + + + + + + + + + + diff --git a/jtoon-support/logging/src/main/resources/logging.yml b/jtoon-support/logging/src/main/resources/logging.yml new file mode 100644 index 0000000..2039fe5 --- /dev/null +++ b/jtoon-support/logging/src/main/resources/logging.yml @@ -0,0 +1,7 @@ +spring: + sleuth: + trace-id128: true + sampler: + probability: 1.0 + +logging.config: classpath:logback/logback-${spring.profiles.active}.xml \ No newline at end of file diff --git a/jtoon-support/monitoring/build.gradle b/jtoon-support/monitoring/build.gradle new file mode 100644 index 0000000..e69de29 diff --git a/jtoon-system/README.md b/jtoon-system/README.md new file mode 100644 index 0000000..82a94cc --- /dev/null +++ b/jtoon-system/README.md @@ -0,0 +1,7 @@ +# Jtoon System +프로젝트 전반에 걸쳐 사용하는 공통 시스템 + +## 종류 +- Exception +- Util +- \ No newline at end of file diff --git a/jtoon-system/build.gradle b/jtoon-system/build.gradle new file mode 100644 index 0000000..e69de29 diff --git a/module-core/src/main/java/shop/jtoon/exception/DuplicatedException.java b/jtoon-system/src/main/java/shop/jtoon/exception/DuplicatedException.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/exception/DuplicatedException.java rename to jtoon-system/src/main/java/shop/jtoon/exception/DuplicatedException.java diff --git a/module-core/src/main/java/shop/jtoon/exception/ForbiddenException.java b/jtoon-system/src/main/java/shop/jtoon/exception/ForbiddenException.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/exception/ForbiddenException.java rename to jtoon-system/src/main/java/shop/jtoon/exception/ForbiddenException.java diff --git a/module-core/src/main/java/shop/jtoon/exception/IamportException.java b/jtoon-system/src/main/java/shop/jtoon/exception/IamportException.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/exception/IamportException.java rename to jtoon-system/src/main/java/shop/jtoon/exception/IamportException.java diff --git a/module-core/src/main/java/shop/jtoon/exception/InvalidRequestException.java b/jtoon-system/src/main/java/shop/jtoon/exception/InvalidRequestException.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/exception/InvalidRequestException.java rename to jtoon-system/src/main/java/shop/jtoon/exception/InvalidRequestException.java diff --git a/module-core/src/main/java/shop/jtoon/exception/NotFoundException.java b/jtoon-system/src/main/java/shop/jtoon/exception/NotFoundException.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/exception/NotFoundException.java rename to jtoon-system/src/main/java/shop/jtoon/exception/NotFoundException.java diff --git a/module-core/src/main/java/shop/jtoon/exception/UnauthorizedException.java b/jtoon-system/src/main/java/shop/jtoon/exception/UnauthorizedException.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/exception/UnauthorizedException.java rename to jtoon-system/src/main/java/shop/jtoon/exception/UnauthorizedException.java diff --git a/module-core/src/main/java/shop/jtoon/type/CustomPageRequest.java b/jtoon-system/src/main/java/shop/jtoon/type/CustomPageRequest.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/type/CustomPageRequest.java rename to jtoon-system/src/main/java/shop/jtoon/type/CustomPageRequest.java diff --git a/module-core/src/main/java/shop/jtoon/type/ErrorStatus.java b/jtoon-system/src/main/java/shop/jtoon/type/ErrorStatus.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/type/ErrorStatus.java rename to jtoon-system/src/main/java/shop/jtoon/type/ErrorStatus.java diff --git a/module-core/src/main/java/shop/jtoon/util/RegExp.java b/jtoon-system/src/main/java/shop/jtoon/util/RegExp.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/util/RegExp.java rename to jtoon-system/src/main/java/shop/jtoon/util/RegExp.java diff --git a/module-core/src/main/java/shop/jtoon/util/SecurityConstant.java b/jtoon-system/src/main/java/shop/jtoon/util/SecurityConstant.java similarity index 100% rename from module-core/src/main/java/shop/jtoon/util/SecurityConstant.java rename to jtoon-system/src/main/java/shop/jtoon/util/SecurityConstant.java diff --git a/module-application/README.md b/module-application/README.md deleted file mode 100644 index 7259711..0000000 --- a/module-application/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Application Layer - -| | **어플리케이션 모듈** | **내부 모듈** | **도메인 모듈** | **공통 모듈** | -|:---------:|:-------------:|:---------:|:----------:|:---------:| -| **사용 가능** | - | O | O | O | - -- 독립적으로 실행 가능한 어플리케이션 모듈 계층입니다. -- 어플리케이션 모듈은 하위 설계 했던 모듈들을 조립하여 서비스 비지니스를 완성시킵니다. - -
- -#### 아래와 같은 모듈을 주로 배치할 수 있습니다. - -> - app-api -> - app-admin diff --git a/module-application/app-api/Dockerfile b/module-application/app-api/Dockerfile deleted file mode 100644 index 2de4f22..0000000 --- a/module-application/app-api/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -### Docker 이미지를 생성할 때 기반이 되는 베이스 이미지를 설정한다. -FROM amazoncorretto:17 -### 조셉팀 ^-^ -MAINTAINER 박세연, 신재윤, 홍혁준, 김영명, 김희빈 -### 경로에 해당하는 파일을 Docker 이미지 내부로 복사한다. -COPY ${PWD}/build/libs/app-api-0.0.1-SNAPSHOT.jar jtoon.jar -### Docker 컨테이너가 시작될 때 실행할 명령을 지정한다. - -ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "/jtoon.jar"] diff --git a/module-application/app-api/build.gradle b/module-application/app-api/build.gradle deleted file mode 100644 index f76ac67..0000000 --- a/module-application/app-api/build.gradle +++ /dev/null @@ -1,77 +0,0 @@ -plugins { - id 'org.asciidoctor.jvm.convert' version '3.3.2' -} - -configurations { - asciidoctorExtensions -} - -ext { - snippetsDir = file('build/generated-snippets') // 스니펫이 생성되는 폴더 설정 -} - -test { - outputs.dir snippetsDir // 스니펫을 'snippetsDir'로 생성하도록 test task 설정 -} - -asciidoctor { - configurations 'asciidoctorExtensions' // 'Asciidoctor' 확장에 대한 설정 - inputs.dir snippetsDir // 불러올 스니펫 위치를 'snippetsDir'로 설정 - dependsOn test // test task 이후에 'asciidoctor'를 실행하도록 설정 -} - -asciidoctor.doFirst { - delete file('src/main/resources/static/docs') -} - -tasks.register('copyDocument', Copy) { - dependsOn asciidoctor - from file("build/docs/asciidoc") - into file("src/main/resources/static/docs") -} - -bootJar { - dependsOn copyDocument -} - -build { - dependsOn copyDocument -} - -dependencies { - // Web - implementation 'org.springframework.boot:spring-boot-starter-web' - - // Bean Validation - implementation 'org.springframework.boot:spring-boot-starter-validation' - - // JPA - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - - // AOP - implementation 'org.springframework.boot:spring-boot-starter-aop' - - // H2 - implementation 'com.h2database:h2' - - // Test - testImplementation 'org.springframework.boot:spring-boot-starter-test' - - // Security - implementation 'org.springframework.boot:spring-boot-starter-security' - testImplementation 'org.springframework.security:spring-security-test' - - // OAuth2 - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - - // JWT - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' - - // Asciidoctor - asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' - - // RestDocs - testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/config/WithCurrentUser.java b/module-application/app-api/src/test/java/shop/jtoon/config/WithCurrentUser.java deleted file mode 100644 index ac7804d..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/config/WithCurrentUser.java +++ /dev/null @@ -1,34 +0,0 @@ -package shop.jtoon.config; - -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.test.context.support.WithSecurityContext; -import org.springframework.security.test.context.support.WithSecurityContextFactory; -import shop.jtoon.dto.MemberDto; -import shop.jtoon.factory.MemberFactory; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.List; - -import static shop.jtoon.util.SecurityConstant.BLANK; - -@Retention(RetentionPolicy.RUNTIME) -@WithSecurityContext(factory = WithCurrentUser.WithCustomSecurityContextFactory.class) -public @interface WithCurrentUser { - - final class WithCustomSecurityContextFactory implements WithSecurityContextFactory { - @Override - public SecurityContext createSecurityContext(WithCurrentUser customUser) { - MemberDto memberDto = MemberFactory.createMemberDto(); - List roles = List.of(new SimpleGrantedAuthority(memberDto.role().toString())); - Authentication auth = new UsernamePasswordAuthenticationToken(memberDto, BLANK, roles); - SecurityContextHolder.getContext().setAuthentication(auth); - - return SecurityContextHolder.getContext(); - } - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/factory/MemberFactory.java b/module-application/app-api/src/test/java/shop/jtoon/factory/MemberFactory.java deleted file mode 100644 index c268db4..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/factory/MemberFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -package shop.jtoon.factory; - -import shop.jtoon.dto.MemberDto; -import shop.jtoon.entity.Gender; -import shop.jtoon.entity.LoginType; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Role; - -public class MemberFactory { - - private static String defaultEmail = "test@naver.com"; - - public static Member createMember() { - return Member.builder() - .email(defaultEmail) - .password("Qwe123!!") - .name("홍도산") - .nickname("개발을담다") - .gender(Gender.MALE) - .phone("01012331233") - .role(Role.USER) - .loginType(LoginType.LOCAL) - .build(); - } - - public static MemberDto createMemberDto() { - return MemberDto.builder() - .id(1L) - .email(defaultEmail) - .name("testName") - .nickname("testNickname") - .gender(Gender.MALE) - .phone("01012331233") - .role(Role.USER) - .build(); - } - - public static MemberDto createMemberDto(Long id, Member member) { - return MemberDto.builder() - .id(id) - .email(member.getEmail()) - .name(member.getName()) - .nickname(member.getNickname()) - .gender(member.getGender()) - .phone(member.getPhone()) - .role(member.getRole()) - .build(); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/factory/PaymentFactory.java b/module-application/app-api/src/test/java/shop/jtoon/factory/PaymentFactory.java deleted file mode 100644 index 32d20b6..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/factory/PaymentFactory.java +++ /dev/null @@ -1,80 +0,0 @@ -package shop.jtoon.factory; - -import shop.jtoon.entity.CookieItem; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PaymentInfo; -import shop.jtoon.payment.request.CancelReq; -import shop.jtoon.payment.request.ConditionReq; -import shop.jtoon.payment.request.PaymentReq; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; - -public class PaymentFactory { - - public static PaymentInfo createPaymentInfo(String impUid, String merchantUid, Member member) { - return PaymentInfo.builder() - .impUid(impUid) - .merchantUid(merchantUid) - .payMethod("card") - .cookieItem(CookieItem.COOKIE_ONE) - .amount(BigDecimal.valueOf(1000)) - .member(member) - .build(); - } - - public static PaymentReq createPaymentReq(String impUid, String merchantUid, String email) { - return PaymentReq.builder() - .impUid(impUid) - .merchantUid(merchantUid) - .payMethod("card") - .itemName(CookieItem.COOKIE_ONE.getItemName()) - .amount(CookieItem.COOKIE_ONE.getAmount()) - .buyerEmail(email) - .buyerName("홍도산") - .buyerPhone("01012311231") - .build(); - } - - public static PaymentReq createPaymentReq(String impUid, String merchantUid, BigDecimal amount, String email) { - return PaymentReq.builder() - .impUid(impUid) - .merchantUid(merchantUid) - .payMethod("card") - .itemName(CookieItem.COOKIE_ONE.getItemName()) - .amount(amount) - .buyerEmail(email) - .buyerName("홍도산") - .buyerPhone("01012311231") - .build(); - } - - public static CancelReq createCancelReq(PaymentReq paymentReq) { - return CancelReq.builder() - .impUid(paymentReq.impUid()) - .merchantUid(paymentReq.merchantUid()) - .reason("reason") - .checksum(CookieItem.COOKIE_ONE.getAmount()) - .refundHolder(paymentReq.buyerEmail()) - .build(); - } - - public static CancelReq createCancelReq(String impUid, String merchantUid, String name) { - return CancelReq.builder() - .impUid(impUid) - .merchantUid(merchantUid) - .reason("reason") - .checksum(CookieItem.COOKIE_ONE.getAmount()) - .refundHolder(name) - .build(); - } - - public static ConditionReq createConditionReq(String... merchantUid) { - List merchantsUid = new ArrayList<>(List.of(merchantUid)); - - return ConditionReq.builder() - .merchantsUid(merchantsUid) - .build(); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/factory/PaymentSnippetFactory.java b/module-application/app-api/src/test/java/shop/jtoon/factory/PaymentSnippetFactory.java deleted file mode 100644 index a0e4640..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/factory/PaymentSnippetFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -package shop.jtoon.factory; - -import org.springframework.restdocs.payload.RequestFieldsSnippet; -import org.springframework.restdocs.payload.ResponseFieldsSnippet; - -import static org.springframework.restdocs.payload.JsonFieldType.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; - -public class PaymentSnippetFactory { - public static final RequestFieldsSnippet PAYMENT_REQUEST = requestFields( - fieldWithPath("impUid").type(STRING).description("포트원 결제 고유번호"), - fieldWithPath("merchantUid").type(STRING).description("가맹점 주문번호"), - fieldWithPath("payMethod").type(STRING).description("결제 방법"), - fieldWithPath("itemName").type(STRING).description("결제된 상품명"), - fieldWithPath("amount").type(NUMBER).description("결제된 금액"), - fieldWithPath("buyerEmail").type(STRING).description("구매자 이메일"), - fieldWithPath("buyerName").type(STRING).description("구매자 이름"), - fieldWithPath("buyerPhone").type(STRING).description("구매자 전화번호") - ); - - public static final RequestFieldsSnippet CANCEL_REQUEST = requestFields( - fieldWithPath("impUid").type(STRING).description("포트원 결제 고유번호"), - fieldWithPath("merchantUid").type(STRING).description("가맹점 주문번호"), - fieldWithPath("reason").type(STRING).description("환불 사유"), - fieldWithPath("checksum").type(NUMBER).description("환불 가능 금액"), - fieldWithPath("refundHolder").type(STRING).description("환불 수령자") - ); - - public static final RequestFieldsSnippet CONDITION_REQUEST = requestFields( - fieldWithPath("merchantsUid").type(ARRAY).description("가맹점 주문번호 리스트") - ); - - public static final ResponseFieldsSnippet CONDITION_RESPONSE = responseFields( - fieldWithPath("[].itemName").type(STRING).description("상품명"), - fieldWithPath("[].itemCount").type(NUMBER).description("상품 수량"), - fieldWithPath("[].amount").type(NUMBER).description("결제 금액"), - fieldWithPath("[].createdAt").type(STRING).description("결제 일시") - ); -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/factory/WebtoonFactory.java b/module-application/app-api/src/test/java/shop/jtoon/factory/WebtoonFactory.java deleted file mode 100644 index 34ccd18..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/factory/WebtoonFactory.java +++ /dev/null @@ -1,98 +0,0 @@ -package shop.jtoon.factory; - -import org.springframework.mock.web.MockMultipartFile; -import shop.jtoon.entity.Episode; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Webtoon; -import shop.jtoon.entity.enums.AgeLimit; -import shop.jtoon.entity.enums.DayOfWeek; -import shop.jtoon.entity.enums.Genre; -import shop.jtoon.webtoon.request.CreateEpisodeReq; -import shop.jtoon.webtoon.request.CreateWebtoonReq; -import shop.jtoon.webtoon.request.GetEpisodesReq; -import shop.jtoon.webtoon.request.GetWebtoonsReq; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.util.HashSet; -import java.util.Set; - -public class WebtoonFactory { - - public static Webtoon createWebtoon(Member member) { - return Webtoon.builder() - .title("웹툰 제목") - .description("웹툰 설명") - .ageLimit(AgeLimit.ALL) - .thumbnailUrl("https://webtoons/thumbnail") - .cookieCount(3) - .author(member) - .build(); - } - - public static CreateWebtoonReq createWebtoonReq() { - Set dayOfWeeks = new HashSet<>(); - dayOfWeeks.add(DayOfWeek.MON); - Set genres = new HashSet<>(); - genres.add(Genre.ROMANCE); - - return CreateWebtoonReq.builder() - .title("재윤이의 모험일기") - .description("재윤이의 개쩌는 모험이야기, 설레지") - .dayOfWeeks(dayOfWeeks) - .genres(genres) - .ageLimit(AgeLimit.ADULT) - .cookieCount(2) - .build(); - } - - public static GetWebtoonsReq getWebtoonsReq() { - return GetWebtoonsReq.builder() - .day(DayOfWeek.MON) - .keyword("") - .build(); - } - - public static Episode createEpisode(Webtoon webtoon, int no) { - return Episode.builder() - .no(no) - .title("회차 제목") - .mainUrl("https://webtoons/episodes/main") - .thumbnailUrl("https://webtoons/episodes/thumbnail") - .hasComment(true) - .openedAt(LocalDateTime.of(2023, 9, 20, 0, 0, 0)) - .webtoon(webtoon) - .build(); - } - - public static CreateEpisodeReq createEpisodeReq() { - return CreateEpisodeReq.builder() - .no(1) - .title("회차 제목") - .hasComment(true) - .openedAt(LocalDateTime.of(2023, 9, 20, 0, 0, 0)) - .build(); - } - - public static GetEpisodesReq createGetEpisodesReq() { - return GetEpisodesReq.builder().build(); - } - - public static MockMultipartFile createMultipartFile() { - Path path = Paths.get("src/test/resources/test.png"); - - try { - return new MockMultipartFile( - "image", - "test.png", - "image/png", - Files.readAllBytes(path) - ); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/payment/application/MemberCookieServiceTest.java b/module-application/app-api/src/test/java/shop/jtoon/payment/application/MemberCookieServiceTest.java deleted file mode 100644 index 7dadddf..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/payment/application/MemberCookieServiceTest.java +++ /dev/null @@ -1,118 +0,0 @@ -package shop.jtoon.payment.application; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import shop.jtoon.entity.CookieItem; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.MemberCookie; -import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.exception.NotFoundException; -import shop.jtoon.factory.MemberFactory; -import shop.jtoon.repository.MemberCookieRepository; -import shop.jtoon.type.ErrorStatus; - -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - - -@ExtendWith(MockitoExtension.class) -class MemberCookieServiceTest { - - @InjectMocks - private MemberCookieService memberCookieService; - - @Mock - private MemberCookieRepository memberCookieRepository; - - private Member member; - - @BeforeEach - void beforeEach() { - member = MemberFactory.createMember(); - } - - @DisplayName("createMemberCookie - 한 회원의 쿠키 정보가 성공적으로 저장될 때, - Void") - @Test - void createMemberCookie_Void() { - // When - memberCookieService.createMemberCookie(CookieItem.COOKIE_ONE.getItemName(), member); - - // Then - verify(memberCookieRepository).save(any(MemberCookie.class)); - } - - @DisplayName("useCookie - 해당 회원에 대한 쿠키 정보가 존재하지 않을 때, - NotFoundException (MemberCookie)") - @Test - void useCookie_NotFoundException_MemberCookie() { - // Given - given(memberCookieRepository.findByMember(any(Member.class))).willReturn(Optional.empty()); - - // When, Then - assertThatThrownBy(() -> memberCookieService.useCookie(2, member)) - .isInstanceOf(NotFoundException.class) - .hasMessage(ErrorStatus.MEMBER_COOKIE_NOT_FOUND.getMessage()); - } - - @DisplayName("useCookie - 사용할 쿠키 갯수가 해당 회원이 가진 쿠키 갯수보다 적을 때, - InvalidRequestException") - @Test - void useCookie_InvalidRequestException() { - // Given - MemberCookie memberCookie = MemberCookie.create(0, member); - given(memberCookieRepository.findByMember(any(Member.class))).willReturn(Optional.of(memberCookie)); - - // When, Then - assertThatThrownBy(() -> memberCookieService.useCookie(2, member)) - .isInstanceOf(InvalidRequestException.class) - .hasMessage(ErrorStatus.EPISODE_NOT_ENOUGH_COOKIES.getMessage()); - } - - @DisplayName("useCookie - 쿠키 갯수가 충분할 때, - 남은 쿠키 갯수") - @Test - void useCookie_CookieCount() { - // Given - MemberCookie memberCookie = MemberCookie.create(7, member); - given(memberCookieRepository.findByMember(any(Member.class))).willReturn(Optional.of(memberCookie)); - - // When - int actual = memberCookieService.useCookie(2, member); - - // Then - assertThat(actual).isEqualTo(5); - } - - @DisplayName("getMemberCookieCount - 해당 회원에 대한 쿠키 정보가 존재하지 않을 때, - NotFoundException (MemberCookie)") - @Test - void getMemberCookieCount_NotFoundException_MemberCookie() { - // Given - given(memberCookieRepository.findByMember(any(Member.class))).willReturn(Optional.empty()); - - // When, Then - assertThatThrownBy(() -> memberCookieService.getMemberCookieCount(member)) - .isInstanceOf(NotFoundException.class) - .hasMessage(ErrorStatus.MEMBER_COOKIE_NOT_FOUND.getMessage()); - } - - @DisplayName("getMemberCookieCount - 해당 회원이 가진 쿠키 갯수를 성공적으로 조회, - 쿠키 갯수") - @Test - void getMemberCookieCount_CookieCount() { - // Given - MemberCookie memberCookie = MemberCookie.create(7, member); - given(memberCookieRepository.findByMember(any(Member.class))).willReturn(Optional.of(memberCookie)); - - // When - int actual = memberCookieService.getMemberCookieCount(member); - - // Then - assertThat(actual).isEqualTo(7); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentInfoServiceTest.java b/module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentInfoServiceTest.java deleted file mode 100644 index 6e179ff..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentInfoServiceTest.java +++ /dev/null @@ -1,134 +0,0 @@ -package shop.jtoon.payment.application; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PaymentInfo; -import shop.jtoon.exception.DuplicatedException; -import shop.jtoon.factory.MemberFactory; -import shop.jtoon.factory.PaymentFactory; -import shop.jtoon.payment.request.PaymentReq; -import shop.jtoon.payment.response.PaymentRes; -import shop.jtoon.repository.PaymentInfoRepository; -import shop.jtoon.repository.PaymentInfoSearchRepository; -import shop.jtoon.service.PaymentInfoDomainService; -import shop.jtoon.type.ErrorStatus; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -class PaymentInfoServiceTest { - - @InjectMocks - private PaymentInfoService paymentInfoService; - - @Mock - private PaymentInfoDomainService paymentInfoDomainService; - - @Mock - private PaymentInfoRepository paymentInfoRepository; - - @Mock - private PaymentInfoSearchRepository paymentInfoSearchRepository; - - private Member member; - private PaymentReq paymentReq; - - @BeforeEach - void beforeEach() { - member = MemberFactory.createMember(); - paymentReq = PaymentFactory.createPaymentReq("imp123", "mer123", member.getEmail()); - } - - @DisplayName("createPaymentInfo - 한 회원의 결제 정보가 성공적으로 저장될 때, - Void") - @Test - void createPaymentInfo_Void() { - // When - paymentInfoService.createPaymentInfo(paymentReq, member); - - // Then - verify(paymentInfoRepository).save(any(PaymentInfo.class)); - } - - @DisplayName("getPaymentsInfo - 조회 결과가 없을 때, - Empty List") - @Test - void getPaymentsInfo_EmptyList() { - // Given - List paymentInfos = new ArrayList<>(); - given(paymentInfoSearchRepository.searchByMerchantsUidAndEmail(anyList(), any(String.class))) - .willReturn(paymentInfos); - - // When - List actual = paymentInfoService.getPaymentsInfo(Collections.emptyList(), member); - - // Then - assertThat(actual).isEmpty(); - } - - @DisplayName("getPaymentsInfo - 조회 결과가 2개 일때, - PaymentInfoRes List") - @Test - void getPaymentsInfo_PaymentInfoResList() { - // Given - List paymentInfos = new ArrayList<>(); - paymentInfos.add(PaymentFactory.createPaymentInfo("imp123", "mer123", member)); - paymentInfos.add(PaymentFactory.createPaymentInfo("imp456", "mer789", member)); - given(paymentInfoSearchRepository.searchByMerchantsUidAndEmail(anyList(), any(String.class))) - .willReturn(paymentInfos); - - // When - List actual = paymentInfoService.getPaymentsInfo(Collections.emptyList(), member); - - // Then - assertThat(actual).hasSize(2); - } - - @DisplayName("validatePaymentInfo - 결제 검증에 대한 서비스를 잘 호출하는 지 검증 - Void") - @Test - void validatePaymentInfo_Void() { - // When - paymentInfoService.validatePaymentInfo(paymentReq); - - // Then - assertThatNoException() - .isThrownBy(() -> paymentInfoDomainService.validatePaymentInfo(any(String.class), any(BigDecimal.class))); - } - - @DisplayName("validatePaymentInfo - 결제 고유번호가 중복 됐을 때, - DuplicatedException (ImpUid)") - @Test - void validatePaymentInfo_DuplicatedException_ImpUid() { - // Given - given(paymentInfoRepository.existsByImpUid(any(String.class))).willReturn(true); - - // When, Then - assertThatThrownBy(() -> paymentInfoService.validatePaymentInfo(paymentReq)) - .isInstanceOf(DuplicatedException.class) - .hasMessage(ErrorStatus.PAYMENT_IMP_UID_DUPLICATED.getMessage()); - } - - @DisplayName("validatePaymentInfo - 주문번호가 중복 됐을 때, - DuplicatedException (MerchantUid)") - @Test - void validatePaymentInfo_DuplicatedException_MerchantUid() { - // Given - given(paymentInfoRepository.existsByImpUid(any(String.class))).willReturn(false); - given(paymentInfoRepository.existsByMerchantUid(any(String.class))).willReturn(true); - - // When, Then - assertThatThrownBy(() -> paymentInfoService.validatePaymentInfo(paymentReq)) - .isInstanceOf(DuplicatedException.class) - .hasMessage(ErrorStatus.PAYMENT_MERCHANT_UID_DUPLICATED.getMessage()); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentServiceTest.java b/module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentServiceTest.java deleted file mode 100644 index 864ca9e..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/payment/application/PaymentServiceTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package shop.jtoon.payment.application; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import shop.jtoon.dto.MemberDto; -import shop.jtoon.entity.Member; -import shop.jtoon.factory.MemberFactory; -import shop.jtoon.factory.PaymentFactory; -import shop.jtoon.member.application.MemberService; -import shop.jtoon.payment.request.CancelReq; -import shop.jtoon.payment.request.ConditionReq; -import shop.jtoon.payment.request.PaymentReq; -import shop.jtoon.payment.response.PaymentRes; -import shop.jtoon.service.IamportService; - -import java.math.BigDecimal; -import java.util.Collections; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.verify; - -@ExtendWith(MockitoExtension.class) -class PaymentServiceTest { - - @InjectMocks - private PaymentService paymentService; - - @Mock - private IamportService iamportService; - - @Mock - private PaymentInfoService paymentInfoService; - - @Mock - private MemberCookieService memberCookieService; - - @Mock - private MemberService memberService; - - private PaymentReq paymentReq; - private CancelReq cancelReq; - private Member member; - private MemberDto memberDto; - - @BeforeEach - void beforeEach() { - member = MemberFactory.createMember(); - memberDto = MemberFactory.createMemberDto(1L, member); - paymentReq = PaymentFactory.createPaymentReq("imp123", "mer123", member.getEmail()); - cancelReq = PaymentFactory.createCancelReq(paymentReq); - } - - @DisplayName("validateAndCreatePayment - 결제에 대한 검증 및 생성 서비스를 정상적으로 호출하는 지 검증, - BigDecimal(Amount)") - @Test - void validateAndCreatePayment_Amount() { - // Given - given(memberService.findByEmail(any(String.class))).willReturn(member); - - // When - BigDecimal actual = paymentService.validateAndCreatePayment(paymentReq, memberDto); - - // Then - verify(iamportService).validateIamport(any(String.class), any(BigDecimal.class)); - verify(paymentInfoService).validatePaymentInfo(any(PaymentReq.class)); - verify(paymentInfoService).createPaymentInfo(any(PaymentReq.class), any(Member.class)); - verify(memberCookieService).createMemberCookie(any(String.class), any(Member.class)); - assertThat(actual).isEqualTo(paymentReq.amount()); - } - - @DisplayName("cancelPayment - 결제 취소에 대한 검증 및 취소 서비스를 정상적으로 호출하는 지 검증, - Void ") - @Test - void cancelPayment_Void() { - // When - paymentService.cancelPayment(cancelReq); - - // Then - verify(iamportService).validateIamport(any(String.class), any(BigDecimal.class)); - verify(iamportService).cancelIamport(any(String.class), any(String.class), any(BigDecimal.class), - any(String.class)); - } - - @DisplayName("getPayments - 결제 내역 조회에 대한 서비스를 정상적으로 호출하는 지 검증 - PaymentRes List") - @Test - void getPayments_PaymentRes_List() { - // Given - ConditionReq conditionReq = ConditionReq.builder() - .merchantsUid(Collections.emptyList()) - .build(); - given(memberService.findByEmail(any(String.class))).willReturn(member); - given(paymentInfoService.getPaymentsInfo(anyList(), any(Member.class))).willReturn(Collections.emptyList()); - - // When - List actual = paymentService.getPayments(conditionReq, memberDto); - - // Then - assertThat(actual).isEmpty(); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/payment/presentation/PaymentControllerTest.java b/module-application/app-api/src/test/java/shop/jtoon/payment/presentation/PaymentControllerTest.java deleted file mode 100644 index 5a7c2f0..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/payment/presentation/PaymentControllerTest.java +++ /dev/null @@ -1,348 +0,0 @@ -package shop.jtoon.payment.presentation; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.transaction.annotation.Transactional; -import shop.jtoon.config.WithCurrentUser; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PaymentInfo; -import shop.jtoon.exception.IamportException; -import shop.jtoon.factory.MemberFactory; -import shop.jtoon.factory.PaymentFactory; -import shop.jtoon.factory.PaymentSnippetFactory; -import shop.jtoon.payment.request.CancelReq; -import shop.jtoon.payment.request.ConditionReq; -import shop.jtoon.payment.request.PaymentReq; -import shop.jtoon.repository.MemberRepository; -import shop.jtoon.repository.PaymentInfoRepository; -import shop.jtoon.service.IamportService; - -import java.math.BigDecimal; -import java.util.List; - -import static org.hamcrest.Matchers.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.willDoNothing; -import static org.mockito.BDDMockito.willThrow; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import static shop.jtoon.type.ErrorStatus.*; - -@Transactional -@SpringBootTest -@AutoConfigureMockMvc -@AutoConfigureRestDocs -@ActiveProfiles("test") -class PaymentControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - @Autowired - private PaymentInfoRepository paymentInfoRepository; - - @Autowired - private MemberRepository memberRepository; - - @MockBean - private IamportService iamportService; - - private String impUid; - private String merchantUid; - private Member member; - - @BeforeEach - void beforeEach() { - impUid = "impUid123"; - merchantUid = "merchant123"; - member = MemberFactory.createMember(); - memberRepository.save(member); - } - - @DisplayName("POST: /payments/validation - 결제 승인 후 결제 정보에 대해 검증 및 생성이 성공적으로 됐을 때, - Amount") - @WithCurrentUser - @Test - void validatePayment_Amount() throws Exception { - // Given - PaymentReq paymentReq = PaymentFactory.createPaymentReq(impUid, merchantUid, member.getEmail()); - willDoNothing() - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - - // When, Then - mockMvc.perform(post("/payments/validation") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(paymentReq))) - .andDo(print()) - .andDo(document("payments/validation", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.PAYMENT_REQUEST)) - .andExpect(status().isCreated()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().string(paymentReq.amount().toString())); - } - - @DisplayName("POST: /payments/validation - 아임포트 서버에서 결제 정보가 조회되지 않거나, 조회된 결제 금액과 환불될 금액이 다를 때, - IamportException") - @WithCurrentUser - @Test - void validatePayment_IamportException() throws Exception { - // Given - PaymentReq paymentReq = PaymentFactory.createPaymentReq(impUid, merchantUid, member.getEmail()); - willThrow(IamportException.class) - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - - // When, Then - mockMvc.perform(post("/payments/validation") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(paymentReq))) - .andDo(print()) - .andDo(document("payments/validation", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.PAYMENT_REQUEST)) - .andExpect(status().isInternalServerError()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)); - } - - @DisplayName("POST: /payments/validation - 결제된 금액과 서버에서 알고 있는 금액이 다를 때, - InvalidRequestException") - @WithCurrentUser - @Test - void validatePayment_InvalidRequestException() throws Exception { - // Given - PaymentReq paymentReq = PaymentFactory.createPaymentReq(impUid, merchantUid, BigDecimal.ONE, member.getEmail()); - willDoNothing() - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - - // When, Then - mockMvc.perform(post("/payments/validation") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(paymentReq))) - .andDo(print()) - .andDo(document("payments/validation", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.PAYMENT_REQUEST)) - .andExpect(status().isBadRequest()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.message").value(PAYMENT_AMOUNT_INVALID.getMessage())); - } - - @DisplayName("POST: /payments/validation - 포트원 결제 고유번호가 중복 됐을 때, - ImpUid DuplicatedException") - @WithCurrentUser - @Test - void validatePayment_ImpUid_DuplicatedException() throws Exception { - // Given - PaymentInfo paymentInfo = PaymentFactory.createPaymentInfo(impUid, merchantUid + "7", member); - PaymentReq paymentReq = PaymentFactory.createPaymentReq(impUid, merchantUid, member.getEmail()); - paymentInfoRepository.save(paymentInfo); - willDoNothing() - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - - // When, Then - mockMvc.perform(post("/payments/validation") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(paymentReq))) - .andDo(print()) - .andDo(document("payments/validation", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.PAYMENT_REQUEST)) - .andExpect(status().isConflict()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.message").value(PAYMENT_IMP_UID_DUPLICATED.getMessage())); - } - - @DisplayName("POST: /payments/validation - 가맹점 주문번호가 중복 됐을 때, - MerchantUid DuplicatedException") - @WithCurrentUser - @Test - void validatePayment_MerchantUid_DuplicatedException() throws Exception { - // Given - PaymentInfo paymentInfo = PaymentFactory.createPaymentInfo(impUid + "7", merchantUid, member); - PaymentReq paymentReq = PaymentFactory.createPaymentReq(impUid, merchantUid, member.getEmail()); - paymentInfoRepository.save(paymentInfo); - willDoNothing() - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - - // When, Then - mockMvc.perform(post("/payments/validation") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(paymentReq))) - .andDo(print()) - .andDo(document("payments/validation", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.PAYMENT_REQUEST)) - .andExpect(status().isConflict()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.message", is(PAYMENT_MERCHANT_UID_DUPLICATED.getMessage()))); - } - - @DisplayName("POST: /payments/cancel - 결제 취소 요청 후 결제 취소 정보에 대해 검증 및 취소 요청이 성공적으로 됐을 때, - Void") - @Test - void cancelPayment_Void() throws Exception { - // Given - CancelReq cancelReq = PaymentFactory.createCancelReq(impUid, merchantUid, member.getName()); - willDoNothing() - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - willDoNothing() - .given(iamportService) - .cancelIamport(any(String.class), any(String.class), any(BigDecimal.class), any(String.class)); - - // When, Then - mockMvc.perform(post("/payments/cancel") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(cancelReq))) - .andDo(print()) - .andDo(document("payments/cancel", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.CANCEL_REQUEST)) - .andExpect(status().isOk()); - } - - @DisplayName("POST: /payments/cancel - 아임포트 서버에서 결제 취소 요청을 실패할 때, - IamportException") - @Test - void cancelPayment_IamportException() throws Exception { - // Given - CancelReq cancelReq = PaymentFactory.createCancelReq(impUid, merchantUid, member.getName()); - willThrow(IamportException.class) - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - - // When, Then - mockMvc.perform(post("/payments/cancel") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(cancelReq))) - .andDo(print()) - .andDo(document("payments/cancel", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.CANCEL_REQUEST)) - .andExpect(status().isInternalServerError()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)); - } - - @DisplayName("POST: /payments/cancel - 아임포트 서버에서 조회된 결제 금액과 환불될 금액이 다를 때, - IamportException") - @Test - void cancelPayment_validate_IamportException() throws Exception { - // Given - CancelReq cancelReq = PaymentFactory.createCancelReq(impUid, merchantUid, member.getName()); - willDoNothing() - .given(iamportService) - .validateIamport(any(String.class), any(BigDecimal.class)); - willThrow(IamportException.class) - .given(iamportService) - .cancelIamport(any(String.class), any(String.class), any(BigDecimal.class), any(String.class)); - - // When, Then - mockMvc.perform(post("/payments/cancel") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(cancelReq))) - .andDo(print()) - .andDo(document("payments/cancel", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.CANCEL_REQUEST)) - .andExpect(status().isInternalServerError()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)); - } - - @DisplayName("POST: /payments/search - 한 사용자에 대해 모든 결제 내역을 조회 했을 때, - List") - @WithCurrentUser - @Test - void getPayments_PaymentInfo_List() throws Exception { - // Given - ConditionReq conditionReq = PaymentFactory.createConditionReq(); - PaymentInfo paymentInfo1 = PaymentFactory.createPaymentInfo(impUid + "1", merchantUid + "1", member); - PaymentInfo paymentInfo2 = PaymentFactory.createPaymentInfo(impUid + "2", merchantUid + "2", member); - PaymentInfo paymentInfo3 = PaymentFactory.createPaymentInfo(impUid + "3", merchantUid + "3", member); - paymentInfoRepository.saveAll(List.of(paymentInfo1, paymentInfo2, paymentInfo3)); - - // When, Then - mockMvc.perform(post("/payments/search") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(conditionReq))) - .andDo(print()) - .andDo(document("payments/search", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.CONDITION_REQUEST, - PaymentSnippetFactory.CONDITION_RESPONSE)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(3))); - } - - @DisplayName("POST: /payments/search - 한 사용자에 대해 특정 결제 내역을 조회 했을 때, - List") - @WithCurrentUser - @Test - void getPayments_PaymentInfo() throws Exception { - // Given - ConditionReq conditionReq = PaymentFactory.createConditionReq(merchantUid + "1"); - PaymentInfo paymentInfo1 = PaymentFactory.createPaymentInfo(impUid + "1", merchantUid + "1", member); - PaymentInfo paymentInfo2 = PaymentFactory.createPaymentInfo(impUid + "2", merchantUid + "2", member); - paymentInfoRepository.saveAll(List.of(paymentInfo1, paymentInfo2)); - - // When, Then - mockMvc.perform(post("/payments/search") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(conditionReq))) - .andDo(print()) - .andDo(document("payments/search", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.CONDITION_REQUEST, - PaymentSnippetFactory.CONDITION_RESPONSE)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$", hasSize(1))) - .andExpect(jsonPath("$[0].itemName", is(paymentInfo1.getCookieItem().getItemName()))) - .andExpect(jsonPath("$[0].itemCount", is((paymentInfo1.getCookieItem().getCount())))) - .andExpect(jsonPath("$[0].amount", is(paymentInfo1.getAmount().intValue()))); - } - - @DisplayName("POST: /payments/search - 한 사용자에 대해 존재하지 않는 결제 내역을 조회 했을 때, - Empty List") - @WithCurrentUser - @Test - void getPayments_Empty_List() throws Exception { - // Given - ConditionReq conditionReq = PaymentFactory.createConditionReq("empty merchant"); - PaymentInfo paymentInfo = PaymentFactory.createPaymentInfo(impUid, merchantUid, member); - paymentInfoRepository.save(paymentInfo); - - // When, Then - mockMvc.perform(post("/payments/search") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(conditionReq))) - .andDo(print()) - .andDo(document("payments/search", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - PaymentSnippetFactory.CONDITION_REQUEST)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$", empty())); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/security/application/AuthenticationServiceTest.java b/module-application/app-api/src/test/java/shop/jtoon/security/application/AuthenticationServiceTest.java deleted file mode 100644 index 093c131..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/security/application/AuthenticationServiceTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package shop.jtoon.security.application; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.servlet.HandlerExceptionResolver; -import shop.jtoon.member.application.EmailService; -import shop.jtoon.member.application.MemberService; -import shop.jtoon.member.presentation.MemberController; -import shop.jtoon.payment.application.PaymentService; -import shop.jtoon.payment.presentation.PaymentController; -import shop.jtoon.security.filter.AuthenticationFilter; -import shop.jtoon.security.service.AuthorizationService; -import shop.jtoon.security.service.RefreshTokenService; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@WebMvcTest(controllers = {MemberController.class, PaymentController.class}) -class AuthenticationServiceTest { - - @Autowired - MemberController memberController; - - @MockBean - MemberService memberService; - - @MockBean - EmailService emailService; - - @MockBean - RefreshTokenService refreshTokenService; - - MockMvc mockMvc; - - @MockBean - PaymentService paymentService; - - AuthenticationFilter authenticationFilter; - - @Autowired - HandlerExceptionResolver handlerExceptionResolver; - - @BeforeEach - void init() { - authenticationFilter = new AuthenticationFilter( - handlerExceptionResolver, - new AuthorizationService(), - new AuthenticationServiceImpl(memberService), - new JwtServiceImpl(refreshTokenService) - ); - - mockMvc = MockMvcBuilders.standaloneSetup(memberController) - .addFilter(authenticationFilter) - .build(); - } - - @DisplayName("인증없이 접근 성공") - @Test - void noAuthentication_access_success() throws Exception { - // given - mockMvc.perform(get("/members/email-authorization?email=example@naver.com")) - .andExpect(status().isCreated()); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/security/application/JwtServiceImplTest.java b/module-application/app-api/src/test/java/shop/jtoon/security/application/JwtServiceImplTest.java deleted file mode 100644 index 82df283..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/security/application/JwtServiceImplTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package shop.jtoon.security.application; - -import io.jsonwebtoken.security.Keys; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; -import shop.jtoon.exception.UnauthorizedException; -import shop.jtoon.security.service.RefreshTokenService; - -import java.nio.charset.StandardCharsets; -import java.security.Key; - -import static org.assertj.core.api.Assertions.assertThatNoException; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.given; - -@ExtendWith(MockitoExtension.class) -class JwtServiceImplTest { - - @InjectMocks - JwtServiceImpl jwtServiceImpl; - - @Mock - RefreshTokenService refreshTokenService; - - Key secretKey; - - @BeforeEach - void initProperties() { - String test = "testtesttesttesttesttesttesttesttesttesttesttesttesttest"; - ReflectionTestUtils.setField(jwtServiceImpl, "ISS", "test"); - ReflectionTestUtils.setField(jwtServiceImpl, "SALT", test); - ReflectionTestUtils.setField(jwtServiceImpl, "ACCESS_EXPIRE", 600); - ReflectionTestUtils.setField(jwtServiceImpl, "REFRESH_EXPIRE", 10080); - secretKey = Keys.hmacShaKeyFor(test.getBytes(StandardCharsets.UTF_8)); - ReflectionTestUtils.setField(jwtServiceImpl, "secretKey", secretKey); - } - - @DisplayName("Access Token 생성 성공 테스트") - @Test - void accessToken_create_success() { - // given - String email = "abc@gmail.com"; - - // when, then - assertThatNoException().isThrownBy(() -> jwtServiceImpl.generateAccessToken(email)); - } - - @DisplayName("Refresh Token 생성 성공 테스트") - @Test - void refreshToken_create_success() { - // when, then - assertThatNoException().isThrownBy(() -> jwtServiceImpl.generateRefreshToken()); - } - - @DisplayName("Refresh Token이 존재하지 않으면 예외 발생 테스트") - @Test - void refreshToken_notExists_thenThrowException() { - // given - String refreshToken = jwtServiceImpl.generateRefreshToken(); - given(refreshTokenService.hasRefreshToken(refreshToken)).willReturn(Boolean.FALSE); - - // when, then - assertThatThrownBy(() -> jwtServiceImpl.validateRefreshTokenRedis(refreshToken)) - .isInstanceOf(UnauthorizedException.class); - } - - @DisplayName("Refresh Token 업데이트 성공 테스트") - @Disabled - @Test - void updateRefreshToken_success() { - // given - String accessToken = jwtServiceImpl.generateAccessToken("abc@gmail.com"); - String oldRefreshToken = jwtServiceImpl.generateRefreshToken(); - String newRefreshToken = jwtServiceImpl.generateRefreshToken(); - - // when, then - assertThatNoException().isThrownBy(() -> jwtServiceImpl.updateRefreshTokenDb(accessToken, newRefreshToken, oldRefreshToken)); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/webtoon/application/EpisodeServiceTest.java b/module-application/app-api/src/test/java/shop/jtoon/webtoon/application/EpisodeServiceTest.java deleted file mode 100644 index fa5b64a..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/webtoon/application/EpisodeServiceTest.java +++ /dev/null @@ -1,203 +0,0 @@ -package shop.jtoon.webtoon.application; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.mock.web.MockMultipartFile; -import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.entity.Episode; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PurchasedEpisode; -import shop.jtoon.entity.Webtoon; -import shop.jtoon.exception.DuplicatedException; -import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.exception.NotFoundException; -import shop.jtoon.factory.MemberFactory; -import shop.jtoon.factory.WebtoonFactory; -import shop.jtoon.member.application.MemberService; -import shop.jtoon.payment.application.MemberCookieService; -import shop.jtoon.repository.EpisodeRepository; -import shop.jtoon.repository.EpisodeSearchRepository; -import shop.jtoon.repository.PurchasedEpisodeRepository; -import shop.jtoon.response.EpisodeInfoRes; -import shop.jtoon.response.EpisodeItemRes; -import shop.jtoon.service.S3Service; -import shop.jtoon.webtoon.request.CreateEpisodeReq; -import shop.jtoon.webtoon.request.GetEpisodesReq; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.BDDMockito.*; - -@ExtendWith(MockitoExtension.class) -class EpisodeServiceTest { - - @InjectMocks - private EpisodeService episodeService; - - @Mock - private MemberService memberService; - - @Mock - private MemberCookieService memberCookieService; - - @Mock - private WebtoonService webtoonService; - - @Mock - private S3Service s3Service; - - @Mock - private EpisodeRepository episodeRepository; - - @Mock - private EpisodeSearchRepository episodeSearchRepository; - - @Mock - private PurchasedEpisodeRepository purchasedEpisodeRepository; - - private Member member; - private Webtoon webtoon; - - @BeforeEach - void beforeEach() { - member = spy(MemberFactory.createMember()); - lenient().when(member.getId()).thenReturn(1L); - webtoon = spy(WebtoonFactory.createWebtoon(member)); - lenient().when(webtoon.getId()).thenReturn(1L); - } - - @DisplayName("createEpisode - 회차 생성 성공, - Void") - @Test - void createEpisode_Void() { - // Given - CreateEpisodeReq request = WebtoonFactory.createEpisodeReq(); - MockMultipartFile image = WebtoonFactory.createMultipartFile(); - given(webtoonService.getWebtoonById(webtoon.getId())).willReturn(webtoon); - given(s3Service.uploadImage(any(UploadImageDto.class))).willReturn("https://webtoons/episodes/image"); - - // When - episodeService.createEpisode(member.getId(), webtoon.getId(), image, image, request); - - // Then - verify(episodeRepository).save(any(Episode.class)); - } - - @DisplayName("createEpisode - 회차 번호 중복, - DuplicatedException") - @Test - void createEpisode_DuplicatedException() { - // Given - CreateEpisodeReq request = WebtoonFactory.createEpisodeReq(); - MockMultipartFile image = WebtoonFactory.createMultipartFile(); - given(webtoonService.getWebtoonById(webtoon.getId())).willReturn(webtoon); - given(episodeRepository.existsByWebtoonAndNo(any(Webtoon.class), anyInt())).willReturn(true); - - // When, Then - assertThatThrownBy(() -> episodeService.createEpisode(member.getId(), webtoon.getId(), image, image, request)) - .isInstanceOf(DuplicatedException.class) - .hasMessage("이미 존재하는 회차 번호입니다."); - } - - @DisplayName("createEpisode - 회차 생성 실패 시 이미지 삭제 서비스 호출, - InvalidRequestException") - @Test - void createEpisode_InvalidRequestException() { - // Given - CreateEpisodeReq request = WebtoonFactory.createEpisodeReq(); - MockMultipartFile image = WebtoonFactory.createMultipartFile(); - given(webtoonService.getWebtoonById(webtoon.getId())).willReturn(webtoon); - given(s3Service.uploadImage(any(UploadImageDto.class))).willReturn("https://webtoons/episodes/image"); - given(episodeRepository.save(any(Episode.class))).willThrow(new RuntimeException()); - - // When, Then - assertThatThrownBy(() -> episodeService.createEpisode(member.getId(), webtoon.getId(), image, image, request)) - .isInstanceOf(InvalidRequestException.class) - .hasMessage("회차 생성에 실패했습니다."); - verify(s3Service, times(2)).deleteImage(anyString()); - } - - @DisplayName("getEpisodes - 조회할 회차 리스트가 없을 때, - Empty List") - @Test - void getEpisodes_EmptyList() { - // Given - GetEpisodesReq request = WebtoonFactory.createGetEpisodesReq(); - List episodes = new ArrayList<>(); - given(episodeSearchRepository.getEpisodes(webtoon.getId(), request.getSize(), request.getOffset())) - .willReturn(episodes); - - // When - List actual = episodeService.getEpisodes(webtoon.getId(), request); - - // Then - assertThat(actual).isEmpty(); - } - - @DisplayName("getEpisodes - 회차 리스트 조회 성공, - List") - @Test - void getEpisodes_EpisodeItemResList() { - // Given - GetEpisodesReq request = WebtoonFactory.createGetEpisodesReq(); - List episodes = new ArrayList<>(); - episodes.add(WebtoonFactory.createEpisode(webtoon, 1)); - episodes.add(WebtoonFactory.createEpisode(webtoon, 2)); - given(episodeSearchRepository.getEpisodes(webtoon.getId(), request.getSize(), request.getOffset())) - .willReturn(episodes); - - // When - List actual = episodeService.getEpisodes(webtoon.getId(), request); - - // Then - assertThat(actual).hasSize(episodes.size()); - } - - @DisplayName("getEpisode - 회차 정보가 존재하지 않을 때, - NotFoundException") - @Test - void getEpisode_NotFoundException() { - // Given - given(episodeRepository.findById(anyLong())).willReturn(Optional.empty()); - - // When, Then - assertThatThrownBy(() -> episodeService.getEpisode(1L)) - .isInstanceOf(NotFoundException.class) - .hasMessage("존재하지 않는 회차입니다."); - } - - @DisplayName("getEpisode - 회차 정보 조회 성공, - EpisodeInfoRes") - @Test - void getEpisode_EpisodeInfoRes() { - // Given - Episode episode = WebtoonFactory.createEpisode(webtoon, 1); - given(episodeRepository.findById(anyLong())).willReturn(Optional.of(episode)); - - // When - EpisodeInfoRes actual = episodeService.getEpisode(1L); - - // Then - assertThat(actual.mainUrl()).isEqualTo("https://webtoons/episodes/main"); - } - - @DisplayName("purchaseEpisode - 회차 구매 성공, - Void") - @Test - void purchaseEpisode_Void() { - // Given - Episode episode = spy(WebtoonFactory.createEpisode(webtoon, 1)); - given(episode.getId()).willReturn(1L); - given(memberService.findById(member.getId())).willReturn(member); - given(episodeRepository.findById(anyLong())).willReturn(Optional.of(episode)); - - // When - episodeService.purchaseEpisode(member.getId(), episode.getId()); - - // Then - verify(memberCookieService).useCookie(episode.getCookieCount(), member); - verify(purchasedEpisodeRepository).save(any(PurchasedEpisode.class)); - } -} diff --git a/module-application/app-api/src/test/java/shop/jtoon/webtoon/application/WebtoonServiceTest.java b/module-application/app-api/src/test/java/shop/jtoon/webtoon/application/WebtoonServiceTest.java deleted file mode 100644 index 79614b2..0000000 --- a/module-application/app-api/src/test/java/shop/jtoon/webtoon/application/WebtoonServiceTest.java +++ /dev/null @@ -1,203 +0,0 @@ -package shop.jtoon.webtoon.application; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentMatchers; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.mock.web.MockMultipartFile; -import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.entity.DayOfWeekWebtoon; -import shop.jtoon.entity.GenreWebtoon; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Webtoon; -import shop.jtoon.entity.enums.DayOfWeek; -import shop.jtoon.entity.enums.Genre; -import shop.jtoon.exception.DuplicatedException; -import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.exception.NotFoundException; -import shop.jtoon.factory.MemberFactory; -import shop.jtoon.factory.WebtoonFactory; -import shop.jtoon.member.application.MemberService; -import shop.jtoon.repository.DayOfWeekWebtoonRepository; -import shop.jtoon.repository.GenreWebtoonRepository; -import shop.jtoon.repository.WebtoonRepository; -import shop.jtoon.repository.WebtoonSearchRepository; -import shop.jtoon.response.WebtoonInfoRes; -import shop.jtoon.response.WebtoonItemRes; -import shop.jtoon.service.S3Service; -import shop.jtoon.type.ErrorStatus; -import shop.jtoon.webtoon.request.CreateWebtoonReq; -import shop.jtoon.webtoon.request.GetWebtoonsReq; - -import java.util.*; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.*; - -@ExtendWith(MockitoExtension.class) -class WebtoonServiceTest { - - @InjectMocks - private WebtoonService webtoonService; - - @Mock - private MemberService memberService; - - @Mock - private S3Service s3Service; - - @Mock - private WebtoonRepository webtoonRepository; - - @Mock - private WebtoonSearchRepository webtoonSearchRepository; - - @Mock - private DayOfWeekWebtoonRepository dayOfWeekWebtoonRepository; - - @Mock - private GenreWebtoonRepository genreWebtoonRepository; - - private Member member; - - @BeforeEach - void init() { - member = spy(MemberFactory.createMember()); - lenient().when(member.getId()).thenReturn(1L); - } - - @DisplayName("createWebtoon - 웹툰 생성 성공 - Void") - @Test - void createWebtoon_success() { - // Given - CreateWebtoonReq request = WebtoonFactory.createWebtoonReq(); - MockMultipartFile image = WebtoonFactory.createMultipartFile(); - given(memberService.findById(member.getId())).willReturn(member); - given(s3Service.uploadImage(any(UploadImageDto.class))).willReturn("thumbnailUrl"); - - // When - webtoonService.createWebtoon(member.getId(), image, request); - - // Then - verify(webtoonRepository).save(any(Webtoon.class)); - verify(dayOfWeekWebtoonRepository).saveAll(ArgumentMatchers.anyList()); - verify(genreWebtoonRepository).saveAll(ArgumentMatchers.anyList()); - } - - @DisplayName("createWebtoon - 웹툰 생성 실패 시 이미지 삭제 서비스 호출 - InvalidRequestException") - @Test - void createWebtoon_fail_invalid_request() { - // Given - CreateWebtoonReq request = WebtoonFactory.createWebtoonReq(); - MockMultipartFile image = WebtoonFactory.createMultipartFile(); - Long memberId = member.getId(); - given(memberService.findById(member.getId())).willReturn(member); - given(s3Service.uploadImage(any(UploadImageDto.class))).willReturn("thumbnailUrl"); - given(webtoonRepository.save(any(Webtoon.class))).willThrow(new RuntimeException()); - - // When, Then - assertThatThrownBy(() -> webtoonService.createWebtoon(memberId, image, request)) - .isInstanceOf(InvalidRequestException.class) - .hasMessage(ErrorStatus.WEBTOON_CREATE_FAIL.getMessage()); - verify(s3Service).deleteImage("thumbnailUrl"); - } - - @DisplayName("createWebtoon - 웹툰 생성 실패, 제목 중복 - DuplicatedException") - @Test - void createWebtoon_fail_duplicate_title() { - // Given - CreateWebtoonReq request = WebtoonFactory.createWebtoonReq(); - MockMultipartFile image = WebtoonFactory.createMultipartFile(); - Long memberId = member.getId(); - given(webtoonRepository.existsByTitle(any(String.class))).willReturn(true); - - // When, Then - assertThatThrownBy(() -> webtoonService.createWebtoon(memberId, image, request)) - .isInstanceOf(DuplicatedException.class) - .hasMessage(ErrorStatus.WEBTOON_TITLE_DUPLICATED.getMessage()); - } - - @DisplayName("getWebtoons - 웹툰 목록 조회 리스트 없을 때 - Empty Map") - @Test - void getWebtoons_empty_map() { - // Given - GetWebtoonsReq request = WebtoonFactory.getWebtoonsReq(); - Map> actual = new HashMap<>(); - List expect = new ArrayList<>(); - - given(webtoonSearchRepository.findWebtoons(any(DayOfWeek.class), any(String.class))).willReturn(expect); - - // When - actual = webtoonService.getWebtoons(request); - - // Then - assertThat(actual).isEmpty(); - } - - @DisplayName("getWebtoons - 웹툰 목록 조회 성공 - Map") - @Test - void getWebtoons_success() { - // Given - GetWebtoonsReq request = WebtoonFactory.getWebtoonsReq(); - Webtoon webtoon = WebtoonFactory.createWebtoon(member); - Map> actual = new HashMap<>(); - - List expect = new ArrayList<>(); - expect.add(DayOfWeekWebtoon.create(DayOfWeek.MON, webtoon)); - expect.add(DayOfWeekWebtoon.create(DayOfWeek.MON, webtoon)); - expect.add(DayOfWeekWebtoon.create(DayOfWeek.FRI, webtoon)); - - given(webtoonSearchRepository.findWebtoons(any(DayOfWeek.class), any(String.class))).willReturn(expect); - - // When - actual = webtoonService.getWebtoons(request); - - // Then - assertThat(actual).hasSize(2); - assertThat(actual.get(DayOfWeek.MON)).hasSize(2); - assertThat(actual.get(DayOfWeek.FRI)).hasSize(1); - } - - @DisplayName("getWebtoon - 웹툰 단건 조회 성공 - WebtoonInfoRes") - @Test - void getWebtoon_success() { - // Given - Webtoon webtoon = WebtoonFactory.createWebtoon(member); - List dayOfWeekWebtoon = new ArrayList<>(); - List genres = new ArrayList<>(); - dayOfWeekWebtoon.add(DayOfWeekWebtoon.create(DayOfWeek.MON, webtoon)); - dayOfWeekWebtoon.add(DayOfWeekWebtoon.create(DayOfWeek.FRI, webtoon)); - genres.add(GenreWebtoon.create(Genre.ACTION, webtoon)); - - given(webtoonRepository.findById(anyLong())).willReturn(Optional.of(webtoon)); - given(dayOfWeekWebtoonRepository.findByWebtoon(webtoon)).willReturn(dayOfWeekWebtoon); - given(genreWebtoonRepository.findByWebtoon(webtoon)).willReturn(genres); - - // When - WebtoonInfoRes actual = webtoonService.getWebtoon(anyLong()); - - // Then - assertThat(actual.thumbnailUrl()).isEqualTo("https://webtoons/thumbnail"); - assertThat(actual.dayOfWeeks()).hasSize(2); - assertThat(actual.dayOfWeeks().get(0)).isEqualTo(DayOfWeek.MON.toString()); - assertThat(actual.genres()).hasSize(1); - assertThat(actual.genres().get(0).type()).isEqualTo(Genre.ACTION); - } - - @DisplayName("getWebtoon - 웹턴 단건 조회 실패, 웹툰 없음 - NotFoundException") - @Test - void getWebtoon_fail_notfound_webtoon() { - // Given - given(webtoonRepository.findById(anyLong())).willReturn(Optional.empty()); - - // When, Then - assertThatThrownBy(() -> webtoonService.getWebtoon(1L)) - .isInstanceOf(NotFoundException.class) - .hasMessage(ErrorStatus.WEBTOON_NOT_FOUND.getMessage()); - } -} diff --git a/module-application/build.gradle b/module-application/build.gradle deleted file mode 100644 index d7dec73..0000000 --- a/module-application/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -project(':module-application:app-api') { - dependencies { - // Domain Layer - implementation project(':module-domain:domain-member') - implementation project(':module-domain:domain-payment') - implementation project(':module-domain:domain-webtoon') - implementation project(':module-domain:domain-redis') - - // Internal Layer - implementation project(':module-internal:core-web') - implementation project(':module-internal:iamport-client') - implementation project(':module-internal:s3-client') - implementation project(':module-internal:smtp-client') - - // Core Layer - implementation project(':module-core') - } -} diff --git a/module-core/README.md b/module-core/README.md deleted file mode 100644 index dce7497..0000000 --- a/module-core/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Core Layer - -| | **어플리케이션 모듈** | **내부 모듈** | **도메인 모듈** | **공통 모듈** | -|:---------:|:-------------:|:---------:|:----------:|:---------:| -| **사용 가능** | X | X | X | - | - -- 시스템 내 모든 모듈들이 의존할 수 있을만큼 얇은 의존성을 제공해야 하기 때문에, 프로젝트 내 어떠한 모듈도 의존하지 않아야 합니다. -- 즉 순수 Java Class 만 정의할 수 있습니다. - -
- -#### 아래와 같은 클래스를 배치할 수 있습니다. - -> - Type 성격의 DTO -> - 기본적인 Util Class diff --git a/module-domain/README.md b/module-domain/README.md deleted file mode 100644 index 0d3f904..0000000 --- a/module-domain/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Domain Layer - -| | **어플리케이션 모듈** | **내부 모듈** | **도메인 모듈** | **공통 모듈** | -|:---------:|:-------------:|:---------:|:----------:|:---------:| -| **사용 가능** | X | X | - | O | - -- 시스템의 중심 도메인을 다루는 모듈을 이 계층에 배치하였습니다. -- 저장소와 밀접한 중심 도메인을 다루는 계층은 더 견고하고 특별하게 격리되고 관리되어야 하기 때문에 반드시 분리되어야 합니다. -- 이 계층의 모듈은 오로지 도메인에 집중합니다. -- 어떠한 도메인이든 그 도메인이 가져야할 서비스와 무관한 도메인의 비지니스가 있습니다. -- 도메인 중심 설계에 대한 내용으로 견고한 도메인에서부터 프로젝트를 만들어 올라가면 자연스럽게 이러한 구조가 나올 수 있기도 합니다. -- 하나의 모듈은 최대 하나의 인프라스터럭처를 갖는 것은 의존성의 전파를 방지하기 위해서입니다. - -
- -#### 이 계층은 아래와 같은 원칙을 갖습니다. - -> 1) 어플리케이션 서비스 비지니스를 모른다. -> 2) 하나의 모듈은 최대 하나의 인프라스트럭처에 대한 책임만 갖는다. -> 3) 도메인 모듈을 조합한 더 큰 단위의 도메인 모듈이 있을 수 있다. - -#### 아래와 같은 클래스를 배치할 수 있습니다. - -> 1) Domain Entity: Java Class 로 표현된 도메인 Class들이 이곳에 위치한다. -> 2) Domain Repository: 도메인의 조회, 저장, 수정, 삭제 역할을 한다. -> 3) Domain Service: 도메인의 비지니스의 책임을 가진다. diff --git a/module-domain/build.gradle b/module-domain/build.gradle deleted file mode 100644 index 25b1ce4..0000000 --- a/module-domain/build.gradle +++ /dev/null @@ -1,47 +0,0 @@ -project(':module-domain:domain-jpa') { - bootJar.enabled = false - - dependencies { - implementation project(':module-core') - } -} - -project(':module-domain:domain-member') { - bootJar.enabled = false - - dependencies { - api project(':module-domain:domain-jpa') - implementation project(':module-core') - } -} - -project(':module-domain:domain-payment') { - bootJar.enabled = false - - dependencies { - api project(':module-domain:domain-jpa') - implementation project(':module-domain:domain-member') - implementation project(':module-core') - } -} - -project(':module-domain:domain-redis') { - bootJar.enabled = false - - dependencies { - api project(':module-domain:domain-jpa') - implementation project(':module-domain:domain-member') - implementation project(':module-core') - } -} - -project(':module-domain:domain-webtoon') { - bootJar.enabled = false - - dependencies { - api project(':module-domain:domain-jpa') - implementation project(':module-domain:domain-member') - implementation project(':module-domain:domain-payment') - implementation project(':module-core') - } -} diff --git a/module-domain/domain-jpa/build.gradle b/module-domain/domain-jpa/build.gradle deleted file mode 100644 index 857161d..0000000 --- a/module-domain/domain-jpa/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -dependencies { - // MySQL - implementation 'com.mysql:mysql-connector-j:8.0.33' - - // JPA - api 'org.springframework.boot:spring-boot-starter-data-jpa' - - // Querydsl - api 'com.querydsl:querydsl-jpa:5.0.0:jakarta' - annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' - annotationProcessor 'jakarta.annotation:jakarta.annotation-api' - annotationProcessor 'jakarta.persistence:jakarta.persistence-api' -} diff --git a/module-domain/domain-member/build.gradle b/module-domain/domain-member/build.gradle deleted file mode 100644 index 268b7cd..0000000 --- a/module-domain/domain-member/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -dependencies { - // Bean Validation - implementation 'org.springframework.boot:spring-boot-starter-validation' - - // Security - implementation 'org.springframework.boot:spring-boot-starter-security' - - // Querydsl - annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' - annotationProcessor 'jakarta.annotation:jakarta.annotation-api' - annotationProcessor 'jakarta.persistence:jakarta.persistence-api' - - // Test - testImplementation 'org.springframework.boot:spring-boot-starter-test' - - // H2 - testImplementation 'com.h2database:h2' -} diff --git a/module-domain/domain-member/src/test/java/shop/jtoon/MemberDomainApplicationTest.java b/module-domain/domain-member/src/test/java/shop/jtoon/MemberDomainApplicationTest.java deleted file mode 100644 index a8cb8bd..0000000 --- a/module-domain/domain-member/src/test/java/shop/jtoon/MemberDomainApplicationTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package shop.jtoon; - -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class MemberDomainApplicationTest { -} diff --git a/module-domain/domain-member/src/test/java/shop/jtoon/repository/MemberRepositoryTest.java b/module-domain/domain-member/src/test/java/shop/jtoon/repository/MemberRepositoryTest.java deleted file mode 100644 index 274dae9..0000000 --- a/module-domain/domain-member/src/test/java/shop/jtoon/repository/MemberRepositoryTest.java +++ /dev/null @@ -1,170 +0,0 @@ -package shop.jtoon.repository; - -import static org.assertj.core.api.Assertions.*; -import static shop.jtoon.entity.Gender.*; -import static shop.jtoon.entity.LoginType.*; -import static shop.jtoon.entity.Role.*; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; - -import shop.jtoon.config.JpaConfig; -import shop.jtoon.entity.Gender; -import shop.jtoon.entity.LoginType; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.Role; - -@DataJpaTest -@Import(JpaConfig.class) -class MemberRepositoryTest { - - @Autowired - MemberRepository memberRepository; - - Member member; - - @BeforeEach - void initMember() { - member = Member.builder() - .email("abc@naver.com") - .password("Testing!123") - .name("HI") - .nickname("Unique") - .gender(MALE) - .phone("01012345678") - .role(USER) - .loginType(LOCAL) - .build(); - } - - @Test - @DisplayName("MemberRepository 빈 등록 성공") - void MemberRepository_bean_NotNull() { - assertThat(memberRepository).isNotNull(); - } - - @Test - @DisplayName("멤버 저장 성공") - void MemberRepository_save_success() { - // given, when - Member saved = memberRepository.save(member); - - // then - assertThat(saved.getId()).isNotNull(); - } - - @Nested - @DisplayName("멤버 엔티티 생성 실패 테스트") - class MemberEntityTest { - - String email = "abc@gmail.com"; - String password = "testing!123"; - String name = "HI"; - String nickname = "Unique"; - Gender gender = MALE; - String phone = "01012345678"; - Role role = USER; - LoginType loginType = LOCAL; - - @Test - @DisplayName("멤버 엔티티 이메일 null 테스트") - void Member_email_null_fail() { - // given, when, then - assertThatThrownBy(() -> Member.builder() - .email(null) - .password(password) - .name(name) - .nickname(nickname) - .gender(gender) - .phone(phone) - .role(role) - .loginType(loginType) - .build()).isInstanceOf(NullPointerException.class); - } - - @Test - @DisplayName("멤버 엔티티 비밀번호 null 테스트") - void Member_password_null_fail() { - // given, when, then - assertThatThrownBy(() -> Member.builder() - .email(email) - .password(null) - .name(name) - .nickname(nickname) - .gender(gender) - .phone(phone) - .role(role) - .loginType(loginType) - .build()).isInstanceOf(NullPointerException.class); - } - - @Test - @DisplayName("멤버 엔티티 이름 null 테스트") - void Member_name_null_fail() { - // given, when, then - assertThatThrownBy(() -> Member.builder() - .email(email) - .password(password) - .name(null) - .nickname(nickname) - .gender(gender) - .phone(phone) - .role(role) - .loginType(loginType) - .build()).isInstanceOf(NullPointerException.class); - } - - @Test - @DisplayName("멤버 엔티티 닉네임 null 테스트") - void Member_nickname_null_fail() { - // given, when, then - assertThatThrownBy(() -> Member.builder() - .email(email) - .password(password) - .name(name) - .nickname(null) - .gender(gender) - .phone(phone) - .role(role) - .loginType(loginType) - .build()).isInstanceOf(NullPointerException.class); - } - - @Test - @DisplayName("멤버 엔티티 성별 null 테스트") - void Member_gender_null_fail() { - // given, when, then - assertThatThrownBy(() -> Member.builder() - .email(email) - .password(password) - .name(name) - .nickname(nickname) - .gender(null) - .phone(phone) - .role(role) - .loginType(loginType) - .build()).isInstanceOf(NullPointerException.class); - } - - @Test - @DisplayName("멤버 엔티티 전화번호 null 테스트") - void Member_phone_null_fail() { - // given, when, then - assertThatThrownBy(() -> Member.builder() - .email(email) - .password(password) - .name(name) - .nickname(nickname) - .gender(gender) - .phone(null) - .role(role) - .loginType(loginType) - .build()).isInstanceOf(NullPointerException.class); - } - } -} diff --git a/module-domain/domain-payment/build.gradle b/module-domain/domain-payment/build.gradle deleted file mode 100644 index 4951fe5..0000000 --- a/module-domain/domain-payment/build.gradle +++ /dev/null @@ -1,15 +0,0 @@ -dependencies { - // Bean Validation - implementation 'org.springframework.boot:spring-boot-starter-validation' - - // Querydsl - annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' - annotationProcessor 'jakarta.annotation:jakarta.annotation-api' - annotationProcessor 'jakarta.persistence:jakarta.persistence-api' - - // H2 - runtimeOnly 'com.h2database:h2' - - // Test - testImplementation 'org.springframework.boot:spring-boot-starter-test' -} diff --git a/module-domain/domain-payment/src/test/java/shop/jtoon/DomainPaymentApplicationTest.java b/module-domain/domain-payment/src/test/java/shop/jtoon/DomainPaymentApplicationTest.java deleted file mode 100644 index 210c4fa..0000000 --- a/module-domain/domain-payment/src/test/java/shop/jtoon/DomainPaymentApplicationTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package shop.jtoon; - -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -class DomainPaymentApplicationTest { -} diff --git a/module-domain/domain-payment/src/test/java/shop/jtoon/factory/CreatorFactory.java b/module-domain/domain-payment/src/test/java/shop/jtoon/factory/CreatorFactory.java deleted file mode 100644 index a054533..0000000 --- a/module-domain/domain-payment/src/test/java/shop/jtoon/factory/CreatorFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -package shop.jtoon.factory; - -import shop.jtoon.entity.*; - -import java.math.BigDecimal; - -public class CreatorFactory { - - public static PaymentInfo createPaymentInfo(String impUid, String merchantUid, Member member) { - return PaymentInfo.builder() - .impUid(impUid) - .merchantUid(merchantUid) - .payMethod("card") - .cookieItem(CookieItem.COOKIE_ONE) - .amount(BigDecimal.valueOf(1000)) - .member(member) - .build(); - } - - public static Member createMember(String email) { - return Member.builder() - .email(email) - .password("Qwe123!!") - .name("홍도산") - .nickname("개발을담다") - .gender(Gender.MALE) - .phone("01012331233") - .role(Role.USER) - .loginType(LoginType.LOCAL) - .build(); - } -} diff --git a/module-domain/domain-payment/src/test/java/shop/jtoon/repository/PaymentInfoSearchRepositoryTest.java b/module-domain/domain-payment/src/test/java/shop/jtoon/repository/PaymentInfoSearchRepositoryTest.java deleted file mode 100644 index 6d36d3f..0000000 --- a/module-domain/domain-payment/src/test/java/shop/jtoon/repository/PaymentInfoSearchRepositoryTest.java +++ /dev/null @@ -1,124 +0,0 @@ -package shop.jtoon.repository; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import shop.jtoon.config.JpaConfig; -import shop.jtoon.entity.Member; -import shop.jtoon.entity.PaymentInfo; -import shop.jtoon.factory.CreatorFactory; - -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -@DataJpaTest -@Import({JpaConfig.class, PaymentInfoSearchRepository.class}) -class PaymentInfoSearchRepositoryTest { - - @Autowired - private MemberRepository memberRepository; - - @Autowired - private PaymentInfoRepository paymentInfoRepository; - - @Autowired - private PaymentInfoSearchRepository paymentInfoSearchRepository; - - private Member member; - private PaymentInfo paymentInfo1; - private PaymentInfo paymentInfo2; - - @BeforeEach - void beforeEach() { - member = CreatorFactory.createMember("example123@naver.com"); - memberRepository.save(member); - paymentInfo1 = CreatorFactory.createPaymentInfo("imp123", "mer123", member); - paymentInfoRepository.save(paymentInfo1); - paymentInfo2 = CreatorFactory.createPaymentInfo("imp789", "mer789", member); - paymentInfoRepository.save(paymentInfo2); - } - - @DisplayName("paymentInfoSearchRepository - Bean 등록 여부 테스트 - NotNull") - @Test - void paymentInfoSearchRepository_NotNull() { - // Then - assertThat(paymentInfoSearchRepository).isNotNull(); - } - - @DisplayName("searchByMerchantsUidAndEmail - 해당 이메일과 일치하는 회원의 결제 정보 조회 - 모든 결제 정보") - @Test - void searchByMerchantsUidAndEmail_PaymentInfo_List1() { - // When - List actual = paymentInfoSearchRepository - .searchByMerchantsUidAndEmail(null, member.getEmail()); - - // Then - assertThat(actual).hasSize(2); - } - - @DisplayName("searchByMerchantsUidAndEmail - 해당 이메일과 일치하고 주문번호들과 일치하는 결제 정보 조회 - 결제 정보 2건") - @Test - void searchByMerchantsUidAndEmail_PaymentInfo_List2() { - //Given - List merchantsUid = new ArrayList<>(); - merchantsUid.add(paymentInfo1.getMerchantUid()); - merchantsUid.add(paymentInfo2.getMerchantUid()); - - // When - List actual = paymentInfoSearchRepository - .searchByMerchantsUidAndEmail(merchantsUid, member.getEmail()); - - // Then - assertThat(actual).hasSize(2); - } - - @DisplayName("searchByMerchantsUidAndEmail - 해당 이메일과 일치하고 주문번호와 일치하는 결제 정보 조회 - 결제 정보 1건") - @Test - void searchByMerchantsUidAndEmail_PaymentInfo() { - //Given - List merchantsUid = new ArrayList<>(); - merchantsUid.add(paymentInfo1.getMerchantUid()); - - // When - List actual = paymentInfoSearchRepository - .searchByMerchantsUidAndEmail(merchantsUid, member.getEmail()); - - // Then - assertThat(actual).hasSize(1); - } - - @DisplayName("searchByMerchantsUidAndEmail - 해당 이메일과 일치하지만 주문번호가 일치하지 않는 경우 - 0건") - @Test - void searchByMerchantsUidAndEmail_PaymentInfo_Null1() { - //Given - List merchantsUid = new ArrayList<>(); - merchantsUid.add(paymentInfo1.getMerchantUid()); - - // When - List actual = paymentInfoSearchRepository - .searchByMerchantsUidAndEmail(merchantsUid, "notfoundemail@naver.com"); - - // Then - assertThat(actual).isEmpty(); - } - - @DisplayName("searchByMerchantsUidAndEmail - 해당 이메일과 일치하지 않지만 주문번호가 일치하는 경우 - 0건") - @Test - void searchByMerchantsUidAndEmail_PaymentInfo_Null2() { - //Given - List merchantsUid = new ArrayList<>(); - merchantsUid.add("notfoundmerchantuid"); - - // When - List actual = paymentInfoSearchRepository - .searchByMerchantsUidAndEmail(merchantsUid, member.getEmail()); - - // Then - assertThat(actual).isEmpty(); - } -} diff --git a/module-domain/domain-payment/src/test/java/shop/jtoon/service/PaymentInfoDomainServiceTest.java b/module-domain/domain-payment/src/test/java/shop/jtoon/service/PaymentInfoDomainServiceTest.java deleted file mode 100644 index e72bce0..0000000 --- a/module-domain/domain-payment/src/test/java/shop/jtoon/service/PaymentInfoDomainServiceTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package shop.jtoon.service; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.junit.jupiter.MockitoExtension; -import shop.jtoon.entity.CookieItem; -import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.type.ErrorStatus; - -import java.math.BigDecimal; - -import static org.assertj.core.api.Assertions.assertThatNoException; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -@ExtendWith(MockitoExtension.class) -class PaymentInfoDomainServiceTest { - - @InjectMocks - private PaymentInfoDomainService paymentInfoDomainService; - - private String itemName; - private BigDecimal amount; - - @BeforeEach - void beforeEach() { - itemName = CookieItem.COOKIE_ONE.getItemName(); - amount = CookieItem.COOKIE_ONE.getAmount(); - } - - @DisplayName("validatePaymentInfo - 결제 정보의 쿠키 가격과 실제 서버에 존재하는 쿠키 가격이 같을 때, - Void") - @Test - void validatePaymentInfo_Void() { - // When, Then - assertThatNoException() - .isThrownBy(() -> paymentInfoDomainService.validatePaymentInfo(itemName, amount)); - } - - @DisplayName("validatePaymentInfo - 결제 정보의 쿠키 가격과 실제 서버에서 알고 있는 쿠키 가격이 다를 때, - InvalidRequestException") - @Test - void validatePaymentInfo_InvalidRequestException() { - // When, Then - assertThatThrownBy(() -> paymentInfoDomainService.validatePaymentInfo(itemName, BigDecimal.ONE)) - .isInstanceOf(InvalidRequestException.class) - .hasMessage(ErrorStatus.PAYMENT_AMOUNT_INVALID.getMessage()); - } -} diff --git a/module-domain/domain-redis/build.gradle b/module-domain/domain-redis/build.gradle deleted file mode 100644 index fea6135..0000000 --- a/module-domain/domain-redis/build.gradle +++ /dev/null @@ -1,15 +0,0 @@ -dependencies { - // Security - implementation 'org.springframework.boot:spring-boot-starter-security' - - // JWT - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' - - // Test - testImplementation 'org.springframework.boot:spring-boot-starter-test' - - // Redis - implementation 'org.springframework.boot:spring-boot-starter-data-redis' -} diff --git a/module-domain/domain-webtoon/build.gradle b/module-domain/domain-webtoon/build.gradle deleted file mode 100644 index 5e9b79b..0000000 --- a/module-domain/domain-webtoon/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -dependencies { - // Bean Validation - implementation 'org.springframework.boot:spring-boot-starter-validation' - - // Querydsl - annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' - annotationProcessor 'jakarta.annotation:jakarta.annotation-api' - annotationProcessor 'jakarta.persistence:jakarta.persistence-api' - - // Test - testImplementation 'org.springframework.boot:spring-boot-starter-test' -} diff --git a/module-internal/README.md b/module-internal/README.md deleted file mode 100644 index 9f8c43f..0000000 --- a/module-internal/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Internal Layer - -| | **어플리케이션 모듈** | **내부 모듈** | **도메인 모듈** | **공통 모듈** | -|:---------:|:-------------:|:---------:|:----------:|:---------:| -| **사용 가능** | X | - | X | O | - -- 저장소, 도메인 외 시스템에서 필요한 모듈들은 이 계층에 속하게 됩니다. -- 이 계층은 시스템 전체적인 기능을 서포트하기 위한 기능 모듈이 만들어질 수 있습니다. -- 이 계층 역시 프로젝트 안의 어떠한 실행 가능한 어플리케이션에서도 독립 사용 가능한 모듈이 위치되어야 하므로, 도메인 계층을 의존하지 않습니다. - -
- -#### 이 계층은 아래와 같은 원칙을 갖습니다. - -> 1) 어플리케이션 비지니스를 모른다. -> 2) 도메인 비지니스를 모른다. - -#### 아래와 같은 모듈들을 배치할 수 있습니다. - -> - core-web: web 설정을 사용하는 프로젝트에서 사용할 수 있는 모듈로, 주로 Web Filter 를 이용한 보안, 로깅 등으로 활용되며, 웹에 대한 필수적인 공통 설정을 하기도 한다. -> - xxx-client: 외부의 xxx 시스템과 통신을 책임지는 모듈로, 각 외부 시스템별로 따로 모듈을 만든다. 이 모듈은 비지니스와 관계없이 요청과 응답을 할 수 있는 사용성을 제공한다. diff --git a/module-internal/build.gradle b/module-internal/build.gradle deleted file mode 100644 index 4b9bfbd..0000000 --- a/module-internal/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -project(':module-internal:core-web') { - bootJar.enabled = false - - dependencies { - implementation project(':module-core') - } -} - -project(':module-internal:s3-client') { - bootJar.enabled = false - - dependencies { - implementation project(':module-core') - } -} - -project(':module-internal:iamport-client') { - bootJar.enabled = false - - dependencies { - implementation project(':module-core') - } -} - -project(':module-internal:smtp-client') { - bootJar.enabled = false - - dependencies { - implementation project(':module-core') - } -} diff --git a/settings.gradle b/settings.gradle index fa694a6..b522979 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,19 +1,20 @@ +pluginManagement { + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.springframework.boot") useVersion(springBootVersion) + if (requested.id.id == "io.spring.dependency-management") useVersion(springDependencyManagementVersion) + } + } +} rootProject.name = 'jtoon' -include 'module-application' -include 'module-application:app-api' +include 'jtoon-core:core-api' -include 'module-domain' -include 'module-domain:domain-member' -include 'module-domain:domain-payment' -include 'module-domain:domain-redis' -include 'module-domain:domain-webtoon' -include 'module-domain:domain-jpa' +include 'jtoon-support:logging' +include 'jtoon-support:monitoring' -include 'module-internal' -include 'module-internal:core-web' -include 'module-internal:s3-client' -include 'module-internal:iamport-client' -include 'module-internal:smtp-client' - -include 'module-core' +include 'jtoon-system' +include 'jtoon-internal:core-web' +include 'jtoon-internal:s3-client' +include 'jtoon-internal:iamport-client' +include 'jtoon-internal:smtp-client' From 3ec0ca8fa6fa164f7436341771ef63ffb0efb963 Mon Sep 17 00:00:00 2001 From: parksey Date: Wed, 17 Apr 2024 06:29:33 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20core-api=EB=AA=A8=EB=93=88=20->?= =?UTF-8?q?=20core-api=20&=20core-domain=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20r?= =?UTF-8?q?edis=EB=AA=A8=EB=93=88=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 + build.gradle | 2 +- gradle.properties | 2 +- jtoon-core/README.md | 34 ++++++- jtoon-core/core-api/build.gradle | 43 +------- .../member/application/EmailService.java | 25 ----- .../member/application/LoginService.java | 49 +++++++++ .../member/application/MemberService.java | 99 ------------------- .../java/shop/jtoon/member/dto/MemberDto.java | 18 ++-- .../shop/jtoon/member/dto/OAuthSignUpDto.java | 18 ++-- ...erController.java => LoginController.java} | 26 ++--- .../jtoon/member/request/LocalSignUpReq.java | 18 ++-- .../application/MemberCookieService.java | 46 --------- .../application/PaymentInfoService.java | 65 ------------ .../payment/application/PaymentService.java | 41 ++++---- .../shop/jtoon/payment/request/CancelReq.java | 11 +++ .../jtoon/payment/request/PaymentReq.java | 26 +++++ .../jtoon/payment/response/PaymentRes.java | 18 +++- .../service/PaymentInfoDomainService.java | 28 ------ .../AuthenticationServiceImpl.java | 8 +- .../security/application/OAuth2Service.java | 6 +- .../application/RefreshTokenServiceImpl.java | 2 +- .../shop/jtoon/security/request/LoginReq.java | 10 ++ .../webtoon/application/EpisodeService.java | 73 ++++---------- .../application/WebtoonClientService.java | 37 +++++++ .../webtoon/application/WebtoonService.java | 78 +++------------ .../webtoon/request/CreateEpisodeReq.java | 8 +- .../webtoon/request/CreateWebtoonReq.java | 22 ++--- .../jtoon/webtoon/request/GetEpisodesReq.java | 1 + .../jtoon/webtoon/request/GetWebtoonsReq.java | 8 ++ .../jtoon/webtoon/response/AuthorRes.java | 7 +- .../webtoon/response/EpisodeInfoRes.java | 5 +- .../webtoon/response/EpisodeItemRes.java | 20 ++-- .../shop/jtoon/webtoon/response/GenreRes.java | 14 ++- .../webtoon/response/WebtoonInfoRes.java | 19 ++-- .../webtoon/response/WebtoonItemRes.java | 28 ++++-- .../src/main/resources/application.yml | 1 + jtoon-core/core-domain/build.gradle | 40 ++++++++ .../shop/jtoon/common}/BaseTimeEntity.java | 2 +- .../main/java/shop/jtoon/config/DbConfig.java | 24 +++++ .../java/shop/jtoon}/config/JpaConfig.java | 2 +- .../shop/jtoon/login/domain/LoginInfo.java | 20 ++++ .../shop/jtoon/login/domain/UserInfo.java | 14 +++ .../jtoon/login/service/CrytoService.java | 21 ++++ .../login/service/LoginDomainService.java | 50 ++++++++++ .../jtoon/login/service/LoginManager.java | 32 ++++++ .../shop/jtoon/login/service/LoginMapper.java | 25 +++++ .../java/shop/jtoon/member/domain/MyInfo.java | 30 ++++++ .../java/shop/jtoon/member/entity/Gender.java | 0 .../shop/jtoon/member/entity/LoginType.java | 0 .../java/shop/jtoon/member/entity/Member.java | 20 ++-- .../jtoon/member/entity/MemberStatus.java | 0 .../java/shop/jtoon/member/entity/Role.java | 0 .../jtoon/member/repository/MemberReader.java | 57 +++++++++++ .../member/repository/MemberRepository.java | 0 .../jtoon/member/repository/MemberWriter.java | 26 +++++ .../jtoon/member/service/MemberService.java | 19 ++++ .../java/shop/jtoon/payment/domain/Buyer.java | 12 +++ .../jtoon/payment/domain/CancelPayInfo.java | 16 +++ .../java/shop/jtoon/payment/domain/Item.java | 13 +++ .../java/shop/jtoon/payment/domain/Pay.java | 12 +++ .../shop/jtoon/payment/domain/Receipt.java | 24 +++++ .../shop/jtoon/payment/entity/CookieItem.java | 0 .../jtoon/payment/entity/MemberCookie.java | 2 +- .../jtoon/payment/entity/PaymentInfo.java | 2 +- .../payment/repository/CookieReader.java | 21 ++++ .../payment/repository/CookieWriter.java | 18 ++++ .../repository/MemberCookieRepository.java | 0 .../repository/PaymentInfoRepository.java | 0 .../PaymentInfoSearchRepository.java | 15 ++- .../payment/repository/PaymentReader.java | 28 ++++++ .../payment/repository/PaymentWriter.java | 17 ++++ .../jtoon/payment/service/CookieManager.java | 34 +++++++ .../shop/jtoon/payment/service/PayMapper.java | 25 +++++ .../jtoon/payment/service/PayService.java | 55 +++++++++++ .../jtoon/payment/service/PaymentManager.java | 50 ++++++++++ .../java/shop/jtoon}/util/DynamicQuery.java | 2 +- .../shop/jtoon/webtoon/domain/Author.java | 18 ++++ .../jtoon/webtoon/domain/EpisodeMainInfo.java | 16 +++ .../jtoon/webtoon/domain/EpisodeSchema.java | 29 ++++++ .../jtoon/webtoon/domain/SearchEpisode.java | 25 +++++ .../jtoon/webtoon/domain/SearchWebtoon.java | 12 +++ .../webtoon/domain/WebtoonDayOfWeeks.java | 20 ++++ .../jtoon/webtoon/domain/WebtoonDetail.java | 35 +++++++ .../jtoon/webtoon/domain/WebtoonGenres.java | 21 ++++ .../jtoon/webtoon/domain/WebtoonInfo.java | 26 +++++ .../jtoon/webtoon/domain/WebtoonSchema.java | 23 +++++ .../webtoon/entity/DayOfWeekWebtoon.java | 2 +- .../shop/jtoon/webtoon/entity/Episode.java | 2 +- .../jtoon/webtoon/entity/GenreWebtoon.java | 2 +- .../webtoon/entity/PurchasedEpisode.java | 2 +- .../shop/jtoon/webtoon/entity/Webtoon.java | 2 +- .../jtoon/webtoon/entity/enums/AgeLimit.java | 0 .../jtoon/webtoon/entity/enums/DayOfWeek.java | 0 .../jtoon/webtoon/entity/enums/Genre.java | 0 .../DayOfWeekWebtoonRepository.java | 0 .../webtoon/repository/EpisodeReader.java | 33 +++++++ .../webtoon/repository/EpisodeRepository.java | 0 .../repository/EpisodeSearchRepository.java | 13 +-- .../webtoon/repository/EpisodeWriter.java | 29 ++++++ .../repository/GenreWebtoonRepository.java | 0 .../PurchasedEpisodeRepository.java | 0 .../webtoon/repository/WebtoonReader.java | 49 +++++++++ .../webtoon/repository/WebtoonRepository.java | 0 .../repository/WebtoonSearchRepository.java | 22 ++--- .../webtoon/repository/WebtoonWriter.java | 26 +++++ .../webtoon/service/EpisodeDomainService.java | 64 ++++++++++++ .../webtoon/service/WebtoonDomainService.java | 68 +++++++++++++ .../jtoon/webtoon/service/WebtoonManger.java | 47 +++++++++ jtoon-db/db-redis/build.gradle | 7 ++ .../java/shop/jtoon}/config/RedisConfig.java | 2 +- .../repository/StringRedisRepository.java | 5 +- .../jtoon}/service/RedisTokenService.java | 4 +- .../error/handler/GlobalExceptionHandler.java | 13 ++- jtoon-internal/iamport-client/build.gradle | 1 + jtoon-internal/s3-client/build.gradle | 2 +- jtoon-internal/smtp-client/build.gradle | 6 -- .../shop/jtoon/application/SmtpService.java | 13 ++- .../shop/jtoon/config/MailProperties.java | 32 ++++++ .../java/shop/jtoon/config/SmtpConfig.java | 35 +++++++ .../shop/jtoon/{entity => domain}/Mail.java | 2 +- .../jtoon/application/SmtpServiceTest.java | 2 +- jtoon-system/build.gradle | 3 + settings.gradle | 4 + 124 files changed, 1758 insertions(+), 608 deletions(-) delete mode 100644 jtoon-core/core-api/src/main/java/shop/jtoon/member/application/EmailService.java create mode 100644 jtoon-core/core-api/src/main/java/shop/jtoon/member/application/LoginService.java delete mode 100644 jtoon-core/core-api/src/main/java/shop/jtoon/member/application/MemberService.java rename jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/{MemberController.java => LoginController.java} (67%) delete mode 100644 jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java delete mode 100644 jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java delete mode 100644 jtoon-core/core-api/src/main/java/shop/jtoon/payment/service/PaymentInfoDomainService.java create mode 100644 jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonClientService.java create mode 100644 jtoon-core/core-domain/build.gradle rename jtoon-core/{core-api/src/main/java/shop/jtoon/global/entity => core-domain/src/main/java/shop/jtoon/common}/BaseTimeEntity.java (95%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/config/DbConfig.java rename jtoon-core/{core-api/src/main/java/shop/jtoon/global => core-domain/src/main/java/shop/jtoon}/config/JpaConfig.java (94%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/LoginInfo.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/UserInfo.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/CrytoService.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginDomainService.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginManager.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginMapper.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/member/domain/MyInfo.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/member/entity/Gender.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/member/entity/LoginType.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/member/entity/Member.java (73%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/member/entity/MemberStatus.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/member/entity/Role.java (100%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberReader.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/member/repository/MemberRepository.java (100%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberWriter.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/member/service/MemberService.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Buyer.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/CancelPayInfo.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Item.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Pay.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Receipt.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/payment/entity/CookieItem.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/payment/entity/MemberCookie.java (97%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java (98%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieReader.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieWriter.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java (58%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentReader.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentWriter.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/CookieManager.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayMapper.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayService.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PaymentManager.java rename jtoon-core/{core-api/src/main/java/shop/jtoon/global => core-domain/src/main/java/shop/jtoon}/util/DynamicQuery.java (96%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/Author.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeMainInfo.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeSchema.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchEpisode.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchWebtoon.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDayOfWeeks.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDetail.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonGenres.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonInfo.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonSchema.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java (97%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/Episode.java (98%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java (96%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java (96%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java (98%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java (100%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeReader.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java (66%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeWriter.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java (100%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonReader.java rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java (100%) rename jtoon-core/{core-api => core-domain}/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java (55%) create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonWriter.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/EpisodeDomainService.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonDomainService.java create mode 100644 jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonManger.java create mode 100644 jtoon-db/db-redis/build.gradle rename {jtoon-core/core-api/src/main/java/shop/jtoon/internal => jtoon-db/db-redis/src/main/java/shop/jtoon}/config/RedisConfig.java (97%) rename {jtoon-core/core-api/src/main/java/shop/jtoon/internal => jtoon-db/db-redis/src/main/java/shop/jtoon}/repository/StringRedisRepository.java (79%) rename {jtoon-core/core-api/src/main/java/shop/jtoon/internal => jtoon-db/db-redis/src/main/java/shop/jtoon}/service/RedisTokenService.java (89%) create mode 100644 jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/MailProperties.java create mode 100644 jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/SmtpConfig.java rename jtoon-internal/smtp-client/src/main/java/shop/jtoon/{entity => domain}/Mail.java (96%) diff --git a/.gitignore b/.gitignore index 76d31bf..6efd80f 100644 --- a/.gitignore +++ b/.gitignore @@ -121,3 +121,8 @@ gradle-app.setting application-*.yml !application.yml !application-test.yml + +smtp.yml +redis.yml +db-main.yml +logging.yml diff --git a/build.gradle b/build.gradle index ead039d..4189c0c 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ subprojects { } tasks.getByName("jar") { - enabled = false + enabled = true } } diff --git a/gradle.properties b/gradle.properties index 9ee1350..84243cb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ applicationVersion=0.0.1 javaVersion=17 # Project Configs -projectGroup=org.example +projectGroup=shop.jtoon # Spring dependency versions diff --git a/jtoon-core/README.md b/jtoon-core/README.md index 427f306..e5dcffa 100644 --- a/jtoon-core/README.md +++ b/jtoon-core/README.md @@ -10,4 +10,36 @@ Jtoon 서비스의 해결하고자하는 도메인에 대한 모듈 - Repository Layer : 상세 구현 로직이 다양한 자원에 접근할 수 있는 기능을 제공하는 레이어 ## Include -- `core-api`: 전체 도메인 로직에 대한 모듈만 존재 \ No newline at end of file + +### 초기 +- `core-api`: 전체 도메인 로직에 대한 모듈만 존재 + +단점: +1. 모든 기능이 해당 모듈에 몰려있어서 많은 의존성을 가지고 있다. +2. 도메인은 문제를 해결하기 위한 영역이기 때문에 외부의 의존성을 가지는 것이 맞을까? +3. Batch서버를 따로 올린다고 했을 때, Runnable한 API가 2개가 생기게 되는데 이때 동일한 도메인 기능을 서로 다르게 관리하게 된다. + +## 2번째 리팩토링 + +### Core API +Presentation 영역, 외부 의존성이 높다. + +- Controller, Dto가 존재 +- 확장되지 않는 서비스에 대한 로직 예를들어 Admin은 여기에 추가하고 추후에 변경 + +### Core domain +오직 Domain 서비스만 관리하는 모듈 + +- Domain서 서비스를 문제만 해결하기 위해 spring framework의 의존성을 없애는 것으로 한다. +- spring framework가 자체적으로 변경되든, framework를 변경할때 domain 로직이 변경되는 것이 옳지 않다고 생각 + - 단 DB가 존재하기 때문에, JPA는 추가 + +#### 문제 +- Bean등록을 어떻게 하면 좋을까? +- Transaction은 어떻게 해야할까 + + +이렇게하면, 여러 개의 Runnable한 서비스가 가능하다 + +단점: +- 도메인이 DB에 의존적이다. 근데 DB를 변경하는 경우가 많을까? 에 대한 생각을 해볼 필요가 있다. \ No newline at end of file diff --git a/jtoon-core/core-api/build.gradle b/jtoon-core/core-api/build.gradle index 9a30f58..cfd400a 100644 --- a/jtoon-core/core-api/build.gradle +++ b/jtoon-core/core-api/build.gradle @@ -6,27 +6,10 @@ tasks.getByName("jar") { enabled = false } -def generatedDir = "src/main/generated" - -sourceSets { - main { - java { - srcDirs = ['src/main/java'] - } - - resources { - srcDir "${project.projectDir}/src/main/java" - } - } -} - -clean { - delete file(generatedDir) -} - dependencies { - implementation project(":jtoon-system") + implementation project(":jtoon-core:core-domain") + implementation project(":jtoon-internal:core-web") implementation project(":jtoon-internal:iamport-client") implementation project(":jtoon-internal:s3-client") @@ -36,8 +19,8 @@ dependencies { implementation project(":jtoon-support:monitoring") implementation project(":jtoon-system") - // Redis - implementation 'org.springframework.boot:spring-boot-starter-data-redis' + + implementation project(":jtoon-db:db-redis") // Web implementation 'org.springframework.boot:spring-boot-starter-web' @@ -45,18 +28,9 @@ dependencies { // Bean Validation implementation 'org.springframework.boot:spring-boot-starter-validation' - // JPA - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - // AOP implementation 'org.springframework.boot:spring-boot-starter-aop' - // H2 - implementation 'com.h2database:h2' - - // Test - testImplementation 'org.springframework.boot:spring-boot-starter-test' - // Security implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.security:spring-security-test' @@ -71,13 +45,4 @@ dependencies { // RestDocs testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' - - // MySQL - implementation 'com.mysql:mysql-connector-j:8.0.33' - - // Querydsl - api 'com.querydsl:querydsl-jpa:5.0.0:jakarta' - annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' - annotationProcessor 'jakarta.annotation:jakarta.annotation-api' - annotationProcessor 'jakarta.persistence:jakarta.persistence-api' } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/EmailService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/EmailService.java deleted file mode 100644 index 71512b7..0000000 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/EmailService.java +++ /dev/null @@ -1,25 +0,0 @@ -package shop.jtoon.member.application; - -import java.util.UUID; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import lombok.RequiredArgsConstructor; -import shop.jtoon.application.SmtpService; -import shop.jtoon.entity.Mail; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class EmailService { - - private final SmtpService smtpService; - - public void sendEmailAuthentication(String email) { - UUID uuid = UUID.randomUUID(); - String randomUuid = uuid.toString().substring(0, 6); - - smtpService.sendMail(Mail.forAuthentication(email, randomUuid)); - } -} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/LoginService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/LoginService.java new file mode 100644 index 0000000..070bad6 --- /dev/null +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/LoginService.java @@ -0,0 +1,49 @@ +package shop.jtoon.member.application; + +import org.springframework.stereotype.Service; + +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import shop.jtoon.login.service.LoginDomainService; +import shop.jtoon.member.domain.MyInfo; +import shop.jtoon.member.dto.OAuthSignUpDto; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.request.LocalSignUpReq; +import shop.jtoon.security.request.LoginReq; +import shop.jtoon.security.service.JwtService; +import shop.jtoon.security.service.RefreshTokenService; +import shop.jtoon.security.util.TokenCookie; +import shop.jtoon.util.SecurityConstant; + +@Service +@RequiredArgsConstructor +public class LoginService { + + private final JwtService jwtProvider; + private final RefreshTokenService refreshTokenServiceImpl; + + private final LoginDomainService loginService; + + public void signUp(LocalSignUpReq localSignUpReq) { + loginService.signUp(localSignUpReq.toLoginInfo(), localSignUpReq.toUserInfo()); + } + + public void loginMember(LoginReq loginReq, HttpServletResponse response) { + loginService.login(loginReq.toLoginInfo()); + + String accessToken = jwtProvider.generateAccessToken(loginReq.email()); + String refreshToken = jwtProvider.generateRefreshToken(); + refreshTokenServiceImpl.saveRefreshToken(refreshToken, loginReq.email()); + + response.addCookie(TokenCookie.of(SecurityConstant.ACCESS_TOKEN_HEADER, accessToken)); + response.addCookie(TokenCookie.of(SecurityConstant.REFRESH_TOKEN_HEADER, refreshToken)); + } + + public Member generateOrGetSocialMember(OAuthSignUpDto oAuthSignUpDto) { + return loginService.generateOrGetSocialMember(oAuthSignUpDto.toLoginInfo(), oAuthSignUpDto.toUserInfo()); + } + + public MyInfo readMyInfo(String email) { + return loginService.findMemberDtoByEmail(email); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/MemberService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/MemberService.java deleted file mode 100644 index 6bf1a38..0000000 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/member/application/MemberService.java +++ /dev/null @@ -1,99 +0,0 @@ -package shop.jtoon.member.application; - -import static shop.jtoon.type.ErrorStatus.*; -import static shop.jtoon.util.SecurityConstant.*; - -import java.util.Optional; - -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; - -import shop.jtoon.exception.DuplicatedException; -import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.exception.NotFoundException; -import shop.jtoon.member.dto.MemberDto; -import shop.jtoon.member.dto.OAuthSignUpDto; -import shop.jtoon.member.entity.LoginType; -import shop.jtoon.member.entity.Member; -import shop.jtoon.member.repository.MemberRepository; -import shop.jtoon.member.request.LocalSignUpReq; - -import shop.jtoon.security.request.LoginReq; -import shop.jtoon.security.service.JwtService; -import shop.jtoon.security.service.RefreshTokenService; -import shop.jtoon.security.util.TokenCookie; - -@Service -@Transactional(readOnly = true) -@RequiredArgsConstructor -public class MemberService { - - private final JwtService jwtServiceImpl; - private final RefreshTokenService refreshTokenServiceImpl; - private final MemberRepository memberRepository; - private final PasswordEncoder passwordEncoder; - - @Transactional - public void signUp(LocalSignUpReq localSignUpReq) { - validateDuplicateEmail(localSignUpReq.email()); - String encryptedPassword = passwordEncoder.encode(localSignUpReq.password()); - Member member = localSignUpReq.toEntity(encryptedPassword); - - memberRepository.save(member); - } - - public void validateDuplicateEmail(String email) { - if (memberRepository.findByEmail(email).isPresent()) { - throw new DuplicatedException(MEMBER_EMAIL_CONFLICT); - } - } - - @Transactional - public void loginMember(LoginReq loginReq, HttpServletResponse response) { - Member member = findByEmail(loginReq.email()); - - if (!passwordEncoder.matches(loginReq.password(), member.getPassword())) { - throw new InvalidRequestException(MEMBER_WRONG_LOGIN_INFO); - } - - if (!member.getLoginType().equals(LoginType.LOCAL)) { - throw new InvalidRequestException(MEMBER_DUPLICATE_SOCIAL_LOGIN); - } - - member.updateLastLogin(); - - String accessToken = jwtServiceImpl.generateAccessToken(loginReq.email()); - String refreshToken = jwtServiceImpl.generateRefreshToken(); - refreshTokenServiceImpl.saveRefreshToken(refreshToken, loginReq.email()); - - response.addCookie(TokenCookie.of(ACCESS_TOKEN_HEADER, accessToken)); - response.addCookie(TokenCookie.of(REFRESH_TOKEN_HEADER, refreshToken)); - } - - @Transactional - public Member generateOrGetSocialMember(OAuthSignUpDto OAuthSignUpDto) { - Optional member = memberRepository.findByEmail(OAuthSignUpDto.email()); - - return member.orElseGet(() -> memberRepository.save(OAuthSignUpDto.toEntity(BLANK))); - } - - public MemberDto findMemberDtoByEmail(String email) { - Member member = findByEmail(email); - - return MemberDto.toDto(member); - } - - public Member findById(Long id) { - return memberRepository.findById(id) - .orElseThrow(() -> new NotFoundException(MEMBER_NOT_FOUND)); - } - - public Member findByEmail(String email) { - return memberRepository.findByEmail(email) - .orElseThrow(() -> new NotFoundException(MEMBER_EMAIL_NOT_FOUND)); - } -} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/MemberDto.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/MemberDto.java index 1e1c308..b465340 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/MemberDto.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/MemberDto.java @@ -1,8 +1,8 @@ package shop.jtoon.member.dto; import lombok.Builder; +import shop.jtoon.member.domain.MyInfo; import shop.jtoon.member.entity.Gender; -import shop.jtoon.member.entity.Member; import shop.jtoon.member.entity.Role; @Builder @@ -15,15 +15,15 @@ public record MemberDto( Role role, String phone ) { - public static MemberDto toDto(Member member) { + public static MemberDto toDto(MyInfo myInfo) { return MemberDto.builder() - .id(member.getId()) - .email(member.getEmail()) - .name(member.getName()) - .nickname(member.getNickname()) - .gender(member.getGender()) - .role(member.getRole()) - .phone(member.getPhone()) + .id(myInfo.id()) + .email(myInfo.email()) + .name(myInfo.name()) + .nickname(myInfo.nickname()) + .gender(myInfo.gender()) + .role(myInfo.role()) + .phone(myInfo.phone()) .build(); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthSignUpDto.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthSignUpDto.java index c31429f..f75ef1e 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthSignUpDto.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/dto/OAuthSignUpDto.java @@ -2,10 +2,10 @@ import lombok.Builder; +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.login.domain.UserInfo; import shop.jtoon.member.entity.Gender; import shop.jtoon.member.entity.LoginType; -import shop.jtoon.member.entity.Member; -import shop.jtoon.member.entity.Role; @Builder public record OAuthSignUpDto( @@ -17,16 +17,20 @@ public record OAuthSignUpDto( String phone, String loginType ) { - public Member toEntity(String encryptedPassword) { - return Member.builder() + public LoginInfo toLoginInfo() { + return LoginInfo.builder() .email(email) - .password(encryptedPassword) + .password(password) + .loginType(LoginType.from(loginType)) + .build(); + } + + public UserInfo toUserInfo() { + return UserInfo.builder() .name(name) .nickname(nickname) .gender(Gender.from(gender)) .phone(phone) - .role(Role.USER) - .loginType(LoginType.from(loginType)) .build(); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/MemberController.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/LoginController.java similarity index 67% rename from jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/MemberController.java rename to jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/LoginController.java index 19f7ebc..9ea1ba8 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/MemberController.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/presentation/LoginController.java @@ -12,33 +12,33 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import shop.jtoon.member.application.EmailService; -import shop.jtoon.member.application.MemberService; +import shop.jtoon.application.SmtpService; +import shop.jtoon.member.application.LoginService; import shop.jtoon.member.request.LocalSignUpReq; import shop.jtoon.security.request.LoginReq; @RestController @RequiredArgsConstructor @RequestMapping("/members") -public class MemberController { +public class LoginController { - private final MemberService memberService; - private final EmailService emailService; + private final LoginService memberService; + private final SmtpService smtpService; @PostMapping("/sign-up") @ResponseStatus(HttpStatus.CREATED) - public void signUp(@RequestBody @Valid LocalSignUpReq localSignUpReq) { - memberService.signUp(localSignUpReq); + public void signUp(@RequestBody @Valid LocalSignUpReq request) { + memberService.signUp(request); + } + + @PostMapping("/local-login") + public void login(@RequestBody @Valid LoginReq request, HttpServletResponse servletResponse) { + memberService.loginMember(request, servletResponse); } @GetMapping("/email-authorization") @ResponseStatus(HttpStatus.CREATED) public void authenticateEmail(@RequestParam(value = "email") String email) { - emailService.sendEmailAuthentication(email); - } - - @PostMapping("/local-login") - public void login(@RequestBody @Valid LoginReq loginReq, HttpServletResponse response) { - memberService.loginMember(loginReq, response); + smtpService.sendMail(email); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java index 94b2959..ae6001d 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/member/request/LocalSignUpReq.java @@ -6,10 +6,10 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.login.domain.UserInfo; import shop.jtoon.member.entity.Gender; import shop.jtoon.member.entity.LoginType; -import shop.jtoon.member.entity.Member; -import shop.jtoon.member.entity.Role; public record LocalSignUpReq( @Pattern(regexp = EMAIL_PATTERN) String email, @@ -20,16 +20,20 @@ public record LocalSignUpReq( @Pattern(regexp = PHONE_PATTERN) String phone, @NotNull String loginType ) { - public Member toEntity(String encryptedPassword) { - return Member.builder() + public LoginInfo toLoginInfo() { + return LoginInfo.builder() .email(email) - .password(encryptedPassword) + .password(password) + .loginType(LoginType.from(loginType)) + .build(); + } + + public UserInfo toUserInfo() { + return UserInfo.builder() .name(name) .nickname(nickname) .gender(Gender.from(gender)) .phone(phone) - .role(Role.USER) - .loginType(LoginType.from(loginType)) .build(); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java deleted file mode 100644 index 36df6fe..0000000 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/MemberCookieService.java +++ /dev/null @@ -1,46 +0,0 @@ -package shop.jtoon.payment.application; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import lombok.RequiredArgsConstructor; -import shop.jtoon.exception.NotFoundException; -import shop.jtoon.member.entity.Member; -import shop.jtoon.payment.entity.CookieItem; -import shop.jtoon.payment.entity.MemberCookie; -import shop.jtoon.payment.repository.MemberCookieRepository; -import shop.jtoon.type.ErrorStatus; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class MemberCookieService { - - private final MemberCookieRepository memberCookieRepository; - - @Transactional - public void createMemberCookie(String cookieItem, Member member) { - CookieItem item = CookieItem.from(cookieItem); - MemberCookie memberCookie = MemberCookie.create(item.getCount(), member); - memberCookieRepository.save(memberCookie); - } - - @Transactional - public int useCookie(int cookieCount, Member member) { - MemberCookie memberCookie = getByMember(member); - memberCookie.decreaseCookieCount(cookieCount); - - return memberCookie.getCookieCount(); - } - - public int getMemberCookieCount(Member member) { - MemberCookie memberCookie = getByMember(member); - - return memberCookie.getCookieCount(); - } - - private MemberCookie getByMember(Member member) { - return memberCookieRepository.findByMember(member) - .orElseThrow(() -> new NotFoundException(ErrorStatus.MEMBER_COOKIE_NOT_FOUND)); - } -} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java deleted file mode 100644 index 2ff8365..0000000 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentInfoService.java +++ /dev/null @@ -1,65 +0,0 @@ -package shop.jtoon.payment.application; - -import java.util.List; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import lombok.RequiredArgsConstructor; - -import shop.jtoon.exception.DuplicatedException; -import shop.jtoon.member.entity.Member; -import shop.jtoon.payment.entity.PaymentInfo; -import shop.jtoon.payment.repository.PaymentInfoRepository; -import shop.jtoon.payment.repository.PaymentInfoSearchRepository; -import shop.jtoon.payment.request.PaymentReq; -import shop.jtoon.payment.response.PaymentRes; - -import shop.jtoon.payment.service.PaymentInfoDomainService; -import shop.jtoon.type.ErrorStatus; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class PaymentInfoService { - - private final PaymentInfoDomainService paymentInfoDomainService; - private final PaymentInfoRepository paymentInfoRepository; - private final PaymentInfoSearchRepository paymentInfoSearchRepository; - - @Transactional - public void createPaymentInfo(PaymentReq paymentReq, Member member) { - PaymentInfo paymentInfo = paymentReq.toEntity(member); - paymentInfoRepository.save(paymentInfo); - } - - public List getPaymentsInfo(List merchantsUid, Member member) { - List paymentsInfo = paymentInfoSearchRepository.searchByMerchantsUidAndEmail( - merchantsUid, - member.getEmail() - ); - - return paymentsInfo.stream() - .map(PaymentRes::toDto) - .toList(); - } - - public void validatePaymentInfo(PaymentReq paymentReq) { - paymentInfoDomainService.validatePaymentInfo(paymentReq.itemName(), paymentReq.amount()); - validateImpUid(paymentReq.impUid()); - validateMerchantUid(paymentReq.merchantUid()); - } - - - private void validateImpUid(String impUid) { - if (paymentInfoRepository.existsByImpUid(impUid)) { - throw new DuplicatedException(ErrorStatus.PAYMENT_IMP_UID_DUPLICATED); - } - } - - private void validateMerchantUid(String merchantUid) { - if (paymentInfoRepository.existsByMerchantUid(merchantUid)) { - throw new DuplicatedException(ErrorStatus.PAYMENT_MERCHANT_UID_DUPLICATED); - } - } -} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentService.java index 0ad3e34..d89b6f2 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/application/PaymentService.java @@ -4,53 +4,56 @@ import java.util.List; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; -import shop.jtoon.member.application.MemberService; import shop.jtoon.member.dto.MemberDto; import shop.jtoon.member.entity.Member; +import shop.jtoon.member.service.MemberService; +import shop.jtoon.payment.domain.CancelPayInfo; +import shop.jtoon.payment.domain.Item; +import shop.jtoon.payment.domain.Pay; +import shop.jtoon.payment.domain.Receipt; import shop.jtoon.payment.request.CancelReq; import shop.jtoon.payment.request.ConditionReq; import shop.jtoon.payment.request.PaymentReq; import shop.jtoon.payment.response.PaymentRes; +import shop.jtoon.payment.service.PayService; import shop.jtoon.service.IamportService; @Service @RequiredArgsConstructor -@Transactional(readOnly = true) public class PaymentService { private final IamportService iamportService; - private final PaymentInfoService paymentInfoService; - private final MemberCookieService memberCookieService; private final MemberService memberService; + private final PayService payService; - @Transactional public BigDecimal validateAndCreatePayment(PaymentReq paymentReq, MemberDto memberDto) { - Member member = memberService.findByEmail(memberDto.email()); - iamportService.validateIamport(paymentReq.impUid(), paymentReq.amount()); - paymentInfoService.validatePaymentInfo(paymentReq); - paymentInfoService.createPaymentInfo(paymentReq, member); - memberCookieService.createMemberCookie(paymentReq.itemName(), member); + Pay pay = paymentReq.toPay(); + Item item = paymentReq.toItem(); + + Member member = memberService.read(memberDto.email()); + iamportService.validateIamport(pay.impUid(), item.amount()); + payService.createPaymentInfo(pay, item, member); return paymentReq.amount(); } - @Transactional public void cancelPayment(CancelReq cancelReq) { - iamportService.validateIamport(cancelReq.impUid(), cancelReq.checksum()); + CancelPayInfo cancelPayInfo = cancelReq.cancelPayInfo(); + + iamportService.validateIamport(cancelPayInfo.impUid(), cancelPayInfo.checksum()); iamportService.cancelIamport( - cancelReq.impUid(), - cancelReq.reason(), - cancelReq.checksum(), - cancelReq.refundHolder() + cancelPayInfo.impUid(), + cancelPayInfo.reason(), + cancelPayInfo.checksum(), + cancelPayInfo.refundHolder() ); } public List getPayments(ConditionReq conditionReq, MemberDto memberDto) { - Member member = memberService.findByEmail(memberDto.email()); + List paymentInfos = payService.readPayments(conditionReq.merchantsUid(), memberDto.email()); - return paymentInfoService.getPaymentsInfo(conditionReq.merchantsUid(), member); + return PaymentRes.of(paymentInfos); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/CancelReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/CancelReq.java index c3cccbe..6bf1e32 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/CancelReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/CancelReq.java @@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Builder; +import shop.jtoon.payment.domain.CancelPayInfo; @Builder public record CancelReq( @@ -16,4 +17,14 @@ public record CancelReq( @NotNull @DecimalMin("1") BigDecimal checksum, @NotBlank @Size(max = 10) String refundHolder ) { + + public CancelPayInfo cancelPayInfo() { + return CancelPayInfo.builder() + .impUid(impUid) + .merchantUid(merchantUid) + .reason(reason) + .checksum(checksum) + .refundHolder(refundHolder) + .build(); + } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java index ab196ba..1a4b566 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/request/PaymentReq.java @@ -11,6 +11,9 @@ import jakarta.validation.constraints.Size; import lombok.Builder; import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.domain.Buyer; +import shop.jtoon.payment.domain.Item; +import shop.jtoon.payment.domain.Pay; import shop.jtoon.payment.entity.CookieItem; import shop.jtoon.payment.entity.PaymentInfo; @@ -36,4 +39,27 @@ public PaymentInfo toEntity(Member member) { .member(member) .build(); } + + public Pay toPay() { + return Pay.builder() + .impUid(impUid) + .merchantUid(merchantUid) + .payMethod(payMethod) + .build(); + } + + public Item toItem() { + return Item.builder() + .itemName(itemName) + .amount(amount) + .build(); + } + + public Buyer toBuyer() { + return Buyer.builder() + .buyerEmail(buyerEmail) + .buyerName(buyerName) + .buyerPhone(buyerPhone) + .build(); + } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java index 63d77fc..d5c3c4d 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/response/PaymentRes.java @@ -2,8 +2,10 @@ import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; import lombok.Builder; +import shop.jtoon.payment.domain.Receipt; import shop.jtoon.payment.entity.PaymentInfo; @Builder @@ -14,12 +16,18 @@ public record PaymentRes( LocalDateTime createdAt ) { - public static PaymentRes toDto(PaymentInfo paymentInfo) { + public static PaymentRes toDto(Receipt receipt) { return PaymentRes.builder() - .itemName(paymentInfo.getCookieItem().getItemName()) - .itemCount(paymentInfo.getCookieItem().getCount()) - .amount(paymentInfo.getAmount()) - .createdAt(paymentInfo.getCreatedAt()) + .itemName(receipt.itemName()) + .itemCount(receipt.itemCount()) + .amount(receipt.amount()) + .createdAt(receipt.createdAt()) .build(); } + + public static List of(List paymentInfos) { + return paymentInfos.stream() + .map(PaymentRes::toDto) + .toList(); + } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/service/PaymentInfoDomainService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/payment/service/PaymentInfoDomainService.java deleted file mode 100644 index bcf92ed..0000000 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/service/PaymentInfoDomainService.java +++ /dev/null @@ -1,28 +0,0 @@ -package shop.jtoon.payment.service; - -import java.math.BigDecimal; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import lombok.RequiredArgsConstructor; -import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.payment.entity.CookieItem; -import shop.jtoon.type.ErrorStatus; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class PaymentInfoDomainService { - - public void validatePaymentInfo(String itemName, BigDecimal amount) { - CookieItem cookieItem = CookieItem.from(itemName); - validateAmount(amount, cookieItem.getAmount()); - } - - private void validateAmount(BigDecimal amount, BigDecimal cookieAmount) { - if (!amount.equals(cookieAmount)) { - throw new InvalidRequestException(ErrorStatus.PAYMENT_AMOUNT_INVALID); - } - } -} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java index b671837..18116df 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/AuthenticationServiceImpl.java @@ -10,7 +10,8 @@ import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; -import shop.jtoon.member.application.MemberService; +import shop.jtoon.member.application.LoginService; +import shop.jtoon.member.domain.MyInfo; import shop.jtoon.member.dto.MemberDto; import shop.jtoon.security.service.AuthenticationService; @@ -18,11 +19,12 @@ @RequiredArgsConstructor public class AuthenticationServiceImpl implements AuthenticationService { - private final MemberService memberService; + private final LoginService memberService; @Override public Authentication getAuthentication(String claimsEmail) { - MemberDto memberDto = memberService.findMemberDtoByEmail(claimsEmail); + MyInfo myInfo = memberService.readMyInfo(claimsEmail); + MemberDto memberDto = MemberDto.toDto(myInfo); return new UsernamePasswordAuthenticationToken(memberDto, BLANK, List.of(new SimpleGrantedAuthority(memberDto.role().toString()))); diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java index 28446ad..21cb94b 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/OAuth2Service.java @@ -11,11 +11,10 @@ import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import shop.jtoon.exception.DuplicatedException; -import shop.jtoon.member.application.MemberService; +import shop.jtoon.member.application.LoginService; import shop.jtoon.member.dto.OAuthAttributes; import shop.jtoon.member.entity.LoginType; import shop.jtoon.member.entity.Member; @@ -23,11 +22,10 @@ import shop.jtoon.type.ErrorStatus; @Service -@Transactional @RequiredArgsConstructor public class OAuth2Service implements CustomOAuth2UserService { - private final MemberService memberService; + private final LoginService memberService; @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java index 334424d..2f58668 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/application/RefreshTokenServiceImpl.java @@ -3,7 +3,7 @@ import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; -import shop.jtoon.internal.service.RedisTokenService; +import shop.jtoon.service.RedisTokenService; import shop.jtoon.security.service.RefreshTokenService; @Service diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/security/request/LoginReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/security/request/LoginReq.java index e972cfb..39f6167 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/security/request/LoginReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/security/request/LoginReq.java @@ -4,9 +4,19 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.member.entity.LoginType; public record LoginReq( @Pattern(regexp = EMAIL_PATTERN) String email, @Pattern(regexp = PASSWORD_PATTERN) @NotBlank String password ) { + + public LoginInfo toLoginInfo() { + return LoginInfo.builder() + .email(email) + .password(password) + .loginType(LoginType.KAKAO) + .build(); + } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java index 485e439..908c908 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/EpisodeService.java @@ -6,45 +6,28 @@ import java.util.List; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import lombok.RequiredArgsConstructor; -import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.exception.DuplicatedException; import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.exception.NotFoundException; -import shop.jtoon.member.application.MemberService; -import shop.jtoon.member.entity.Member; -import shop.jtoon.payment.application.MemberCookieService; -import shop.jtoon.service.S3Service; -import shop.jtoon.webtoon.entity.Episode; -import shop.jtoon.webtoon.entity.PurchasedEpisode; +import shop.jtoon.webtoon.domain.EpisodeMainInfo; +import shop.jtoon.webtoon.domain.EpisodeSchema; import shop.jtoon.webtoon.entity.Webtoon; -import shop.jtoon.webtoon.repository.EpisodeRepository; -import shop.jtoon.webtoon.repository.EpisodeSearchRepository; -import shop.jtoon.webtoon.repository.PurchasedEpisodeRepository; import shop.jtoon.webtoon.request.CreateEpisodeReq; import shop.jtoon.webtoon.request.GetEpisodesReq; import shop.jtoon.webtoon.response.EpisodeInfoRes; import shop.jtoon.webtoon.response.EpisodeItemRes; +import shop.jtoon.webtoon.service.EpisodeDomainService; @Service -@Transactional(readOnly = true) @RequiredArgsConstructor public class EpisodeService { - private final MemberService memberService; - private final MemberCookieService memberCookieService; - private final WebtoonService webtoonService; - private final S3Service s3Service; - private final EpisodeRepository episodeRepository; - private final EpisodeSearchRepository episodeSearchRepository; - private final PurchasedEpisodeRepository purchasedEpisodeRepository; + private final WebtoonClientService webtoonClientService; + private final EpisodeDomainService episodeDomainService; - @Transactional public void createEpisode( Long memberId, Long webtoonId, @@ -52,57 +35,35 @@ public void createEpisode( MultipartFile thumbnailImage, CreateEpisodeReq request ) { - Webtoon webtoon = webtoonService.getWebtoonById(webtoonId); - webtoon.validateAuthor(memberId); - validateDuplicateNo(webtoon, request.no()); - UploadImageDto uploadMainImageDto = request.toUploadImageDto(EPISODE_MAIN, webtoon.getTitle(), mainImage); - UploadImageDto uploadThumbnailImageDto = request.toUploadImageDto( + Webtoon webtoon = episodeDomainService.readWebtoon(webtoonId, memberId, request.no()); + String mainUrl = webtoonClientService.upload(request.toUploadImageDto(EPISODE_MAIN, webtoon.getTitle(), mainImage)); + String thumbnailUrl = webtoonClientService.upload(request.toUploadImageDto( EPISODE_THUMBNAIL, webtoon.getTitle(), thumbnailImage - ); - String mainUrl = s3Service.uploadImage(uploadMainImageDto); - String thumbnailUrl = s3Service.uploadImage(uploadThumbnailImageDto); + )); try { - Episode episode = request.toEntity(webtoon, mainUrl, thumbnailUrl); - episodeRepository.save(episode); + EpisodeSchema episode = request.toEpisodeSchema(); + episodeDomainService.createEpisode(episode, webtoon, mainUrl, thumbnailUrl); } catch (RuntimeException e) { - s3Service.deleteImage(mainUrl); - s3Service.deleteImage(thumbnailUrl); + webtoonClientService.deleteImage(mainUrl); + webtoonClientService.deleteImage(thumbnailUrl); throw new InvalidRequestException(EPISODE_CREATE_FAIL); } } public List getEpisodes(Long webtoonId, GetEpisodesReq request) { - return episodeSearchRepository.getEpisodes(webtoonId, request.getSize(), request.getOffset()) - .stream() - .map(EpisodeItemRes::from) - .toList(); + return EpisodeItemRes.from(episodeDomainService.readEpisodes(webtoonId, request.getSize(), request.getOffset())); } public EpisodeInfoRes getEpisode(Long episodeId) { - Episode episode = getEpisodeById(episodeId); + EpisodeMainInfo episode = episodeDomainService.readEpisode(episodeId); + return EpisodeInfoRes.from(episode); } - @Transactional public void purchaseEpisode(Long memberId, Long episodeId) { - Member member = memberService.findById(memberId); - Episode episode = getEpisodeById(episodeId); - memberCookieService.useCookie(episode.getCookieCount(), member); - PurchasedEpisode purchasedEpisode = PurchasedEpisode.create(member, episode); - purchasedEpisodeRepository.save(purchasedEpisode); - } - - private Episode getEpisodeById(Long episodeId) { - return episodeRepository.findById(episodeId) - .orElseThrow(() -> new NotFoundException(EPISODE_NOT_FOUND)); - } - - private void validateDuplicateNo(Webtoon webtoon, int no) { - if (episodeRepository.existsByWebtoonAndNo(webtoon, no)) { - throw new DuplicatedException(EPISODE_NUMBER_DUPLICATED); - } + episodeDomainService.purchaseEpisode(memberId, episodeId); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonClientService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonClientService.java new file mode 100644 index 0000000..77a7420 --- /dev/null +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonClientService.java @@ -0,0 +1,37 @@ +package shop.jtoon.webtoon.application; + +import static shop.jtoon.common.ImageType.*; + +import java.util.function.Function; +import java.util.function.Supplier; + +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.common.ImageType; +import shop.jtoon.dto.UploadImageDto; +import shop.jtoon.service.S3Service; +import shop.jtoon.webtoon.request.CreateEpisodeReq; +import shop.jtoon.webtoon.request.CreateWebtoonReq; + +@Service +@RequiredArgsConstructor +public class WebtoonClientService { + + private final S3Service s3Service; + + public String upload(ImageType imageType, CreateWebtoonReq request, MultipartFile thumbnailImage) { + UploadImageDto uploadImageDto = request.toUploadImageDto(imageType, thumbnailImage); + + return s3Service.uploadImage(uploadImageDto); + } + + public String upload(UploadImageDto uploadImageDto) { + return s3Service.uploadImage(uploadImageDto); + } + + public void deleteImage(String thumbnailUrl) { + s3Service.deleteImage(thumbnailUrl); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java index 806b7fb..362090a 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/application/WebtoonService.java @@ -1,6 +1,5 @@ package shop.jtoon.webtoon.application; -import static java.util.stream.Collectors.*; import static shop.jtoon.common.ImageType.*; import static shop.jtoon.type.ErrorStatus.*; @@ -8,98 +7,51 @@ import java.util.Map; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import lombok.RequiredArgsConstructor; import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.exception.DuplicatedException; import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.exception.NotFoundException; -import shop.jtoon.member.application.MemberService; -import shop.jtoon.member.entity.Member; -import shop.jtoon.service.S3Service; -import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; -import shop.jtoon.webtoon.entity.GenreWebtoon; -import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.domain.WebtoonDetail; import shop.jtoon.webtoon.entity.enums.DayOfWeek; -import shop.jtoon.webtoon.repository.DayOfWeekWebtoonRepository; -import shop.jtoon.webtoon.repository.GenreWebtoonRepository; -import shop.jtoon.webtoon.repository.WebtoonRepository; -import shop.jtoon.webtoon.repository.WebtoonSearchRepository; import shop.jtoon.webtoon.request.CreateWebtoonReq; import shop.jtoon.webtoon.request.GetWebtoonsReq; -import shop.jtoon.webtoon.response.GenreRes; import shop.jtoon.webtoon.response.WebtoonInfoRes; import shop.jtoon.webtoon.response.WebtoonItemRes; +import shop.jtoon.webtoon.service.WebtoonDomainService; @Service -@Transactional(readOnly = true) @RequiredArgsConstructor public class WebtoonService { - private final MemberService memberService; - private final S3Service s3Service; - private final WebtoonRepository webtoonRepository; - private final WebtoonSearchRepository webtoonSearchRepository; - private final DayOfWeekWebtoonRepository dayOfWeekWebtoonRepository; - private final GenreWebtoonRepository genreWebtoonRepository; - @Transactional + private final WebtoonClientService webtoonClientService; + private final WebtoonDomainService webtoonDomainService; + public void createWebtoon(Long memberId, MultipartFile thumbnailImage, CreateWebtoonReq request) { - Member member = memberService.findById(memberId); - validateDuplicateTitle(request.title()); - UploadImageDto uploadImageDto = request.toUploadImageDto(WEBTOON_THUMBNAIL, thumbnailImage); - String thumbnailUrl = s3Service.uploadImage(uploadImageDto); + webtoonDomainService.validateDuplicateTitle(request.title()); + String thumbnailUrl = webtoonClientService.upload(request.toUploadImageDto(WEBTOON_THUMBNAIL, thumbnailImage)); try { - Webtoon webtoon = request.toWebtoonEntity(member, thumbnailUrl); - List dayOfWeekWebtoons = request.toDayOfWeekWebtoonEntity(webtoon); - List genreWebtoons = request.toGenreWebtoonEntity(webtoon); - webtoonRepository.save(webtoon); - dayOfWeekWebtoonRepository.saveAll(dayOfWeekWebtoons); - genreWebtoonRepository.saveAll(genreWebtoons); + webtoonDomainService.createWebtoon(memberId, + request.toWebtoonInfo(thumbnailUrl), + request.toWebtoonGenres(), + request.toWebtoonDayOfWeeks()); } catch (RuntimeException e) { - s3Service.deleteImage(thumbnailUrl); + webtoonClientService.deleteImage(thumbnailUrl); throw new InvalidRequestException(WEBTOON_CREATE_FAIL); } } public Map> getWebtoons(GetWebtoonsReq request) { - return webtoonSearchRepository.findWebtoons(request.day(), request.keyword()) - .stream() - .collect(groupingBy(DayOfWeekWebtoon::getDayOfWeek, - mapping(dayOfWeekWebtoon -> WebtoonItemRes.from(dayOfWeekWebtoon.getWebtoon()), toList()))); + return WebtoonItemRes.from(webtoonDomainService.readWebtoons(request.toSearchWebtoon())); } public WebtoonInfoRes getWebtoon(Long webtoonId) { - Webtoon webtoon = getWebtoonById(webtoonId); - List dayOfWeeks = getDayOfWeeks(webtoon); - List genres = getGenres(webtoon); - - return WebtoonInfoRes.of(webtoon, dayOfWeeks, genres); - } - - public Webtoon getWebtoonById(Long webtoonId) { - return webtoonRepository.findById(webtoonId).orElseThrow(() -> new NotFoundException(WEBTOON_NOT_FOUND)); - } + WebtoonDetail detail = webtoonDomainService.readWebtoonDetail(webtoonId); - private List getDayOfWeeks(Webtoon webtoon) { - return dayOfWeekWebtoonRepository.findByWebtoon(webtoon) - .stream() - .map(DayOfWeekWebtoon::getDayOfWeekName) - .toList(); - } - - private List getGenres(Webtoon webtoon) { - return genreWebtoonRepository.findByWebtoon(webtoon).stream().map(GenreRes::from).toList(); - } - - private void validateDuplicateTitle(String title) { - if (webtoonRepository.existsByTitle(title)) { - throw new DuplicatedException(WEBTOON_TITLE_DUPLICATED); - } + return WebtoonInfoRes.of(detail); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java index a935d35..4cd487f 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateEpisodeReq.java @@ -12,6 +12,7 @@ import shop.jtoon.common.FileName; import shop.jtoon.common.ImageType; import shop.jtoon.dto.UploadImageDto; +import shop.jtoon.webtoon.domain.EpisodeSchema; import shop.jtoon.webtoon.entity.Episode; import shop.jtoon.webtoon.entity.Webtoon; @@ -23,15 +24,12 @@ public record CreateEpisodeReq( @NotNull LocalDateTime openedAt ) { - public Episode toEntity(Webtoon webtoon, String mainUrl, String thumbnailUrl) { - return Episode.builder() + public EpisodeSchema toEpisodeSchema() { + return EpisodeSchema.builder() .no(no) .title(title) .hasComment(hasComment) .openedAt(openedAt) - .mainUrl(mainUrl) - .thumbnailUrl(thumbnailUrl) - .webtoon(webtoon) .build(); } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java index d80cd6e..e6f52b8 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/CreateWebtoonReq.java @@ -12,7 +12,9 @@ import shop.jtoon.common.FileName; import shop.jtoon.common.ImageType; import shop.jtoon.dto.UploadImageDto; -import shop.jtoon.member.entity.Member; +import shop.jtoon.webtoon.domain.WebtoonDayOfWeeks; +import shop.jtoon.webtoon.domain.WebtoonGenres; +import shop.jtoon.webtoon.domain.WebtoonInfo; import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; import shop.jtoon.webtoon.entity.GenreWebtoon; import shop.jtoon.webtoon.entity.Webtoon; @@ -30,29 +32,25 @@ public record CreateWebtoonReq( @Min(0) int cookieCount ) { - public Webtoon toWebtoonEntity(Member member, String thumbnailUrl) { - return Webtoon.builder() + public WebtoonInfo toWebtoonInfo(String thumbnailUrl) { + return WebtoonInfo.builder() .title(title) .description(description) .ageLimit(ageLimit) .thumbnailUrl(thumbnailUrl) .cookieCount(cookieCount) - .author(member) .build(); } - public List toDayOfWeekWebtoonEntity(Webtoon webtoon) { - return dayOfWeeks.stream() - .map(dayOfWeek -> DayOfWeekWebtoon.create(dayOfWeek, webtoon)) - .toList(); + public WebtoonGenres toWebtoonGenres() { + return WebtoonGenres.builder().genres(genres).build(); } - public List toGenreWebtoonEntity(Webtoon webtoon) { - return genres.stream() - .map(genre -> GenreWebtoon.create(genre, webtoon)) - .toList(); + public WebtoonDayOfWeeks toWebtoonDayOfWeeks() { + return WebtoonDayOfWeeks.builder().dayOfWeeks(dayOfWeeks).build(); } + public UploadImageDto toUploadImageDto(ImageType imageType, MultipartFile image) { return UploadImageDto.builder() .imageType(imageType) diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java index e32364e..d77297f 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetEpisodesReq.java @@ -7,4 +7,5 @@ @Getter @SuperBuilder public class GetEpisodesReq extends CustomPageRequest { + } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java index 6158178..55d563c 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/request/GetWebtoonsReq.java @@ -1,6 +1,7 @@ package shop.jtoon.webtoon.request; import lombok.Builder; +import shop.jtoon.webtoon.domain.SearchWebtoon; import shop.jtoon.webtoon.entity.enums.DayOfWeek; @Builder @@ -8,4 +9,11 @@ public record GetWebtoonsReq( DayOfWeek day, String keyword ) { + + public SearchWebtoon toSearchWebtoon() { + return SearchWebtoon.builder() + .day(day) + .keyword(keyword) + .build(); + } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/AuthorRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/AuthorRes.java index 0fb1bfa..02e5c2a 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/AuthorRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/AuthorRes.java @@ -2,6 +2,7 @@ import lombok.Builder; import shop.jtoon.member.entity.Member; +import shop.jtoon.webtoon.domain.Author; @Builder public record AuthorRes( @@ -9,10 +10,10 @@ public record AuthorRes( String nickname ) { - public static AuthorRes from(Member author) { + public static AuthorRes from(Author author) { return AuthorRes.builder() - .id(author.getId()) - .nickname(author.getNickname()) + .id(author.id()) + .nickname(author.nickname()) .build(); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeInfoRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeInfoRes.java index d47159f..fad7d6a 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeInfoRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeInfoRes.java @@ -1,6 +1,7 @@ package shop.jtoon.webtoon.response; import lombok.Builder; +import shop.jtoon.webtoon.domain.EpisodeMainInfo; import shop.jtoon.webtoon.entity.Episode; @Builder @@ -8,9 +9,9 @@ public record EpisodeInfoRes( String mainUrl ) { - public static EpisodeInfoRes from(Episode episode) { + public static EpisodeInfoRes from(EpisodeMainInfo episode) { return EpisodeInfoRes.builder() - .mainUrl(episode.getMainUrl()) + .mainUrl(episode.mainUrl()) .build(); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeItemRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeItemRes.java index 4aa984c..ffc7320 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeItemRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/EpisodeItemRes.java @@ -1,8 +1,10 @@ package shop.jtoon.webtoon.response; import java.time.format.DateTimeFormatter; +import java.util.List; import lombok.Builder; +import shop.jtoon.webtoon.domain.SearchEpisode; import shop.jtoon.webtoon.entity.Episode; @Builder @@ -14,13 +16,19 @@ public record EpisodeItemRes( String openedAt ) { - public static EpisodeItemRes from(Episode episode) { + public static EpisodeItemRes from(SearchEpisode episode) { return EpisodeItemRes.builder() - .episodeId(episode.getId()) - .no(episode.getNo()) - .title(episode.getTitle()) - .thumbnailUrl(episode.getThumbnailUrl()) - .openedAt(episode.getOpenedAt().format(DateTimeFormatter.ofPattern("yy.MM.dd"))) + .episodeId(episode.episodeId()) + .no(episode.no()) + .title(episode.title()) + .thumbnailUrl(episode.thumbnailUrl()) + .openedAt(episode.openedAt()) .build(); } + + public static List from(List episodes) { + return episodes.stream() + .map(EpisodeItemRes::from) + .toList(); + } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/GenreRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/GenreRes.java index a5d1e75..af5faa6 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/GenreRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/GenreRes.java @@ -1,5 +1,7 @@ package shop.jtoon.webtoon.response; +import java.util.List; + import lombok.Builder; import shop.jtoon.webtoon.entity.GenreWebtoon; import shop.jtoon.webtoon.entity.enums.Genre; @@ -10,10 +12,16 @@ public record GenreRes( String name ) { - public static GenreRes from(GenreWebtoon genreWebtoon) { + public static GenreRes from(Genre genre) { return GenreRes.builder() - .type(genreWebtoon.getGenre()) - .name(genreWebtoon.getGenre().getText()) + .type(genre) + .name(genre.getText()) .build(); } + + public static List from(List genres) { + return genres.stream() + .map(GenreRes::from) + .toList(); + } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonInfoRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonInfoRes.java index ef4a588..2eca58b 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonInfoRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonInfoRes.java @@ -3,6 +3,7 @@ import java.util.List; import lombok.Builder; +import shop.jtoon.webtoon.domain.WebtoonDetail; import shop.jtoon.webtoon.entity.Webtoon; import shop.jtoon.webtoon.entity.enums.AgeLimit; @@ -18,16 +19,16 @@ public record WebtoonInfoRes( AuthorRes author ) { - public static WebtoonInfoRes of(Webtoon webtoon, List dayOfWeeks, List genres) { + public static WebtoonInfoRes of(WebtoonDetail webtoonDetail) { return WebtoonInfoRes.builder() - .title(webtoon.getTitle()) - .description(webtoon.getDescription()) - .dayOfWeeks(dayOfWeeks) - .genres(genres) - .ageLimit(webtoon.getAgeLimit()) - .thumbnailUrl(webtoon.getThumbnailUrl()) - .favoriteCount(webtoon.getFavoriteCount()) - .author(AuthorRes.from(webtoon.getAuthor())) + .title(webtoonDetail.title()) + .description(webtoonDetail.description()) + .dayOfWeeks(webtoonDetail.dayOfWeeks()) + .genres(GenreRes.from(webtoonDetail.genres())) + .ageLimit(webtoonDetail.ageLimit()) + .thumbnailUrl(webtoonDetail.thumbnailUrl()) + .favoriteCount(webtoonDetail.favoriteCount()) + .author(AuthorRes.from(webtoonDetail.author())) .build(); } } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonItemRes.java b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonItemRes.java index 9badfbb..3fcee98 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonItemRes.java +++ b/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/response/WebtoonItemRes.java @@ -1,7 +1,12 @@ package shop.jtoon.webtoon.response; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import lombok.Builder; -import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.domain.WebtoonSchema; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; @Builder public record WebtoonItemRes( @@ -12,13 +17,22 @@ public record WebtoonItemRes( AuthorRes author ) { - public static WebtoonItemRes from(Webtoon webtoon) { + public static WebtoonItemRes from(WebtoonSchema webtoon) { return WebtoonItemRes.builder() - .webtoonId(webtoon.getId()) - .title(webtoon.getTitle()) - .thumbnailUrl(webtoon.getThumbnailUrl()) - .ageLimit(webtoon.getAgeLimit().getValue()) - .author(AuthorRes.from(webtoon.getAuthor())) + .webtoonId(webtoon.webtoonId()) + .title(webtoon.title()) + .thumbnailUrl(webtoon.thumbnailUrl()) + .ageLimit(webtoon.ageLimit()) + .author(AuthorRes.from(webtoon.author())) .build(); } + + public static Map> from(Map> webtoons) { + Map> webtoonRes = new HashMap<>(); + for (DayOfWeek day : webtoons.keySet()) { + webtoonRes.put(day, webtoons.get(day).stream().map(WebtoonItemRes::from).toList()); + } + + return webtoonRes; + } } diff --git a/jtoon-core/core-api/src/main/resources/application.yml b/jtoon-core/core-api/src/main/resources/application.yml index e69de29..745d475 100644 --- a/jtoon-core/core-api/src/main/resources/application.yml +++ b/jtoon-core/core-api/src/main/resources/application.yml @@ -0,0 +1 @@ +spring.profiles.active: local \ No newline at end of file diff --git a/jtoon-core/core-domain/build.gradle b/jtoon-core/core-domain/build.gradle new file mode 100644 index 0000000..1a777e9 --- /dev/null +++ b/jtoon-core/core-domain/build.gradle @@ -0,0 +1,40 @@ +def generatedDir = "src/main/generated" + +sourceSets { + main { + java { + srcDirs = ['src/main/java'] + } + + resources { + srcDir "${project.projectDir}/src/main/java" + } + } +} + +clean { + delete file(generatedDir) +} + +dependencies { + + implementation project(":jtoon-system") + + // Password Encoder + implementation 'org.springframework.security:spring-security-crypto' + + // JPA + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + // H2 + implementation 'com.h2database:h2' + + // MySQL + implementation 'com.mysql:mysql-connector-j:8.0.33' + + // Querydsl + api 'com.querydsl:querydsl-jpa:5.0.0:jakarta' + annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' + annotationProcessor 'jakarta.annotation:jakarta.annotation-api' + annotationProcessor 'jakarta.persistence:jakarta.persistence-api' +} \ No newline at end of file diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/global/entity/BaseTimeEntity.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/common/BaseTimeEntity.java similarity index 95% rename from jtoon-core/core-api/src/main/java/shop/jtoon/global/entity/BaseTimeEntity.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/common/BaseTimeEntity.java index 981936f..d817c5b 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/global/entity/BaseTimeEntity.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/common/BaseTimeEntity.java @@ -1,4 +1,4 @@ -package shop.jtoon.global.entity; +package shop.jtoon.common; import java.time.LocalDateTime; diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/config/DbConfig.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/config/DbConfig.java new file mode 100644 index 0000000..39d5685 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/config/DbConfig.java @@ -0,0 +1,24 @@ +package shop.jtoon.config; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +@Configuration +public class DbConfig { + + @Bean + @ConfigurationProperties(prefix = "jtoon-db.datasource.main") + public HikariConfig mainHikariConfig() { + return new HikariConfig(); + } + + @Bean + public HikariDataSource hikariDataSource(@Qualifier("mainHikariConfig") HikariConfig mainHikariConfig) { + return new HikariDataSource(mainHikariConfig); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/global/config/JpaConfig.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/config/JpaConfig.java similarity index 94% rename from jtoon-core/core-api/src/main/java/shop/jtoon/global/config/JpaConfig.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/config/JpaConfig.java index a044afe..ebc4476 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/global/config/JpaConfig.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/config/JpaConfig.java @@ -1,4 +1,4 @@ -package shop.jtoon.global.config; +package shop.jtoon.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/LoginInfo.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/LoginInfo.java new file mode 100644 index 0000000..fb04acb --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/LoginInfo.java @@ -0,0 +1,20 @@ +package shop.jtoon.login.domain; + +import lombok.Builder; +import shop.jtoon.member.entity.LoginType; + +@Builder +public record LoginInfo( + String email, + String password, + LoginType loginType +) { + + public LoginInfo encode(String encodedPassword) { + return LoginInfo.builder() + .email(email) + .password(encodedPassword) + .loginType(loginType) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/UserInfo.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/UserInfo.java new file mode 100644 index 0000000..f7ab0f8 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/domain/UserInfo.java @@ -0,0 +1,14 @@ +package shop.jtoon.login.domain; + +import lombok.Builder; +import shop.jtoon.member.entity.Gender; + +@Builder +public record UserInfo( + String name, + String nickname, + Gender gender, + String phone +) { + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/CrytoService.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/CrytoService.java new file mode 100644 index 0000000..1a7305f --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/CrytoService.java @@ -0,0 +1,21 @@ +package shop.jtoon.login.service; + +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class CrytoService { + + private final PasswordEncoder passwordEncoder; + + public String encoded(String originPassword) { + return passwordEncoder.encode(originPassword); + } + + public boolean passwordMatch(String requestPassword, String encodedPassword) { + return passwordEncoder.matches(requestPassword, encodedPassword); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginDomainService.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginDomainService.java new file mode 100644 index 0000000..03025d8 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginDomainService.java @@ -0,0 +1,50 @@ +package shop.jtoon.login.service; + +import java.util.Optional; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; + +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.member.domain.MyInfo; +import shop.jtoon.login.domain.UserInfo; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.repository.MemberReader; +import shop.jtoon.member.repository.MemberWriter; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class LoginDomainService { + + private final LoginManager loginManager; + private final MemberReader memberReader; + private final MemberWriter memberWriter; + + @Transactional + public void signUp(LoginInfo loginInfo, UserInfo userInfo) { + Member member = loginManager.signUp(loginInfo, userInfo); + memberWriter.write(member); + } + + @Transactional + public void login(LoginInfo loginInfo) { + Member member = memberReader.readLoginRequestMember(loginInfo); + member.updateLastLogin(); + } + + @Transactional + public Member generateOrGetSocialMember(LoginInfo loginInfo, UserInfo userInfo) { + Optional member = memberReader.readOptionalByEmail(loginInfo.email()); + + return member.orElseGet(() -> memberWriter.signUp(loginInfo, userInfo)); + } + + public MyInfo findMemberDtoByEmail(String email) { + Member member = memberReader.readByEmail(email); + + return MyInfo.of(member); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginManager.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginManager.java new file mode 100644 index 0000000..ba5e249 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginManager.java @@ -0,0 +1,32 @@ +package shop.jtoon.login.service; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.DuplicatedException; +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.login.domain.UserInfo; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.repository.MemberReader; +import shop.jtoon.type.ErrorStatus; + +@Service +@RequiredArgsConstructor +public class LoginManager { + + private final CrytoService crytoService; + private final MemberReader memberReader; + + public Member signUp(LoginInfo loginInfo, UserInfo userInfo) { + LoginInfo encodedLoginInfo = loginInfo.encode(crytoService.encoded(loginInfo.password())); + validateDuplicateEmail(encodedLoginInfo.email()); + + return LoginMapper.toMember(loginInfo, userInfo); + } + + private void validateDuplicateEmail(String email) { + if (memberReader.readMemberExist(email)) { + throw new DuplicatedException(ErrorStatus.MEMBER_EMAIL_CONFLICT); + } + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginMapper.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginMapper.java new file mode 100644 index 0000000..1a0cbaf --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/login/service/LoginMapper.java @@ -0,0 +1,25 @@ +package shop.jtoon.login.service; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.login.domain.UserInfo; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.entity.Role; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class LoginMapper { + + public static Member toMember(LoginInfo loginInfo, UserInfo userInfo) { + return Member.builder() + .email(loginInfo.email()) + .password(loginInfo.password()) + .loginType(loginInfo.loginType()) + .name(userInfo.name()) + .nickname(userInfo.nickname()) + .gender(userInfo.gender()) + .phone(userInfo.phone()) + .role(Role.USER) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/member/domain/MyInfo.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/domain/MyInfo.java new file mode 100644 index 0000000..644e879 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/domain/MyInfo.java @@ -0,0 +1,30 @@ +package shop.jtoon.member.domain; + +import lombok.Builder; +import shop.jtoon.member.entity.Gender; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.entity.Role; + +@Builder +public record MyInfo( + Long id, + String email, + String name, + String nickname, + Gender gender, + Role role, + String phone +) { + + public static MyInfo of(Member member) { + return MyInfo.builder() + .id(member.getId()) + .email(member.getEmail()) + .name(member.getName()) + .nickname(member.getNickname()) + .gender(member.getGender()) + .role(member.getRole()) + .phone(member.getPhone()) + .build(); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Gender.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/Gender.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Gender.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/Gender.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/LoginType.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/LoginType.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/LoginType.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/LoginType.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Member.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/Member.java similarity index 73% rename from jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Member.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/Member.java index 2e0fc97..8b4059d 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Member.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/Member.java @@ -1,7 +1,7 @@ package shop.jtoon.member.entity; import static java.util.Objects.*; -import static shop.jtoon.util.RegExp.*; +import static shop.jtoon.type.ErrorStatus.*; import java.time.LocalDateTime; import java.util.Objects; @@ -14,13 +14,11 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; -import jakarta.validation.constraints.Pattern; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.global.entity.BaseTimeEntity; -import shop.jtoon.type.ErrorStatus; +import shop.jtoon.common.BaseTimeEntity; @Entity @Getter @@ -33,7 +31,6 @@ public class Member extends BaseTimeEntity { @Column(name = "member_id") private Long id; - @Pattern(regexp = EMAIL_PATTERN) @Column(name = "email", nullable = false, unique = true, length = 40, updatable = false) private String email; @@ -50,7 +47,6 @@ public class Member extends BaseTimeEntity { @Column(name = "gender", nullable = false, updatable = false) private Gender gender; - @Pattern(regexp = PHONE_PATTERN) @Column(name = "phone", nullable = false, unique = true, length = 11) private String phone; @@ -80,12 +76,12 @@ private Member( Role role, LoginType loginType ) { - this.email = requireNonNull(email, ErrorStatus.MEMBER_EMAIL_INVALID_FORMAT.getMessage()); - this.password = requireNonNull(password, ErrorStatus.MEMBER_PASSWORD_INVALID_FORMAT.getMessage()); - this.name = requireNonNull(name, ErrorStatus.MEMBER_NAME_INVALID_FORMAT.getMessage()); - this.nickname = requireNonNull(nickname, ErrorStatus.MEMBER_NICKNAME_INVALID_FORMAT.getMessage()); - this.gender = requireNonNull(gender, ErrorStatus.MEMBER_GENDER_INVALID_FORMAT.getMessage()); - this.phone = requireNonNull(phone, ErrorStatus.MEMBER_PHONE_INVALID_FORMAT.getMessage()); + this.email = requireNonNull(email, MEMBER_EMAIL_INVALID_FORMAT.getMessage()); + this.password = requireNonNull(password, MEMBER_PASSWORD_INVALID_FORMAT.getMessage()); + this.name = requireNonNull(name, MEMBER_NAME_INVALID_FORMAT.getMessage()); + this.nickname = requireNonNull(nickname, MEMBER_NICKNAME_INVALID_FORMAT.getMessage()); + this.gender = requireNonNull(gender, MEMBER_GENDER_INVALID_FORMAT.getMessage()); + this.phone = requireNonNull(phone, MEMBER_PHONE_INVALID_FORMAT.getMessage()); this.role = role; this.loginType = loginType; } diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/MemberStatus.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/MemberStatus.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/MemberStatus.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/MemberStatus.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Role.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/Role.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/member/entity/Role.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/member/entity/Role.java diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberReader.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberReader.java new file mode 100644 index 0000000..527bc7b --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberReader.java @@ -0,0 +1,57 @@ +package shop.jtoon.member.repository; + +import java.util.Optional; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.exception.NotFoundException; +import shop.jtoon.login.service.CrytoService; +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.member.entity.LoginType; +import shop.jtoon.member.entity.Member; +import shop.jtoon.type.ErrorStatus; + +@Repository +@RequiredArgsConstructor +public class MemberReader { + + private final CrytoService crytoService; + private final MemberRepository memberRepository; + + public Member read(Long id) { + return memberRepository.findById(id) + .orElseThrow(() -> new NotFoundException(ErrorStatus.MEMBER_NOT_FOUND)); + } + + public Optional readOptionalByEmail(String email) { + return memberRepository.findByEmail(email); + } + + public Member readByEmail(String email) { + return memberRepository.findByEmail(email) + .orElseThrow(() -> new NotFoundException(ErrorStatus.MEMBER_EMAIL_NOT_FOUND)); + } + + public boolean readMemberExist(String email) { + return memberRepository.findByEmail(email).isPresent(); + } + + public Member readLoginRequestMember(LoginInfo loginInfo) { + Member member = readByEmail(loginInfo.email()); + validateLoginRequest(loginInfo, member); + + return member; + } + + private void validateLoginRequest(LoginInfo loginInfo, Member member) { + if (!crytoService.passwordMatch(loginInfo.password(), member.getPassword())) { + throw new InvalidRequestException(ErrorStatus.MEMBER_WRONG_LOGIN_INFO); + } + + if (!member.getLoginType().equals(LoginType.LOCAL)) { + throw new InvalidRequestException(ErrorStatus.MEMBER_DUPLICATE_SOCIAL_LOGIN); + } + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/member/repository/MemberRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/member/repository/MemberRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberRepository.java diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberWriter.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberWriter.java new file mode 100644 index 0000000..81a6e7e --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/repository/MemberWriter.java @@ -0,0 +1,26 @@ +package shop.jtoon.member.repository; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.login.service.LoginMapper; +import shop.jtoon.login.domain.LoginInfo; +import shop.jtoon.login.domain.UserInfo; +import shop.jtoon.member.entity.Member; + +@Repository +@RequiredArgsConstructor +public class MemberWriter { + + private final MemberRepository memberRepository; + + public void write(Member member) { + memberRepository.save(member); + } + + public Member signUp(LoginInfo loginInfo, UserInfo userInfo) { + Member member = LoginMapper.toMember(loginInfo, userInfo); + + return memberRepository.save(member); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/member/service/MemberService.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/service/MemberService.java new file mode 100644 index 0000000..e2fb89a --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/member/service/MemberService.java @@ -0,0 +1,19 @@ +package shop.jtoon.member.service; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.member.domain.MyInfo; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.repository.MemberReader; + +@Service +@RequiredArgsConstructor +public class MemberService { + + private final MemberReader memberReader; + + public Member read(String email) { + return memberReader.readByEmail(email); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Buyer.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Buyer.java new file mode 100644 index 0000000..56af5f8 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Buyer.java @@ -0,0 +1,12 @@ +package shop.jtoon.payment.domain; + +import lombok.Builder; + +@Builder +public record Buyer( + String buyerEmail, + String buyerName, + String buyerPhone +) { + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/CancelPayInfo.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/CancelPayInfo.java new file mode 100644 index 0000000..6216b7e --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/CancelPayInfo.java @@ -0,0 +1,16 @@ +package shop.jtoon.payment.domain; + +import java.math.BigDecimal; + +import lombok.Builder; + +@Builder +public record CancelPayInfo( + String impUid, + String merchantUid, + String reason, + BigDecimal checksum, + String refundHolder +) { + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Item.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Item.java new file mode 100644 index 0000000..cc780bd --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Item.java @@ -0,0 +1,13 @@ +package shop.jtoon.payment.domain; + +import java.math.BigDecimal; + +import lombok.Builder; + +@Builder +public record Item( + String itemName, + BigDecimal amount +) { + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Pay.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Pay.java new file mode 100644 index 0000000..4229e92 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Pay.java @@ -0,0 +1,12 @@ +package shop.jtoon.payment.domain; + +import lombok.Builder; + +@Builder +public record Pay( + String impUid, + String merchantUid, + String payMethod +) { + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Receipt.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Receipt.java new file mode 100644 index 0000000..5482da5 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/domain/Receipt.java @@ -0,0 +1,24 @@ +package shop.jtoon.payment.domain; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import lombok.Builder; +import shop.jtoon.payment.entity.PaymentInfo; + +@Builder +public record Receipt( + String itemName, + int itemCount, + BigDecimal amount, + LocalDateTime createdAt +) { + public static Receipt toReceipt(PaymentInfo paymentInfo) { + return Receipt.builder() + .itemName(paymentInfo.getCookieItem().getItemName()) + .itemCount(paymentInfo.getCookieItem().getCount()) + .amount(paymentInfo.getAmount()) + .createdAt(paymentInfo.getCreatedAt()) + .build(); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/CookieItem.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/CookieItem.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/CookieItem.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/CookieItem.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/MemberCookie.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/MemberCookie.java similarity index 97% rename from jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/MemberCookie.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/MemberCookie.java index f5903f7..92b3b29 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/MemberCookie.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/MemberCookie.java @@ -17,7 +17,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.common.BaseTimeEntity; import shop.jtoon.member.entity.Member; @Entity diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java similarity index 98% rename from jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java index 155c0f4..2df8419 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/entity/PaymentInfo.java @@ -19,7 +19,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.common.BaseTimeEntity; import shop.jtoon.member.entity.Member; import shop.jtoon.type.ErrorStatus; diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieReader.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieReader.java new file mode 100644 index 0000000..e30f87f --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieReader.java @@ -0,0 +1,21 @@ +package shop.jtoon.payment.repository; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.NotFoundException; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.entity.MemberCookie; +import shop.jtoon.type.ErrorStatus; + +@Repository +@RequiredArgsConstructor +public class CookieReader { + + private final MemberCookieRepository memberCookieRepository; + + public MemberCookie read(Member member) { + return memberCookieRepository.findByMember(member) + .orElseThrow(() -> new NotFoundException(ErrorStatus.MEMBER_COOKIE_NOT_FOUND)); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieWriter.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieWriter.java new file mode 100644 index 0000000..f2fe0e1 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/CookieWriter.java @@ -0,0 +1,18 @@ +package shop.jtoon.payment.repository; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.entity.MemberCookie; + +@Repository +@RequiredArgsConstructor +public class CookieWriter { + + private final MemberCookieRepository memberCookieRepository; + + public void write(MemberCookie memberCookie) { + memberCookieRepository.save(memberCookie); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/MemberCookieRepository.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentInfoRepository.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java similarity index 58% rename from jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java index 5a94564..172bf7a 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentInfoSearchRepository.java @@ -1,6 +1,4 @@ package shop.jtoon.payment.repository; -import static shop.jtoon.member.entity.QMember.*; -import static shop.jtoon.payment.entity.QPaymentInfo.*; import java.util.List; @@ -9,22 +7,23 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; -import shop.jtoon.global.util.DynamicQuery; +import shop.jtoon.member.entity.QMember; import shop.jtoon.payment.entity.PaymentInfo; +import shop.jtoon.payment.entity.QPaymentInfo; +import shop.jtoon.util.DynamicQuery; @Repository @RequiredArgsConstructor public class PaymentInfoSearchRepository { private final JPAQueryFactory queryFactory; - private final PaymentInfoRepository paymentInfoRepository; public List searchByMerchantsUidAndEmail(List merchantsUid, String email) { - return queryFactory.selectFrom(paymentInfo) - .join(paymentInfo.member, member).fetchJoin() + return queryFactory.selectFrom(QPaymentInfo.paymentInfo) + .join(QPaymentInfo.paymentInfo.member, QMember.member).fetchJoin() .where( - DynamicQuery.filterCondition(merchantsUid, paymentInfo.merchantUid::in), - DynamicQuery.generateEq(email, paymentInfo.member.email::eq) + DynamicQuery.filterCondition(merchantsUid, QPaymentInfo.paymentInfo.merchantUid::in), + DynamicQuery.generateEq(email, QPaymentInfo.paymentInfo.member.email::eq) ) .fetch(); } diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentReader.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentReader.java new file mode 100644 index 0000000..64f77b0 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentReader.java @@ -0,0 +1,28 @@ +package shop.jtoon.payment.repository; + +import java.util.List; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.payment.entity.PaymentInfo; + +@Repository +@RequiredArgsConstructor +public class PaymentReader { + + private final PaymentInfoRepository paymentInfoRepository; + private final PaymentInfoSearchRepository paymentInfoSearchRepository; + + public boolean existsImpUid(String impUid) { + return paymentInfoRepository.existsByImpUid(impUid); + } + + public boolean existsMerchantUid(String merchantUid) { + return paymentInfoRepository.existsByMerchantUid(merchantUid); + } + + public List searchByMerchantsUidAndEmail(List merchantsUid, String email) { + return paymentInfoSearchRepository.searchByMerchantsUidAndEmail(merchantsUid, email); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentWriter.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentWriter.java new file mode 100644 index 0000000..6b6f2ce --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/repository/PaymentWriter.java @@ -0,0 +1,17 @@ +package shop.jtoon.payment.repository; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.payment.entity.PaymentInfo; + +@Repository +@RequiredArgsConstructor +public class PaymentWriter { + + private final PaymentInfoRepository paymentInfoRepository; + + public void write(final PaymentInfo paymentInfo) { + paymentInfoRepository.save(paymentInfo); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/CookieManager.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/CookieManager.java new file mode 100644 index 0000000..32d9626 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/CookieManager.java @@ -0,0 +1,34 @@ +package shop.jtoon.payment.service; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.domain.Item; +import shop.jtoon.payment.entity.CookieItem; +import shop.jtoon.payment.entity.MemberCookie; +import shop.jtoon.payment.repository.CookieReader; +import shop.jtoon.payment.repository.CookieWriter; +import shop.jtoon.webtoon.entity.PurchasedEpisode; + +@Service +@RequiredArgsConstructor +public class CookieManager { + + private final CookieWriter cookieWriter; + private final CookieReader cookieReader; + + public void bakeCookie(Item item, Member member) { + CookieItem cookie = CookieItem.from(item.itemName()); + MemberCookie memberCookie = MemberCookie.create(cookie.getCount(), member); + cookieWriter.write(memberCookie); + } + + public int useCookie(int cookieCount, Member member) { + MemberCookie memberCookie = cookieReader.read(member); + memberCookie.decreaseCookieCount(cookieCount); + + return memberCookie.getCookieCount(); + } + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayMapper.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayMapper.java new file mode 100644 index 0000000..8e1c027 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayMapper.java @@ -0,0 +1,25 @@ +package shop.jtoon.payment.service; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.domain.Buyer; +import shop.jtoon.payment.domain.Item; +import shop.jtoon.payment.domain.Pay; +import shop.jtoon.payment.entity.CookieItem; +import shop.jtoon.payment.entity.PaymentInfo; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class PayMapper { + + public static PaymentInfo toPaymentInfo(Pay pay, Item item, Member member) { + return PaymentInfo.builder() + .impUid(pay.impUid()) + .merchantUid(pay.merchantUid()) + .payMethod(pay.payMethod()) + .cookieItem(CookieItem.from(item.itemName())) + .amount(item.amount()) + .member(member) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayService.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayService.java new file mode 100644 index 0000000..d76277a --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PayService.java @@ -0,0 +1,55 @@ +package shop.jtoon.payment.service; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.repository.MemberReader; +import shop.jtoon.payment.domain.Item; +import shop.jtoon.payment.domain.Pay; +import shop.jtoon.payment.domain.Receipt; +import shop.jtoon.payment.entity.PaymentInfo; +import shop.jtoon.payment.repository.PaymentReader; +import shop.jtoon.payment.repository.PaymentWriter; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class PayService { + + private final MemberReader memberReader; + private final PaymentManager paymentManager; + private final CookieManager cookieManager; + private final PaymentReader paymentReader; + private final PaymentWriter paymentWriter; + + @Transactional + public void createPaymentInfo(Pay pay, Item item, Member member) { + createPayInfo(pay, item, member); + createCookie(item, member); + } + + public List readPayments(List merchantsUid, String email) { + Member member = memberReader.readByEmail(email); + List paymentInfos = paymentReader.searchByMerchantsUidAndEmail( + merchantsUid, + member.getEmail() + ); + + return paymentInfos.stream() + .map(Receipt::toReceipt) + .toList(); + } + + private void createPayInfo(Pay pay, Item item, Member member) { + paymentManager.validatePayItem(pay, item); + paymentWriter.write(PayMapper.toPaymentInfo(pay, item, member)); + } + + private void createCookie(Item item, Member member) { + cookieManager.bakeCookie(item, member); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PaymentManager.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PaymentManager.java new file mode 100644 index 0000000..a003cce --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/payment/service/PaymentManager.java @@ -0,0 +1,50 @@ +package shop.jtoon.payment.service; + +import java.math.BigDecimal; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.DuplicatedException; +import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.payment.domain.Item; +import shop.jtoon.payment.domain.Pay; +import shop.jtoon.payment.entity.CookieItem; +import shop.jtoon.payment.repository.PaymentReader; +import shop.jtoon.type.ErrorStatus; + +@Service +@RequiredArgsConstructor +public class PaymentManager { + + private final PaymentReader paymentReader; + + public void validatePayItem(Pay pay, Item item) { + validatePaymentInfo(item.itemName(), item.amount()); + validateImpUid(pay.impUid()); + validateMerchantUid(pay.merchantUid()); + } + + public void validatePaymentInfo(String itemName, BigDecimal amount) { + CookieItem cookieItem = CookieItem.from(itemName); + validateAmount(amount, cookieItem.getAmount()); + } + + private void validateAmount(BigDecimal amount, BigDecimal cookieAmount) { + if (!amount.equals(cookieAmount)) { + throw new InvalidRequestException(ErrorStatus.PAYMENT_AMOUNT_INVALID); + } + } + + private void validateImpUid(String impUid) { + if (paymentReader.existsImpUid(impUid)) { + throw new DuplicatedException(ErrorStatus.PAYMENT_IMP_UID_DUPLICATED); + } + } + + private void validateMerchantUid(String merchantUid) { + if (paymentReader.existsMerchantUid(merchantUid)) { + throw new DuplicatedException(ErrorStatus.PAYMENT_MERCHANT_UID_DUPLICATED); + } + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/global/util/DynamicQuery.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/util/DynamicQuery.java similarity index 96% rename from jtoon-core/core-api/src/main/java/shop/jtoon/global/util/DynamicQuery.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/util/DynamicQuery.java index 5211e9b..cb530a2 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/global/util/DynamicQuery.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/util/DynamicQuery.java @@ -1,4 +1,4 @@ -package shop.jtoon.global.util; +package shop.jtoon.util; import java.util.List; import java.util.Objects; diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/Author.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/Author.java new file mode 100644 index 0000000..5fdfa6d --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/Author.java @@ -0,0 +1,18 @@ +package shop.jtoon.webtoon.domain; + +import lombok.Builder; +import shop.jtoon.member.entity.Member; + +@Builder +public record Author( + Long id, + String nickname +) { + + public static Author from(Member author) { + return Author.builder() + .id(author.getId()) + .nickname(author.getNickname()) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeMainInfo.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeMainInfo.java new file mode 100644 index 0000000..c21db2b --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeMainInfo.java @@ -0,0 +1,16 @@ +package shop.jtoon.webtoon.domain; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.Episode; + +@Builder +public record EpisodeMainInfo( + String mainUrl +) { + + public static EpisodeMainInfo of(Episode episode) { + return EpisodeMainInfo.builder() + .mainUrl(episode.getMainUrl()) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeSchema.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeSchema.java new file mode 100644 index 0000000..b2d2faf --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/EpisodeSchema.java @@ -0,0 +1,29 @@ +package shop.jtoon.webtoon.domain; + +import java.time.LocalDateTime; + +import org.antlr.v4.runtime.misc.NotNull; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Webtoon; + +@Builder +public record EpisodeSchema( + int no, + String title, + boolean hasComment, + LocalDateTime openedAt +) { + public Episode toEpisode(Webtoon webtoon, String mainUrl, String thumbnailUrl) { + return Episode.builder() + .no(no) + .title(title) + .hasComment(hasComment) + .openedAt(openedAt) + .mainUrl(mainUrl) + .thumbnailUrl(thumbnailUrl) + .webtoon(webtoon) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchEpisode.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchEpisode.java new file mode 100644 index 0000000..f84038f --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchEpisode.java @@ -0,0 +1,25 @@ +package shop.jtoon.webtoon.domain; + +import java.time.format.DateTimeFormatter; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.Episode; + +@Builder +public record SearchEpisode( + Long episodeId, + int no, + String title, + String thumbnailUrl, + String openedAt +) { + public static SearchEpisode from(Episode episode) { + return SearchEpisode.builder() + .episodeId(episode.getId()) + .no(episode.getNo()) + .title(episode.getTitle()) + .thumbnailUrl(episode.getThumbnailUrl()) + .openedAt(episode.getOpenedAt().format(DateTimeFormatter.ofPattern("yy.MM.dd"))) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchWebtoon.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchWebtoon.java new file mode 100644 index 0000000..8a07244 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/SearchWebtoon.java @@ -0,0 +1,12 @@ +package shop.jtoon.webtoon.domain; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; + +@Builder +public record SearchWebtoon( + DayOfWeek day, + String keyword +) { + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDayOfWeeks.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDayOfWeeks.java new file mode 100644 index 0000000..8d1dde2 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDayOfWeeks.java @@ -0,0 +1,20 @@ +package shop.jtoon.webtoon.domain; + +import java.util.List; +import java.util.Set; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; + +@Builder +public record WebtoonDayOfWeeks( + Set dayOfWeeks +) { + public List toDayOfWeekWebtoonEntity(Webtoon webtoon) { + return dayOfWeeks.stream() + .map(dayOfWeek -> DayOfWeekWebtoon.create(dayOfWeek, webtoon)) + .toList(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDetail.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDetail.java new file mode 100644 index 0000000..777b641 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonDetail.java @@ -0,0 +1,35 @@ +package shop.jtoon.webtoon.domain; + +import java.util.List; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.AgeLimit; +import shop.jtoon.webtoon.entity.enums.Genre; + +@Builder +public record WebtoonDetail( + String title, + String description, + List dayOfWeeks, + List genres, + AgeLimit ageLimit, + String thumbnailUrl, + int favoriteCount, + Author author +) { + + public static WebtoonDetail of(Webtoon webtoon, List dayOfWeeks, List genres) { + return WebtoonDetail.builder() + .title(webtoon.getTitle()) + .description(webtoon.getDescription()) + .dayOfWeeks(dayOfWeeks) + .genres(genres) + .ageLimit(webtoon.getAgeLimit()) + .thumbnailUrl(webtoon.getThumbnailUrl()) + .favoriteCount(webtoon.getFavoriteCount()) + .author(Author.from(webtoon.getAuthor())) + .build(); + } + +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonGenres.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonGenres.java new file mode 100644 index 0000000..9033cde --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonGenres.java @@ -0,0 +1,21 @@ +package shop.jtoon.webtoon.domain; + +import java.util.List; +import java.util.Set; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.Genre; + +@Builder +public record WebtoonGenres( + Set genres +) { + public List toGenreWebtoonEntity(Webtoon webtoon) { + return genres.stream() + .map(genre -> GenreWebtoon.create(genre, webtoon)) + .toList(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonInfo.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonInfo.java new file mode 100644 index 0000000..53b6ac1 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonInfo.java @@ -0,0 +1,26 @@ +package shop.jtoon.webtoon.domain; + +import lombok.Builder; +import shop.jtoon.member.entity.Member; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.AgeLimit; + +@Builder +public record WebtoonInfo( + String title, + String description, + String thumbnailUrl, + AgeLimit ageLimit, + int cookieCount +) { + public Webtoon toWebtoonEntity(Member member) { + return Webtoon.builder() + .title(title) + .description(description) + .ageLimit(ageLimit) + .thumbnailUrl(thumbnailUrl) + .cookieCount(cookieCount) + .author(member) + .build(); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonSchema.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonSchema.java new file mode 100644 index 0000000..cec10f1 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/domain/WebtoonSchema.java @@ -0,0 +1,23 @@ +package shop.jtoon.webtoon.domain; + +import lombok.Builder; +import shop.jtoon.webtoon.entity.Webtoon; + +@Builder +public record WebtoonSchema( + Long webtoonId, + String title, + String thumbnailUrl, + int ageLimit, + Author author +) { + public static WebtoonSchema from(Webtoon webtoon) { + return WebtoonSchema.builder() + .webtoonId(webtoon.getId()) + .title(webtoon.getTitle()) + .thumbnailUrl(webtoon.getThumbnailUrl()) + .ageLimit(webtoon.getAgeLimit().getValue()) + .author(Author.from(webtoon.getAuthor())) + .build(); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java similarity index 97% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java index 3c0eefb..68bf7ba 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/DayOfWeekWebtoon.java @@ -18,7 +18,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.common.BaseTimeEntity; import shop.jtoon.webtoon.entity.enums.DayOfWeek; @Entity diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Episode.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/Episode.java similarity index 98% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Episode.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/Episode.java index bc0f12b..a45bdc2 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Episode.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/Episode.java @@ -22,7 +22,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.common.BaseTimeEntity; @Entity @Getter diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java similarity index 96% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java index ecee740..9bdde2d 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/GenreWebtoon.java @@ -18,7 +18,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.common.BaseTimeEntity; import shop.jtoon.webtoon.entity.enums.Genre; @Entity diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java similarity index 96% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java index 17b6cb2..ea7010e 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/PurchasedEpisode.java @@ -16,7 +16,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.common.BaseTimeEntity; import shop.jtoon.member.entity.Member; @Entity diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java similarity index 98% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java index b59bccb..61daa8d 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/Webtoon.java @@ -17,7 +17,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import shop.jtoon.exception.InvalidRequestException; -import shop.jtoon.global.entity.BaseTimeEntity; +import shop.jtoon.common.BaseTimeEntity; import shop.jtoon.member.entity.Member; import shop.jtoon.webtoon.entity.enums.AgeLimit; diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/enums/AgeLimit.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/enums/DayOfWeek.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/entity/enums/Genre.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/DayOfWeekWebtoonRepository.java diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeReader.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeReader.java new file mode 100644 index 0000000..63fb2e8 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeReader.java @@ -0,0 +1,33 @@ +package shop.jtoon.webtoon.repository; + +import static shop.jtoon.type.ErrorStatus.*; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.NotFoundException; +import shop.jtoon.payment.repository.CookieReader; +import shop.jtoon.payment.repository.PaymentReader; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.PurchasedEpisode; +import shop.jtoon.webtoon.entity.Webtoon; + +@Repository +@RequiredArgsConstructor +public class EpisodeReader { + + private final EpisodeRepository episodeRepository; + private final PurchasedEpisodeRepository purchasedEpisodeRepository; + + public boolean validateDuplicateNo(Webtoon webtoon, int no) { + return episodeRepository.existsByWebtoonAndNo(webtoon, no); + } + + public Episode read(Long episodeId) { + return episodeRepository.findById(episodeId).orElseThrow(() -> new NotFoundException(EPISODE_NOT_FOUND)); + } + + public void save(PurchasedEpisode purchasedEpisode) { + purchasedEpisodeRepository.save(purchasedEpisode); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeRepository.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java similarity index 66% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java index 79a75f2..cae6bca 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeSearchRepository.java @@ -1,9 +1,5 @@ package shop.jtoon.webtoon.repository; - - -import static shop.jtoon.webtoon.entity.QEpisode.*; - import java.util.List; import org.springframework.stereotype.Repository; @@ -11,8 +7,9 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; -import shop.jtoon.global.util.DynamicQuery; +import shop.jtoon.util.DynamicQuery; import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.QEpisode; @Repository @RequiredArgsConstructor @@ -21,11 +18,11 @@ public class EpisodeSearchRepository { private final JPAQueryFactory jpaQueryFactory; public List getEpisodes(Long webtoonId, int size, Long offset) { - return jpaQueryFactory.selectFrom(episode) - .where(DynamicQuery.generateEq(webtoonId, episode.webtoon.id::eq)) + return jpaQueryFactory.selectFrom(QEpisode.episode) + .where(DynamicQuery.generateEq(webtoonId, QEpisode.episode.webtoon.id::eq)) .limit(size) .offset(offset) - .orderBy(episode.no.desc()) + .orderBy(QEpisode.episode.no.desc()) .fetch(); } } diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeWriter.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeWriter.java new file mode 100644 index 0000000..0183989 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/EpisodeWriter.java @@ -0,0 +1,29 @@ +package shop.jtoon.webtoon.repository; + +import java.util.List; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.webtoon.domain.SearchEpisode; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Webtoon; + +@Repository +@RequiredArgsConstructor +public class EpisodeWriter { + + private final EpisodeRepository episodeRepository; + private final EpisodeSearchRepository episodeSearchRepository; + + public void write(Episode episode) { + episodeRepository.save(episode); + } + + public List readEpisodes(Long webtoonId, int size, Long offset) { + return episodeSearchRepository.getEpisodes(webtoonId, size, offset) + .stream() + .map(SearchEpisode::from) + .toList(); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/GenreWebtoonRepository.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/PurchasedEpisodeRepository.java diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonReader.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonReader.java new file mode 100644 index 0000000..c89d6b8 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonReader.java @@ -0,0 +1,49 @@ +package shop.jtoon.webtoon.repository; + +import static shop.jtoon.type.ErrorStatus.*; + +import java.util.List; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.NotFoundException; +import shop.jtoon.webtoon.domain.SearchWebtoon; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.Genre; + +@Repository +@RequiredArgsConstructor +public class WebtoonReader { + + private final WebtoonRepository webtoonRepository; + private final WebtoonSearchRepository webtoonSearchRepository; + private final DayOfWeekWebtoonRepository dayOfWeekWebtoonRepository; + private final GenreWebtoonRepository genreWebtoonRepository; + + public List search(SearchWebtoon search) { + return webtoonSearchRepository.findWebtoons(search.day(), search.keyword()); + } + + public Webtoon read(Long webtoonId) { + return webtoonRepository.findById(webtoonId).orElseThrow(() -> new NotFoundException(WEBTOON_NOT_FOUND)); + } + + public List readDayOfWebtoon(Webtoon webtoon) { + return dayOfWeekWebtoonRepository.findByWebtoon(webtoon) + .stream() + .map(DayOfWeekWebtoon::getDayOfWeekName) + .toList(); + } + + public List readGenreOfWebtoon(Webtoon webtoon) { + return genreWebtoonRepository.findByWebtoon(webtoon).stream() + .map(GenreWebtoon::getGenre).toList(); + } + + public boolean exsistsTitie(String title) { + return webtoonRepository.existsByTitle(title); + } +} diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java similarity index 100% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonRepository.java diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java similarity index 55% rename from jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java rename to jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java index 6bac138..12f3208 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonSearchRepository.java @@ -1,9 +1,5 @@ package shop.jtoon.webtoon.repository; -import static shop.jtoon.member.entity.QMember.*; -import static shop.jtoon.webtoon.entity.QDayOfWeekWebtoon.*; -import static shop.jtoon.webtoon.entity.QWebtoon.*; - import java.util.List; import org.springframework.stereotype.Repository; @@ -12,8 +8,11 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; -import shop.jtoon.global.util.DynamicQuery; +import shop.jtoon.member.entity.QMember; +import shop.jtoon.util.DynamicQuery; import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.QDayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.QWebtoon; import shop.jtoon.webtoon.entity.enums.DayOfWeek; @Repository @@ -21,21 +20,20 @@ public class WebtoonSearchRepository { private final JPAQueryFactory jpaQueryFactory; - private final DayOfWeekWebtoonRepository dayOfWeekWebtoonRepository; public List findWebtoons(DayOfWeek dayOfWeek, String keyword) { - return jpaQueryFactory.selectFrom(dayOfWeekWebtoon) - .join(dayOfWeekWebtoon.webtoon, webtoon) - .join(webtoon.author, member) + return jpaQueryFactory.selectFrom(QDayOfWeekWebtoon.dayOfWeekWebtoon) + .join(QDayOfWeekWebtoon.dayOfWeekWebtoon.webtoon, QWebtoon.webtoon) + .join(QWebtoon.webtoon.author, QMember.member) .where( - DynamicQuery.generateEq(dayOfWeek, dayOfWeekWebtoon.dayOfWeek::eq), + DynamicQuery.generateEq(dayOfWeek, QDayOfWeekWebtoon.dayOfWeekWebtoon.dayOfWeek::eq), DynamicQuery.generateEq(keyword, this::containsKeyword) ) .fetch(); } private BooleanExpression containsKeyword(String keyword) { - return webtoon.title.contains(keyword) - .or(webtoon.author.nickname.contains(keyword)); + return QWebtoon.webtoon.title.contains(keyword) + .or(QWebtoon.webtoon.author.nickname.contains(keyword)); } } diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonWriter.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonWriter.java new file mode 100644 index 0000000..f5e31a7 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/repository/WebtoonWriter.java @@ -0,0 +1,26 @@ +package shop.jtoon.webtoon.repository; + +import java.util.List; + +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; + +@Repository +@RequiredArgsConstructor +public class WebtoonWriter { + + private final WebtoonRepository webtoonRepository; + private final DayOfWeekWebtoonRepository dayOfWeekWebtoonRepository; + private final GenreWebtoonRepository genreWebtoonRepository; + + public void createWebtoon(Webtoon webtoon, List dayOfWeekWebtoons, + List genreWebtoons) { + webtoonRepository.save(webtoon); + dayOfWeekWebtoonRepository.saveAll(dayOfWeekWebtoons); + genreWebtoonRepository.saveAll(genreWebtoons); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/EpisodeDomainService.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/EpisodeDomainService.java new file mode 100644 index 0000000..2f99597 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/EpisodeDomainService.java @@ -0,0 +1,64 @@ +package shop.jtoon.webtoon.service; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.repository.MemberReader; +import shop.jtoon.payment.service.CookieManager; +import shop.jtoon.webtoon.domain.EpisodeMainInfo; +import shop.jtoon.webtoon.domain.EpisodeSchema; +import shop.jtoon.webtoon.domain.SearchEpisode; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.repository.EpisodeReader; +import shop.jtoon.webtoon.repository.EpisodeWriter; +import shop.jtoon.webtoon.repository.WebtoonReader; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class EpisodeDomainService { + + private final WebtoonManger webtoonManger; + private final CookieManager cookieManager; + + private final WebtoonReader webtoonReader; + private final EpisodeReader episodeReader; + private final MemberReader memberReader; + private final EpisodeWriter episodeWriter; + + + public Webtoon readWebtoon(Long webtoonId, Long memberId, int no) { + Webtoon webtoon = webtoonReader.read(webtoonId); + webtoonManger.validationWebtoon(webtoon, memberId, no); + + return webtoon; + } + + public void createEpisode(EpisodeSchema episodeSchema,Webtoon webtoon, String mainUrl, String thumbnailUrl) { + Episode episode = episodeSchema.toEpisode(webtoon,mainUrl,thumbnailUrl); + episodeWriter.write(episode); + } + + public EpisodeMainInfo readEpisode(Long episodeId) { + Episode episode = episodeReader.read(episodeId); + + return EpisodeMainInfo.of(episode); + } + + @Transactional + public void purchaseEpisode(Long memberId, Long episodeId) { + Member member = memberReader.read(memberId); + Episode episode = episodeReader.read(episodeId); + cookieManager.useCookie(episode.getCookieCount(), member); + webtoonManger.purchase(episode, member); + } + + public List readEpisodes(Long webtoonId, int size, Long offset) { + return episodeWriter.readEpisodes(webtoonId, size, offset); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonDomainService.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonDomainService.java new file mode 100644 index 0000000..6adf7a8 --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonDomainService.java @@ -0,0 +1,68 @@ +package shop.jtoon.webtoon.service; + +import static java.util.stream.Collectors.*; +import static shop.jtoon.type.ErrorStatus.*; + +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.NotFoundException; +import shop.jtoon.member.entity.Member; +import shop.jtoon.member.repository.MemberReader; +import shop.jtoon.webtoon.domain.SearchWebtoon; +import shop.jtoon.webtoon.domain.WebtoonDayOfWeeks; +import shop.jtoon.webtoon.domain.WebtoonDetail; +import shop.jtoon.webtoon.domain.WebtoonSchema; +import shop.jtoon.webtoon.domain.WebtoonGenres; +import shop.jtoon.webtoon.domain.WebtoonInfo; +import shop.jtoon.webtoon.entity.DayOfWeekWebtoon; +import shop.jtoon.webtoon.entity.GenreWebtoon; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.entity.enums.DayOfWeek; +import shop.jtoon.webtoon.entity.enums.Genre; +import shop.jtoon.webtoon.repository.WebtoonReader; +import shop.jtoon.webtoon.repository.WebtoonWriter; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class WebtoonDomainService { + + private final WebtoonManger webtoonManger; + private final MemberReader memberReader; + private final WebtoonWriter webtoonWriter; + private final WebtoonReader webtoonReader; + + public void validateDuplicateTitle(String title) { + webtoonManger.validationTitle(title); + } + + @Transactional + public void createWebtoon(Long memberId, WebtoonInfo info, WebtoonGenres genres, WebtoonDayOfWeeks dayOfWeeks) { + Member member = memberReader.read(memberId); + + Webtoon webtoon = info.toWebtoonEntity(member); + List dayOfWeekWebtoons = dayOfWeeks.toDayOfWeekWebtoonEntity(webtoon); + List genreWebtoons = genres.toGenreWebtoonEntity(webtoon); + + webtoonWriter.createWebtoon(webtoon, dayOfWeekWebtoons, genreWebtoons); + } + + public Map> readWebtoons(SearchWebtoon search) { + return webtoonReader.search(search).stream() + .collect(groupingBy(DayOfWeekWebtoon::getDayOfWeek, + mapping(dayOfWeekWebtoon -> WebtoonSchema.from(dayOfWeekWebtoon.getWebtoon()), toList()))); + } + + public WebtoonDetail readWebtoonDetail(Long webtoonId) { + Webtoon webtoon = webtoonReader.read(webtoonId); + List dayOfWeeks = webtoonReader.readDayOfWebtoon(webtoon); + List genres = webtoonReader.readGenreOfWebtoon(webtoon); + + return WebtoonDetail.of(webtoon, dayOfWeeks, genres); + } +} diff --git a/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonManger.java b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonManger.java new file mode 100644 index 0000000..acecf6a --- /dev/null +++ b/jtoon-core/core-domain/src/main/java/shop/jtoon/webtoon/service/WebtoonManger.java @@ -0,0 +1,47 @@ +package shop.jtoon.webtoon.service; + +import static shop.jtoon.type.ErrorStatus.*; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import shop.jtoon.exception.DuplicatedException; +import shop.jtoon.member.entity.Member; +import shop.jtoon.payment.repository.CookieReader; +import shop.jtoon.payment.service.CookieManager; +import shop.jtoon.webtoon.entity.Episode; +import shop.jtoon.webtoon.entity.PurchasedEpisode; +import shop.jtoon.webtoon.entity.Webtoon; +import shop.jtoon.webtoon.repository.EpisodeReader; +import shop.jtoon.webtoon.repository.WebtoonReader; + +@Service +@RequiredArgsConstructor +public class WebtoonManger { + + private final WebtoonReader webtoonReader; + private final EpisodeReader episodeReader; + + + public void validationTitle(String title) { + if (webtoonReader.exsistsTitie(title)) { + throw new DuplicatedException(WEBTOON_TITLE_DUPLICATED); + } + } + + public void validationWebtoon(Webtoon webtoon, Long memberId, int no) { + webtoon.validateAuthor(memberId); + validateDuplicateNo(webtoon, no); + } + + private void validateDuplicateNo(Webtoon webtoon, int no) { + if (episodeReader.validateDuplicateNo(webtoon, no)) { + throw new DuplicatedException(EPISODE_NUMBER_DUPLICATED); + } + } + + public void purchase(Episode episode, Member member) { + PurchasedEpisode purchasedEpisode = PurchasedEpisode.create(member, episode); + episodeReader.save(purchasedEpisode); + } +} diff --git a/jtoon-db/db-redis/build.gradle b/jtoon-db/db-redis/build.gradle new file mode 100644 index 0000000..a4e9c74 --- /dev/null +++ b/jtoon-db/db-redis/build.gradle @@ -0,0 +1,7 @@ +dependencies { + // Redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + + compileOnly project(":jtoon-system") + compileOnly project(":jtoon-core:core-domain") +} \ No newline at end of file diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/internal/config/RedisConfig.java b/jtoon-db/db-redis/src/main/java/shop/jtoon/config/RedisConfig.java similarity index 97% rename from jtoon-core/core-api/src/main/java/shop/jtoon/internal/config/RedisConfig.java rename to jtoon-db/db-redis/src/main/java/shop/jtoon/config/RedisConfig.java index abf480a..5aa5a80 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/internal/config/RedisConfig.java +++ b/jtoon-db/db-redis/src/main/java/shop/jtoon/config/RedisConfig.java @@ -1,4 +1,4 @@ -package shop.jtoon.internal.config; +package shop.jtoon.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/internal/repository/StringRedisRepository.java b/jtoon-db/db-redis/src/main/java/shop/jtoon/repository/StringRedisRepository.java similarity index 79% rename from jtoon-core/core-api/src/main/java/shop/jtoon/internal/repository/StringRedisRepository.java rename to jtoon-db/db-redis/src/main/java/shop/jtoon/repository/StringRedisRepository.java index f7a8f97..8845247 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/internal/repository/StringRedisRepository.java +++ b/jtoon-db/db-redis/src/main/java/shop/jtoon/repository/StringRedisRepository.java @@ -1,4 +1,4 @@ -package shop.jtoon.internal.repository; +package shop.jtoon.repository; import static shop.jtoon.util.SecurityConstant.*; @@ -8,6 +8,7 @@ import org.springframework.stereotype.Repository; import lombok.RequiredArgsConstructor; +import shop.jtoon.util.SecurityConstant; @Repository @RequiredArgsConstructor @@ -16,7 +17,7 @@ public class StringRedisRepository { private final StringRedisTemplate redisTemplate; public void save(String key, String value, Long expireMin) { - redisTemplate.opsForValue().set(key, value, expireMin * MINUTE, TimeUnit.MILLISECONDS); + redisTemplate.opsForValue().set(key, value, expireMin * SecurityConstant.MINUTE, TimeUnit.MILLISECONDS); } public String getData(String key) { diff --git a/jtoon-core/core-api/src/main/java/shop/jtoon/internal/service/RedisTokenService.java b/jtoon-db/db-redis/src/main/java/shop/jtoon/service/RedisTokenService.java similarity index 89% rename from jtoon-core/core-api/src/main/java/shop/jtoon/internal/service/RedisTokenService.java rename to jtoon-db/db-redis/src/main/java/shop/jtoon/service/RedisTokenService.java index c2b8393..33b9042 100644 --- a/jtoon-core/core-api/src/main/java/shop/jtoon/internal/service/RedisTokenService.java +++ b/jtoon-db/db-redis/src/main/java/shop/jtoon/service/RedisTokenService.java @@ -1,10 +1,10 @@ -package shop.jtoon.internal.service; +package shop.jtoon.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; -import shop.jtoon.internal.repository.StringRedisRepository; +import shop.jtoon.repository.StringRedisRepository; @Service @RequiredArgsConstructor diff --git a/jtoon-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java b/jtoon-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java index 393b41a..af65683 100644 --- a/jtoon-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java +++ b/jtoon-internal/core-web/src/main/java/shop/jtoon/error/handler/GlobalExceptionHandler.java @@ -1,5 +1,8 @@ package shop.jtoon.error.handler; + +import java.util.List; + import org.springframework.http.HttpStatus; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; @@ -7,12 +10,16 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; + import shop.jtoon.error.model.ErrorResponse; -import shop.jtoon.exception.*; +import shop.jtoon.exception.DuplicatedException; +import shop.jtoon.exception.ForbiddenException; +import shop.jtoon.exception.IamportException; +import shop.jtoon.exception.InvalidRequestException; +import shop.jtoon.exception.NotFoundException; +import shop.jtoon.exception.UnauthorizedException; import shop.jtoon.type.ErrorStatus; -import java.util.List; - @RestControllerAdvice public class GlobalExceptionHandler { diff --git a/jtoon-internal/iamport-client/build.gradle b/jtoon-internal/iamport-client/build.gradle index 2c1bbaa..a23f6bf 100644 --- a/jtoon-internal/iamport-client/build.gradle +++ b/jtoon-internal/iamport-client/build.gradle @@ -1,4 +1,5 @@ dependencies { + implementation project(':jtoon-system') // JPA implementation 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/jtoon-internal/s3-client/build.gradle b/jtoon-internal/s3-client/build.gradle index d756664..4d7d080 100644 --- a/jtoon-internal/s3-client/build.gradle +++ b/jtoon-internal/s3-client/build.gradle @@ -1,6 +1,6 @@ dependencies { - implementation project(':jtoon-system') + implementation project(":jtoon-system") // S3 implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/jtoon-internal/smtp-client/build.gradle b/jtoon-internal/smtp-client/build.gradle index 0de8cd2..72a6c28 100644 --- a/jtoon-internal/smtp-client/build.gradle +++ b/jtoon-internal/smtp-client/build.gradle @@ -2,12 +2,6 @@ dependencies { implementation project(':jtoon-system') - // Bean Validation - implementation 'org.springframework.boot:spring-boot-starter-validation' - // SMTP implementation 'org.springframework.boot:spring-boot-starter-mail' - - // Test - testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/jtoon-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java index 732e6eb..b20cb17 100644 --- a/jtoon-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java +++ b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/application/SmtpService.java @@ -1,5 +1,7 @@ package shop.jtoon.application; +import java.util.UUID; + import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; @@ -8,7 +10,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import shop.jtoon.entity.Mail; +import shop.jtoon.domain.Mail; @Service @Slf4j @@ -17,9 +19,16 @@ public class SmtpService { private final JavaMailSender javaMailSender; - @Value("${spring.mail.username}") + @Value("${mail.username}") private String senderUsername; + public void sendMail(String email) { + UUID uuid = UUID.randomUUID(); + String randomUuid = uuid.toString().substring(0, 6); + + sendMail(Mail.forAuthentication(email, randomUuid)); + } + public void sendMail(Mail mail) { MimeMessagePreparator mimeMessagePreparator = mimeMessage -> { MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8"); diff --git a/jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/MailProperties.java b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/MailProperties.java new file mode 100644 index 0000000..a863ec2 --- /dev/null +++ b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/MailProperties.java @@ -0,0 +1,32 @@ +package shop.jtoon.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import lombok.Getter; + +@Getter +@Configuration +public class MailProperties { + + @Value("${mail.host}") + private String host; + + @Value("${mail.port}") + private Integer port; + + @Value("${mail.username}") + private String username; + + @Value("${mail.password}") + private String password; + + @Value("${mail.properties.mail.smtp.auth}") + private String auth; + + @Value("${mail.properties.mail.smtp.starttls.enable}") + private String starttls; + + @Value("${mail.properties.mail.smtp.ssl.trust}") + private String sslTrust; +} \ No newline at end of file diff --git a/jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/SmtpConfig.java b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/SmtpConfig.java new file mode 100644 index 0000000..09e6a23 --- /dev/null +++ b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/config/SmtpConfig.java @@ -0,0 +1,35 @@ +package shop.jtoon.config; + +import java.util.Properties; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +import lombok.RequiredArgsConstructor; + +@Configuration +@RequiredArgsConstructor +public class SmtpConfig { + + private final MailProperties mailProperties; + + @Bean + public JavaMailSender javaMailSender() { + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setHost(mailProperties.getHost()); + mailSender.setPort(mailProperties.getPort()); + + mailSender.setUsername(mailProperties.getUsername()); + mailSender.setPassword(mailProperties.getPassword()); + + Properties props = mailSender.getJavaMailProperties(); + props.put("mail.transport.protocol", "smtp"); + props.put("mail.smtp.auth", mailProperties.getAuth()); + props.put("mail.smtp.starttls.enable", mailProperties.getStarttls()); + props.put("mail.debug", "true"); + + return mailSender; + } +} diff --git a/jtoon-internal/smtp-client/src/main/java/shop/jtoon/entity/Mail.java b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/domain/Mail.java similarity index 96% rename from jtoon-internal/smtp-client/src/main/java/shop/jtoon/entity/Mail.java rename to jtoon-internal/smtp-client/src/main/java/shop/jtoon/domain/Mail.java index ff8ecdd..fed900e 100644 --- a/jtoon-internal/smtp-client/src/main/java/shop/jtoon/entity/Mail.java +++ b/jtoon-internal/smtp-client/src/main/java/shop/jtoon/domain/Mail.java @@ -1,4 +1,4 @@ -package shop.jtoon.entity; +package shop.jtoon.domain; import static java.util.Objects.*; diff --git a/jtoon-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java b/jtoon-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java index 3ab5abb..cb22a7b 100644 --- a/jtoon-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java +++ b/jtoon-internal/smtp-client/src/test/java/shop/jtoon/application/SmtpServiceTest.java @@ -12,7 +12,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.mail.javamail.JavaMailSenderImpl; -import shop.jtoon.entity.Mail; +import shop.jtoon.domain.Mail; @ExtendWith(MockitoExtension.class) class SmtpServiceTest { diff --git a/jtoon-system/build.gradle b/jtoon-system/build.gradle index e69de29..0ce6a16 100644 --- a/jtoon-system/build.gradle +++ b/jtoon-system/build.gradle @@ -0,0 +1,3 @@ +dependencies { + +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index b522979..f910ea2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,6 +9,7 @@ pluginManagement { rootProject.name = 'jtoon' include 'jtoon-core:core-api' +include 'jtoon-core:core-domain' include 'jtoon-support:logging' include 'jtoon-support:monitoring' @@ -18,3 +19,6 @@ include 'jtoon-internal:core-web' include 'jtoon-internal:s3-client' include 'jtoon-internal:iamport-client' include 'jtoon-internal:smtp-client' + +include 'jtoon-db:db-redis' +