From 76916bd5a8926f4b9e4974a2764776a2ab072fd0 Mon Sep 17 00:00:00 2001 From: 1Seob Date: Fri, 12 Jun 2026 17:33:28 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EA=B0=9C=EB=B0=9C=EC=9A=A9=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B3=84=EC=A0=95=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nadab/domain/test/api/TestController.java | 14 +++++ .../dto/request/CreateTestUserRequest.java | 16 +++++ .../dto/response/CreateTestUserResponse.java | 9 +++ .../test/application/TestUserService.java | 62 +++++++++++++++++++ .../nadab/global/core/response/ErrorCode.java | 1 + src/main/resources/application-dev.yml | 6 +- 6 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/request/CreateTestUserRequest.java create mode 100644 src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/response/CreateTestUserResponse.java create mode 100644 src/main/java/com/devkor/ifive/nadab/domain/test/application/TestUserService.java diff --git a/src/main/java/com/devkor/ifive/nadab/domain/test/api/TestController.java b/src/main/java/com/devkor/ifive/nadab/domain/test/api/TestController.java index c7e125ef..5de97689 100644 --- a/src/main/java/com/devkor/ifive/nadab/domain/test/api/TestController.java +++ b/src/main/java/com/devkor/ifive/nadab/domain/test/api/TestController.java @@ -1,11 +1,14 @@ package com.devkor.ifive.nadab.domain.test.api; import com.devkor.ifive.nadab.domain.dailyreport.api.dto.response.DailyReportResponse; +import com.devkor.ifive.nadab.domain.test.api.dto.request.CreateTestUserRequest; import com.devkor.ifive.nadab.domain.test.api.dto.request.PromptTestDailyReportRequest; import com.devkor.ifive.nadab.domain.test.api.dto.request.TestDailyReportRequest; import com.devkor.ifive.nadab.domain.dailyreport.api.dto.response.CreateDailyReportResponse; +import com.devkor.ifive.nadab.domain.test.api.dto.response.CreateTestUserResponse; import com.devkor.ifive.nadab.domain.test.api.dto.response.TestDailyReportResponse; import com.devkor.ifive.nadab.domain.test.application.TestReportService; +import com.devkor.ifive.nadab.domain.test.application.TestUserService; import com.devkor.ifive.nadab.global.core.response.ApiResponseDto; import com.devkor.ifive.nadab.global.core.response.ApiResponseEntity; import com.devkor.ifive.nadab.global.security.principal.UserPrincipal; @@ -33,6 +36,17 @@ public class TestController { private final TestReportService testReportService; + private final TestUserService testUserService; + + @Hidden + @PostMapping("/users") + @PermitAll + public ResponseEntity> createTestUser( + @Valid @RequestBody CreateTestUserRequest request + ) { + CreateTestUserResponse response = testUserService.createTestUser(request); + return ApiResponseEntity.ok(response); + } @PostMapping("/generate/daily-report") @PermitAll diff --git a/src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/request/CreateTestUserRequest.java b/src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/request/CreateTestUserRequest.java new file mode 100644 index 00000000..1cbed82e --- /dev/null +++ b/src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/request/CreateTestUserRequest.java @@ -0,0 +1,16 @@ +package com.devkor.ifive.nadab.domain.test.api.dto.request; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public record CreateTestUserRequest( + @NotBlank(message = "email is required") + @Email(message = "email format is invalid") + String email, + + @NotBlank(message = "nickname is required") + @Size(min = 2, max = 10, message = "nickname must be between 2 and 10 characters") + String nickname +) { +} diff --git a/src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/response/CreateTestUserResponse.java b/src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/response/CreateTestUserResponse.java new file mode 100644 index 00000000..d5671f61 --- /dev/null +++ b/src/main/java/com/devkor/ifive/nadab/domain/test/api/dto/response/CreateTestUserResponse.java @@ -0,0 +1,9 @@ +package com.devkor.ifive.nadab.domain.test.api.dto.response; + +public record CreateTestUserResponse( + Long userId, + String email, + String nickname, + String signupStatus +) { +} diff --git a/src/main/java/com/devkor/ifive/nadab/domain/test/application/TestUserService.java b/src/main/java/com/devkor/ifive/nadab/domain/test/application/TestUserService.java new file mode 100644 index 00000000..1a7e39b9 --- /dev/null +++ b/src/main/java/com/devkor/ifive/nadab/domain/test/application/TestUserService.java @@ -0,0 +1,62 @@ +package com.devkor.ifive.nadab.domain.test.application; + +import com.devkor.ifive.nadab.domain.terms.application.TermsCommandService; +import com.devkor.ifive.nadab.domain.test.api.dto.request.CreateTestUserRequest; +import com.devkor.ifive.nadab.domain.test.api.dto.response.CreateTestUserResponse; +import com.devkor.ifive.nadab.domain.user.core.entity.SignupStatusType; +import com.devkor.ifive.nadab.domain.user.core.entity.User; +import com.devkor.ifive.nadab.domain.user.core.repository.UserRepository; +import com.devkor.ifive.nadab.domain.user.core.service.UserProfileUpdateService; +import com.devkor.ifive.nadab.domain.wallet.core.entity.UserWallet; +import com.devkor.ifive.nadab.domain.wallet.core.repository.UserWalletRepository; +import com.devkor.ifive.nadab.global.core.response.ErrorCode; +import com.devkor.ifive.nadab.global.exception.BadRequestException; +import com.devkor.ifive.nadab.global.exception.ConflictException; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Profile; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Profile({"local", "dev"}) +@Service +@Transactional +@RequiredArgsConstructor +public class TestUserService { + + private final UserRepository userRepository; + private final UserWalletRepository userWalletRepository; + private final UserProfileUpdateService userProfileUpdateService; + private final TermsCommandService termsCommandService; + private final PasswordEncoder passwordEncoder; + + @Value("${test.account.password:}") + private String testUserPassword; + + public CreateTestUserResponse createTestUser(CreateTestUserRequest request) { + if (testUserPassword == null || testUserPassword.isBlank()) { + throw new BadRequestException(ErrorCode.TEST_USER_PASSWORD_NOT_CONFIGURED); + } + if (userRepository.existsByEmail(request.email())) { + throw new ConflictException(ErrorCode.EMAIL_ALREADY_EXISTS); + } + + String passwordHash = passwordEncoder.encode(testUserPassword); + User user = User.createUser(request.email(), passwordHash); + userRepository.save(user); + + userProfileUpdateService.updateNickname(user, request.nickname()); + user.updateSignupStatus(SignupStatusType.COMPLETED); + + userWalletRepository.save(UserWallet.create(user)); + termsCommandService.saveConsents(user.getId(), true, true, true, false); + + return new CreateTestUserResponse( + user.getId(), + user.getEmail(), + user.getNickname(), + user.getSignupStatus().name() + ); + } +} diff --git a/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java b/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java index c8b4595e..398ee556 100644 --- a/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java +++ b/src/main/java/com/devkor/ifive/nadab/global/core/response/ErrorCode.java @@ -14,6 +14,7 @@ public enum ErrorCode { USER_NOT_FOUND(HttpStatus.NOT_FOUND, "사용자를 찾을 수 없습니다"), EMAIL_ALREADY_EXISTS(HttpStatus.CONFLICT, "이미 사용 중인 이메일입니다"), FILE_STORAGE_NOT_FOUND(HttpStatus.NOT_FOUND, "스토리지에서 해당 파일을 찾을 수 없습니다"), // S3 등 스토리지에 실제 파일 객체가 없는 경우 + TEST_USER_PASSWORD_NOT_CONFIGURED(HttpStatus.BAD_REQUEST, "테스트 계정 비밀번호가 설정되지 않았습니다"), // ==================== AUTH (인증) ==================== // 400 Bad Request diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index e89709a2..3a62b47a 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -48,6 +48,10 @@ profile-image: env: dev base-url: ${PROFILE_IMAGE_BASE_URL} +test: + account: + password: ${DEV_TEST_ACCOUNT_PASSWORD:} + app: cookie: secure: true @@ -60,4 +64,4 @@ cors: - ${FRONTEND_DEV_URL} - ${FRONTEND_DEV_URL_2} - ${SWAGGER_ORIGIN_PUBLIC_IP} - - ${SWAGGER_ORIGIN_DOMAIN} \ No newline at end of file + - ${SWAGGER_ORIGIN_DOMAIN} From f19ef222df7ae2e8de4e405c9ec55c0662de605c Mon Sep 17 00:00:00 2001 From: 1Seob Date: Fri, 12 Jun 2026 17:39:21 +0900 Subject: [PATCH 2/2] =?UTF-8?q?ci(infra):=20dev=20=EB=B0=B0=ED=8F=AC=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EB=B3=80=EC=88=98=EC=97=90=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EA=B3=84=EC=A0=95=20=EB=B9=84=EB=B0=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-to-dev-ec2.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-to-dev-ec2.yml b/.github/workflows/deploy-to-dev-ec2.yml index f7975e20..c91c5710 100644 --- a/.github/workflows/deploy-to-dev-ec2.yml +++ b/.github/workflows/deploy-to-dev-ec2.yml @@ -148,6 +148,7 @@ jobs: GOOGLE_GENAI_API_KEY="${{ secrets.GOOGLE_GENAI_API_KEY }}" \ FIREBASE_ADMIN_KEY="${{ secrets.FIREBASE_ADMIN_KEY }}" \ ADMIN_PAGE_PASSWORD="${{ secrets.ADMIN_PAGE_PASSWORD }}" \ + DEV_TEST_ACCOUNT_PASSWORD="${{ secrets.DEV_TEST_ACCOUNT_PASSWORD }}" \ nohup java -jar "$JAR_PATH" \ --spring.profiles.active=dev > app.log 2>&1 &