From c1f727a77adcced463716072e27127df36bb0787 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Sat, 28 Dec 2024 12:38:29 +0900 Subject: [PATCH 01/17] =?UTF-8?q?#50=20(build.gradle)=20oauth2=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index ae19a442..21415211 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,6 @@ plugins { id 'java' id 'org.springframework.boot' version '3.3.5' id 'io.spring.dependency-management' version '1.1.6' - id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10' } group = 'com.example' @@ -28,7 +27,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' - implementation 'org.springframework.boot:spring-boot-starter-websocket' compileOnly 'org.projectlombok:lombok' // runtimeOnly 'com.mysql:mysql-connector-j' @@ -54,6 +52,7 @@ dependencies { // SMTP implementation 'org.springframework.boot:spring-boot-starter-mail' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" // JWT @@ -88,6 +87,9 @@ dependencies { //객체 간 매핑 처리 implementation 'org.modelmapper:modelmapper:3.1.0' + + // OAUTH2 + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' } tasks.named('test') { @@ -114,4 +116,4 @@ sourceSets { srcDirs = ['src/test/java'] } } -} +} \ No newline at end of file From 54ad45c62b2efb67106ec8c2dd1cf601444fae11 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Mon, 30 Dec 2024 16:34:43 +0900 Subject: [PATCH 02/17] =?UTF-8?q?#50=20Mockito,=20wireMock=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 21415211..98b67c8f 100644 --- a/build.gradle +++ b/build.gradle @@ -90,6 +90,12 @@ dependencies { // OAUTH2 implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + + // MOCKITO + testImplementation "org.mockito:mockito-core:3.+" + + //WIREMOCK (외부 의존성 테스트용) + implementation 'org.wiremock.integrations:wiremock-spring-boot:3.3.0' } tasks.named('test') { From fe302758a1b92366044a1f53dd882ba98afcc603 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Mon, 30 Dec 2024 16:35:36 +0900 Subject: [PATCH 03/17] =?UTF-8?q?#50=20=EC=B6=A9=EB=8F=8C=EB=82=98?= =?UTF-8?q?=EB=8A=94=20=EA=B3=B5=ED=86=B5=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EB=B3=91=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/account/service/AccountService.java | 6 +++++ .../api/board/service/BoardService.java | 1 - .../api/board/service/EmployeeService.java | 26 ++++++++----------- .../PossibleBoardRepository.java | 8 +++++- .../api/global/BaseIntegrationTest.java | 10 ++++++- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/example/api/account/service/AccountService.java b/src/main/java/com/example/api/account/service/AccountService.java index b16b8cc5..57a366b0 100644 --- a/src/main/java/com/example/api/account/service/AccountService.java +++ b/src/main/java/com/example/api/account/service/AccountService.java @@ -30,6 +30,7 @@ public class AccountService { private final CodeRepository codeRepository; private final PasswordEncoder passwordEncoder; private final MailSender mailSender; + private final AccountRepository accountRepository; public Code sendEmail(@Validated final EmailRequest request) throws BusinessException { // 이미 가입된 이메일인지 검증 @@ -111,4 +112,9 @@ private void validateDuplicateEmail(final EmailRequest emailRequest) { throw new BusinessException(ErrorCode.DUPLICATE_EMAIL); } } + + public Account loadAccount(final Long requestMemberId) { + return accountRepository.findById(requestMemberId) + .orElseThrow(() -> new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND_EXCEPTION)); + } } \ No newline at end of file diff --git a/src/main/java/com/example/api/board/service/BoardService.java b/src/main/java/com/example/api/board/service/BoardService.java index 54c1b5eb..5084cde4 100644 --- a/src/main/java/com/example/api/board/service/BoardService.java +++ b/src/main/java/com/example/api/board/service/BoardService.java @@ -6,7 +6,6 @@ import com.example.api.domain.repository.FlavoredRepository; import com.example.api.domain.repository.MyInfoRepository; import com.example.api.domain.repository.OfferEmploymentRepository; -import com.example.api.possbileboard.PossibleBoardRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/com/example/api/board/service/EmployeeService.java b/src/main/java/com/example/api/board/service/EmployeeService.java index 4f6615a9..d1149429 100644 --- a/src/main/java/com/example/api/board/service/EmployeeService.java +++ b/src/main/java/com/example/api/board/service/EmployeeService.java @@ -5,9 +5,6 @@ import com.example.api.board.dto.response.ExternalCareerDTO; import com.example.api.board.dto.response.MyInfoDTO; import com.example.api.board.dto.response.PossibleBoardDTO; -import com.example.api.board.dto.update.UpdateOpenStatusRequest; -import com.example.api.board.dto.update.UpdateUserInfoRequest; -import com.example.api.board.entitiy.update.UpdateAccountConditionManager; import com.example.api.domain.Account; import com.example.api.domain.Category; import com.example.api.domain.ExternalCareer; @@ -21,6 +18,7 @@ import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; + import java.util.HashSet; import java.util.List; import java.util.Set; @@ -33,12 +31,11 @@ public class EmployeeService { private final ExternalCareerRepository externalCareerRepository; private final FlavoredRepository flavoredRepository; private final PossibleBoardRepository possibleBoardRepository; - private final UpdateAccountConditionManager updateAccountConditionManager; @Transactional public Boolean changeOpenStatus(final EmployeeIdRequest employeeIdRequest, boolean openStatus) { return employeeRepository.findByAccountId(employeeIdRequest.employeeId()).map(employee -> { - updateAccountConditionManager.updateAccount(employee, new UpdateOpenStatusRequest(openStatus)); + employee.setOpenStatus(openStatus); employeeRepository.save(employee); return true; }).orElse(false); @@ -47,15 +44,7 @@ public Boolean changeOpenStatus(final EmployeeIdRequest employeeIdRequest, boole @Transactional public boolean updateUserInfo(final EmployeeIdRequest employeeIdRequest, MyInfoDTO myInfo) { return employeeRepository.findByAccountId(employeeIdRequest.employeeId()).map(employee -> { - updateAccountConditionManager.updateAccount(employee, new UpdateUserInfoRequest( - myInfo.getName(), - myInfo.getSex(), - myInfo.getAge(), - myInfo.getPhone(), - myInfo.getEmail(), - myInfo.getNickname() - ) - ); + setUserInfo(employee, myInfo); employeeRepository.save(employee); updateExternalCareer(employee, myInfo.getExternalCareerList()); @@ -64,7 +53,14 @@ public boolean updateUserInfo(final EmployeeIdRequest employeeIdRequest, MyInfoD return true; }).orElse(false); } - + void setUserInfo(Account employee, MyInfoDTO myInfo) { + employee.setName(myInfo.getName()); + employee.setSex(myInfo.getSex()); + employee.setAge(myInfo.getAge()); + employee.setPhoneNumber(myInfo.getPhone()); + employee.setEmail(myInfo.getEmail()); + employee.setNickname(myInfo.getNickname()); + } public void updateExternalCareer(Account employee, List newExternalCareerList) { List existList = externalCareerRepository.findAllByEmployeeAccountId(employee.getAccountId()); Set newSet = new HashSet<>(newExternalCareerList); diff --git a/src/main/java/com/example/api/possbileboard/PossibleBoardRepository.java b/src/main/java/com/example/api/possbileboard/PossibleBoardRepository.java index 0eefac4a..5c325a45 100644 --- a/src/main/java/com/example/api/possbileboard/PossibleBoardRepository.java +++ b/src/main/java/com/example/api/possbileboard/PossibleBoardRepository.java @@ -21,7 +21,7 @@ public interface PossibleBoardRepository extends JpaRepository findAllByEmployeeAccountId(Long employeeId); + @Query("select new com.example.api.board.controller.domain.response.PossibleBoardDTO(p.possibleId, p.startTime, p.endTime) " + + "from PossibleBoard p where p.employee.accountId = :employeeId") + List findAllDTOByEmployeeAccountId(@Param("employeeId")Long employeeId); + +} + @Query("select new com.example.api.board.dto.response.PossibleBoardDTO(p.possibleId, p.startTime, p.endTime) " + "from PossibleBoard p where p.employee.accountId = :employeeId") List findAllDTOByEmployeeAccountId(@Param("employeeId")Long employeeId); diff --git a/src/test/java/com/example/api/global/BaseIntegrationTest.java b/src/test/java/com/example/api/global/BaseIntegrationTest.java index 4a73db13..8beba30e 100644 --- a/src/test/java/com/example/api/global/BaseIntegrationTest.java +++ b/src/test/java/com/example/api/global/BaseIntegrationTest.java @@ -25,12 +25,20 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import com.example.api.domain.*; +import com.example.api.domain.repository.*; +import com.example.api.possbileboard.PossibleBoardRepository; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ActiveProfiles; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + @SpringBootTest @ActiveProfiles("test") @Rollback(false) @@ -160,4 +168,4 @@ void setUpData() { flavoredCategoryList = new ArrayList<>(); flavoredCategoryList.addAll(flavoredRepository.findAllCategoryDTOByEmployeeId(1L)); } -} +} \ No newline at end of file From 1a1d5d795bad897d2fc551c3d6ed8279bb1b47b6 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:07:00 +0900 Subject: [PATCH 04/17] =?UTF-8?q?#54=20(AccountController)=20=EC=82=AC?= =?UTF-8?q?=EC=97=85=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=EA=B2=80=EC=A6=9D,?= =?UTF-8?q?=20=EC=82=AC=EC=9E=A5=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/controller/AccountController.java | 23 +++++++++++----- .../account/dto/BusinessNumberRequest.java | 4 +++ .../account/dto/BusinessNumberResponse.java | 4 +++ ...equest.java => SignUpEmployeeRequest.java} | 0 .../account/dto/SignUpEmployerRequest.java | 27 +++++++++++++++++++ .../example/api/account/entity/Location.java | 17 ++++++++++++ .../api/auth/repository/AuthRepository.java | 10 ------- .../api/global/config/RestTemplateConfig.java | 4 +++ .../global/properties/VendorProperties.java | 4 +++ 9 files changed, 77 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/example/api/account/dto/BusinessNumberRequest.java create mode 100644 src/main/java/com/example/api/account/dto/BusinessNumberResponse.java rename src/main/java/com/example/api/account/dto/{SignUpRequest.java => SignUpEmployeeRequest.java} (100%) create mode 100644 src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java create mode 100644 src/main/java/com/example/api/account/entity/Location.java delete mode 100644 src/main/java/com/example/api/auth/repository/AuthRepository.java create mode 100644 src/main/java/com/example/api/global/config/RestTemplateConfig.java create mode 100644 src/main/java/com/example/api/global/properties/VendorProperties.java diff --git a/src/main/java/com/example/api/account/controller/AccountController.java b/src/main/java/com/example/api/account/controller/AccountController.java index 4604cf6f..5a48a335 100644 --- a/src/main/java/com/example/api/account/controller/AccountController.java +++ b/src/main/java/com/example/api/account/controller/AccountController.java @@ -1,10 +1,8 @@ package com.example.api.account.controller; -import com.example.api.account.dto.EmailCodeRequest; -import com.example.api.account.dto.EmailRequest; +import com.example.api.account.dto.*; import com.example.api.account.entity.Code; import com.example.api.account.service.AccountService; -import com.example.api.account.dto.SignUpRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -12,6 +10,7 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; + @RestController @RequestMapping("/api/v1/account") @RequiredArgsConstructor @@ -32,9 +31,15 @@ public ResponseEntity verifyEmail(@Valid @RequestBody final EmailCodeReq return ResponseEntity.ok(successMessage); } - @PostMapping("/sign-up") - public ResponseEntity signUp(@Valid @RequestBody final SignUpRequest request) { - String successMessage = signUpService.signUp(request); + @PostMapping("/sign-up/employee") + public ResponseEntity signUpEmployee(@Valid @RequestBody final SignUpEmployeeRequest request) { + String successMessage = signUpService.signUpEmployee(request); + return ResponseEntity.status(HttpStatus.CREATED).body(successMessage); + } + + @PostMapping("/sign-up/employer") + public ResponseEntity signUpEmployer(@Valid @RequestBody final SignUpEmployerRequest request) { + String successMessage = signUpService.signUpEmployer(request); return ResponseEntity.status(HttpStatus.CREATED).body(successMessage); } @@ -50,4 +55,10 @@ public ResponseEntity deleteAccount( accountService.deleteAccount(memberId); return ResponseEntity.ok("delete account"); } + + @PostMapping("/validation/business-number") + public ResponseEntity verifyBusinessNumber(@Valid @RequestBody final BusinessNumberRequest request) { + String successMessage = signUpService.verifyBusinessNumber(request); + return ResponseEntity.ok(successMessage); + } } \ No newline at end of file diff --git a/src/main/java/com/example/api/account/dto/BusinessNumberRequest.java b/src/main/java/com/example/api/account/dto/BusinessNumberRequest.java new file mode 100644 index 00000000..1d22b24c --- /dev/null +++ b/src/main/java/com/example/api/account/dto/BusinessNumberRequest.java @@ -0,0 +1,4 @@ +package com.example.api.account.dto; + +public class BusinessNumberRequest { +} diff --git a/src/main/java/com/example/api/account/dto/BusinessNumberResponse.java b/src/main/java/com/example/api/account/dto/BusinessNumberResponse.java new file mode 100644 index 00000000..236f32e7 --- /dev/null +++ b/src/main/java/com/example/api/account/dto/BusinessNumberResponse.java @@ -0,0 +1,4 @@ +package com.example.api.account.dto; + +public class BusinessNumberResponse { +} diff --git a/src/main/java/com/example/api/account/dto/SignUpRequest.java b/src/main/java/com/example/api/account/dto/SignUpEmployeeRequest.java similarity index 100% rename from src/main/java/com/example/api/account/dto/SignUpRequest.java rename to src/main/java/com/example/api/account/dto/SignUpEmployeeRequest.java diff --git a/src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java b/src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java new file mode 100644 index 00000000..85ddd205 --- /dev/null +++ b/src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java @@ -0,0 +1,27 @@ +package com.example.api.account.dto; + +import com.example.api.account.entity.Nationality; +import com.example.api.account.entity.UserRole; +import com.example.api.global.config.resolver.ValidEmail; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +public record SignUpEmployeeRequest( + @NotBlank + String loginId, + @NotBlank + String password, + @NotBlank + String name, + @NotBlank + String nickname, + @ValidEmail + String email, + @NotNull + Nationality nationality, + @NotNull + UserRole role, + @NotBlank + String phoneNumber +) { +} \ No newline at end of file diff --git a/src/main/java/com/example/api/account/entity/Location.java b/src/main/java/com/example/api/account/entity/Location.java new file mode 100644 index 00000000..5e2d4eb1 --- /dev/null +++ b/src/main/java/com/example/api/account/entity/Location.java @@ -0,0 +1,17 @@ +package com.example.api.account.entity; + +import jakarta.persistence.*; + +@Entity +public class Address { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "ADDRESS_UNIQUE_ID") + private Long id; + @Column(name = "ADDRESS_ZIPCODE") + private String zipcode; + @Column(name = "ADDRESS_") + private String address; + @Column(name = "ADDRESS_DETAIL_ADDRESS") + private String detailAddress; +} diff --git a/src/main/java/com/example/api/auth/repository/AuthRepository.java b/src/main/java/com/example/api/auth/repository/AuthRepository.java deleted file mode 100644 index d7181ad9..00000000 --- a/src/main/java/com/example/api/auth/repository/AuthRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.api.auth.repository; - -import com.example.api.domain.Account; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface AuthRepository extends JpaRepository { - Optional findUserByLoginId(String loginId); -} \ No newline at end of file diff --git a/src/main/java/com/example/api/global/config/RestTemplateConfig.java b/src/main/java/com/example/api/global/config/RestTemplateConfig.java new file mode 100644 index 00000000..9d297017 --- /dev/null +++ b/src/main/java/com/example/api/global/config/RestTemplateConfig.java @@ -0,0 +1,4 @@ +package com.example.api.global.config; + +public class RestTemplateConfig { +} diff --git a/src/main/java/com/example/api/global/properties/VendorProperties.java b/src/main/java/com/example/api/global/properties/VendorProperties.java new file mode 100644 index 00000000..65ddcbd2 --- /dev/null +++ b/src/main/java/com/example/api/global/properties/VendorProperties.java @@ -0,0 +1,4 @@ +package com.example.api.global.properties; + +public class VendorProperties { +} From c92461ab1a7103bd3a7a281e830ca77cf82e5f8a Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:08:12 +0900 Subject: [PATCH 05/17] =?UTF-8?q?#54=20(dto)=20=EC=82=AC=EC=97=85=EC=9E=90?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20=EA=B2=80=EC=A6=9D=20=EB=B0=8F=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20dto=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/dto/BusinessNumberRequest.java | 12 ++++- .../account/dto/BusinessNumberResponse.java | 46 ++++++++++++++++++- .../account/dto/SignUpEmployeeRequest.java | 3 +- .../account/dto/SignUpEmployerRequest.java | 27 +++++++---- 4 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/example/api/account/dto/BusinessNumberRequest.java b/src/main/java/com/example/api/account/dto/BusinessNumberRequest.java index 1d22b24c..06744c94 100644 --- a/src/main/java/com/example/api/account/dto/BusinessNumberRequest.java +++ b/src/main/java/com/example/api/account/dto/BusinessNumberRequest.java @@ -1,4 +1,14 @@ package com.example.api.account.dto; -public class BusinessNumberRequest { +import jakarta.validation.constraints.NotBlank; + +public record BusinessNumberRequest( + @NotBlank + String businessRegistrationNumber, + @NotBlank + String businessName, + @NotBlank + String representationName, + @NotBlank + String businessOpenDate) { } diff --git a/src/main/java/com/example/api/account/dto/BusinessNumberResponse.java b/src/main/java/com/example/api/account/dto/BusinessNumberResponse.java index 236f32e7..a312d946 100644 --- a/src/main/java/com/example/api/account/dto/BusinessNumberResponse.java +++ b/src/main/java/com/example/api/account/dto/BusinessNumberResponse.java @@ -1,4 +1,46 @@ package com.example.api.account.dto; -public class BusinessNumberResponse { -} +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + + +public record BusinessNumberResponse( + @JsonProperty("request_cnt") int requestCount, + @JsonProperty("valid_cnt") int validCount, + @JsonProperty("status_code") String statusCode, + List data +) { + private record Data( + @JsonProperty("b_no") String businessNumber, + String valid, + @JsonProperty("request_param") RequestParam requestParam, + Status status + ) { + } + private record RequestParam( + @JsonProperty("b_no") String businessNumber, + @JsonProperty("start_dt") String startDate, + @JsonProperty("p_nm") String name, + @JsonProperty("b_nm") String businessName + ) { + } + private record Status( + @JsonProperty("b_no") String businessNumber, + @JsonProperty("b_stt") String businessStatus, + @JsonProperty("b_stt_cd") String businessStatusCode, + @JsonProperty("tax_type") String taxType, + @JsonProperty("tax_type_cd") String taxTypeCode, + @JsonProperty("end_dt") String endDate, + @JsonProperty("utcc_yn") String utccYn, + @JsonProperty("tax_type_change_dt") String taxTypeChangeDate, + @JsonProperty("invoice_apply_dt") String invoiceApplyDate, + @JsonProperty("rbf_tax_type") String rbfTaxType, + @JsonProperty("rbf_tax_type_cd") String rbfTaxTypeCode + ) { + } + + public String getValid(){ + return data.get(0).valid; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/api/account/dto/SignUpEmployeeRequest.java b/src/main/java/com/example/api/account/dto/SignUpEmployeeRequest.java index bbd37f5d..3ac7a843 100644 --- a/src/main/java/com/example/api/account/dto/SignUpEmployeeRequest.java +++ b/src/main/java/com/example/api/account/dto/SignUpEmployeeRequest.java @@ -3,11 +3,10 @@ import com.example.api.account.entity.Nationality; import com.example.api.account.entity.UserRole; import com.example.api.global.config.resolver.ValidEmail; -import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -public record SignUpRequest( +public record SignUpEmployeeRequest( @NotBlank String loginId, @NotBlank diff --git a/src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java b/src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java index 85ddd205..1c9fda8e 100644 --- a/src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java +++ b/src/main/java/com/example/api/account/dto/SignUpEmployerRequest.java @@ -1,27 +1,34 @@ package com.example.api.account.dto; +import com.example.api.account.entity.Location; import com.example.api.account.entity.Nationality; import com.example.api.account.entity.UserRole; import com.example.api.global.config.resolver.ValidEmail; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -public record SignUpEmployeeRequest( +public record SignUpEmployerRequest( @NotBlank - String loginId, + String loginId, // 로그인 id @NotBlank - String password, + String password, // 비밀번호 + @ValidEmail + String email, // 이메일 @NotBlank - String name, + String businessRegistrationNumber, // 사업자 번호 @NotBlank - String nickname, - @ValidEmail - String email, + String businessName, // 회사명 + @NotBlank + String representationName, // 대표명 + @NotBlank + String businessOpenDate, // 개업연월일 + @NotNull + Location location, @NotNull - Nationality nationality, + Nationality nationality, // 국적 @NotNull - UserRole role, + UserRole role, // 권한 @NotBlank - String phoneNumber + String phoneNumber // 휴대폰 번호 ) { } \ No newline at end of file From 9da9f181ee0829ae8e1eeca943db03ac46785ea2 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:08:41 +0900 Subject: [PATCH 06/17] =?UTF-8?q?#54=20(AccountController)=20=EC=82=AC?= =?UTF-8?q?=EC=97=85=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=EA=B2=80=EC=A6=9D,?= =?UTF-8?q?=20=EC=82=AC=EC=9E=A5=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/api/account/controller/AccountController.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/example/api/account/controller/AccountController.java b/src/main/java/com/example/api/account/controller/AccountController.java index 5a48a335..2478fefc 100644 --- a/src/main/java/com/example/api/account/controller/AccountController.java +++ b/src/main/java/com/example/api/account/controller/AccountController.java @@ -61,4 +61,10 @@ public ResponseEntity verifyBusinessNumber(@Valid @RequestBody final Bus String successMessage = signUpService.verifyBusinessNumber(request); return ResponseEntity.ok(successMessage); } + + @PostMapping("/sign-up/employer") + public ResponseEntity signUpEmployer(@Valid @RequestBody final SignUpEmployerRequest request) { + String successMessage = signUpService.signUpEmployer(request); + return ResponseEntity.status(HttpStatus.CREATED).body(successMessage); + } } \ No newline at end of file From e39df4efa7e42db0432240c191302a965424adfa Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:12:34 +0900 Subject: [PATCH 07/17] =?UTF-8?q?#54=20(Location)=20=EC=82=AC=EC=97=85?= =?UTF-8?q?=EC=9E=A5=20=EC=9C=84=EC=B9=98(Location)=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/api/account/entity/Location.java | 23 ++++++++++++++----- .../repository/LocationRepository.java | 4 ++++ 2 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/example/api/account/repository/LocationRepository.java diff --git a/src/main/java/com/example/api/account/entity/Location.java b/src/main/java/com/example/api/account/entity/Location.java index 5e2d4eb1..813025fb 100644 --- a/src/main/java/com/example/api/account/entity/Location.java +++ b/src/main/java/com/example/api/account/entity/Location.java @@ -1,17 +1,28 @@ package com.example.api.account.entity; import jakarta.persistence.*; +import lombok.Getter; @Entity -public class Address { +@Getter +public class Location { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "ADDRESS_UNIQUE_ID") + @Column(name = "LOCATION_UNIQUE_ID") private Long id; - @Column(name = "ADDRESS_ZIPCODE") + @Column(name = "LOCATION_ZIPCODE") private String zipcode; - @Column(name = "ADDRESS_") + @Column(name = "LOCATION_ADDRESS") private String address; - @Column(name = "ADDRESS_DETAIL_ADDRESS") + @Column(name = "LOCATION_DETAIL_ADDRESS") private String detailAddress; -} + + public Location() { + } + + public Location(String zipcode, String address, String detailAddress) { + this.zipcode = zipcode; + this.address = address; + this.detailAddress = detailAddress; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/api/account/repository/LocationRepository.java b/src/main/java/com/example/api/account/repository/LocationRepository.java new file mode 100644 index 00000000..6bb0e495 --- /dev/null +++ b/src/main/java/com/example/api/account/repository/LocationRepository.java @@ -0,0 +1,4 @@ +package com.example.api.account.repository; + +public interface LocationRepository { +} From 8f8187145e461c5e405eda4461b160a3462c9f31 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:13:37 +0900 Subject: [PATCH 08/17] =?UTF-8?q?#54=20(Repository)=20AuthRepository?= =?UTF-8?q?=EB=A5=BC=20AccountRepository=EB=A1=9C=20=EB=B3=91=ED=95=A9=20?= =?UTF-8?q?=EB=B0=8F=20LocationRepository=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/api/account/repository/AccountRepository.java | 2 ++ .../example/api/account/repository/LocationRepository.java | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/api/account/repository/AccountRepository.java b/src/main/java/com/example/api/account/repository/AccountRepository.java index 04853654..3921f015 100644 --- a/src/main/java/com/example/api/account/repository/AccountRepository.java +++ b/src/main/java/com/example/api/account/repository/AccountRepository.java @@ -11,4 +11,6 @@ public interface AccountRepository extends JpaRepository { boolean existsByEmail(String email); Optional findByEmail(String email); + + Optional findUserByLoginId(String loginId); } \ No newline at end of file diff --git a/src/main/java/com/example/api/account/repository/LocationRepository.java b/src/main/java/com/example/api/account/repository/LocationRepository.java index 6bb0e495..80b9b8c3 100644 --- a/src/main/java/com/example/api/account/repository/LocationRepository.java +++ b/src/main/java/com/example/api/account/repository/LocationRepository.java @@ -1,4 +1,9 @@ package com.example.api.account.repository; -public interface LocationRepository { +import com.example.api.account.entity.Location; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface LocationRepository extends JpaRepository { } From 53a7702d4743aafba9e27a1863425a8364ccc444 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:14:23 +0900 Subject: [PATCH 09/17] =?UTF-8?q?#54=20(Service)=20=EC=82=AC=EC=97=85?= =?UTF-8?q?=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=EA=B2=80=EC=A6=9D=20=EB=B0=8F?= =?UTF-8?q?=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/account/service/AccountService.java | 121 ++++++++++++++++-- 1 file changed, 110 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/example/api/account/service/AccountService.java b/src/main/java/com/example/api/account/service/AccountService.java index 57a366b0..d92d4ce3 100644 --- a/src/main/java/com/example/api/account/service/AccountService.java +++ b/src/main/java/com/example/api/account/service/AccountService.java @@ -1,36 +1,54 @@ package com.example.api.account.service; -import com.example.api.account.dto.EmailCodeRequest; -import com.example.api.account.dto.EmailRequest; -import com.example.api.account.dto.LoginIdRequest; +import com.example.api.account.dto.*; import com.example.api.account.entity.Code; +import com.example.api.account.entity.Location; import com.example.api.account.entity.UserRole; import com.example.api.account.repository.AccountRepository; -import com.example.api.account.dto.SignUpRequest; import com.example.api.account.repository.CodeRepository; import com.example.api.account.entity.MailSender; +import com.example.api.account.repository.LocationRepository; +import com.example.api.business.BusinessRepository; import com.example.api.domain.Account; +import com.example.api.domain.Business; import com.example.api.exception.BusinessException; import com.example.api.exception.ErrorCode; - +import com.example.api.global.properties.VendorProperties; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import org.springframework.web.client.RestTemplate; -import java.util.Collection; -import java.util.List; -import java.util.Optional; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; @Service @RequiredArgsConstructor +@Slf4j public class AccountService { private final AccountRepository accountRepository; private final CodeRepository codeRepository; private final PasswordEncoder passwordEncoder; private final MailSender mailSender; private final AccountRepository accountRepository; + private final BusinessRepository businessRepository; + private final RestTemplate restTemplate; + private final VendorProperties vendorProperties; + private final LocationRepository locationRepository; public Code sendEmail(@Validated final EmailRequest request) throws BusinessException { // 이미 가입된 이메일인지 검증 @@ -42,7 +60,6 @@ public Code sendEmail(@Validated final EmailRequest request) throws BusinessExce public String saveCode(@Validated final Code code){ try { codeRepository.save(code); - return "이메일 전송을 완료하였습니다."; } catch (Exception e){ throw new BusinessException(ErrorCode.FAIL_SAVE_CODE); @@ -63,14 +80,24 @@ public String verifyEmail(@Validated final EmailCodeRequest request) { } @Transactional - public String signUp(@Validated final SignUpRequest request) { + public String signUpEmployee(@Validated final SignUpEmployeeRequest request) { // 중복 로그인 ID 확인 validateDuplicateLoginId(new LoginIdRequest(request.loginId())); // 계정 저장 - saveAccount(request); + saveEmployeeAccount(request); return "회원가입이 완료되었습니다"; } + @Transactional + public String signUpEmployer(@Valid final SignUpEmployerRequest request) { + // 중복 로그인 ID 확인 (사장) + validateDuplicateLoginId(new LoginIdRequest(request.loginId())); + // 계정 저장 + saveEmployerAccount(request); + return "회원가입이 완료되었습니다"; + } + + private void saveEmployeeAccount(final SignUpEmployeeRequest request) { @Transactional(readOnly = true) public Account loadAccount(final Long requestMemberId) { return accountRepository.findById(requestMemberId) @@ -97,7 +124,31 @@ private void saveAccount(final SignUpRequest request) { roles, request.emailReceivable() ); + accountRepository.save(account); + } + private void saveEmployerAccount(final SignUpEmployerRequest request) { + Collection roles = List.of(request.role()); + Account account = new Account( + request.loginId(), + passwordEncoder.encode(request.password()), + request.email(), + request.phoneNumber(), + request.nationality(), + roles + ); + Account savedUser = accountRepository.save(account); + + Location savedLocation = locationRepository.save(request.location()); + Business business = new Business( + savedUser, + request.businessRegistrationNumber(), + request.businessName(), + request.representationName(), + request.businessOpenDate(), + savedLocation + ); + businessRepository.save(business); accountRepository.save(account); } @@ -117,4 +168,52 @@ public Account loadAccount(final Long requestMemberId) { return accountRepository.findById(requestMemberId) .orElseThrow(() -> new BusinessException(ErrorCode.ACCOUNT_NOT_FOUND_EXCEPTION)); } + + @Transactional + public String verifyBusinessNumber(@Validated final BusinessNumberRequest request){ + URI uri = createUrl(); + HttpEntity> requestEntity = getBusinessValidateApiRequestEntity(request); + + ResponseEntity response = restTemplate.exchange( + uri, + HttpMethod.POST, + requestEntity, + BusinessNumberResponse.class + ); + + log.info("response.getBody()={}", response.getBody()); + + String valid = Optional.ofNullable(response.getBody()) + .map(BusinessNumberResponse::getValid) + .orElseThrow(() -> new BusinessException(ErrorCode.INVALID_BUSINESS_NUMBER)); + + if (!"01".equals(valid)) { + throw new BusinessException(ErrorCode.INVALID_BUSINESS_NUMBER); + } + + return "유효한 사업자 등록 정보입니다."; + } + + @NotNull + private URI createUrl() { + try { + String encodedServiceKey = URLEncoder.encode(vendorProperties.getServiceKey(), StandardCharsets.UTF_8); + String url = vendorProperties.getBaseUrl() + "?serviceKey=" + encodedServiceKey; + return new URI(url); + } catch (Exception e) { + log.error(e.getMessage()); + // 프론트 서버 배포 후 수정, 회원가입 end point로 변경 + return URI.create("http://localhost:3000/"); + } + } + + @NotNull + private HttpEntity> getBusinessValidateApiRequestEntity(BusinessNumberRequest request) { + Map business = new HashMap<>(); + business.put("b_no", request.businessRegistrationNumber()); + business.put("start_dt", request.businessOpenDate()); + business.put("p_nm", request.representationName()); + business.put("b_nm", request.businessName()); + return new HttpEntity<>(Collections.singletonMap("businesses", Collections.singletonList(business))); + } } \ No newline at end of file From f14de3f722a4d2ac2c98734ef257b48a5a0fb07a Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:15:22 +0900 Subject: [PATCH 10/17] =?UTF-8?q?#54=20(application.properties)=20?= =?UTF-8?q?=EC=82=AC=EC=97=85=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20openApi=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 714f320e..5c44b70a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -52,7 +52,7 @@ jwt.access_token_valid_time=3600 # 30? jwt.refresh_token_valid_time=2592000 -# ??? ?? ?? +# mail code code.length=6 code.digit_range=10 @@ -85,4 +85,8 @@ spring.security.oauth2.client.provider.naver.user-info-uri=https://openapi.naver spring.security.oauth2.client.provider.naver.user-name-attribute=response # redirect allow path -app.oauth2.authorized-redirect-uris=* \ No newline at end of file +app.oauth2.authorized-redirect-uris=* + +# vendor +vendor.api.base-url=https://api.odcloud.kr/api/nts-businessman/v1/validate +vendor.api.service-key=${VENDOR_API_SERVICE-KEY} \ No newline at end of file From fb024d4d014809e8b84390613b597ef425ffb3e0 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:16:44 +0900 Subject: [PATCH 11/17] =?UTF-8?q?#54=20(RestTemplateConfig)=20RestTemplate?= =?UTF-8?q?=20=EB=B9=88=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/global/config/RestTemplateConfig.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/api/global/config/RestTemplateConfig.java b/src/main/java/com/example/api/global/config/RestTemplateConfig.java index 9d297017..708cbf0e 100644 --- a/src/main/java/com/example/api/global/config/RestTemplateConfig.java +++ b/src/main/java/com/example/api/global/config/RestTemplateConfig.java @@ -1,4 +1,23 @@ package com.example.api.global.config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +@Configuration public class RestTemplateConfig { -} + @Bean + public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) { + return new RestTemplate(clientHttpRequestFactory); + } + + @Bean + public ClientHttpRequestFactory clientHttpRequestFactory() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(5000); // 연결 타임아웃 5초 + factory.setReadTimeout(5000); // 읽기 타임아웃 5초 + return factory; + } +} \ No newline at end of file From 789dd4dd265bbc078d240584b5776eb1a071fcb1 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:17:27 +0900 Subject: [PATCH 12/17] =?UTF-8?q?#54=20(VendorProperties)=20=EC=82=AC?= =?UTF-8?q?=EC=97=85=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?api=20=EC=86=8D=EC=84=B1=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/global/properties/VendorProperties.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/api/global/properties/VendorProperties.java b/src/main/java/com/example/api/global/properties/VendorProperties.java index 65ddcbd2..643c0fba 100644 --- a/src/main/java/com/example/api/global/properties/VendorProperties.java +++ b/src/main/java/com/example/api/global/properties/VendorProperties.java @@ -1,4 +1,14 @@ package com.example.api.global.properties; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Getter +@Component public class VendorProperties { -} + @Value("${vendor.api.base-url}") + private String baseUrl; + @Value("${vendor.api.service-key}") + private String serviceKey; +} \ No newline at end of file From ba1effb3f009f1c9ebc7a40d8b632b6e319e97e5 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:20:23 +0900 Subject: [PATCH 13/17] =?UTF-8?q?#54=20(ErrorCode)=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EC=82=AC=EC=97=85?= =?UTF-8?q?=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=EA=B2=80=EC=A6=9D=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EC=97=90=EB=9F=AC=20=EC=BD=94=EB=93=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/api/exception/ErrorCode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/example/api/exception/ErrorCode.java b/src/main/java/com/example/api/exception/ErrorCode.java index 3936d1c8..494a7034 100644 --- a/src/main/java/com/example/api/exception/ErrorCode.java +++ b/src/main/java/com/example/api/exception/ErrorCode.java @@ -15,6 +15,7 @@ public enum ErrorCode { INCORRECT_PASSWORD(HttpStatus.BAD_REQUEST, "-107", "틀린 비밀번호입니다."), INCORRECT_DATA(HttpStatus.BAD_REQUEST, "-108", "올바르지 않은 정보입니다."), INVALID_REDIRECT_URI(HttpStatus.BAD_REQUEST,"-109","유효하지 않은 REDIRECT URI입니다."), + INVALID_BUSINESS_NUMBER(HttpStatus.BAD_REQUEST,"-110","사업자 등록 정보를 확인할 수 없습니다."), INVALID_TOKEN(HttpStatus.BAD_REQUEST, "-T1", "올바르지 않은 AccessToken입니다."), EXPIRED_ACCESS_TOKEN(HttpStatus.UNAUTHORIZED, "-T2", "만료된 AccessToken입니다."), From 37456df55afeca71bef66adcc81ece2b85a223d6 Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:22:25 +0900 Subject: [PATCH 14/17] =?UTF-8?q?#54=20Business=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20location=EC=9D=84=20String=20->=20Location=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/contracts/dto/BusinessInfoDTO.java | 3 ++- .../java/com/example/api/domain/Business.java | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/api/contracts/dto/BusinessInfoDTO.java b/src/main/java/com/example/api/contracts/dto/BusinessInfoDTO.java index 96c46da4..7ea7942d 100644 --- a/src/main/java/com/example/api/contracts/dto/BusinessInfoDTO.java +++ b/src/main/java/com/example/api/contracts/dto/BusinessInfoDTO.java @@ -1,5 +1,6 @@ package com.example.api.contracts.dto; +import com.example.api.account.entity.Location; import lombok.*; import java.time.LocalDateTime; @@ -14,7 +15,7 @@ public class BusinessInfoDTO { private String representationName; private LocalDateTime startTime; private LocalDateTime endTime; - private String location; + private Location location; private String businessPhone; private LocalDateTime signedDate; } diff --git a/src/main/java/com/example/api/domain/Business.java b/src/main/java/com/example/api/domain/Business.java index 37398ff8..f816a60b 100644 --- a/src/main/java/com/example/api/domain/Business.java +++ b/src/main/java/com/example/api/domain/Business.java @@ -1,10 +1,10 @@ package com.example.api.domain; +import com.example.api.account.entity.Location; import jakarta.persistence.*; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; import java.time.LocalDate; import java.util.ArrayList; @@ -32,8 +32,9 @@ public class Business extends BaseEntity { @Column(name = "BUSINESS_NAME") private String businessName; - @Column(name = "BUSINESS_LOCATION") - private String location; + @OneToOne(fetch = LAZY) + @JoinColumn(name = "BUSINESS_LOCATION") + private Location location; private String representationName; @@ -50,6 +51,18 @@ public void setBusinessName(String businessName) { public void setLocation(String location) { this.location = location; } + public Business() { + } + + public Business(Account user, String businessRegistrationNumber, String businessName, String representationName, String businessOpenDate, Location location) { + this.employer = user; + this.registrationNumber = businessRegistrationNumber; + this.businessName = businessName; + this.representationName = representationName; + this.openDate = LocalDate.parse(businessOpenDate); + this.location = location; + } +} public Business(String businessName, String location, String representationName) { this.businessName = businessName; From 79c0bc17d269d5633f0cc06689f82462758aa82c Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Fri, 3 Jan 2025 22:22:40 +0900 Subject: [PATCH 15/17] =?UTF-8?q?#54=20=EC=BB=A8=EB=B2=A4=EC=85=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradlew | 2 +- .../example/api/account/entity/QLocation.java | 43 +++++++++++++++++++ .../com/example/api/domain/QBusiness.java | 3 +- .../example/api/auth/service/AuthService.java | 8 ++-- .../java/com/example/api/domain/Account.java | 12 +++++- .../service/CustomOauth2UserService.java | 2 - .../api/global/BaseIntegrationTest.java | 7 ++- 7 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/main/generated/com/example/api/account/entity/QLocation.java diff --git a/gradlew b/gradlew index f5feea6d..b26d4110 100755 --- a/gradlew +++ b/gradlew @@ -249,4 +249,4 @@ eval "set -- $( tr '\n' ' ' )" '"$@"' -exec "$JAVACMD" "$@" +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/src/main/generated/com/example/api/account/entity/QLocation.java b/src/main/generated/com/example/api/account/entity/QLocation.java new file mode 100644 index 00000000..c15f6d8b --- /dev/null +++ b/src/main/generated/com/example/api/account/entity/QLocation.java @@ -0,0 +1,43 @@ +package com.example.api.account.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QLocation is a Querydsl query type for Location + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QLocation extends EntityPathBase { + + private static final long serialVersionUID = -590127238L; + + public static final QLocation location = new QLocation("location"); + + public final StringPath address = createString("address"); + + public final StringPath detailAddress = createString("detailAddress"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath zipcode = createString("zipcode"); + + public QLocation(String variable) { + super(Location.class, forVariable(variable)); + } + + public QLocation(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QLocation(PathMetadata metadata) { + super(Location.class, metadata); + } + +} + diff --git a/src/main/generated/com/example/api/domain/QBusiness.java b/src/main/generated/com/example/api/domain/QBusiness.java index 8cc945d1..e3b8979c 100644 --- a/src/main/generated/com/example/api/domain/QBusiness.java +++ b/src/main/generated/com/example/api/domain/QBusiness.java @@ -35,7 +35,7 @@ public class QBusiness extends EntityPathBase { public final QAccount employer; - public final StringPath location = createString("location"); + public final com.example.api.account.entity.QLocation location; public final DatePath openDate = createDate("openDate", java.time.LocalDate.class); @@ -65,6 +65,7 @@ public QBusiness(PathMetadata metadata, PathInits inits) { public QBusiness(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); this.employer = inits.isInitialized("employer") ? new QAccount(forProperty("employer")) : null; + this.location = inits.isInitialized("location") ? new com.example.api.account.entity.QLocation(forProperty("location")) : null; } } diff --git a/src/main/java/com/example/api/auth/service/AuthService.java b/src/main/java/com/example/api/auth/service/AuthService.java index 8c250aa9..35bf5a05 100644 --- a/src/main/java/com/example/api/auth/service/AuthService.java +++ b/src/main/java/com/example/api/auth/service/AuthService.java @@ -1,8 +1,8 @@ package com.example.api.auth.service; +import com.example.api.account.repository.AccountRepository; import com.example.api.auth.entitiy.RefreshToken; import com.example.api.auth.dto.*; -import com.example.api.auth.repository.AuthRepository; import com.example.api.auth.repository.TokenRepository; import com.example.api.domain.Account; import com.example.api.exception.BusinessException; @@ -16,7 +16,7 @@ @Service @RequiredArgsConstructor public class AuthService { - private final AuthRepository authRepository; + private final AccountRepository accountRepository; private final PasswordEncoder passwordEncoder; private final JwtTokenProvider jwtTokenProvider; private final TokenRepository tokenRepository; @@ -29,7 +29,7 @@ public LoginSuccessResponse login(@Validated final LoginRequest request) { } private Account getUserByLoginId(final String loginId) { - final Account user = authRepository.findUserByLoginId(loginId) + final Account user = accountRepository.findUserByLoginId(loginId) .orElseThrow(() -> new BusinessException(ErrorCode.NULL_USER)); if(user.isDeleted()) @@ -84,6 +84,6 @@ public LoginSuccessResponse logout(@Validated final LoginUserRequest loginUserRe } private Account getUserById(final Long userId) { - return authRepository.findById(userId).orElseThrow(() -> new BusinessException(ErrorCode.NULL_USER)); + return accountRepository.findById(userId).orElseThrow(() -> new BusinessException(ErrorCode.NULL_USER)); } } \ No newline at end of file diff --git a/src/main/java/com/example/api/domain/Account.java b/src/main/java/com/example/api/domain/Account.java index 2bd87a09..798deefd 100644 --- a/src/main/java/com/example/api/domain/Account.java +++ b/src/main/java/com/example/api/domain/Account.java @@ -6,6 +6,8 @@ import com.example.api.board.dto.update.UpdateOpenStatusRequest; import com.example.api.board.dto.update.UpdateUserInfoRequest; import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -22,7 +24,6 @@ public class Account extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ACCOUNT_UNIQUE_ID") private Long accountId; - @Column(name = "ACCOUNT_ID") private String loginId; @Column(name = "ACCOUNT_PASSWORD") @@ -83,6 +84,15 @@ public Account(String loginId, String password, String name, String nickname, St this.emailReceivable = emailReceivable; } + public Account(String loginId, String password, String email, String phoneNumber, Nationality nationality, Collection roles) { + this.loginId = loginId; + this.password = password; + this.email = email; + this.phoneNumber = phoneNumber; + this.nationality = nationality; + this.roles = roles; + } + public LoginUserRequest getLoginUser(){ return new LoginUserRequest(accountId); } diff --git a/src/main/java/com/example/api/oauth2/service/CustomOauth2UserService.java b/src/main/java/com/example/api/oauth2/service/CustomOauth2UserService.java index 4702091e..08b2c24c 100644 --- a/src/main/java/com/example/api/oauth2/service/CustomOauth2UserService.java +++ b/src/main/java/com/example/api/oauth2/service/CustomOauth2UserService.java @@ -30,9 +30,7 @@ public class CustomOauth2UserService extends DefaultOAuth2UserService { @Override @Transactional public OAuth2User loadUser(@Validated final OAuth2UserRequest request) throws OAuth2AuthenticationException { - log.info("OAuth2UserRequest: {}", request.getAdditionalParameters()); OAuth2User oAuth2User = super.loadUser(request); - log.info("OAuth2User : {} ", oAuth2User); String registrationId = request.getClientRegistration().getRegistrationId(); OAuth2Response oAuth2Response = createOAuth2Response(registrationId, oAuth2User); diff --git a/src/test/java/com/example/api/global/BaseIntegrationTest.java b/src/test/java/com/example/api/global/BaseIntegrationTest.java index 8beba30e..36adccaa 100644 --- a/src/test/java/com/example/api/global/BaseIntegrationTest.java +++ b/src/test/java/com/example/api/global/BaseIntegrationTest.java @@ -2,6 +2,11 @@ import com.example.api.board.dto.response.InnerCareerDTO; import com.example.api.board.dto.response.PossibleBoardDTO; +import com.example.api.account.entity.Location; +import com.example.api.board.controller.domain.response.CategoryDTO; +import com.example.api.board.controller.domain.response.ExternalCareerDTO; +import com.example.api.board.controller.domain.response.InnerCareerDTO; +import com.example.api.board.controller.domain.response.PossibleBoardDTO; import com.example.api.business.BusinessRepository; import com.example.api.contracts.ContractRepository; import com.example.api.domain.Account; @@ -102,7 +107,7 @@ void setUpData() { Business business = new Business(); business.setBusinessName("Tech Solutions Inc."); - business.setLocation("Seoul, South Korea"); + business.setLocation(new Location("우편번호", "주소", "상세주소")); business.setRepresentationName("James"); business.setOpenDate(LocalDate.now()); business.setRegistrationNumber("123-456-789"); From 6eeaf547228996c685f6bc9f3866e31b3ab5d39c Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Sat, 4 Jan 2025 15:18:23 +0900 Subject: [PATCH 16/17] =?UTF-8?q?#54=20(AccountServiceTest)=20=EC=82=AC?= =?UTF-8?q?=EC=97=85=EC=9E=90=20=EB=93=B1=EB=A1=9D=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=B0=8F=20=EC=A4=91=EB=B3=B5=20id=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/service/AccountServiceTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/test/java/com/example/api/account/service/AccountServiceTest.java diff --git a/src/test/java/com/example/api/account/service/AccountServiceTest.java b/src/test/java/com/example/api/account/service/AccountServiceTest.java new file mode 100644 index 00000000..61997561 --- /dev/null +++ b/src/test/java/com/example/api/account/service/AccountServiceTest.java @@ -0,0 +1,62 @@ +package com.example.api.account.service; + +import com.example.api.account.dto.BusinessNumberRequest; +import com.example.api.account.dto.SignUpEmployerRequest; +import com.example.api.account.repository.AccountRepository; +import com.example.api.exception.BusinessException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@SpringBootTest +class UserServiceTest { + @MockBean + private AccountRepository accountRepository; + @Autowired + private AccountService accountService; + + @Test + @DisplayName("중복된 ID로 회원가입 시 예외가 발생해야 한다") + void shouldThrowExceptionWhenUserIdAlreadyExists() { + String userId = "existingUser"; + SignUpEmployerRequest mockRequest = mock(SignUpEmployerRequest.class); + when(mockRequest.loginId()).thenReturn(userId); + when(accountRepository.existsByLoginId(userId)).thenReturn(true); + + BusinessException thrown = assertThrows(BusinessException.class, + () -> accountService.signUpEmployer(mockRequest)); + assertEquals("중복된 ID입니다.", thrown.getErrorCode().getErrorDescription()); + } + + @Test + @DisplayName("유효하지 않은 사업자 번호로 검증 요청 시 예외가 발생해야 한다") + void shouldThrowExceptionWhenBusinessNumberIsInvalid() { + BusinessNumberRequest businessNumberRequest = new BusinessNumberRequest( + "1041736263 가짜지롱", + "20231123", + "김태영", + "김태영닷컴"); + + BusinessException thrown = assertThrows(BusinessException.class, + () -> accountService.verifyBusinessNumber(businessNumberRequest)); + assertEquals("사업자 등록 정보를 확인할 수 없습니다.", thrown.getErrorCode().getErrorDescription()); + } + + @Test + @DisplayName("유효한 사업자 번호로 검증 요청 시 성공해야 한다.") + void shouldReturnSuccessWhenValidBusinessNumberIsProvided() { + BusinessNumberRequest businessNumberRequest = new BusinessNumberRequest( + "1041736263", + "김태영닷컴", + "김태영", + "20231123"); + + String isValid = accountService.verifyBusinessNumber(businessNumberRequest); + assertEquals("유효한 사업자 등록 정보입니다.", isValid); + } +} From 0691cd21314b868a0d3d7c3a2e2b15eca628308e Mon Sep 17 00:00:00 2001 From: taeyeongkims Date: Mon, 6 Jan 2025 22:15:57 +0900 Subject: [PATCH 17/17] . --- .../com/example/api/account/repository/AccountRepository.java | 3 +++ src/main/java/com/example/api/domain/Account.java | 2 ++ .../java/com/example/api/global/config/SecurityConfig.java | 2 +- .../entity/handler/OAuth2AuthenticationSuccessHandler.java | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/api/account/repository/AccountRepository.java b/src/main/java/com/example/api/account/repository/AccountRepository.java index 3921f015..37cbb752 100644 --- a/src/main/java/com/example/api/account/repository/AccountRepository.java +++ b/src/main/java/com/example/api/account/repository/AccountRepository.java @@ -1,7 +1,9 @@ package com.example.api.account.repository; import com.example.api.domain.Account; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.util.Optional; @@ -10,6 +12,7 @@ public interface AccountRepository extends JpaRepository { boolean existsByEmail(String email); + @EntityGraph(attributePaths = "roles") Optional findByEmail(String email); Optional findUserByLoginId(String loginId); diff --git a/src/main/java/com/example/api/domain/Account.java b/src/main/java/com/example/api/domain/Account.java index 798deefd..bd9b7bd7 100644 --- a/src/main/java/com/example/api/domain/Account.java +++ b/src/main/java/com/example/api/domain/Account.java @@ -14,6 +14,8 @@ import java.util.Collection; +import static jakarta.persistence.FetchType.*; + @Entity @Getter diff --git a/src/main/java/com/example/api/global/config/SecurityConfig.java b/src/main/java/com/example/api/global/config/SecurityConfig.java index 0d3eabd6..c0f4bcc8 100644 --- a/src/main/java/com/example/api/global/config/SecurityConfig.java +++ b/src/main/java/com/example/api/global/config/SecurityConfig.java @@ -89,7 +89,7 @@ static class FailedAuthenticationEntryPoint implements AuthenticationEntryPoint @Override public void commence(HttpServletRequest request, HttpServletResponse response, - AuthenticationException authException) throws IOException, ServletException { + AuthenticationException authException) throws IOException { response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_FORBIDDEN); diff --git a/src/main/java/com/example/api/oauth2/entity/handler/OAuth2AuthenticationSuccessHandler.java b/src/main/java/com/example/api/oauth2/entity/handler/OAuth2AuthenticationSuccessHandler.java index 21dcd530..68d0ab9a 100644 --- a/src/main/java/com/example/api/oauth2/entity/handler/OAuth2AuthenticationSuccessHandler.java +++ b/src/main/java/com/example/api/oauth2/entity/handler/OAuth2AuthenticationSuccessHandler.java @@ -19,6 +19,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; @@ -34,6 +35,7 @@ import static com.example.api.oauth2.entity.HttpCookieOAuth2AuthorizationRequestRepository.REDIRECT_URI_PARAM_COOKIE_NAME; @Component +@Slf4j @RequiredArgsConstructor public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private final JwtTokenProvider tokenProvider;