diff --git a/CLAUDE.md b/CLAUDE.md index 88bedfb8..92e2d552 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,10 +19,10 @@ Kokomen (꼬꼬면) is an AI-powered mock interview platform for developers. The ./gradlew test # Run single test class -./gradlew test --tests "com.samhap.kokomen.interview.service.InterviewServiceTest" +./gradlew test --tests "com.samhap.kokomen.interview.service.core.InterviewServiceTest" # Run single test method -./gradlew test --tests "com.samhap.kokomen.interview.service.InterviewServiceTest.메소드명" +./gradlew test --tests "com.samhap.kokomen.interview.service.core.InterviewServiceTest.메소드명" # Start test infrastructure (MySQL + Redis) docker compose -f test.yml up -d @@ -33,59 +33,73 @@ docker compose -f test.yml up -d ## Architecture -### Project Structure -``` -kokomen-backend/ -├── src/main/java/com/samhap/kokomen/ -│ ├── admin/ -│ ├── answer/ -│ ├── auth/ -│ ├── category/ -│ ├── global/ -│ ├── interview/ -│ ├── member/ -│ ├── product/ -│ ├── recruit/ -│ ├── resume/ -│ └── token/ -├── src/main/resources/ -│ ├── db/migration/ # Flyway migrations -│ ├── application.yml # Common config -│ └── application-{profile}.yml -├── src/test/ -├── src/docs/asciidoc/ # REST Docs -├── docker/ # Deployment configs -└── build.gradle -``` - ### Key Technologies - Java 17, Spring Boot 3.x -- MySQL 8.0 (Primary DB), Redis/Valkey (Session & Cache) +- MySQL 8.0 (Primary DB), Redis/Valkey (Session & Cache, Redisson for distributed locks) - OpenAI GPT-4 / AWS Bedrock for AI features - Supertone for TTS (voice mode) - Kakao/Google OAuth for authentication - Flyway for DB migrations (`src/main/resources/db/migration/`) +- Spring REST Docs for API documentation +- Micrometer + Prometheus for metrics (management port: 8081) -### Domain Package Structure +### Domain Packages +``` +src/main/java/com/samhap/kokomen/ +├── admin/ # Admin operations (root question voice management) +├── answer/ # Interview answers, likes, memos +├── auth/ # OAuth login (Kakao, Google) +├── category/ # Interview categories +├── global/ # Cross-cutting concerns (AOP, config, exceptions, fixtures) +├── interview/ # Core interview domain (start, proceed, questions, resume-based) +├── member/ # User profiles and scores +├── payment/ # Tosspayments integration (payments, webhooks, refunds) +├── product/ # Purchasable products +├── recruit/ # Job recruitment listings +├── resume/ # Resume/portfolio upload and AI evaluation +└── token/ # Interview tokens (purchase, consumption) +``` + +### Domain Package Convention ``` {domain}/ ├── controller/ ├── service/ -│ └── dto/ # Request/Response DTOs +│ └── dto/ # Request/Response DTOs (suffixed with Request or Response) ├── repository/ -│ └── dto/ # Query projections -├── entity/ # JPA entities -├── domain/ # Domain logic & enums -├── tool/ # Utility classes -└── external/ # External API clients +│ └── dto/ # Query projections +├── entity/ # JPA entities +├── domain/ # Domain logic & enums +├── tool/ # Utility classes +└── external/ # External API clients ``` +### Interview Service Sub-Packages +The interview domain uses sub-packages to organize its service layer. Facade services and InterviewQueryService remain at the root for controller access: +``` +interview/service/ +├── InterviewStartFacadeService # Orchestrates interview start flow +├── InterviewProceedFacadeService # Orchestrates answer submission flow +├── InterviewQueryService # Read-only query delegation for controllers +├── core/ # InterviewService, InterviewProceedService +├── question/ # QuestionService, RootQuestionService, QuestionGeneration* +├── resume/ # ResumeBasedInterviewService, ResumeContentService +├── social/ # InterviewLikeService, InterviewViewCountService +├── infra/ # InterviewSchedulerService, InterviewProceedBedrockFlowAsyncService +└── dto/ +``` + +### Cross-Cutting Patterns +- **Facade pattern**: Domains with complex orchestration use `*FacadeService` classes. Other domains should depend on facade services, not internal services directly. +- **Custom annotations**: `@DistributedLock` (Redis-based), `@ExecutionTimer`, `@RedisExceptionWrapper` +- **Base entity**: `BaseEntity` with `@CreatedDate createdAt` + ## Code Conventions (from docs/convention.md) ### Style Guide - Follows Woowacourse Java Style Guide (based on Google Java Style) -- Line limit: 160 characters -- Indent: 4 spaces +- Column limit: **120 characters** +- Indent: 4 spaces, continuation indent: +8 spaces minimum ### Naming - Methods: `행위 + 도메인` (e.g., `saveMember()`) @@ -108,38 +122,33 @@ public void example() {} 3. Business methods (CRUD order, private methods after their calling public method) 4. Override methods (equals, hashCode, toString) -### Testing -- Test method names in **Korean** -- No `@DisplayName` annotation -- Controller tests: MockMvc + real beans (integration test, generates RestDocs) -- Service tests: integration with repository -- Domain tests: unit tests -- Test isolation: `MySQLDatabaseCleaner` (not `@Transactional`) -- Fixtures: `global/fixture/XxxFixtureBuilder` classes -- Tests use real MySQL container (not H2) - ### Exception Handling - Custom exceptions: `BadRequestException`, `UnauthorizedException`, `ForbiddenException`, etc. - Validation: `@Valid` in DTO, entity-level validation in constructors - Business validation that needs external data goes in service layer -## Test Infrastructure +## Testing + +### Test Conventions +- Test method names in **Korean** +- No `@DisplayName` annotation +- Controller tests: MockMvc + real beans (integration test, generates RestDocs) +- Service tests: integration with repository +- Domain tests: unit tests +- Test isolation: `MySQLDatabaseCleaner` truncates all tables (not `@Transactional`) +- Fixtures: `global/fixture/{domain}/XxxFixtureBuilder` — static `builder()`, fluent setters, sensible defaults +### Test Infrastructure Tests require MySQL and Redis containers: - MySQL: port 13306 (database: kokomen-test, password: root) - Redis: port 16379 Start with: `docker compose -f test.yml up -d` -Test base classes: -- `BaseTest`: `@SpringBootTest` with mock beans for external services (GPT, S3, etc.) -- `BaseControllerTest`: Extends BaseTest, adds MockMvc with RestDocs configuration - -## API Documentation - -- Generated via Spring REST Docs -- Build generates docs into `build/docs/` -- Access at: `http://localhost:8080/docs/index.html` +### Test Base Classes +- **`BaseTest`**: `@SpringBootTest` with `@ActiveProfiles("test")`, mocks external services (GPT, S3, Supertone, Tosspayments, OAuth clients, Bedrock), spies on Redis. Uses real MySQL container + `MySQLDatabaseCleaner`. +- **`BaseControllerTest`**: Extends BaseTest, adds MockMvc with RestDocs configuration. +- **`DocsTest`**: `@ActiveProfiles("docs")`, uses H2 in-memory DB with `@Transactional`. For lightweight REST Docs generation without Docker. ## Environment Variables @@ -158,7 +167,5 @@ SUPERTONE_API_TOKEN - `dev`: Development server - `prod`: Production - `load-test`: Load testing -- `test`: Test environment (used by tests) - -# currentDate -Today's date is 2026-02-24. +- `test`: Test environment (real MySQL + Redis containers) +- `docs`: REST Docs generation (H2 in-memory, no Docker needed) diff --git a/src/main/java/com/samhap/kokomen/admin/service/AdminService.java b/src/main/java/com/samhap/kokomen/admin/service/AdminService.java index c2e3d736..c520a4a8 100644 --- a/src/main/java/com/samhap/kokomen/admin/service/AdminService.java +++ b/src/main/java/com/samhap/kokomen/admin/service/AdminService.java @@ -2,9 +2,9 @@ import com.samhap.kokomen.admin.service.dto.RootQuestionVoiceResponse; import com.samhap.kokomen.global.exception.BadRequestException; -import com.samhap.kokomen.interview.entity.RootQuestion; -import com.samhap.kokomen.interview.entity.RootQuestionState; -import com.samhap.kokomen.interview.service.RootQuestionService; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestionState; +import com.samhap.kokomen.interview.service.question.RootQuestionService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -30,7 +30,8 @@ public RootQuestionVoiceResponse uploadRootQuestionVoiceWithApiKey(Long rootQues if (rootQuestionService.isRootQuestionVoiceExists(rootQuestionId)) { throw new BadRequestException("이미 S3에 올라가있는 음성파일입니다. rootQuestionId = " + rootQuestionId); } - String rootQuestionVoiceCdnUrl = rootQuestionService.createAndUploadRootQuestionVoiceWithApiKey(rootQuestionId, oneTimeApiKey); + String rootQuestionVoiceCdnUrl = rootQuestionService.createAndUploadRootQuestionVoiceWithApiKey(rootQuestionId, + oneTimeApiKey); return new RootQuestionVoiceResponse(rootQuestionVoiceCdnUrl); } } diff --git a/src/main/java/com/samhap/kokomen/answer/domain/Answer.java b/src/main/java/com/samhap/kokomen/answer/domain/Answer.java index c791c9d6..6a117f38 100644 --- a/src/main/java/com/samhap/kokomen/answer/domain/Answer.java +++ b/src/main/java/com/samhap/kokomen/answer/domain/Answer.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.answer.domain; import com.samhap.kokomen.global.domain.BaseEntity; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Question; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/src/main/java/com/samhap/kokomen/answer/repository/AnswerMemoRepository.java b/src/main/java/com/samhap/kokomen/answer/repository/AnswerMemoRepository.java index 1f6edf32..1428d4eb 100644 --- a/src/main/java/com/samhap/kokomen/answer/repository/AnswerMemoRepository.java +++ b/src/main/java/com/samhap/kokomen/answer/repository/AnswerMemoRepository.java @@ -4,7 +4,7 @@ import com.samhap.kokomen.answer.domain.AnswerMemo; import com.samhap.kokomen.answer.domain.AnswerMemoState; import com.samhap.kokomen.answer.domain.AnswerMemoVisibility; -import com.samhap.kokomen.interview.entity.Interview; +import com.samhap.kokomen.interview.domain.Interview; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/samhap/kokomen/answer/repository/AnswerRepository.java b/src/main/java/com/samhap/kokomen/answer/repository/AnswerRepository.java index 340bdf65..4a66d22e 100644 --- a/src/main/java/com/samhap/kokomen/answer/repository/AnswerRepository.java +++ b/src/main/java/com/samhap/kokomen/answer/repository/AnswerRepository.java @@ -2,7 +2,7 @@ import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Question; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/samhap/kokomen/answer/service/AnswerService.java b/src/main/java/com/samhap/kokomen/answer/service/AnswerService.java index cf2026f5..04d75876 100644 --- a/src/main/java/com/samhap/kokomen/answer/service/AnswerService.java +++ b/src/main/java/com/samhap/kokomen/answer/service/AnswerService.java @@ -4,7 +4,7 @@ import com.samhap.kokomen.answer.repository.AnswerRepository; import com.samhap.kokomen.global.exception.BadRequestException; import com.samhap.kokomen.global.exception.NotFoundException; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Question; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/samhap/kokomen/global/TestDataInitializer.java b/src/main/java/com/samhap/kokomen/global/TestDataInitializer.java index 5a07f12f..9cbe2a22 100644 --- a/src/main/java/com/samhap/kokomen/global/TestDataInitializer.java +++ b/src/main/java/com/samhap/kokomen/global/TestDataInitializer.java @@ -4,10 +4,10 @@ import com.samhap.kokomen.answer.domain.AnswerRank; import com.samhap.kokomen.answer.repository.AnswerRepository; import com.samhap.kokomen.category.domain.Category; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; diff --git a/src/main/java/com/samhap/kokomen/global/aop/RootQuestionMetricAspect.java b/src/main/java/com/samhap/kokomen/global/aop/RootQuestionMetricAspect.java index c97598f9..75aa7b5a 100644 --- a/src/main/java/com/samhap/kokomen/global/aop/RootQuestionMetricAspect.java +++ b/src/main/java/com/samhap/kokomen/global/aop/RootQuestionMetricAspect.java @@ -3,17 +3,15 @@ import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; import com.samhap.kokomen.answer.service.AnswerService; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.domain.QuestionAndAnswers; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.tool.QuestionAndAnswers; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; -import com.samhap.kokomen.interview.service.InterviewService; -import com.samhap.kokomen.interview.service.dto.InterviewProceedResponse; +import com.samhap.kokomen.interview.service.core.InterviewService; import com.samhap.kokomen.interview.service.dto.start.InterviewStartResponse; import io.micrometer.core.instrument.MeterRegistry; import java.util.Objects; -import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.annotation.AfterReturning; @@ -35,7 +33,7 @@ public class RootQuestionMetricAspect { private final InterviewRepository interviewRepository; private final QuestionRepository questionRepository; - @Pointcut("execution(* com.samhap.kokomen.interview.service.InterviewFacadeService.startInterview(..))") + @Pointcut("execution(* com.samhap.kokomen.interview.service.InterviewStartFacadeService.startInterview(..))") public void startInterviewMethod() { } @@ -50,39 +48,7 @@ public void increaseRootQuestionInterviewCount(InterviewStartResponse result) { ).increment(); } - @Pointcut("execution(* com.samhap.kokomen.interview.service.InterviewFacadeService.proceedInterview(..)) && args(interviewId, curQuestionId, ..)") - public void proceedInterviewPointcut(Long interviewId, Long curQuestionId) { - } - - @AfterReturning(pointcut = "proceedInterviewPointcut(interviewId, curQuestionId)", returning = "result") - public void increaseRootQuestionInterviewEndCount(Optional result, Long interviewId, - Long curQuestionId) { - boolean isInterviewEnded = result.isEmpty(); - if (isInterviewEnded) { - Long rootQuestionId = interviewRepository.findRootQuestionIdByInterviewId(interviewId); - meterRegistry.counter( - "root_question_interview_end_count_total", - "root_question_id", String.valueOf(rootQuestionId) - ).increment(); - } - } - - @AfterReturning(pointcut = "proceedInterviewPointcut(interviewId, curQuestionId)", returning = "result") - public void increaseRootQuestionAnswerRankCount(Optional result, Long interviewId, - Long curQuestionId) { - Long firstQuestionId = questionRepository.findFirstQuestionIdByInterviewIdOrderByIdAsc(interviewId); - boolean isRootQuestionAnswer = Objects.equals(curQuestionId, firstQuestionId); - if (isRootQuestionAnswer) { - AnswerRank answerRank = result.get().curAnswerRank(); - Long rootQuestionId = interviewRepository.findRootQuestionIdByInterviewId(interviewId); - meterRegistry.counter( - "root_question_answer_rank_count_" + answerRank.name().toLowerCase(), - "root_question_id", String.valueOf(rootQuestionId) - ).increment(); - } - } - - @Pointcut("execution(* com.samhap.kokomen.interview.service.InterviewProceedBedrockFlowAsyncService.proceedInterviewByBedrockFlowAsync(..)) && args(memberId, questionAndAnswers, interviewId)") + @Pointcut("execution(* com.samhap.kokomen.interview.service.infra.InterviewProceedBedrockFlowAsyncService.proceedInterviewByBedrockFlowAsync(..)) && args(memberId, questionAndAnswers, interviewId)") public void asyncProceedInterviewPointcut(Long memberId, QuestionAndAnswers questionAndAnswers, Long interviewId) { } diff --git a/src/main/java/com/samhap/kokomen/interview/controller/InterviewController.java b/src/main/java/com/samhap/kokomen/interview/controller/InterviewController.java index ad939550..db438a8b 100644 --- a/src/main/java/com/samhap/kokomen/interview/controller/InterviewController.java +++ b/src/main/java/com/samhap/kokomen/interview/controller/InterviewController.java @@ -3,10 +3,11 @@ import com.samhap.kokomen.global.annotation.Authentication; import com.samhap.kokomen.global.dto.ClientIp; import com.samhap.kokomen.global.dto.MemberAuth; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.InterviewState; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewState; import com.samhap.kokomen.interview.external.dto.response.InterviewSummaryResponses; -import com.samhap.kokomen.interview.service.InterviewFacadeService; +import com.samhap.kokomen.interview.service.InterviewQueryService; +import com.samhap.kokomen.interview.service.InterviewStartFacadeService; import com.samhap.kokomen.interview.service.dto.InterviewRequest; import com.samhap.kokomen.interview.service.dto.InterviewResultResponse; import com.samhap.kokomen.interview.service.dto.InterviewSummaryResponse; @@ -34,14 +35,15 @@ @RestController public class InterviewController { - private final InterviewFacadeService interviewFacadeService; + private final InterviewStartFacadeService interviewStartFacadeService; + private final InterviewQueryService interviewQueryService; @PostMapping public ResponseEntity startInterview( @RequestBody @Valid InterviewRequest interviewRequest, @Authentication MemberAuth memberAuth ) { - return ResponseEntity.ok(interviewFacadeService.startInterview(interviewRequest, memberAuth)); + return ResponseEntity.ok(interviewStartFacadeService.startInterview(interviewRequest, memberAuth)); } @PostMapping("/{interviewId}/like") @@ -49,7 +51,7 @@ public ResponseEntity likeInterview( @PathVariable Long interviewId, @Authentication MemberAuth memberAuth ) { - interviewFacadeService.likeInterview(interviewId, memberAuth); + interviewQueryService.likeInterview(interviewId, memberAuth); return ResponseEntity.noContent().build(); } @@ -59,7 +61,7 @@ public ResponseEntity checkInterview( @RequestParam InterviewMode mode, @Authentication MemberAuth memberAuth ) { - return ResponseEntity.ok(interviewFacadeService.checkInterview(interviewId, mode, memberAuth)); + return ResponseEntity.ok(interviewQueryService.checkInterview(interviewId, mode, memberAuth)); } @GetMapping("/me") @@ -68,7 +70,7 @@ public ResponseEntity> findMyInterviews( @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable, @Authentication MemberAuth memberAuth ) { - return ResponseEntity.ok(interviewFacadeService.findMyInterviews(memberAuth, state, pageable)); + return ResponseEntity.ok(interviewQueryService.findMyInterviews(memberAuth, state, pageable)); } @GetMapping @@ -77,7 +79,7 @@ public ResponseEntity findOtherMemberInterviews( @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable, @Authentication(required = false) MemberAuth memberAuth ) { - return ResponseEntity.ok(interviewFacadeService.findOtherMemberInterviews(memberId, memberAuth, pageable)); + return ResponseEntity.ok(interviewQueryService.findOtherMemberInterviews(memberId, memberAuth, pageable)); } @GetMapping("/{interviewId}/my-result") @@ -85,7 +87,7 @@ public ResponseEntity findMyInterviewResult( @PathVariable Long interviewId, @Authentication MemberAuth memberAuth ) { - return ResponseEntity.ok(interviewFacadeService.findMyInterviewResult(interviewId, memberAuth)); + return ResponseEntity.ok(interviewQueryService.findMyInterviewResult(interviewId, memberAuth)); } @GetMapping("/{interviewId}/result") @@ -95,7 +97,7 @@ public ResponseEntity findOtherMemberInterviewResult( ClientIp clientIp ) { return ResponseEntity.ok( - interviewFacadeService.findOtherMemberInterviewResult(interviewId, memberAuth, clientIp)); + interviewQueryService.findOtherMemberInterviewResult(interviewId, memberAuth, clientIp)); } @DeleteMapping("/{interviewId}/like") @@ -103,7 +105,7 @@ public ResponseEntity unlikeInterview( @PathVariable Long interviewId, @Authentication MemberAuth memberAuth ) { - interviewFacadeService.unlikeInterview(interviewId, memberAuth); + interviewQueryService.unlikeInterview(interviewId, memberAuth); return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV2.java b/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV2.java index b0b55579..ba31f099 100644 --- a/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV2.java +++ b/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV2.java @@ -2,8 +2,8 @@ import com.samhap.kokomen.global.annotation.Authentication; import com.samhap.kokomen.global.dto.MemberAuth; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.service.InterviewFacadeService; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.service.InterviewProceedFacadeService; import com.samhap.kokomen.interview.service.dto.AnswerRequestV2; import com.samhap.kokomen.interview.service.dto.proceedstate.InterviewProceedStateResponse; import jakarta.validation.Valid; @@ -22,7 +22,7 @@ @RestController public class InterviewControllerV2 { - private final InterviewFacadeService interviewFacadeService; + private final InterviewProceedFacadeService interviewProceedFacadeService; @PostMapping("/{interviewId}/questions/{curQuestionId}/answers") public ResponseEntity proceedInterviewBlockAsync( @@ -31,7 +31,7 @@ public ResponseEntity proceedInterviewBlockAsync( @RequestBody @Valid AnswerRequestV2 answerRequest, @Authentication MemberAuth memberAuth ) { - interviewFacadeService.proceedInterviewByBedrockFlow(interviewId, curQuestionId, answerRequest, memberAuth); + interviewProceedFacadeService.proceedInterviewByBedrockFlow(interviewId, curQuestionId, answerRequest, memberAuth); return ResponseEntity.noContent().build(); } @@ -42,6 +42,6 @@ public ResponseEntity findInterviewProceedState( @RequestParam InterviewMode mode, @Authentication MemberAuth memberAuth ) { - return ResponseEntity.ok(interviewFacadeService.findInterviewProceedState(interviewId, curQuestionId, mode, memberAuth)); + return ResponseEntity.ok(interviewProceedFacadeService.findInterviewProceedState(interviewId, curQuestionId, mode, memberAuth)); } } diff --git a/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV3.java b/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV3.java index 88b971a2..0bc633d3 100644 --- a/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV3.java +++ b/src/main/java/com/samhap/kokomen/interview/controller/InterviewControllerV3.java @@ -3,7 +3,8 @@ import com.samhap.kokomen.category.domain.Category; import com.samhap.kokomen.global.annotation.Authentication; import com.samhap.kokomen.global.dto.MemberAuth; -import com.samhap.kokomen.interview.service.InterviewFacadeService; +import com.samhap.kokomen.interview.service.InterviewQueryService; +import com.samhap.kokomen.interview.service.InterviewStartFacadeService; import com.samhap.kokomen.interview.service.dto.RootQuestionCustomInterviewRequest; import com.samhap.kokomen.interview.service.dto.RootQuestionResponse; import com.samhap.kokomen.interview.service.dto.start.InterviewStartResponse; @@ -24,13 +25,14 @@ @RestController public class InterviewControllerV3 { - private final InterviewFacadeService interviewFacadeService; + private final InterviewStartFacadeService interviewStartFacadeService; + private final InterviewQueryService interviewQueryService; @GetMapping("/questions") public ResponseEntity> getRootQuestions( @RequestParam(name = "category") Category category ) { - return ResponseEntity.ok(interviewFacadeService.getRootQuestionsByCategory(category)); + return ResponseEntity.ok(interviewQueryService.getRootQuestionsByCategory(category)); } @PostMapping("/custom") @@ -39,6 +41,6 @@ public ResponseEntity createCustomInterview( @Authentication MemberAuth memberAuth ) { return ResponseEntity.status(HttpStatus.CREATED) - .body(interviewFacadeService.startRootQuestionCustomInterview(request, memberAuth)); + .body(interviewStartFacadeService.startRootQuestionCustomInterview(request, memberAuth)); } } diff --git a/src/main/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewController.java b/src/main/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewController.java index 5fafdcbc..2d29cb0c 100644 --- a/src/main/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewController.java +++ b/src/main/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewController.java @@ -3,9 +3,9 @@ import com.samhap.kokomen.global.annotation.Authentication; import com.samhap.kokomen.global.dto.MemberAuth; import com.samhap.kokomen.global.exception.BadRequestException; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; -import com.samhap.kokomen.interview.service.InterviewFacadeService; -import com.samhap.kokomen.interview.service.ResumeBasedInterviewService; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.service.InterviewStartFacadeService; +import com.samhap.kokomen.interview.service.resume.ResumeBasedInterviewService; import com.samhap.kokomen.interview.service.dto.resumebased.GeneratedQuestionsResponse; import com.samhap.kokomen.interview.service.dto.resumebased.QuestionGenerationStateResponse; import com.samhap.kokomen.interview.service.dto.resumebased.QuestionGenerationSubmitResponse; @@ -38,7 +38,7 @@ public class ResumeBasedInterviewController { private final ResumeBasedInterviewService resumeBasedInterviewService; - private final InterviewFacadeService interviewFacadeService; + private final InterviewStartFacadeService interviewStartFacadeService; @PostMapping(value = "/questions/generate", consumes = {"multipart/form-data"}) public ResponseEntity generateQuestions( @@ -129,7 +129,7 @@ public ResponseEntity startResumeBasedInterview( @RequestBody @Valid ResumeBasedInterviewStartRequest request, @Authentication MemberAuth memberAuth ) { - InterviewStartResponse response = interviewFacadeService.startResumeBasedInterview( + InterviewStartResponse response = interviewStartFacadeService.startResumeBasedInterview( resumeBasedInterviewResultId, request, memberAuth diff --git a/src/main/java/com/samhap/kokomen/interview/entity/GeneratedQuestion.java b/src/main/java/com/samhap/kokomen/interview/domain/GeneratedQuestion.java similarity index 97% rename from src/main/java/com/samhap/kokomen/interview/entity/GeneratedQuestion.java rename to src/main/java/com/samhap/kokomen/interview/domain/GeneratedQuestion.java index a330e6b1..20624036 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/GeneratedQuestion.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/GeneratedQuestion.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; import com.samhap.kokomen.global.domain.BaseEntity; import jakarta.persistence.Column; diff --git a/src/main/java/com/samhap/kokomen/interview/entity/Interview.java b/src/main/java/com/samhap/kokomen/interview/domain/Interview.java similarity index 99% rename from src/main/java/com/samhap/kokomen/interview/entity/Interview.java rename to src/main/java/com/samhap/kokomen/interview/domain/Interview.java index 6eacd042..5141c716 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/Interview.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/Interview.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; import com.samhap.kokomen.global.domain.BaseEntity; import com.samhap.kokomen.global.exception.BadRequestException; diff --git a/src/main/java/com/samhap/kokomen/interview/entity/InterviewLike.java b/src/main/java/com/samhap/kokomen/interview/domain/InterviewLike.java similarity index 96% rename from src/main/java/com/samhap/kokomen/interview/entity/InterviewLike.java rename to src/main/java/com/samhap/kokomen/interview/domain/InterviewLike.java index 2bdd4efa..28cb610f 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/InterviewLike.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/InterviewLike.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; import com.samhap.kokomen.global.domain.BaseEntity; import com.samhap.kokomen.member.domain.Member; diff --git a/src/main/java/com/samhap/kokomen/interview/entity/InterviewMode.java b/src/main/java/com/samhap/kokomen/interview/domain/InterviewMode.java similarity index 81% rename from src/main/java/com/samhap/kokomen/interview/entity/InterviewMode.java rename to src/main/java/com/samhap/kokomen/interview/domain/InterviewMode.java index b7adb596..e7e63937 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/InterviewMode.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/InterviewMode.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/samhap/kokomen/interview/entity/InterviewState.java b/src/main/java/com/samhap/kokomen/interview/domain/InterviewState.java similarity index 70% rename from src/main/java/com/samhap/kokomen/interview/entity/InterviewState.java rename to src/main/java/com/samhap/kokomen/interview/domain/InterviewState.java index 127e2fc6..4acb4de8 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/InterviewState.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/InterviewState.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; public enum InterviewState { IN_PROGRESS, // 면접 진행 중 diff --git a/src/main/java/com/samhap/kokomen/interview/entity/InterviewType.java b/src/main/java/com/samhap/kokomen/interview/domain/InterviewType.java similarity index 60% rename from src/main/java/com/samhap/kokomen/interview/entity/InterviewType.java rename to src/main/java/com/samhap/kokomen/interview/domain/InterviewType.java index 3920d1d4..94dcf0e7 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/InterviewType.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/InterviewType.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; public enum InterviewType { CATEGORY_BASED, diff --git a/src/main/java/com/samhap/kokomen/interview/entity/Question.java b/src/main/java/com/samhap/kokomen/interview/domain/Question.java similarity index 95% rename from src/main/java/com/samhap/kokomen/interview/entity/Question.java rename to src/main/java/com/samhap/kokomen/interview/domain/Question.java index dcfeb45d..b6b224c7 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/Question.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/Question.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; import com.samhap.kokomen.global.domain.BaseEntity; import jakarta.persistence.Column; diff --git a/src/main/java/com/samhap/kokomen/interview/entity/ResumeQuestionGeneration.java b/src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGeneration.java similarity index 98% rename from src/main/java/com/samhap/kokomen/interview/entity/ResumeQuestionGeneration.java rename to src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGeneration.java index 6884629e..568c0852 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/ResumeQuestionGeneration.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGeneration.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; import com.samhap.kokomen.global.domain.BaseEntity; import com.samhap.kokomen.member.domain.Member; diff --git a/src/main/java/com/samhap/kokomen/interview/entity/ResumeQuestionGenerationState.java b/src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGenerationState.java similarity index 79% rename from src/main/java/com/samhap/kokomen/interview/entity/ResumeQuestionGenerationState.java rename to src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGenerationState.java index adc3eb66..d30e4cc0 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/ResumeQuestionGenerationState.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/ResumeQuestionGenerationState.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; public enum ResumeQuestionGenerationState { diff --git a/src/main/java/com/samhap/kokomen/interview/entity/RootQuestion.java b/src/main/java/com/samhap/kokomen/interview/domain/RootQuestion.java similarity index 97% rename from src/main/java/com/samhap/kokomen/interview/entity/RootQuestion.java rename to src/main/java/com/samhap/kokomen/interview/domain/RootQuestion.java index 89e6ba61..d3bcee83 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/RootQuestion.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/RootQuestion.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; import com.samhap.kokomen.category.domain.Category; import com.samhap.kokomen.global.domain.BaseEntity; diff --git a/src/main/java/com/samhap/kokomen/interview/entity/RootQuestionState.java b/src/main/java/com/samhap/kokomen/interview/domain/RootQuestionState.java similarity index 59% rename from src/main/java/com/samhap/kokomen/interview/entity/RootQuestionState.java rename to src/main/java/com/samhap/kokomen/interview/domain/RootQuestionState.java index a4fa8303..762b3678 100644 --- a/src/main/java/com/samhap/kokomen/interview/entity/RootQuestionState.java +++ b/src/main/java/com/samhap/kokomen/interview/domain/RootQuestionState.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.entity; +package com.samhap.kokomen.interview.domain; public enum RootQuestionState { ACTIVE, diff --git a/src/main/java/com/samhap/kokomen/interview/external/InterviewProceedGptClient.java b/src/main/java/com/samhap/kokomen/interview/external/InterviewProceedGptClient.java index e393e486..de184495 100644 --- a/src/main/java/com/samhap/kokomen/interview/external/InterviewProceedGptClient.java +++ b/src/main/java/com/samhap/kokomen/interview/external/InterviewProceedGptClient.java @@ -4,8 +4,8 @@ import com.samhap.kokomen.global.annotation.ExecutionTimer; import com.samhap.kokomen.global.exception.ExternalApiException; import com.samhap.kokomen.global.external.BaseGptClient; -import com.samhap.kokomen.interview.domain.InterviewMessagesFactory; -import com.samhap.kokomen.interview.domain.QuestionAndAnswers; +import com.samhap.kokomen.interview.tool.InterviewMessagesFactory; +import com.samhap.kokomen.interview.tool.QuestionAndAnswers; import com.samhap.kokomen.interview.external.dto.request.GptMessage; import com.samhap.kokomen.interview.external.dto.request.GptRequest; import com.samhap.kokomen.interview.external.dto.response.GptResponse; diff --git a/src/main/java/com/samhap/kokomen/interview/external/dto/request/InterviewInvokeFlowRequestFactory.java b/src/main/java/com/samhap/kokomen/interview/external/dto/request/InterviewInvokeFlowRequestFactory.java index f48f74ac..9a799f4b 100644 --- a/src/main/java/com/samhap/kokomen/interview/external/dto/request/InterviewInvokeFlowRequestFactory.java +++ b/src/main/java/com/samhap/kokomen/interview/external/dto/request/InterviewInvokeFlowRequestFactory.java @@ -1,8 +1,8 @@ package com.samhap.kokomen.interview.external.dto.request; import com.samhap.kokomen.answer.domain.AnswerRank; -import com.samhap.kokomen.interview.domain.InterviewMessagesFactory; -import com.samhap.kokomen.interview.domain.QuestionAndAnswers; +import com.samhap.kokomen.interview.tool.InterviewMessagesFactory; +import com.samhap.kokomen.interview.tool.QuestionAndAnswers; import software.amazon.awssdk.core.document.Document; import software.amazon.awssdk.services.bedrockagentruntime.model.FlowInput; import software.amazon.awssdk.services.bedrockagentruntime.model.FlowInputContent; diff --git a/src/main/java/com/samhap/kokomen/interview/external/dto/response/InterviewSummaryResponses.java b/src/main/java/com/samhap/kokomen/interview/external/dto/response/InterviewSummaryResponses.java index 6a5b9333..c1fc811e 100644 --- a/src/main/java/com/samhap/kokomen/interview/external/dto/response/InterviewSummaryResponses.java +++ b/src/main/java/com/samhap/kokomen/interview/external/dto/response/InterviewSummaryResponses.java @@ -1,6 +1,6 @@ package com.samhap.kokomen.interview.external.dto.response; -import com.samhap.kokomen.interview.entity.Interview; +import com.samhap.kokomen.interview.domain.Interview; import com.samhap.kokomen.interview.service.dto.InterviewSummaryResponse; import java.util.List; import java.util.Map; diff --git a/src/main/java/com/samhap/kokomen/interview/repository/GeneratedQuestionRepository.java b/src/main/java/com/samhap/kokomen/interview/repository/GeneratedQuestionRepository.java index b4b2d9c6..53f18e64 100644 --- a/src/main/java/com/samhap/kokomen/interview/repository/GeneratedQuestionRepository.java +++ b/src/main/java/com/samhap/kokomen/interview/repository/GeneratedQuestionRepository.java @@ -1,6 +1,6 @@ package com.samhap.kokomen.interview.repository; -import com.samhap.kokomen.interview.entity.GeneratedQuestion; +import com.samhap.kokomen.interview.domain.GeneratedQuestion; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/samhap/kokomen/interview/repository/InterviewLikeRepository.java b/src/main/java/com/samhap/kokomen/interview/repository/InterviewLikeRepository.java index a533c535..0532928e 100644 --- a/src/main/java/com/samhap/kokomen/interview/repository/InterviewLikeRepository.java +++ b/src/main/java/com/samhap/kokomen/interview/repository/InterviewLikeRepository.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.repository; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewLike; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewLike; import com.samhap.kokomen.member.domain.Member; import java.util.List; import java.util.Set; diff --git a/src/main/java/com/samhap/kokomen/interview/repository/InterviewRepository.java b/src/main/java/com/samhap/kokomen/interview/repository/InterviewRepository.java index 475ffaa1..f7aa72b2 100644 --- a/src/main/java/com/samhap/kokomen/interview/repository/InterviewRepository.java +++ b/src/main/java/com/samhap/kokomen/interview/repository/InterviewRepository.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.repository; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; import com.samhap.kokomen.interview.repository.dto.DailyInterviewCount; import com.samhap.kokomen.member.domain.Member; import java.util.List; diff --git a/src/main/java/com/samhap/kokomen/interview/repository/QuestionRepository.java b/src/main/java/com/samhap/kokomen/interview/repository/QuestionRepository.java index 3e261637..4e560e2e 100644 --- a/src/main/java/com/samhap/kokomen/interview/repository/QuestionRepository.java +++ b/src/main/java/com/samhap/kokomen/interview/repository/QuestionRepository.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.repository; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/com/samhap/kokomen/interview/repository/ResumeQuestionGenerationRepository.java b/src/main/java/com/samhap/kokomen/interview/repository/ResumeQuestionGenerationRepository.java index 3461d432..4c2f4824 100644 --- a/src/main/java/com/samhap/kokomen/interview/repository/ResumeQuestionGenerationRepository.java +++ b/src/main/java/com/samhap/kokomen/interview/repository/ResumeQuestionGenerationRepository.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.repository; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/samhap/kokomen/interview/repository/RootQuestionRepository.java b/src/main/java/com/samhap/kokomen/interview/repository/RootQuestionRepository.java index c45ee5fa..a48c038f 100644 --- a/src/main/java/com/samhap/kokomen/interview/repository/RootQuestionRepository.java +++ b/src/main/java/com/samhap/kokomen/interview/repository/RootQuestionRepository.java @@ -1,8 +1,8 @@ package com.samhap.kokomen.interview.repository; import com.samhap.kokomen.category.domain.Category; -import com.samhap.kokomen.interview.entity.RootQuestion; -import com.samhap.kokomen.interview.entity.RootQuestionState; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestionState; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewFacadeService.java b/src/main/java/com/samhap/kokomen/interview/service/InterviewFacadeService.java deleted file mode 100644 index 609efb51..00000000 --- a/src/main/java/com/samhap/kokomen/interview/service/InterviewFacadeService.java +++ /dev/null @@ -1,317 +0,0 @@ -package com.samhap.kokomen.interview.service; - -import com.samhap.kokomen.answer.domain.Answer; -import com.samhap.kokomen.answer.service.AnswerService; -import com.samhap.kokomen.category.domain.Category; -import com.samhap.kokomen.global.dto.ClientIp; -import com.samhap.kokomen.global.dto.MemberAuth; -import com.samhap.kokomen.global.exception.BadRequestException; -import com.samhap.kokomen.global.exception.ForbiddenException; -import com.samhap.kokomen.global.service.RedisService; -import com.samhap.kokomen.interview.entity.GeneratedQuestion; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewLike; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.domain.QuestionAndAnswers; -import com.samhap.kokomen.interview.domain.QuestionVoicePathResolver; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; -import com.samhap.kokomen.interview.entity.RootQuestion; -import com.samhap.kokomen.interview.external.dto.response.InterviewSummaryResponses; -import com.samhap.kokomen.interview.service.dto.AnswerRequestV2; -import com.samhap.kokomen.interview.service.dto.InterviewRequest; -import com.samhap.kokomen.interview.service.dto.InterviewResultResponse; -import com.samhap.kokomen.interview.service.dto.InterviewSummaryResponse; -import com.samhap.kokomen.interview.service.dto.RootQuestionCustomInterviewRequest; -import com.samhap.kokomen.interview.service.dto.RootQuestionResponse; -import com.samhap.kokomen.interview.service.dto.check.InterviewCheckResponse; -import com.samhap.kokomen.interview.service.dto.proceedstate.InterviewProceedStateResponse; -import com.samhap.kokomen.interview.service.dto.proceedstate.InterviewProceedStateTextModeResponse; -import com.samhap.kokomen.interview.service.dto.proceedstate.InterviewProceedStateVoiceModeResponse; -import com.samhap.kokomen.interview.service.dto.resumebased.ResumeBasedInterviewStartRequest; -import com.samhap.kokomen.interview.service.dto.start.InterviewStartResponse; -import com.samhap.kokomen.interview.service.dto.start.InterviewStartTextModeResponse; -import com.samhap.kokomen.interview.service.dto.start.InterviewStartVoiceModeResponse; -import com.samhap.kokomen.member.domain.Member; -import com.samhap.kokomen.member.service.MemberService; -import com.samhap.kokomen.token.service.TokenService; -import java.time.Duration; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Slf4j -@RequiredArgsConstructor -@Service -public class InterviewFacadeService { - - public static final String INTERVIEW_PROCEED_LOCK_KEY_PREFIX = "lock:interview:proceed:"; - public static final String INTERVIEW_PROCEED_STATE_KEY_PREFIX = "interview:proceed:state:"; - private static final int TOKEN_NOT_REQUIRED_FOR_ROOT_QUESTION_VOICE = 1; - - private final QuestionVoicePathResolver questionVoicePathResolver; - private final RedisService redisService; - private final InterviewService interviewService; - private final InterviewLikeService interviewLikeService; - private final MemberService memberService; - private final TokenService tokenService; - private final RootQuestionService rootQuestionService; - private final QuestionService questionService; - private final AnswerService answerService; - private final InterviewProceedBedrockFlowAsyncService interviewProceedBedrockFlowAsyncService; - private final ResumeBasedInterviewService resumeBasedInterviewService; - - @Transactional - public InterviewStartResponse startInterview(InterviewRequest interviewRequest, MemberAuth memberAuth) { - InterviewMode interviewMode = interviewRequest.mode(); - int requiredTokenCount = interviewRequest.maxQuestionCount() * interviewMode.getRequiredTokenCount() - - TOKEN_NOT_REQUIRED_FOR_ROOT_QUESTION_VOICE; - tokenService.validateEnoughTokens(memberAuth.memberId(), requiredTokenCount); - Member member = memberService.readById(memberAuth.memberId()); - RootQuestion rootQuestion = rootQuestionService.findNextRootQuestionForMember(member, interviewRequest); - Interview interview = interviewService.saveInterview( - new Interview(member, rootQuestion, interviewRequest.maxQuestionCount(), interviewMode)); - Question question = questionService.saveQuestion(new Question(interview, rootQuestion.getContent())); - - if (interviewMode == InterviewMode.VOICE) { - return new InterviewStartVoiceModeResponse(interview, question, - questionVoicePathResolver.resolveRootQuestionCdnPath(rootQuestion.getId())); - } - return new InterviewStartTextModeResponse(interview, question); - } - - @Transactional - public InterviewStartResponse startRootQuestionCustomInterview(RootQuestionCustomInterviewRequest request, - MemberAuth memberAuth) { - InterviewMode interviewMode = request.mode(); - int requiredTokenCount = request.maxQuestionCount() * interviewMode.getRequiredTokenCount() - - TOKEN_NOT_REQUIRED_FOR_ROOT_QUESTION_VOICE; - tokenService.validateEnoughTokens(memberAuth.memberId(), requiredTokenCount); - Member member = memberService.readById(memberAuth.memberId()); - RootQuestion rootQuestion = rootQuestionService.readRootQuestion(request.rootQuestionId()); - Interview interview = interviewService.saveInterview( - new Interview(member, rootQuestion, request.maxQuestionCount(), interviewMode)); - Question question = questionService.saveQuestion(new Question(interview, rootQuestion.getContent())); - - if (interviewMode == InterviewMode.VOICE) { - return new InterviewStartVoiceModeResponse(interview, question, - questionVoicePathResolver.resolveRootQuestionCdnPath(rootQuestion.getId())); - } - return new InterviewStartTextModeResponse(interview, question); - } - - public void proceedInterviewByBedrockFlow(Long interviewId, Long curQuestionId, AnswerRequestV2 answerRequest, - MemberAuth memberAuth) { - tokenService.validateEnoughTokens(memberAuth.memberId(), answerRequest.mode().getRequiredTokenCount()); - interviewService.validateInterviewMode(interviewId, answerRequest.mode()); - interviewService.validateInterviewee(interviewId, memberAuth.memberId()); - String lockKey = createInterviewProceedLockKey(memberAuth.memberId()); - String lockValue = UUID.randomUUID().toString(); - acquireLockForProceedInterview(lockKey, lockValue); - QuestionAndAnswers questionAndAnswers = createQuestionAndAnswers(interviewId, curQuestionId, - answerRequest.answer()); - try { - log.info("Bedrock API 호출 시도 - interviewId: {}, curQuestionId: {}, memberId: {}", - interviewId, curQuestionId, memberAuth.memberId()); - interviewProceedBedrockFlowAsyncService.proceedInterviewByBedrockFlowAsync(memberAuth.memberId(), - questionAndAnswers, interviewId, lockValue); - } catch (Exception e) { - try { - log.info("Gpt API 호출 시도 - interviewId: {}, curQuestionId: {}, memberId: {}", - interviewId, curQuestionId, memberAuth.memberId()); - log.error("Bedrock API 호출 실패, GPT 폴백에시 기록 - {}", e); - interviewProceedBedrockFlowAsyncService.proceedInterviewByGptFlowAsync(memberAuth.memberId(), - questionAndAnswers, interviewId, lockValue); - } catch (Exception ex) { - log.error("Gpt API 호출 실패 - {}", ex); - redisService.releaseLockSafely(lockKey, lockValue); - } - } - } - - public static String createInterviewProceedLockKey(Long memberId) { - return INTERVIEW_PROCEED_LOCK_KEY_PREFIX + memberId; - } - - private void acquireLockForProceedInterview(String lockKey, String lockValue) { - boolean lockAcquired = redisService.acquireLockWithValue(lockKey, lockValue, Duration.ofMinutes(5)); - if (!lockAcquired) { - throw new BadRequestException("이미 처리 중인 답변이 있습니다. 잠시 후 다시 시도해주세요."); - } - } - - private QuestionAndAnswers createQuestionAndAnswers(Long interviewId, Long curQuestionId, String answerContent) { - Interview interview = interviewService.readInterview(interviewId); - - List questions = questionService.findByInterview(interview); - List prevAnswers = answerService.findByQuestionIn(questions); - - return new QuestionAndAnswers(questions, prevAnswers, answerContent, curQuestionId, interview); - } - - @Transactional(readOnly = true) - public InterviewProceedStateResponse findInterviewProceedState(Long interviewId, Long curQuestionId, - InterviewMode mode, MemberAuth memberAuth) { - interviewService.validateInterviewMode(interviewId, mode); - interviewService.validateInterviewee(interviewId, memberAuth.memberId()); - String interviewProceedStateKey = createInterviewProceedStateKey(interviewId, curQuestionId); - - Optional interviewProceedStateOptional = redisService.get(interviewProceedStateKey, String.class); - if (interviewProceedStateOptional.isPresent()) { - InterviewProceedState interviewProceedState = InterviewProceedState.valueOf( - interviewProceedStateOptional.get()); - return createResponseByLlmProceedState(interviewId, curQuestionId, interviewProceedState); - } - - return recoverWhenRedisStateMissing(interviewId, curQuestionId); - } - - public static String createInterviewProceedStateKey(Long interviewId, Long curQuestionId) { - return INTERVIEW_PROCEED_STATE_KEY_PREFIX + interviewId + ":" + curQuestionId; - } - - private InterviewProceedStateResponse recoverWhenRedisStateMissing(Long interviewId, Long curQuestionId) { - return answerService.findByQuestionId(curQuestionId) - .map(answer -> createCompletedResponse(interviewId, curQuestionId)) - .orElseGet(() -> InterviewProceedStateResponse.createPendingOrFailed(InterviewProceedState.LLM_FAILED)); - } - - private InterviewProceedStateResponse createResponseByLlmProceedState(Long interviewId, Long curQuestionId, - InterviewProceedState interviewProceedState) { - if (interviewProceedState != InterviewProceedState.COMPLETED) { - return InterviewProceedStateResponse.createPendingOrFailed(interviewProceedState); - } - return createCompletedResponse(interviewId, curQuestionId); - } - - private InterviewProceedStateResponse createCompletedResponse(Long interviewId, Long curQuestionId) { - Interview interview = interviewService.readInterview(interviewId); - List lastTwoQuestions = questionService.readLastTwoQuestionsByInterviewId(interviewId); - if (interview.getInterviewState() == InterviewState.FINISHED) { - return createCompletedAndFinishedInterviewResponse(curQuestionId, lastTwoQuestions); - } - return createCompletedAndInProgressInterviewResponse(interview, curQuestionId, lastTwoQuestions); - } - - private InterviewProceedStateResponse createCompletedAndFinishedInterviewResponse( - Long curQuestionId, - List lastTwoQuestions - ) { - Question lastQuestion = lastTwoQuestions.get(0); - if (!curQuestionId.equals(lastQuestion.getId())) { - throw new BadRequestException("현재 질문이 아닙니다. 현재 질문 id: " + lastQuestion.getId()); - } - return InterviewProceedStateResponse.createCompletedAndFinished(); - } - - private InterviewProceedStateResponse createCompletedAndInProgressInterviewResponse( - Interview interview, - Long curQuestionId, - List lastTwoQuestions - ) { - Question lastQuestion = lastTwoQuestions.get(0); - Question curQuestion = lastTwoQuestions.get(1); - if (!curQuestionId.equals(curQuestion.getId())) { - throw new BadRequestException("현재 질문이 아닙니다. 현재 질문 id: " + curQuestion.getId()); - } - Answer curAnswer = answerService.readByQuestionId(curQuestionId); - - if (interview.getInterviewMode() == InterviewMode.VOICE) { - String questionVoiceUrl = questionService.resolveQuestionVoiceUrl(lastQuestion); - return InterviewProceedStateVoiceModeResponse.createCompletedAndInProgress(curAnswer, lastQuestion, - questionVoiceUrl); - } - - return InterviewProceedStateTextModeResponse.createCompletedAndInProgress(curAnswer, lastQuestion); - } - - @Transactional - public void likeInterview(Long interviewId, MemberAuth memberAuth) { - Member member = memberService.readById(memberAuth.memberId()); - Interview interview = interviewService.readInterview(interviewId); - interviewLikeService.likeInterview(new InterviewLike(member, interview)); - interviewService.increaseLikeCountModifying( - interviewId); // X락을 사용하기 때문에 동시에 요청이 와도 올바른 likeCount 값으로 이벤트를 생성할 수 있다. - } - - public InterviewCheckResponse checkInterview(Long interviewId, InterviewMode mode, MemberAuth memberAuth) { - return interviewService.checkInterview(interviewId, mode, memberAuth); - } - - public List findMyInterviews(MemberAuth memberAuth, InterviewState state, - Pageable pageable) { - return interviewService.findMyInterviews(memberAuth, state, pageable); - } - - public InterviewSummaryResponses findOtherMemberInterviews(Long memberId, MemberAuth memberAuth, - Pageable pageable) { - return interviewService.findOtherMemberInterviews(memberId, memberAuth, pageable); - } - - public InterviewResultResponse findMyInterviewResult(Long interviewId, MemberAuth memberAuth) { - return interviewService.findMyInterviewResult(interviewId, memberAuth); - } - - public InterviewResultResponse findOtherMemberInterviewResult(Long interviewId, MemberAuth memberAuth, - ClientIp clientIp) { - return interviewService.findOtherMemberInterviewResult(interviewId, memberAuth, clientIp); - } - - @Transactional - public void unlikeInterview(Long interviewId, MemberAuth memberAuth) { - interviewService.unlikeInterview(interviewId, memberAuth); - } - - public List getRootQuestionsByCategory(Category category) { - return rootQuestionService.findAllRootQuestionByCategory(category).stream() - .map(RootQuestionResponse::from) - .toList(); - } - - @Transactional - public InterviewStartResponse startResumeBasedInterview( - Long generationId, - ResumeBasedInterviewStartRequest request, - MemberAuth memberAuth - ) { - Member member = memberService.readById(memberAuth.memberId()); - ResumeQuestionGeneration generation = resumeBasedInterviewService.readGeneration(generationId); - validateGenerationOwnership(generation, memberAuth.memberId()); - validateGenerationCompleted(generation); - GeneratedQuestion generatedQuestion = resumeBasedInterviewService.readGeneratedQuestion( - request.generatedQuestionId(), generationId); - - InterviewMode interviewMode = request.mode(); - int requiredTokenCount = request.maxQuestionCount() * interviewMode.getRequiredTokenCount(); - tokenService.validateEnoughTokens(memberAuth.memberId(), requiredTokenCount); - - Interview interview = interviewService.saveInterview( - new Interview(member, generatedQuestion, request.maxQuestionCount(), interviewMode)); - Question question = questionService.saveQuestion(new Question(interview, generatedQuestion.getContent())); - - if (interviewMode == InterviewMode.VOICE) { - String voiceUrl = questionService.createAndUploadQuestionVoice(question); - return new InterviewStartVoiceModeResponse(interview, question, voiceUrl); - } - return new InterviewStartTextModeResponse(interview, question); - } - - private void validateGenerationOwnership(ResumeQuestionGeneration generation, Long memberId) { - if (!generation.isOwner(memberId)) { - throw new ForbiddenException("본인의 질문 생성 결과로만 면접을 시작할 수 있습니다."); - } - } - - private void validateGenerationCompleted(ResumeQuestionGeneration generation) { - if (!generation.isCompleted()) { - throw new BadRequestException("질문 생성이 완료되지 않았습니다."); - } - } -} diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedFacadeService.java b/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedFacadeService.java new file mode 100644 index 00000000..ebba752c --- /dev/null +++ b/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedFacadeService.java @@ -0,0 +1,170 @@ +package com.samhap.kokomen.interview.service; + +import com.samhap.kokomen.answer.domain.Answer; +import com.samhap.kokomen.answer.service.AnswerService; +import com.samhap.kokomen.global.dto.MemberAuth; +import com.samhap.kokomen.global.exception.BadRequestException; +import com.samhap.kokomen.global.service.RedisService; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.tool.QuestionAndAnswers; +import com.samhap.kokomen.interview.service.core.InterviewService; +import com.samhap.kokomen.interview.service.dto.AnswerRequestV2; +import com.samhap.kokomen.interview.service.dto.proceedstate.InterviewProceedStateResponse; +import com.samhap.kokomen.interview.service.dto.proceedstate.InterviewProceedStateTextModeResponse; +import com.samhap.kokomen.interview.service.dto.proceedstate.InterviewProceedStateVoiceModeResponse; +import com.samhap.kokomen.interview.service.infra.InterviewProceedBedrockFlowAsyncService; +import com.samhap.kokomen.interview.service.question.QuestionService; +import com.samhap.kokomen.token.service.TokenFacadeService; +import java.time.Duration; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class InterviewProceedFacadeService { + + public static final String INTERVIEW_PROCEED_LOCK_KEY_PREFIX = "lock:interview:proceed:"; + public static final String INTERVIEW_PROCEED_STATE_KEY_PREFIX = "interview:proceed:state:"; + + private final RedisService redisService; + private final InterviewService interviewService; + private final TokenFacadeService tokenFacadeService; + private final QuestionService questionService; + private final AnswerService answerService; + private final InterviewProceedBedrockFlowAsyncService interviewProceedBedrockFlowAsyncService; + + public void proceedInterviewByBedrockFlow(Long interviewId, Long curQuestionId, AnswerRequestV2 answerRequest, + MemberAuth memberAuth) { + tokenFacadeService.validateEnoughTokens(memberAuth.memberId(), answerRequest.mode().getRequiredTokenCount()); + interviewService.validateInterviewMode(interviewId, answerRequest.mode()); + interviewService.validateInterviewee(interviewId, memberAuth.memberId()); + String lockKey = createInterviewProceedLockKey(memberAuth.memberId()); + String lockValue = UUID.randomUUID().toString(); + acquireLockForProceedInterview(lockKey, lockValue); + QuestionAndAnswers questionAndAnswers = createQuestionAndAnswers(interviewId, curQuestionId, + answerRequest.answer()); + try { + log.info("Bedrock API 호출 시도 - interviewId: {}, curQuestionId: {}, memberId: {}", + interviewId, curQuestionId, memberAuth.memberId()); + interviewProceedBedrockFlowAsyncService.proceedInterviewByBedrockFlowAsync(memberAuth.memberId(), + questionAndAnswers, interviewId, lockValue); + } catch (Exception e) { + try { + log.info("Gpt API 호출 시도 - interviewId: {}, curQuestionId: {}, memberId: {}", + interviewId, curQuestionId, memberAuth.memberId()); + log.error("Bedrock API 호출 실패, GPT 폴백에시 기록 - {}", e); + interviewProceedBedrockFlowAsyncService.proceedInterviewByGptFlowAsync(memberAuth.memberId(), + questionAndAnswers, interviewId, lockValue); + } catch (Exception ex) { + log.error("Gpt API 호출 실패 - {}", ex); + redisService.releaseLockSafely(lockKey, lockValue); + } + } + } + + public static String createInterviewProceedLockKey(Long memberId) { + return INTERVIEW_PROCEED_LOCK_KEY_PREFIX + memberId; + } + + private void acquireLockForProceedInterview(String lockKey, String lockValue) { + boolean lockAcquired = redisService.acquireLockWithValue(lockKey, lockValue, Duration.ofMinutes(5)); + if (!lockAcquired) { + throw new BadRequestException("이미 처리 중인 답변이 있습니다. 잠시 후 다시 시도해주세요."); + } + } + + private QuestionAndAnswers createQuestionAndAnswers(Long interviewId, Long curQuestionId, String answerContent) { + Interview interview = interviewService.readInterview(interviewId); + + List questions = questionService.findByInterview(interview); + List prevAnswers = answerService.findByQuestionIn(questions); + + return new QuestionAndAnswers(questions, prevAnswers, answerContent, curQuestionId, interview); + } + + @Transactional(readOnly = true) + public InterviewProceedStateResponse findInterviewProceedState(Long interviewId, Long curQuestionId, + InterviewMode mode, MemberAuth memberAuth) { + interviewService.validateInterviewMode(interviewId, mode); + interviewService.validateInterviewee(interviewId, memberAuth.memberId()); + String interviewProceedStateKey = createInterviewProceedStateKey(interviewId, curQuestionId); + + Optional interviewProceedStateOptional = redisService.get(interviewProceedStateKey, String.class); + if (interviewProceedStateOptional.isPresent()) { + InterviewProceedState interviewProceedState = InterviewProceedState.valueOf( + interviewProceedStateOptional.get()); + return createResponseByLlmProceedState(interviewId, curQuestionId, interviewProceedState); + } + + return recoverWhenRedisStateMissing(interviewId, curQuestionId); + } + + public static String createInterviewProceedStateKey(Long interviewId, Long curQuestionId) { + return INTERVIEW_PROCEED_STATE_KEY_PREFIX + interviewId + ":" + curQuestionId; + } + + private InterviewProceedStateResponse recoverWhenRedisStateMissing(Long interviewId, Long curQuestionId) { + return answerService.findByQuestionId(curQuestionId) + .map(answer -> createCompletedResponse(interviewId, curQuestionId)) + .orElseGet(() -> InterviewProceedStateResponse.createPendingOrFailed(InterviewProceedState.LLM_FAILED)); + } + + private InterviewProceedStateResponse createResponseByLlmProceedState(Long interviewId, Long curQuestionId, + InterviewProceedState interviewProceedState) { + if (interviewProceedState != InterviewProceedState.COMPLETED) { + return InterviewProceedStateResponse.createPendingOrFailed(interviewProceedState); + } + return createCompletedResponse(interviewId, curQuestionId); + } + + private InterviewProceedStateResponse createCompletedResponse(Long interviewId, Long curQuestionId) { + Interview interview = interviewService.readInterview(interviewId); + List lastTwoQuestions = questionService.readLastTwoQuestionsByInterviewId(interviewId); + if (interview.getInterviewState() == InterviewState.FINISHED) { + return createCompletedAndFinishedInterviewResponse(curQuestionId, lastTwoQuestions); + } + return createCompletedAndInProgressInterviewResponse(interview, curQuestionId, lastTwoQuestions); + } + + private InterviewProceedStateResponse createCompletedAndFinishedInterviewResponse( + Long curQuestionId, + List lastTwoQuestions + ) { + Question lastQuestion = lastTwoQuestions.get(0); + if (!curQuestionId.equals(lastQuestion.getId())) { + throw new BadRequestException("현재 질문이 아닙니다. 현재 질문 id: " + lastQuestion.getId()); + } + return InterviewProceedStateResponse.createCompletedAndFinished(); + } + + private InterviewProceedStateResponse createCompletedAndInProgressInterviewResponse( + Interview interview, + Long curQuestionId, + List lastTwoQuestions + ) { + Question lastQuestion = lastTwoQuestions.get(0); + Question curQuestion = lastTwoQuestions.get(1); + if (!curQuestionId.equals(curQuestion.getId())) { + throw new BadRequestException("현재 질문이 아닙니다. 현재 질문 id: " + curQuestion.getId()); + } + Answer curAnswer = answerService.readByQuestionId(curQuestionId); + + if (interview.getInterviewMode() == InterviewMode.VOICE) { + String questionVoiceUrl = questionService.resolveQuestionVoiceUrl(lastQuestion); + return InterviewProceedStateVoiceModeResponse.createCompletedAndInProgress(curAnswer, lastQuestion, + questionVoiceUrl); + } + + return InterviewProceedStateTextModeResponse.createCompletedAndInProgress(curAnswer, lastQuestion); + } +} diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewQueryService.java b/src/main/java/com/samhap/kokomen/interview/service/InterviewQueryService.java new file mode 100644 index 00000000..02bc9dab --- /dev/null +++ b/src/main/java/com/samhap/kokomen/interview/service/InterviewQueryService.java @@ -0,0 +1,77 @@ +package com.samhap.kokomen.interview.service; + +import com.samhap.kokomen.category.domain.Category; +import com.samhap.kokomen.global.dto.ClientIp; +import com.samhap.kokomen.global.dto.MemberAuth; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewLike; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.external.dto.response.InterviewSummaryResponses; +import com.samhap.kokomen.interview.service.core.InterviewService; +import com.samhap.kokomen.interview.service.dto.InterviewResultResponse; +import com.samhap.kokomen.interview.service.dto.InterviewSummaryResponse; +import com.samhap.kokomen.interview.service.dto.RootQuestionResponse; +import com.samhap.kokomen.interview.service.dto.check.InterviewCheckResponse; +import com.samhap.kokomen.interview.service.question.RootQuestionService; +import com.samhap.kokomen.interview.service.social.InterviewLikeService; +import com.samhap.kokomen.member.domain.Member; +import com.samhap.kokomen.member.service.MemberService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +public class InterviewQueryService { + + private final InterviewService interviewService; + private final InterviewLikeService interviewLikeService; + private final MemberService memberService; + private final RootQuestionService rootQuestionService; + + @Transactional + public void likeInterview(Long interviewId, MemberAuth memberAuth) { + Member member = memberService.readById(memberAuth.memberId()); + Interview interview = interviewService.readInterview(interviewId); + interviewLikeService.likeInterview(new InterviewLike(member, interview)); + interviewService.increaseLikeCountModifying( + interviewId); // X락을 사용하기 때문에 동시에 요청이 와도 올바른 likeCount 값으로 이벤트를 생성할 수 있다. + } + + public InterviewCheckResponse checkInterview(Long interviewId, InterviewMode mode, MemberAuth memberAuth) { + return interviewService.checkInterview(interviewId, mode, memberAuth); + } + + public List findMyInterviews(MemberAuth memberAuth, InterviewState state, + Pageable pageable) { + return interviewService.findMyInterviews(memberAuth, state, pageable); + } + + public InterviewSummaryResponses findOtherMemberInterviews(Long memberId, MemberAuth memberAuth, + Pageable pageable) { + return interviewService.findOtherMemberInterviews(memberId, memberAuth, pageable); + } + + public InterviewResultResponse findMyInterviewResult(Long interviewId, MemberAuth memberAuth) { + return interviewService.findMyInterviewResult(interviewId, memberAuth); + } + + public InterviewResultResponse findOtherMemberInterviewResult(Long interviewId, MemberAuth memberAuth, + ClientIp clientIp) { + return interviewService.findOtherMemberInterviewResult(interviewId, memberAuth, clientIp); + } + + @Transactional + public void unlikeInterview(Long interviewId, MemberAuth memberAuth) { + interviewService.unlikeInterview(interviewId, memberAuth); + } + + public List getRootQuestionsByCategory(Category category) { + return rootQuestionService.findAllRootQuestionByCategory(category).stream() + .map(RootQuestionResponse::from) + .toList(); + } +} diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewStartFacadeService.java b/src/main/java/com/samhap/kokomen/interview/service/InterviewStartFacadeService.java new file mode 100644 index 00000000..e40eb5af --- /dev/null +++ b/src/main/java/com/samhap/kokomen/interview/service/InterviewStartFacadeService.java @@ -0,0 +1,124 @@ +package com.samhap.kokomen.interview.service; + +import com.samhap.kokomen.global.dto.MemberAuth; +import com.samhap.kokomen.global.exception.BadRequestException; +import com.samhap.kokomen.global.exception.ForbiddenException; +import com.samhap.kokomen.interview.domain.GeneratedQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.tool.QuestionVoicePathResolver; +import com.samhap.kokomen.interview.service.core.InterviewService; +import com.samhap.kokomen.interview.service.dto.InterviewRequest; +import com.samhap.kokomen.interview.service.dto.RootQuestionCustomInterviewRequest; +import com.samhap.kokomen.interview.service.dto.resumebased.ResumeBasedInterviewStartRequest; +import com.samhap.kokomen.interview.service.dto.start.InterviewStartResponse; +import com.samhap.kokomen.interview.service.dto.start.InterviewStartTextModeResponse; +import com.samhap.kokomen.interview.service.dto.start.InterviewStartVoiceModeResponse; +import com.samhap.kokomen.interview.service.question.QuestionService; +import com.samhap.kokomen.interview.service.question.RootQuestionService; +import com.samhap.kokomen.interview.service.resume.ResumeBasedInterviewService; +import com.samhap.kokomen.member.domain.Member; +import com.samhap.kokomen.member.service.MemberService; +import com.samhap.kokomen.token.service.TokenFacadeService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class InterviewStartFacadeService { + + private static final int TOKEN_NOT_REQUIRED_FOR_ROOT_QUESTION_VOICE = 1; + + private final QuestionVoicePathResolver questionVoicePathResolver; + private final InterviewService interviewService; + private final MemberService memberService; + private final TokenFacadeService tokenFacadeService; + private final RootQuestionService rootQuestionService; + private final QuestionService questionService; + private final ResumeBasedInterviewService resumeBasedInterviewService; + + @Transactional + public InterviewStartResponse startInterview(InterviewRequest interviewRequest, MemberAuth memberAuth) { + InterviewMode interviewMode = interviewRequest.mode(); + int requiredTokenCount = interviewRequest.maxQuestionCount() * interviewMode.getRequiredTokenCount() + - TOKEN_NOT_REQUIRED_FOR_ROOT_QUESTION_VOICE; + tokenFacadeService.validateEnoughTokens(memberAuth.memberId(), requiredTokenCount); + Member member = memberService.readById(memberAuth.memberId()); + RootQuestion rootQuestion = rootQuestionService.findNextRootQuestionForMember(member, interviewRequest); + Interview interview = interviewService.saveInterview( + new Interview(member, rootQuestion, interviewRequest.maxQuestionCount(), interviewMode)); + Question question = questionService.saveQuestion(new Question(interview, rootQuestion.getContent())); + + if (interviewMode == InterviewMode.VOICE) { + return new InterviewStartVoiceModeResponse(interview, question, + questionVoicePathResolver.resolveRootQuestionCdnPath(rootQuestion.getId())); + } + return new InterviewStartTextModeResponse(interview, question); + } + + @Transactional + public InterviewStartResponse startRootQuestionCustomInterview(RootQuestionCustomInterviewRequest request, + MemberAuth memberAuth) { + InterviewMode interviewMode = request.mode(); + int requiredTokenCount = request.maxQuestionCount() * interviewMode.getRequiredTokenCount() + - TOKEN_NOT_REQUIRED_FOR_ROOT_QUESTION_VOICE; + tokenFacadeService.validateEnoughTokens(memberAuth.memberId(), requiredTokenCount); + Member member = memberService.readById(memberAuth.memberId()); + RootQuestion rootQuestion = rootQuestionService.readRootQuestion(request.rootQuestionId()); + Interview interview = interviewService.saveInterview( + new Interview(member, rootQuestion, request.maxQuestionCount(), interviewMode)); + Question question = questionService.saveQuestion(new Question(interview, rootQuestion.getContent())); + + if (interviewMode == InterviewMode.VOICE) { + return new InterviewStartVoiceModeResponse(interview, question, + questionVoicePathResolver.resolveRootQuestionCdnPath(rootQuestion.getId())); + } + return new InterviewStartTextModeResponse(interview, question); + } + + @Transactional + public InterviewStartResponse startResumeBasedInterview( + Long generationId, + ResumeBasedInterviewStartRequest request, + MemberAuth memberAuth + ) { + Member member = memberService.readById(memberAuth.memberId()); + ResumeQuestionGeneration generation = resumeBasedInterviewService.readGeneration(generationId); + validateGenerationOwnership(generation, memberAuth.memberId()); + validateGenerationCompleted(generation); + GeneratedQuestion generatedQuestion = resumeBasedInterviewService.readGeneratedQuestion( + request.generatedQuestionId(), generationId); + + InterviewMode interviewMode = request.mode(); + int requiredTokenCount = request.maxQuestionCount() * interviewMode.getRequiredTokenCount(); + tokenFacadeService.validateEnoughTokens(memberAuth.memberId(), requiredTokenCount); + + Interview interview = interviewService.saveInterview( + new Interview(member, generatedQuestion, request.maxQuestionCount(), interviewMode)); + Question question = questionService.saveQuestion(new Question(interview, generatedQuestion.getContent())); + + if (interviewMode == InterviewMode.VOICE) { + String voiceUrl = questionService.createAndUploadQuestionVoice(question); + return new InterviewStartVoiceModeResponse(interview, question, voiceUrl); + } + return new InterviewStartTextModeResponse(interview, question); + } + + private void validateGenerationOwnership(ResumeQuestionGeneration generation, Long memberId) { + if (!generation.isOwner(memberId)) { + throw new ForbiddenException("본인의 질문 생성 결과로만 면접을 시작할 수 있습니다."); + } + } + + private void validateGenerationCompleted(ResumeQuestionGeneration generation) { + if (!generation.isCompleted()) { + throw new BadRequestException("질문 생성이 완료되지 않았습니다."); + } + } +} diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedService.java b/src/main/java/com/samhap/kokomen/interview/service/core/InterviewProceedService.java similarity index 90% rename from src/main/java/com/samhap/kokomen/interview/service/InterviewProceedService.java rename to src/main/java/com/samhap/kokomen/interview/service/core/InterviewProceedService.java index a1337a3f..c6a6b24c 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/core/InterviewProceedService.java @@ -1,18 +1,19 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.core; import com.fasterxml.jackson.databind.ObjectMapper; import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.service.AnswerService; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.domain.InterviewProceedResult; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.domain.QuestionAndAnswers; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.tool.InterviewProceedResult; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.tool.QuestionAndAnswers; import com.samhap.kokomen.interview.external.dto.response.AnswerFeedbackResponse; import com.samhap.kokomen.interview.external.dto.response.AnswerRankResponse; import com.samhap.kokomen.interview.external.dto.response.LlmResponse; import com.samhap.kokomen.interview.external.dto.response.NextQuestionResponse; import com.samhap.kokomen.interview.external.dto.response.TotalFeedbackResponse; +import com.samhap.kokomen.interview.service.question.QuestionService; import com.samhap.kokomen.interview.service.dto.InterviewProceedResponse; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.service.MemberService; @@ -87,7 +88,8 @@ private Answer saveCurrentAnswer(QuestionAndAnswers questionAndAnswers, LlmRespo return answerService.saveAnswer(questionAndAnswers.createCurAnswer(feedback)); } - private void evaluateInterview(QuestionAndAnswers questionAndAnswers, Answer curAnswer, Interview interview, LlmResponse llmResponse, Member member) { + private void evaluateInterview(QuestionAndAnswers questionAndAnswers, Answer curAnswer, Interview interview, + LlmResponse llmResponse, Member member) { int totalScore = questionAndAnswers.calculateTotalScore(curAnswer.getAnswerRank().getScore()); TotalFeedbackResponse totalFeedbackResponse = llmResponse.extractTotalFeedbackResponse(objectMapper); interview.evaluate(totalFeedbackResponse.totalFeedback(), totalScore); diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewService.java b/src/main/java/com/samhap/kokomen/interview/service/core/InterviewService.java similarity index 97% rename from src/main/java/com/samhap/kokomen/interview/service/InterviewService.java rename to src/main/java/com/samhap/kokomen/interview/service/core/InterviewService.java index f5ab6636..39e76604 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/InterviewService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/core/InterviewService.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.core; import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerMemo; @@ -14,15 +14,17 @@ import com.samhap.kokomen.global.exception.BadRequestException; import com.samhap.kokomen.global.exception.ForbiddenException; import com.samhap.kokomen.global.exception.UnauthorizedException; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.domain.QuestionVoicePathResolver; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.tool.QuestionVoicePathResolver; import com.samhap.kokomen.interview.external.dto.response.InterviewSummaryResponses; import com.samhap.kokomen.interview.repository.InterviewLikeRepository; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; +import com.samhap.kokomen.interview.service.social.InterviewViewCountService; +import com.samhap.kokomen.interview.service.question.QuestionService; import com.samhap.kokomen.interview.service.dto.FeedbackResponse; import com.samhap.kokomen.interview.service.dto.InterviewResultResponse; import com.samhap.kokomen.interview.service.dto.InterviewSummaryResponse; diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/AnswerRequestV2.java b/src/main/java/com/samhap/kokomen/interview/service/dto/AnswerRequestV2.java index c21c4d52..14f3012a 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/AnswerRequestV2.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/AnswerRequestV2.java @@ -1,6 +1,6 @@ package com.samhap.kokomen.interview.service.dto; -import com.samhap.kokomen.interview.entity.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewMode; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewProceedResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewProceedResponse.java index f1694616..7ec21cd6 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewProceedResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewProceedResponse.java @@ -2,7 +2,7 @@ import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Question; public record InterviewProceedResponse( AnswerRank curAnswerRank, diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewRequest.java b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewRequest.java index 0132e0f9..0cf4c939 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewRequest.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewRequest.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.service.dto; import com.samhap.kokomen.category.domain.Category; -import com.samhap.kokomen.interview.entity.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewMode; import jakarta.validation.constraints.NotNull; public record InterviewRequest( diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewResultResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewResultResponse.java index 90d1cca5..11bb947b 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewResultResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewResultResponse.java @@ -2,8 +2,8 @@ import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.dto.AnswerMemos; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; import com.samhap.kokomen.member.domain.Member; import java.util.List; import java.util.Map; diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewSummaryResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewSummaryResponse.java index 55e7a8b7..142dc22a 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewSummaryResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/InterviewSummaryResponse.java @@ -1,8 +1,8 @@ package com.samhap.kokomen.interview.service.dto; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.InterviewState; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewState; import java.time.LocalDateTime; public record InterviewSummaryResponse( diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionCustomInterviewRequest.java b/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionCustomInterviewRequest.java index baa9979f..c21642a9 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionCustomInterviewRequest.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionCustomInterviewRequest.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.service.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import com.samhap.kokomen.interview.entity.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewMode; import jakarta.validation.constraints.NotNull; public record RootQuestionCustomInterviewRequest( diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionResponse.java index 4a6712c1..d49f482b 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/RootQuestionResponse.java @@ -1,6 +1,6 @@ package com.samhap.kokomen.interview.service.dto; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestion; public record RootQuestionResponse( Long id, diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckResponse.java index e660ba9d..a097c6ab 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckResponse.java @@ -1,8 +1,8 @@ package com.samhap.kokomen.interview.service.dto.check; import com.samhap.kokomen.answer.domain.Answer; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; import com.samhap.kokomen.interview.service.dto.QuestionAndAnswerResponse; import java.util.List; diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckTextModeResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckTextModeResponse.java index eafcd3cd..7129063e 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckTextModeResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckTextModeResponse.java @@ -1,9 +1,9 @@ package com.samhap.kokomen.interview.service.dto.check; import com.samhap.kokomen.answer.domain.Answer; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; import com.samhap.kokomen.interview.service.dto.QuestionAndAnswerResponse; import java.util.List; diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckVoiceModeResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckVoiceModeResponse.java index 8e64e2ba..b6d9bce7 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckVoiceModeResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewCheckVoiceModeResponse.java @@ -1,9 +1,9 @@ package com.samhap.kokomen.interview.service.dto.check; import com.samhap.kokomen.answer.domain.Answer; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; import com.samhap.kokomen.interview.service.dto.QuestionAndAnswerResponse; import java.util.List; diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewFinishedCheckResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewFinishedCheckResponse.java index b95907ea..2d459478 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewFinishedCheckResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/check/InterviewFinishedCheckResponse.java @@ -1,6 +1,6 @@ package com.samhap.kokomen.interview.service.dto.check; -import com.samhap.kokomen.interview.entity.InterviewState; +import com.samhap.kokomen.interview.domain.InterviewState; import com.samhap.kokomen.interview.service.dto.QuestionAndAnswerResponse; import java.util.List; diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateResponse.java index 5c917caa..2530faab 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateResponse.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.service.dto.proceedstate; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.entity.InterviewState; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.domain.InterviewState; public interface InterviewProceedStateResponse { diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateTextModeResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateTextModeResponse.java index 06cb1d71..8b431597 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateTextModeResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateTextModeResponse.java @@ -2,9 +2,9 @@ import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; public record InterviewProceedStateTextModeResponse( diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateVoiceModeResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateVoiceModeResponse.java index 275e3b36..24acda52 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateVoiceModeResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/proceedstate/InterviewProceedStateVoiceModeResponse.java @@ -2,9 +2,9 @@ import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; public record InterviewProceedStateVoiceModeResponse( InterviewProceedState proceedState, diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/GeneratedQuestionsResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/GeneratedQuestionsResponse.java index 6c3fdad1..658b4360 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/GeneratedQuestionsResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/GeneratedQuestionsResponse.java @@ -1,6 +1,6 @@ package com.samhap.kokomen.interview.service.dto.resumebased; -import com.samhap.kokomen.interview.entity.GeneratedQuestion; +import com.samhap.kokomen.interview.domain.GeneratedQuestion; public record GeneratedQuestionsResponse( Long id, diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/QuestionGenerationStateResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/QuestionGenerationStateResponse.java index 1be54d4a..5dffc6af 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/QuestionGenerationStateResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/QuestionGenerationStateResponse.java @@ -1,6 +1,6 @@ package com.samhap.kokomen.interview.service.dto.resumebased; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; public record QuestionGenerationStateResponse( ResumeQuestionGenerationState state diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeBasedInterviewStartRequest.java b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeBasedInterviewStartRequest.java index 09e0905c..07cd2a01 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeBasedInterviewStartRequest.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeBasedInterviewStartRequest.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.service.dto.resumebased; import com.fasterxml.jackson.annotation.JsonProperty; -import com.samhap.kokomen.interview.entity.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewMode; import jakarta.validation.constraints.NotNull; public record ResumeBasedInterviewStartRequest( diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeQuestionGenerationResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeQuestionGenerationResponse.java index e54298de..9dd39147 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeQuestionGenerationResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/resumebased/ResumeQuestionGenerationResponse.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.service.dto.resumebased; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; import java.time.LocalDateTime; public record ResumeQuestionGenerationResponse( diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartTextModeResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartTextModeResponse.java index 1f1c6763..9db8908b 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartTextModeResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartTextModeResponse.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.service.dto.start; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; public record InterviewStartTextModeResponse( Long interviewId, diff --git a/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartVoiceModeResponse.java b/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartVoiceModeResponse.java index ab798205..72c89da9 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartVoiceModeResponse.java +++ b/src/main/java/com/samhap/kokomen/interview/service/dto/start/InterviewStartVoiceModeResponse.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.interview.service.dto.start; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; public record InterviewStartVoiceModeResponse( Long interviewId, diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedBedrockFlowAsyncService.java b/src/main/java/com/samhap/kokomen/interview/service/infra/InterviewProceedBedrockFlowAsyncService.java similarity index 95% rename from src/main/java/com/samhap/kokomen/interview/service/InterviewProceedBedrockFlowAsyncService.java rename to src/main/java/com/samhap/kokomen/interview/service/infra/InterviewProceedBedrockFlowAsyncService.java index 5abfee17..40eef2d2 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/InterviewProceedBedrockFlowAsyncService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/infra/InterviewProceedBedrockFlowAsyncService.java @@ -1,16 +1,19 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.infra; import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; import com.samhap.kokomen.global.service.RedisService; -import com.samhap.kokomen.interview.domain.InterviewProceedResult; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.domain.QuestionAndAnswers; +import com.samhap.kokomen.interview.tool.InterviewProceedResult; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.tool.QuestionAndAnswers; import com.samhap.kokomen.interview.external.InterviewProceedGptClient; import com.samhap.kokomen.interview.external.dto.request.InterviewInvokeFlowRequestFactory; import com.samhap.kokomen.interview.external.dto.response.BedrockResponse; import com.samhap.kokomen.interview.external.dto.response.GptResponse; import com.samhap.kokomen.interview.external.dto.response.LlmResponse; +import com.samhap.kokomen.interview.service.InterviewProceedFacadeService; +import com.samhap.kokomen.interview.service.core.InterviewProceedService; +import com.samhap.kokomen.interview.service.question.QuestionService; import com.samhap.kokomen.token.service.TokenFacadeService; import java.time.Duration; import java.util.Map; @@ -62,8 +65,8 @@ public InterviewProceedBedrockFlowAsyncService( public void proceedInterviewByBedrockFlowAsync(Long memberId, QuestionAndAnswers questionAndAnswers, Long interviewId, String lockValue) { Map mdcContext = MDC.getCopyOfContextMap(); - String lockKey = InterviewFacadeService.createInterviewProceedLockKey(memberId); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interviewId, + String lockKey = InterviewProceedFacadeService.createInterviewProceedLockKey(memberId); + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interviewId, questionAndAnswers.readCurQuestion().getId()); bedrockAgentRuntimeAsyncClient.invokeFlow( @@ -77,8 +80,8 @@ public void proceedInterviewByBedrockFlowAsync(Long memberId, QuestionAndAnswers public void proceedInterviewByGptFlowAsync(Long memberId, QuestionAndAnswers questionAndAnswers, Long interviewId, String lockValue) { Map mdcContext = MDC.getCopyOfContextMap(); - String lockKey = InterviewFacadeService.createInterviewProceedLockKey(memberId); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interviewId, + String lockKey = InterviewProceedFacadeService.createInterviewProceedLockKey(memberId); + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interviewId, questionAndAnswers.readCurQuestion().getId()); try { diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewSchedulerService.java b/src/main/java/com/samhap/kokomen/interview/service/infra/InterviewSchedulerService.java similarity index 96% rename from src/main/java/com/samhap/kokomen/interview/service/InterviewSchedulerService.java rename to src/main/java/com/samhap/kokomen/interview/service/infra/InterviewSchedulerService.java index d717c579..014f8bb2 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/InterviewSchedulerService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/infra/InterviewSchedulerService.java @@ -1,7 +1,8 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.infra; import com.samhap.kokomen.global.service.RedisService; import com.samhap.kokomen.interview.repository.InterviewBatchRepository; +import com.samhap.kokomen.interview.service.social.InterviewViewCountService; import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationAsyncService.java b/src/main/java/com/samhap/kokomen/interview/service/question/QuestionGenerationAsyncService.java similarity index 97% rename from src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationAsyncService.java rename to src/main/java/com/samhap/kokomen/interview/service/question/QuestionGenerationAsyncService.java index b1fc33a9..bb8eb6ef 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationAsyncService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/question/QuestionGenerationAsyncService.java @@ -1,8 +1,9 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.question; import com.samhap.kokomen.global.exception.BadRequestException; import com.samhap.kokomen.interview.external.ResumeBasedQuestionBedrockService; import com.samhap.kokomen.interview.external.dto.response.GeneratedQuestionDto; +import com.samhap.kokomen.interview.service.resume.ResumeContentService; import com.samhap.kokomen.interview.service.dto.resumebased.ResumeBasedQuestionGenerateRequest; import com.samhap.kokomen.resume.domain.MemberPortfolio; import com.samhap.kokomen.resume.domain.MemberResume; diff --git a/src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationStateService.java b/src/main/java/com/samhap/kokomen/interview/service/question/QuestionGenerationStateService.java similarity index 91% rename from src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationStateService.java rename to src/main/java/com/samhap/kokomen/interview/service/question/QuestionGenerationStateService.java index 606a5efd..a4e7f1bd 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/QuestionGenerationStateService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/question/QuestionGenerationStateService.java @@ -1,8 +1,8 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.question; import com.samhap.kokomen.global.exception.BadRequestException; -import com.samhap.kokomen.interview.entity.GeneratedQuestion; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.GeneratedQuestion; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; import com.samhap.kokomen.interview.external.dto.response.GeneratedQuestionDto; import com.samhap.kokomen.interview.repository.GeneratedQuestionRepository; import com.samhap.kokomen.interview.repository.ResumeQuestionGenerationRepository; diff --git a/src/main/java/com/samhap/kokomen/interview/service/QuestionService.java b/src/main/java/com/samhap/kokomen/interview/service/question/QuestionService.java similarity index 84% rename from src/main/java/com/samhap/kokomen/interview/service/QuestionService.java rename to src/main/java/com/samhap/kokomen/interview/service/question/QuestionService.java index 2a597395..76dbbe4d 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/QuestionService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/question/QuestionService.java @@ -1,9 +1,9 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.question; import com.samhap.kokomen.global.service.S3Service; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.domain.QuestionVoicePathResolver; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.tool.QuestionVoicePathResolver; import com.samhap.kokomen.interview.external.SupertoneClient; import com.samhap.kokomen.interview.external.dto.request.SupertoneRequest; import com.samhap.kokomen.interview.external.dto.response.SupertoneResponse; @@ -41,7 +41,8 @@ public String resolveQuestionVoiceUrl(Question question) { public String createAndUploadQuestionVoice(Question question) { SupertoneResponse supertoneResponse = supertoneClient.request(new SupertoneRequest(question.getContent())); - s3Service.uploadS3File(questionVoicePathResolver.resolveNextQuestionS3Key(question.getId()), supertoneResponse.voiceData(), "audio/wav"); + s3Service.uploadS3File(questionVoicePathResolver.resolveNextQuestionS3Key(question.getId()), + supertoneResponse.voiceData(), "audio/wav"); return questionVoicePathResolver.resolveNextQuestionCdnPath(question.getId()); } diff --git a/src/main/java/com/samhap/kokomen/interview/service/RootQuestionService.java b/src/main/java/com/samhap/kokomen/interview/service/question/RootQuestionService.java similarity index 94% rename from src/main/java/com/samhap/kokomen/interview/service/RootQuestionService.java rename to src/main/java/com/samhap/kokomen/interview/service/question/RootQuestionService.java index 24378388..e99539ea 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/RootQuestionService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/question/RootQuestionService.java @@ -1,11 +1,11 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.question; import com.samhap.kokomen.category.domain.Category; import com.samhap.kokomen.global.exception.NotFoundException; import com.samhap.kokomen.global.service.S3Service; -import com.samhap.kokomen.interview.domain.QuestionVoicePathResolver; -import com.samhap.kokomen.interview.entity.RootQuestion; -import com.samhap.kokomen.interview.entity.RootQuestionState; +import com.samhap.kokomen.interview.tool.QuestionVoicePathResolver; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestionState; import com.samhap.kokomen.interview.external.SupertoneClient; import com.samhap.kokomen.interview.external.dto.request.SupertoneRequest; import com.samhap.kokomen.interview.external.dto.response.SupertoneResponse; diff --git a/src/main/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewService.java b/src/main/java/com/samhap/kokomen/interview/service/resume/ResumeBasedInterviewService.java similarity index 96% rename from src/main/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewService.java rename to src/main/java/com/samhap/kokomen/interview/service/resume/ResumeBasedInterviewService.java index 1ff12de2..41bad638 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/resume/ResumeBasedInterviewService.java @@ -1,12 +1,12 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.resume; import com.samhap.kokomen.global.annotation.DistributedLock; import com.samhap.kokomen.global.exception.BadRequestException; import com.samhap.kokomen.global.exception.ForbiddenException; import com.samhap.kokomen.global.exception.UnauthorizedException; -import com.samhap.kokomen.interview.entity.GeneratedQuestion; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.domain.GeneratedQuestion; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; import com.samhap.kokomen.interview.repository.GeneratedQuestionRepository; import com.samhap.kokomen.interview.repository.ResumeQuestionGenerationRepository; import com.samhap.kokomen.interview.service.dto.resumebased.GeneratedQuestionsResponse; @@ -16,6 +16,7 @@ import com.samhap.kokomen.interview.service.dto.resumebased.ResumeQuestionGenerationPageResponse; import com.samhap.kokomen.interview.service.dto.resumebased.ResumeQuestionGenerationResponse; import com.samhap.kokomen.interview.service.dto.resumebased.ResumeQuestionUsageStatusResponse; +import com.samhap.kokomen.interview.service.question.QuestionGenerationAsyncService; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import com.samhap.kokomen.resume.domain.MemberPortfolio; diff --git a/src/main/java/com/samhap/kokomen/interview/service/ResumeContentService.java b/src/main/java/com/samhap/kokomen/interview/service/resume/ResumeContentService.java similarity index 97% rename from src/main/java/com/samhap/kokomen/interview/service/ResumeContentService.java rename to src/main/java/com/samhap/kokomen/interview/service/resume/ResumeContentService.java index 1fd072e6..1da4e408 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/ResumeContentService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/resume/ResumeContentService.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.resume; import com.samhap.kokomen.global.exception.BadRequestException; import com.samhap.kokomen.global.service.S3Service; diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewLikeService.java b/src/main/java/com/samhap/kokomen/interview/service/social/InterviewLikeService.java similarity index 85% rename from src/main/java/com/samhap/kokomen/interview/service/InterviewLikeService.java rename to src/main/java/com/samhap/kokomen/interview/service/social/InterviewLikeService.java index 50f931dc..1e26883f 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/InterviewLikeService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/social/InterviewLikeService.java @@ -1,8 +1,8 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.social; import com.samhap.kokomen.global.exception.BadRequestException; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewLike; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewLike; import com.samhap.kokomen.interview.repository.InterviewLikeRepository; import com.samhap.kokomen.member.domain.Member; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/samhap/kokomen/interview/service/InterviewViewCountService.java b/src/main/java/com/samhap/kokomen/interview/service/social/InterviewViewCountService.java similarity index 96% rename from src/main/java/com/samhap/kokomen/interview/service/InterviewViewCountService.java rename to src/main/java/com/samhap/kokomen/interview/service/social/InterviewViewCountService.java index d03d88cd..856a940f 100644 --- a/src/main/java/com/samhap/kokomen/interview/service/InterviewViewCountService.java +++ b/src/main/java/com/samhap/kokomen/interview/service/social/InterviewViewCountService.java @@ -1,10 +1,10 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.social; import com.samhap.kokomen.global.dto.ClientIp; import com.samhap.kokomen.global.dto.MemberAuth; import com.samhap.kokomen.global.exception.RedisException; import com.samhap.kokomen.global.service.RedisService; -import com.samhap.kokomen.interview.entity.Interview; +import com.samhap.kokomen.interview.domain.Interview; import java.time.Duration; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/samhap/kokomen/interview/domain/GptSystemMessageConstant.java b/src/main/java/com/samhap/kokomen/interview/tool/GptSystemMessageConstant.java similarity index 99% rename from src/main/java/com/samhap/kokomen/interview/domain/GptSystemMessageConstant.java rename to src/main/java/com/samhap/kokomen/interview/tool/GptSystemMessageConstant.java index 1d80108e..b450c7a7 100644 --- a/src/main/java/com/samhap/kokomen/interview/domain/GptSystemMessageConstant.java +++ b/src/main/java/com/samhap/kokomen/interview/tool/GptSystemMessageConstant.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; public class GptSystemMessageConstant { diff --git a/src/main/java/com/samhap/kokomen/interview/domain/InterviewMessagesFactory.java b/src/main/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactory.java similarity index 98% rename from src/main/java/com/samhap/kokomen/interview/domain/InterviewMessagesFactory.java rename to src/main/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactory.java index 1bde0769..74372f10 100644 --- a/src/main/java/com/samhap/kokomen/interview/domain/InterviewMessagesFactory.java +++ b/src/main/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactory.java @@ -1,8 +1,8 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Question; import com.samhap.kokomen.interview.external.dto.request.GptMessage; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/samhap/kokomen/interview/domain/InterviewProceedResult.java b/src/main/java/com/samhap/kokomen/interview/tool/InterviewProceedResult.java similarity index 90% rename from src/main/java/com/samhap/kokomen/interview/domain/InterviewProceedResult.java rename to src/main/java/com/samhap/kokomen/interview/tool/InterviewProceedResult.java index 7ac27e35..b5a5b548 100644 --- a/src/main/java/com/samhap/kokomen/interview/domain/InterviewProceedResult.java +++ b/src/main/java/com/samhap/kokomen/interview/tool/InterviewProceedResult.java @@ -1,7 +1,7 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; import com.samhap.kokomen.answer.domain.Answer; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Question; import java.util.Objects; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/samhap/kokomen/interview/domain/InterviewProceedState.java b/src/main/java/com/samhap/kokomen/interview/tool/InterviewProceedState.java similarity index 73% rename from src/main/java/com/samhap/kokomen/interview/domain/InterviewProceedState.java rename to src/main/java/com/samhap/kokomen/interview/tool/InterviewProceedState.java index 1a8824fd..a518c525 100644 --- a/src/main/java/com/samhap/kokomen/interview/domain/InterviewProceedState.java +++ b/src/main/java/com/samhap/kokomen/interview/tool/InterviewProceedState.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; public enum InterviewProceedState { LLM_PENDING, diff --git a/src/main/java/com/samhap/kokomen/interview/domain/QuestionAndAnswers.java b/src/main/java/com/samhap/kokomen/interview/tool/QuestionAndAnswers.java similarity index 95% rename from src/main/java/com/samhap/kokomen/interview/domain/QuestionAndAnswers.java rename to src/main/java/com/samhap/kokomen/interview/tool/QuestionAndAnswers.java index e7f26809..362e7419 100644 --- a/src/main/java/com/samhap/kokomen/interview/domain/QuestionAndAnswers.java +++ b/src/main/java/com/samhap/kokomen/interview/tool/QuestionAndAnswers.java @@ -1,10 +1,10 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; import com.samhap.kokomen.global.exception.BadRequestException; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; import com.samhap.kokomen.interview.external.dto.response.AnswerFeedbackResponse; import com.samhap.kokomen.interview.external.dto.response.AnswerRankResponse; import java.util.Comparator; diff --git a/src/main/java/com/samhap/kokomen/interview/domain/QuestionVoicePathResolver.java b/src/main/java/com/samhap/kokomen/interview/tool/QuestionVoicePathResolver.java similarity index 97% rename from src/main/java/com/samhap/kokomen/interview/domain/QuestionVoicePathResolver.java rename to src/main/java/com/samhap/kokomen/interview/tool/QuestionVoicePathResolver.java index 189f275b..930846ee 100644 --- a/src/main/java/com/samhap/kokomen/interview/domain/QuestionVoicePathResolver.java +++ b/src/main/java/com/samhap/kokomen/interview/tool/QuestionVoicePathResolver.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; import static com.samhap.kokomen.global.constant.AwsConstant.CLOUD_FRONT_DOMAIN_URL; diff --git a/src/main/java/com/samhap/kokomen/member/service/MemberService.java b/src/main/java/com/samhap/kokomen/member/service/MemberService.java index af26ed0c..1bebc4d1 100644 --- a/src/main/java/com/samhap/kokomen/member/service/MemberService.java +++ b/src/main/java/com/samhap/kokomen/member/service/MemberService.java @@ -17,7 +17,7 @@ import com.samhap.kokomen.member.service.dto.RankingResponse; import com.samhap.kokomen.token.domain.Token; import com.samhap.kokomen.token.domain.TokenType; -import com.samhap.kokomen.token.service.TokenService; +import com.samhap.kokomen.token.service.TokenFacadeService; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; @@ -37,7 +37,7 @@ public class MemberService { private final MemberRepository memberRepository; private final MemberSocialLoginRepository memberSocialLoginRepository; - private final TokenService tokenService; + private final TokenFacadeService tokenFacadeService; private final InterviewRepository interviewRepository; @Value("${spring.profiles.active:local}") @@ -47,7 +47,7 @@ public class MemberService { public Member saveSocialMember(SocialProvider provider, String socialId, String nickname) { Member member = memberRepository.save(new Member(nickname)); memberSocialLoginRepository.save(new MemberSocialLogin(member, provider, socialId)); - tokenService.createTokensForNewMember(member.getId()); + tokenFacadeService.createTokensForNewMember(member.getId()); return member; } @@ -71,8 +71,8 @@ public MyProfileResponse findMember(MemberAuth memberAuth) { Member member = readById(memberAuth.memberId()); long rank = memberRepository.findRankByScore(member.getScore()); long totalMemberCount = memberRepository.count(); - Token freeToken = tokenService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.FREE); - Token paidToken = tokenService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.PAID); + Token freeToken = tokenFacadeService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.FREE); + Token paidToken = tokenFacadeService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.PAID); boolean isTestUser = isTestUser(memberAuth.memberId()); return new MyProfileResponse(member, totalMemberCount, rank, freeToken.getTokenCount() + paidToken.getTokenCount(), isTestUser); @@ -82,8 +82,8 @@ public MyProfileResponseV2 findMemberV2(MemberAuth memberAuth) { Member member = readById(memberAuth.memberId()); long rank = memberRepository.findRankByScore(member.getScore()); long totalMemberCount = memberRepository.count(); - Token freeToken = tokenService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.FREE); - Token paidToken = tokenService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.PAID); + Token freeToken = tokenFacadeService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.FREE); + Token paidToken = tokenFacadeService.readTokenByMemberIdAndType(memberAuth.memberId(), TokenType.PAID); return new MyProfileResponseV2(member, totalMemberCount, rank, freeToken.getTokenCount(), paidToken.getTokenCount()); } diff --git a/src/main/java/com/samhap/kokomen/payment/service/WebhookService.java b/src/main/java/com/samhap/kokomen/payment/service/WebhookService.java index 2445fc59..7440a088 100644 --- a/src/main/java/com/samhap/kokomen/payment/service/WebhookService.java +++ b/src/main/java/com/samhap/kokomen/payment/service/WebhookService.java @@ -10,8 +10,7 @@ import com.samhap.kokomen.payment.service.dto.WebhookPaymentData; import com.samhap.kokomen.token.domain.TokenPurchase; import com.samhap.kokomen.token.dto.PurchaseMetadata; -import com.samhap.kokomen.token.service.TokenPurchaseService; -import com.samhap.kokomen.token.service.TokenService; +import com.samhap.kokomen.token.service.TokenFacadeService; import com.samhap.kokomen.global.annotation.DistributedLock; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -25,8 +24,7 @@ public class WebhookService { private final TosspaymentsPaymentService tosspaymentsPaymentService; - private final TokenService tokenService; - private final TokenPurchaseService tokenPurchaseService; + private final TokenFacadeService tokenFacadeService; private final ObjectMapper objectMapper; @DistributedLock(prefix = "payment", key = "#payload.data().paymentKey()") @@ -75,9 +73,7 @@ private void handleDone(TosspaymentsPayment payment, WebhookPaymentData data) { .paymentMethod(data.method()) .easyPayProvider(data.easyPay() != null ? data.easyPay().provider() : null) .build(); - tokenPurchaseService.saveTokenPurchase(tokenPurchase); - - tokenService.addPaidTokens(memberId, tokenCount); + tokenFacadeService.grantPurchasedTokens(tokenPurchase, tokenCount); log.info("웹훅으로 토큰 지급 완료 - memberId: {}, paymentKey: {}, tokenCount: {}", memberId, payment.getPaymentKey(), tokenCount); diff --git a/src/main/java/com/samhap/kokomen/token/service/TokenFacadeService.java b/src/main/java/com/samhap/kokomen/token/service/TokenFacadeService.java index dc080a05..e925245a 100644 --- a/src/main/java/com/samhap/kokomen/token/service/TokenFacadeService.java +++ b/src/main/java/com/samhap/kokomen/token/service/TokenFacadeService.java @@ -9,8 +9,10 @@ import com.samhap.kokomen.payment.service.dto.PaymentResponse; import com.samhap.kokomen.product.domain.TokenProduct; import com.samhap.kokomen.token.domain.RefundReasonCode; +import com.samhap.kokomen.token.domain.Token; import com.samhap.kokomen.token.domain.TokenPurchase; import com.samhap.kokomen.token.domain.TokenPurchaseState; +import com.samhap.kokomen.token.domain.TokenType; import com.samhap.kokomen.token.dto.TokenPurchaseRequest; import com.samhap.kokomen.token.dto.TokenPurchaseResponse; import com.samhap.kokomen.token.dto.TokenPurchaseResponses; @@ -46,10 +48,9 @@ public void purchaseTokens(Long memberId, TokenPurchaseRequest request) { ConfirmRequest confirmRequest = request.toPaymentConfirmRequest(memberId, objectMapper); PaymentResponse paymentResponse = paymentFacadeService.confirmPayment(confirmRequest); - tokenPurchaseService.saveTokenPurchase( - request.toTokenPurchase(memberId, paymentResponse.method(), - paymentResponse.easyPay() != null ? paymentResponse.easyPay().provider() : null)); - tokenService.addPaidTokens(memberId, tokenCount); + TokenPurchase tokenPurchase = request.toTokenPurchase(memberId, paymentResponse.method(), + getEasyPayProvider(paymentResponse)); + grantPurchasedTokens(tokenPurchase, tokenCount); log.info("토큰 구매 완료 - memberId: {}, paymentKey: {}, 증가된 토큰: {}", memberId, request.paymentKey(), tokenCount); } @@ -59,6 +60,13 @@ private int getTokenCountFromProductName(String productName) { return product.getTokenCount(); } + private static String getEasyPayProvider(PaymentResponse paymentResponse) { + if (paymentResponse.easyPay() != null) { + return paymentResponse.easyPay().provider(); + } + return null; + } + private void validateTokenPrice(TokenPurchaseRequest request) { String productName = request.productName(); long totalAmount = request.price(); @@ -149,6 +157,26 @@ public void refundTokens(Long memberId, Long tokenPurchaseId, TokenRefundRequest refundTokenCount); } + @Transactional + public void grantPurchasedTokens(TokenPurchase tokenPurchase, int tokenCount) { + tokenPurchaseService.saveTokenPurchase(tokenPurchase); + tokenService.addPaidTokens(tokenPurchase.getMemberId(), tokenCount); + } + + public void createTokensForNewMember(Long memberId) { + tokenService.createTokensForNewMember(memberId); + } + + @Transactional(readOnly = true) + public void validateEnoughTokens(Long memberId, int requiredCount) { + tokenService.validateEnoughTokens(memberId, requiredCount); + } + + @Transactional(readOnly = true) + public Token readTokenByMemberIdAndType(Long memberId, TokenType type) { + return tokenService.readTokenByMemberIdAndType(memberId, type); + } + @Transactional(readOnly = true) public TokenPurchaseResponses readMyTokenPurchases(Long memberId, TokenPurchaseState state, Pageable pageable) { Page tokenPurchasePage = tokenPurchaseService.findTokenPurchasesByMemberId(memberId, state, diff --git a/src/test/java/com/samhap/kokomen/admin/controller/AdminControllerTest.java b/src/test/java/com/samhap/kokomen/admin/controller/AdminControllerTest.java index fecc7ab8..59404eda 100644 --- a/src/test/java/com/samhap/kokomen/admin/controller/AdminControllerTest.java +++ b/src/test/java/com/samhap/kokomen/admin/controller/AdminControllerTest.java @@ -12,7 +12,7 @@ import com.samhap.kokomen.global.BaseControllerTest; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.external.dto.response.SupertoneResponse; import com.samhap.kokomen.interview.repository.RootQuestionRepository; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/samhap/kokomen/answer/controller/AnswerControllerTest.java b/src/test/java/com/samhap/kokomen/answer/controller/AnswerControllerTest.java index 0f055084..61e36872 100644 --- a/src/test/java/com/samhap/kokomen/answer/controller/AnswerControllerTest.java +++ b/src/test/java/com/samhap/kokomen/answer/controller/AnswerControllerTest.java @@ -28,9 +28,9 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; diff --git a/src/test/java/com/samhap/kokomen/answer/repository/AnswerLikeRepositoryTest.java b/src/test/java/com/samhap/kokomen/answer/repository/AnswerLikeRepositoryTest.java index b040e71c..5e299f43 100644 --- a/src/test/java/com/samhap/kokomen/answer/repository/AnswerLikeRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/answer/repository/AnswerLikeRepositoryTest.java @@ -10,9 +10,9 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; diff --git a/src/test/java/com/samhap/kokomen/answer/repository/AnswerMemoRepositoryTest.java b/src/test/java/com/samhap/kokomen/answer/repository/AnswerMemoRepositoryTest.java index 1cb69012..6f5ebd3b 100644 --- a/src/test/java/com/samhap/kokomen/answer/repository/AnswerMemoRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/answer/repository/AnswerMemoRepositoryTest.java @@ -13,10 +13,10 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; diff --git a/src/test/java/com/samhap/kokomen/answer/service/AnswerFacadeServiceTest.java b/src/test/java/com/samhap/kokomen/answer/service/AnswerFacadeServiceTest.java index db298970..ed69be6a 100644 --- a/src/test/java/com/samhap/kokomen/answer/service/AnswerFacadeServiceTest.java +++ b/src/test/java/com/samhap/kokomen/answer/service/AnswerFacadeServiceTest.java @@ -11,9 +11,9 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; diff --git a/src/test/java/com/samhap/kokomen/global/BaseTest.java b/src/test/java/com/samhap/kokomen/global/BaseTest.java index 147c4ea9..c72f7921 100644 --- a/src/test/java/com/samhap/kokomen/global/BaseTest.java +++ b/src/test/java/com/samhap/kokomen/global/BaseTest.java @@ -7,7 +7,7 @@ import com.samhap.kokomen.interview.external.ResumeBasedQuestionBedrockService; import com.samhap.kokomen.interview.external.ResumeBasedQuestionGptClient; import com.samhap.kokomen.interview.external.SupertoneClient; -import com.samhap.kokomen.interview.service.QuestionGenerationAsyncService; +import com.samhap.kokomen.interview.service.question.QuestionGenerationAsyncService; import com.samhap.kokomen.resume.external.ResumeEvaluationGptClient; import com.samhap.kokomen.payment.external.TosspaymentsClient; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/samhap/kokomen/global/fixture/answer/AnswerFixtureBuilder.java b/src/test/java/com/samhap/kokomen/global/fixture/answer/AnswerFixtureBuilder.java index 87bad25b..d893451f 100644 --- a/src/test/java/com/samhap/kokomen/global/fixture/answer/AnswerFixtureBuilder.java +++ b/src/test/java/com/samhap/kokomen/global/fixture/answer/AnswerFixtureBuilder.java @@ -3,7 +3,7 @@ import com.samhap.kokomen.answer.domain.Answer; import com.samhap.kokomen.answer.domain.AnswerRank; import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Question; public class AnswerFixtureBuilder { diff --git a/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewFixtureBuilder.java b/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewFixtureBuilder.java index f190ba52..8143658c 100644 --- a/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewFixtureBuilder.java +++ b/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewFixtureBuilder.java @@ -1,11 +1,11 @@ package com.samhap.kokomen.global.fixture.interview; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.InterviewType; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.InterviewType; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.member.domain.Member; import java.time.LocalDateTime; diff --git a/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewLikeFixtureBuilder.java b/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewLikeFixtureBuilder.java index afef4670..a17e9c8a 100644 --- a/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewLikeFixtureBuilder.java +++ b/src/test/java/com/samhap/kokomen/global/fixture/interview/InterviewLikeFixtureBuilder.java @@ -1,8 +1,8 @@ package com.samhap.kokomen.global.fixture.interview; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewLike; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewLike; import com.samhap.kokomen.member.domain.Member; public class InterviewLikeFixtureBuilder { diff --git a/src/test/java/com/samhap/kokomen/global/fixture/interview/QuestionFixtureBuilder.java b/src/test/java/com/samhap/kokomen/global/fixture/interview/QuestionFixtureBuilder.java index 7ea65b98..2cbad1c8 100644 --- a/src/test/java/com/samhap/kokomen/global/fixture/interview/QuestionFixtureBuilder.java +++ b/src/test/java/com/samhap/kokomen/global/fixture/interview/QuestionFixtureBuilder.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.global.fixture.interview; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; public class QuestionFixtureBuilder { diff --git a/src/test/java/com/samhap/kokomen/global/fixture/interview/ResumeQuestionGenerationFixtureBuilder.java b/src/test/java/com/samhap/kokomen/global/fixture/interview/ResumeQuestionGenerationFixtureBuilder.java index 27dffd7a..c8d781a7 100644 --- a/src/test/java/com/samhap/kokomen/global/fixture/interview/ResumeQuestionGenerationFixtureBuilder.java +++ b/src/test/java/com/samhap/kokomen/global/fixture/interview/ResumeQuestionGenerationFixtureBuilder.java @@ -1,7 +1,7 @@ package com.samhap.kokomen.global.fixture.interview; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.resume.domain.MemberPortfolio; import com.samhap.kokomen.resume.domain.MemberResume; diff --git a/src/test/java/com/samhap/kokomen/global/fixture/interview/RootQuestionFixtureBuilder.java b/src/test/java/com/samhap/kokomen/global/fixture/interview/RootQuestionFixtureBuilder.java index 598a5b60..75be26c1 100644 --- a/src/test/java/com/samhap/kokomen/global/fixture/interview/RootQuestionFixtureBuilder.java +++ b/src/test/java/com/samhap/kokomen/global/fixture/interview/RootQuestionFixtureBuilder.java @@ -1,8 +1,8 @@ package com.samhap.kokomen.global.fixture.interview; import com.samhap.kokomen.category.domain.Category; -import com.samhap.kokomen.interview.entity.RootQuestion; -import com.samhap.kokomen.interview.entity.RootQuestionState; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestionState; public class RootQuestionFixtureBuilder { diff --git a/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerTest.java b/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerTest.java index d8d7c3b4..023220ed 100644 --- a/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerTest.java +++ b/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerTest.java @@ -35,11 +35,11 @@ import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; import com.samhap.kokomen.global.fixture.token.TokenFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.external.dto.response.SupertoneResponse; import com.samhap.kokomen.interview.repository.InterviewLikeRepository; import com.samhap.kokomen.interview.repository.InterviewRepository; diff --git a/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java b/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java index 95ec9c70..0a13287b 100644 --- a/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java +++ b/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java @@ -25,17 +25,17 @@ import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; import com.samhap.kokomen.global.fixture.token.TokenFixtureBuilder; import com.samhap.kokomen.global.service.RedisService; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.external.dto.response.SupertoneResponse; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; -import com.samhap.kokomen.interview.service.InterviewFacadeService; +import com.samhap.kokomen.interview.service.InterviewProceedFacadeService; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import com.samhap.kokomen.token.domain.TokenType; @@ -127,7 +127,7 @@ class InterviewControllerV2Test extends BaseControllerTest { answerRepository.save(AnswerFixtureBuilder.builder().question(question1).build()); Question question2 = questionRepository.save(QuestionFixtureBuilder.builder().interview(interview).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.LLM_PENDING.name(), Duration.ofSeconds(10)); @@ -177,7 +177,7 @@ class InterviewControllerV2Test extends BaseControllerTest { answerRepository.save(AnswerFixtureBuilder.builder().question(question1).build()); Question question2 = questionRepository.save(QuestionFixtureBuilder.builder().interview(interview).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.LLM_FAILED.name(), Duration.ofSeconds(10)); @@ -228,7 +228,7 @@ class InterviewControllerV2Test extends BaseControllerTest { answerRepository.save(AnswerFixtureBuilder.builder().question(question1).build()); Question question2 = questionRepository.save(QuestionFixtureBuilder.builder().interview(interview).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.TTS_PENDING.name(), Duration.ofSeconds(10)); @@ -279,7 +279,7 @@ class InterviewControllerV2Test extends BaseControllerTest { answerRepository.save(AnswerFixtureBuilder.builder().question(question1).build()); Question question2 = questionRepository.save(QuestionFixtureBuilder.builder().interview(interview).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.TTS_FAILED.name(), Duration.ofSeconds(10)); @@ -331,7 +331,7 @@ class InterviewControllerV2Test extends BaseControllerTest { Question question2 = questionRepository.save(QuestionFixtureBuilder.builder().interview(interview).build()); answerRepository.save(AnswerFixtureBuilder.builder().question(question2).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.COMPLETED.name(), Duration.ofSeconds(10)); @@ -385,7 +385,7 @@ class InterviewControllerV2Test extends BaseControllerTest { questionRepository.save( QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.COMPLETED.name(), Duration.ofSeconds(10)); @@ -447,7 +447,7 @@ class InterviewControllerV2Test extends BaseControllerTest { questionRepository.save( QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.COMPLETED.name(), Duration.ofSeconds(10)); diff --git a/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV3Test.java b/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV3Test.java index 2a6d6337..25f385d1 100644 --- a/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV3Test.java +++ b/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV3Test.java @@ -18,8 +18,8 @@ import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; import com.samhap.kokomen.global.fixture.token.TokenFixtureBuilder; -import com.samhap.kokomen.interview.entity.RootQuestion; -import com.samhap.kokomen.interview.entity.RootQuestionState; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestionState; import com.samhap.kokomen.interview.repository.RootQuestionRepository; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; diff --git a/src/test/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewControllerTest.java b/src/test/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewControllerTest.java index 9ebb0ca8..a7a1352c 100644 --- a/src/test/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewControllerTest.java +++ b/src/test/java/com/samhap/kokomen/interview/controller/ResumeBasedInterviewControllerTest.java @@ -26,9 +26,9 @@ import com.samhap.kokomen.global.fixture.resume.MemberPortfolioFixtureBuilder; import com.samhap.kokomen.global.fixture.resume.MemberResumeFixtureBuilder; import com.samhap.kokomen.global.fixture.token.TokenFixtureBuilder; -import com.samhap.kokomen.interview.entity.GeneratedQuestion; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.domain.GeneratedQuestion; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; import com.samhap.kokomen.interview.external.dto.response.SupertoneResponse; import com.samhap.kokomen.interview.repository.GeneratedQuestionRepository; import com.samhap.kokomen.interview.repository.ResumeQuestionGenerationRepository; diff --git a/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsTest.java b/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsTest.java index 0a93137f..407c4a97 100644 --- a/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsTest.java +++ b/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsTest.java @@ -13,10 +13,10 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; diff --git a/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsV2Test.java b/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsV2Test.java index 1c7779bb..756232b0 100644 --- a/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsV2Test.java +++ b/src/test/java/com/samhap/kokomen/interview/docs/InterviewDocsV2Test.java @@ -20,16 +20,16 @@ import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; import com.samhap.kokomen.global.service.RedisService; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; -import com.samhap.kokomen.interview.service.InterviewFacadeService; +import com.samhap.kokomen.interview.service.InterviewProceedFacadeService; import com.samhap.kokomen.interview.service.dto.AnswerRequestV2; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; @@ -75,7 +75,7 @@ class InterviewDocsV2Test extends DocsTest { Question question3 = questionRepository.save( QuestionFixtureBuilder.builder().interview(interview).content(rootQuestion.getContent()).build()); answerRepository.save(AnswerFixtureBuilder.builder().question(question3).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question3.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.COMPLETED.name(), Duration.ofSeconds(10)); @@ -126,7 +126,7 @@ class InterviewDocsV2Test extends DocsTest { answerRepository.save(AnswerFixtureBuilder.builder().question(question2).build()); questionRepository.save( QuestionFixtureBuilder.builder().interview(interview).content(rootQuestion.getContent()).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.COMPLETED.name(), Duration.ofSeconds(10)); diff --git a/src/test/java/com/samhap/kokomen/interview/repository/AnswerRepositoryTest.java b/src/test/java/com/samhap/kokomen/interview/repository/AnswerRepositoryTest.java index 02627f16..0f4b4b52 100644 --- a/src/test/java/com/samhap/kokomen/interview/repository/AnswerRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/interview/repository/AnswerRepositoryTest.java @@ -11,9 +11,9 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import java.util.List; diff --git a/src/test/java/com/samhap/kokomen/interview/repository/InterviewBatchRepositoryTest.java b/src/test/java/com/samhap/kokomen/interview/repository/InterviewBatchRepositoryTest.java index 0a27a0cf..442fd62b 100644 --- a/src/test/java/com/samhap/kokomen/interview/repository/InterviewBatchRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/interview/repository/InterviewBatchRepositoryTest.java @@ -6,8 +6,8 @@ import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import java.util.HashMap; diff --git a/src/test/java/com/samhap/kokomen/interview/repository/InterviewLikeRepositoryTest.java b/src/test/java/com/samhap/kokomen/interview/repository/InterviewLikeRepositoryTest.java index c1f1442d..14f5ba1e 100644 --- a/src/test/java/com/samhap/kokomen/interview/repository/InterviewLikeRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/interview/repository/InterviewLikeRepositoryTest.java @@ -7,8 +7,8 @@ import com.samhap.kokomen.global.fixture.interview.InterviewLikeFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import java.util.List; diff --git a/src/test/java/com/samhap/kokomen/interview/repository/InterviewRepositoryTest.java b/src/test/java/com/samhap/kokomen/interview/repository/InterviewRepositoryTest.java index dc478a7d..2ba570b1 100644 --- a/src/test/java/com/samhap/kokomen/interview/repository/InterviewRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/interview/repository/InterviewRepositoryTest.java @@ -6,9 +6,9 @@ import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.dto.DailyInterviewCount; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; diff --git a/src/test/java/com/samhap/kokomen/interview/repository/QuestionRepositoryTest.java b/src/test/java/com/samhap/kokomen/interview/repository/QuestionRepositoryTest.java index 9198d07e..b92a263d 100644 --- a/src/test/java/com/samhap/kokomen/interview/repository/QuestionRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/interview/repository/QuestionRepositoryTest.java @@ -7,9 +7,9 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/samhap/kokomen/interview/repository/RootQuestionRepositoryTest.java b/src/test/java/com/samhap/kokomen/interview/repository/RootQuestionRepositoryTest.java index 8f0bde3a..22339966 100644 --- a/src/test/java/com/samhap/kokomen/interview/repository/RootQuestionRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/interview/repository/RootQuestionRepositoryTest.java @@ -7,8 +7,8 @@ import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.RootQuestion; -import com.samhap.kokomen.interview.entity.RootQuestionState; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.domain.RootQuestionState; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import java.util.Optional; diff --git a/src/test/java/com/samhap/kokomen/interview/service/InterviewFacadeServiceTest.java b/src/test/java/com/samhap/kokomen/interview/service/InterviewProceedFacadeServiceTest.java similarity index 57% rename from src/test/java/com/samhap/kokomen/interview/service/InterviewFacadeServiceTest.java rename to src/test/java/com/samhap/kokomen/interview/service/InterviewProceedFacadeServiceTest.java index f104be81..de0c9d7a 100644 --- a/src/test/java/com/samhap/kokomen/interview/service/InterviewFacadeServiceTest.java +++ b/src/test/java/com/samhap/kokomen/interview/service/InterviewProceedFacadeServiceTest.java @@ -14,12 +14,12 @@ import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; import com.samhap.kokomen.global.service.RedisService; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.domain.InterviewProceedState; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.tool.InterviewProceedState; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; @@ -27,14 +27,13 @@ import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import java.time.Duration; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -class InterviewFacadeServiceTest extends BaseTest { +class InterviewProceedFacadeServiceTest extends BaseTest { @Autowired - private InterviewFacadeService interviewFacadeService; + private InterviewProceedFacadeService interviewProceedFacadeService; @Autowired private InterviewRepository interviewRepository; @Autowired @@ -61,12 +60,12 @@ class InterviewFacadeServiceTest extends BaseTest { answerRepository.save(AnswerFixtureBuilder.builder().question(question2).answerRank(AnswerRank.A).build()); questionRepository.save(QuestionFixtureBuilder.builder().build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question2.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.COMPLETED.name(), Duration.ofSeconds(10)); // when & then - assertThatThrownBy(() -> interviewFacadeService.findInterviewProceedState(interview.getId(), question1.getId(), + assertThatThrownBy(() -> interviewProceedFacadeService.findInterviewProceedState(interview.getId(), question1.getId(), InterviewMode.TEXT, new MemberAuth(member.getId()))) .isInstanceOf(BadRequestException.class) @@ -88,12 +87,12 @@ class InterviewFacadeServiceTest extends BaseTest { Question question3 = questionRepository.save(QuestionFixtureBuilder.builder().build()); answerRepository.save(AnswerFixtureBuilder.builder().question(question3).answerRank(AnswerRank.A).build()); - String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(), + String interviewProceedStateKey = InterviewProceedFacadeService.createInterviewProceedStateKey(interview.getId(), question3.getId()); redisService.setValue(interviewProceedStateKey, InterviewProceedState.COMPLETED.name(), Duration.ofSeconds(10)); // when & then - assertThatThrownBy(() -> interviewFacadeService.findInterviewProceedState(interview.getId(), question2.getId(), + assertThatThrownBy(() -> interviewProceedFacadeService.findInterviewProceedState(interview.getId(), question2.getId(), InterviewMode.TEXT, new MemberAuth(member.getId()))) .isInstanceOf(BadRequestException.class) @@ -114,78 +113,10 @@ class InterviewFacadeServiceTest extends BaseTest { // when InterviewProceedStateResponse interviewProceedState = - interviewFacadeService.findInterviewProceedState(interview.getId(), question2.getId(), + interviewProceedFacadeService.findInterviewProceedState(interview.getId(), question2.getId(), InterviewMode.TEXT, new MemberAuth(member.getId())); // then assertThat(interviewProceedState.proceedState()).isEqualTo(InterviewProceedState.LLM_FAILED); } - - @Test - void 아직_좋아요를_누르지_않은_인터뷰에_좋아요를_요청할_수_있다() { - // given - Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); - RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); - Interview interview = interviewRepository.save( - InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(0L).build()); - - // when - interviewFacadeService.likeInterview(interview.getId(), new MemberAuth(member.getId())); - - // then - Interview found = interviewRepository.findById(interview.getId()).get(); - assertThat(found.getLikeCount()).isEqualTo(interview.getLikeCount() + 1); - } - - @Disabled - @Test - void 이미_좋아요를_누른_인터뷰에_좋아요를_요청하면_예외가_발생한다() { - // given - Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); - RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); - Interview interview = interviewRepository.save( - InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(0L).build()); - interviewFacadeService.likeInterview(interview.getId(), new MemberAuth(member.getId())); - - // when & then - assertThatThrownBy( - () -> interviewFacadeService.likeInterview(interview.getId(), new MemberAuth(member.getId()))) - .isInstanceOf(BadRequestException.class) - .hasMessageContaining("이미 좋아요를 누른 인터뷰입니다."); - } - - @Test - void 이미_좋아요를_누른_인터뷰에_대해_좋아요를_취소할_수_있다() { - // given - Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); - RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); - Interview interview = interviewRepository.save( - InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(1L).build()); - interviewFacadeService.likeInterview(interview.getId(), new MemberAuth(member.getId())); - - // when - interviewFacadeService.unlikeInterview(interview.getId(), new MemberAuth(member.getId())); - - // then - Interview found = interviewRepository.findById(interview.getId()).get(); - assertThat(found.getLikeCount()).isEqualTo(interview.getLikeCount()); - } - - @Test - void 인터뷰에_좋아요를_누르면_최신_좋아요_수로_이벤트가_발행된다() { - // given - Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); - RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); - Interview interview = interviewRepository.save( - InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(0L).build()); - MemberAuth memberAuth = new MemberAuth(member.getId()); - Long beforeLikeCount = interview.getLikeCount(); - - // when - interviewFacadeService.likeInterview(interview.getId(), memberAuth); - - // then - Interview updatedInterview = interviewRepository.findById(interview.getId()).get(); - assertThat(updatedInterview.getLikeCount()).isEqualTo(beforeLikeCount + 1); - } } diff --git a/src/test/java/com/samhap/kokomen/interview/service/InterviewQueryServiceTest.java b/src/test/java/com/samhap/kokomen/interview/service/InterviewQueryServiceTest.java new file mode 100644 index 00000000..9e699d08 --- /dev/null +++ b/src/test/java/com/samhap/kokomen/interview/service/InterviewQueryServiceTest.java @@ -0,0 +1,100 @@ +package com.samhap.kokomen.interview.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.samhap.kokomen.global.BaseTest; +import com.samhap.kokomen.global.dto.MemberAuth; +import com.samhap.kokomen.global.exception.BadRequestException; +import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; +import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; +import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.RootQuestion; +import com.samhap.kokomen.interview.repository.InterviewRepository; +import com.samhap.kokomen.interview.repository.RootQuestionRepository; +import com.samhap.kokomen.member.domain.Member; +import com.samhap.kokomen.member.repository.MemberRepository; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class InterviewQueryServiceTest extends BaseTest { + + @Autowired + private InterviewQueryService interviewQueryService; + @Autowired + private InterviewRepository interviewRepository; + @Autowired + private MemberRepository memberRepository; + @Autowired + private RootQuestionRepository rootQuestionRepository; + + @Test + void 아직_좋아요를_누르지_않은_인터뷰에_좋아요를_요청할_수_있다() { + // given + Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); + RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); + Interview interview = interviewRepository.save( + InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(0L).build()); + + // when + interviewQueryService.likeInterview(interview.getId(), new MemberAuth(member.getId())); + + // then + Interview found = interviewRepository.findById(interview.getId()).get(); + assertThat(found.getLikeCount()).isEqualTo(interview.getLikeCount() + 1); + } + + @Disabled + @Test + void 이미_좋아요를_누른_인터뷰에_좋아요를_요청하면_예외가_발생한다() { + // given + Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); + RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); + Interview interview = interviewRepository.save( + InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(0L).build()); + interviewQueryService.likeInterview(interview.getId(), new MemberAuth(member.getId())); + + // when & then + assertThatThrownBy( + () -> interviewQueryService.likeInterview(interview.getId(), new MemberAuth(member.getId()))) + .isInstanceOf(BadRequestException.class) + .hasMessageContaining("이미 좋아요를 누른 인터뷰입니다."); + } + + @Test + void 이미_좋아요를_누른_인터뷰에_대해_좋아요를_취소할_수_있다() { + // given + Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); + RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); + Interview interview = interviewRepository.save( + InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(1L).build()); + interviewQueryService.likeInterview(interview.getId(), new MemberAuth(member.getId())); + + // when + interviewQueryService.unlikeInterview(interview.getId(), new MemberAuth(member.getId())); + + // then + Interview found = interviewRepository.findById(interview.getId()).get(); + assertThat(found.getLikeCount()).isEqualTo(interview.getLikeCount()); + } + + @Test + void 인터뷰에_좋아요를_누르면_최신_좋아요_수로_이벤트가_발행된다() { + // given + Member member = memberRepository.save(MemberFixtureBuilder.builder().build()); + RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); + Interview interview = interviewRepository.save( + InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).likeCount(0L).build()); + MemberAuth memberAuth = new MemberAuth(member.getId()); + Long beforeLikeCount = interview.getLikeCount(); + + // when + interviewQueryService.likeInterview(interview.getId(), memberAuth); + + // then + Interview updatedInterview = interviewRepository.findById(interview.getId()).get(); + assertThat(updatedInterview.getLikeCount()).isEqualTo(beforeLikeCount + 1); + } +} diff --git a/src/test/java/com/samhap/kokomen/interview/service/InterviewServiceTest.java b/src/test/java/com/samhap/kokomen/interview/service/core/InterviewServiceTest.java similarity index 99% rename from src/test/java/com/samhap/kokomen/interview/service/InterviewServiceTest.java rename to src/test/java/com/samhap/kokomen/interview/service/core/InterviewServiceTest.java index 551c0b64..858782ab 100644 --- a/src/test/java/com/samhap/kokomen/interview/service/InterviewServiceTest.java +++ b/src/test/java/com/samhap/kokomen/interview/service/core/InterviewServiceTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.core; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -23,10 +23,10 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewLikeRepository; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; diff --git a/src/test/java/com/samhap/kokomen/interview/service/InterviewSchedulerServiceTest.java b/src/test/java/com/samhap/kokomen/interview/service/infra/InterviewSchedulerServiceTest.java similarity index 82% rename from src/test/java/com/samhap/kokomen/interview/service/InterviewSchedulerServiceTest.java rename to src/test/java/com/samhap/kokomen/interview/service/infra/InterviewSchedulerServiceTest.java index 93062c73..7ed08059 100644 --- a/src/test/java/com/samhap/kokomen/interview/service/InterviewSchedulerServiceTest.java +++ b/src/test/java/com/samhap/kokomen/interview/service/infra/InterviewSchedulerServiceTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.infra; import static org.assertj.core.api.Assertions.assertThat; @@ -7,10 +7,11 @@ import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; import com.samhap.kokomen.global.service.RedisService; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; +import com.samhap.kokomen.interview.service.social.InterviewViewCountService; import com.samhap.kokomen.member.domain.Member; import com.samhap.kokomen.member.repository.MemberRepository; import java.time.Duration; @@ -38,12 +39,14 @@ void batchUpdateInterviewViewCount() { RootQuestion rootQuestion = rootQuestionRepository.save(RootQuestionFixtureBuilder.builder().build()); for (int i = 0; i < interviewCount; i++) { interviewRepository.save( - InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion).interviewState(InterviewState.FINISHED).build()); + InterviewFixtureBuilder.builder().member(member).rootQuestion(rootQuestion) + .interviewState(InterviewState.FINISHED).build()); } for (long interviewId = 1; interviewId <= interviewCount; interviewId++) { String viewCount = String.valueOf(interviewId); - redisService.setIfAbsent(InterviewViewCountService.INTERVIEW_VIEW_COUNT_KEY_PREFIX + interviewId, viewCount, Duration.ofDays(1)); + redisService.setIfAbsent(InterviewViewCountService.INTERVIEW_VIEW_COUNT_KEY_PREFIX + interviewId, viewCount, + Duration.ofDays(1)); } // when diff --git a/src/test/java/com/samhap/kokomen/interview/service/RootQuestionServiceTest.java b/src/test/java/com/samhap/kokomen/interview/service/question/RootQuestionServiceTest.java similarity index 98% rename from src/test/java/com/samhap/kokomen/interview/service/RootQuestionServiceTest.java rename to src/test/java/com/samhap/kokomen/interview/service/question/RootQuestionServiceTest.java index f0df1c17..0871acda 100644 --- a/src/test/java/com/samhap/kokomen/interview/service/RootQuestionServiceTest.java +++ b/src/test/java/com/samhap/kokomen/interview/service/question/RootQuestionServiceTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.question; import static org.assertj.core.api.Assertions.assertThat; @@ -7,8 +7,8 @@ import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.InterviewMode; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.InterviewMode; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; import com.samhap.kokomen.interview.service.dto.InterviewRequest; diff --git a/src/test/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewServiceTest.java b/src/test/java/com/samhap/kokomen/interview/service/resume/ResumeBasedInterviewServiceTest.java similarity index 96% rename from src/test/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewServiceTest.java rename to src/test/java/com/samhap/kokomen/interview/service/resume/ResumeBasedInterviewServiceTest.java index b3ccf727..7227f31b 100644 --- a/src/test/java/com/samhap/kokomen/interview/service/ResumeBasedInterviewServiceTest.java +++ b/src/test/java/com/samhap/kokomen/interview/service/resume/ResumeBasedInterviewServiceTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.resume; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -12,8 +12,8 @@ import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; import com.samhap.kokomen.global.fixture.resume.MemberPortfolioFixtureBuilder; import com.samhap.kokomen.global.fixture.resume.MemberResumeFixtureBuilder; -import com.samhap.kokomen.interview.entity.ResumeQuestionGeneration; -import com.samhap.kokomen.interview.entity.ResumeQuestionGenerationState; +import com.samhap.kokomen.interview.domain.ResumeQuestionGeneration; +import com.samhap.kokomen.interview.domain.ResumeQuestionGenerationState; import com.samhap.kokomen.interview.repository.ResumeQuestionGenerationRepository; import com.samhap.kokomen.interview.service.dto.resumebased.QuestionGenerationSubmitResponse; import com.samhap.kokomen.interview.service.dto.resumebased.ResumeBasedQuestionGenerateRequest; diff --git a/src/test/java/com/samhap/kokomen/interview/service/InterviewViewCountServiceTest.java b/src/test/java/com/samhap/kokomen/interview/service/social/InterviewViewCountServiceTest.java similarity index 98% rename from src/test/java/com/samhap/kokomen/interview/service/InterviewViewCountServiceTest.java rename to src/test/java/com/samhap/kokomen/interview/service/social/InterviewViewCountServiceTest.java index 27054b4b..f566f5b8 100644 --- a/src/test/java/com/samhap/kokomen/interview/service/InterviewViewCountServiceTest.java +++ b/src/test/java/com/samhap/kokomen/interview/service/social/InterviewViewCountServiceTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.service; +package com.samhap.kokomen.interview.service.social; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; @@ -16,10 +16,10 @@ import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.Question; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.Question; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.QuestionRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; diff --git a/src/test/java/com/samhap/kokomen/interview/domain/InterviewMessagesFactoryTest.java b/src/test/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactoryTest.java similarity index 96% rename from src/test/java/com/samhap/kokomen/interview/domain/InterviewMessagesFactoryTest.java rename to src/test/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactoryTest.java index af8cc2e6..3a2fc51e 100644 --- a/src/test/java/com/samhap/kokomen/interview/domain/InterviewMessagesFactoryTest.java +++ b/src/test/java/com/samhap/kokomen/interview/tool/InterviewMessagesFactoryTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; import static org.assertj.core.api.Assertions.assertThat; @@ -6,8 +6,8 @@ import com.samhap.kokomen.global.fixture.answer.AnswerFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; import com.samhap.kokomen.interview.external.dto.request.GptMessage; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/samhap/kokomen/interview/domain/InterviewTest.java b/src/test/java/com/samhap/kokomen/interview/tool/InterviewTest.java similarity index 92% rename from src/test/java/com/samhap/kokomen/interview/domain/InterviewTest.java rename to src/test/java/com/samhap/kokomen/interview/tool/InterviewTest.java index ae624d9d..c5271a95 100644 --- a/src/test/java/com/samhap/kokomen/interview/domain/InterviewTest.java +++ b/src/test/java/com/samhap/kokomen/interview/tool/InterviewTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; @@ -6,8 +6,8 @@ import com.samhap.kokomen.global.exception.BadRequestException; import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.InterviewState; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.InterviewState; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/src/test/java/com/samhap/kokomen/interview/domain/QuestionAndAnswersTest.java b/src/test/java/com/samhap/kokomen/interview/tool/QuestionAndAnswersTest.java similarity index 97% rename from src/test/java/com/samhap/kokomen/interview/domain/QuestionAndAnswersTest.java rename to src/test/java/com/samhap/kokomen/interview/tool/QuestionAndAnswersTest.java index 28afdea0..a3d3e539 100644 --- a/src/test/java/com/samhap/kokomen/interview/domain/QuestionAndAnswersTest.java +++ b/src/test/java/com/samhap/kokomen/interview/tool/QuestionAndAnswersTest.java @@ -1,4 +1,4 @@ -package com.samhap.kokomen.interview.domain; +package com.samhap.kokomen.interview.tool; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -10,8 +10,8 @@ import com.samhap.kokomen.global.fixture.answer.AnswerFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.QuestionFixtureBuilder; -import com.samhap.kokomen.interview.entity.Interview; -import com.samhap.kokomen.interview.entity.Question; +import com.samhap.kokomen.interview.domain.Interview; +import com.samhap.kokomen.interview.domain.Question; import java.util.List; import java.util.stream.IntStream; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/samhap/kokomen/member/controller/MemberControllerTest.java b/src/test/java/com/samhap/kokomen/member/controller/MemberControllerTest.java index c1475a1b..d7417270 100644 --- a/src/test/java/com/samhap/kokomen/member/controller/MemberControllerTest.java +++ b/src/test/java/com/samhap/kokomen/member/controller/MemberControllerTest.java @@ -18,8 +18,8 @@ import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; import com.samhap.kokomen.member.domain.Member; diff --git a/src/test/java/com/samhap/kokomen/member/repository/MemberRepositoryTest.java b/src/test/java/com/samhap/kokomen/member/repository/MemberRepositoryTest.java index 3ba502d6..a4b80eb6 100644 --- a/src/test/java/com/samhap/kokomen/member/repository/MemberRepositoryTest.java +++ b/src/test/java/com/samhap/kokomen/member/repository/MemberRepositoryTest.java @@ -6,8 +6,8 @@ import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; import com.samhap.kokomen.member.domain.Member; diff --git a/src/test/java/com/samhap/kokomen/member/service/MemberServiceTest.java b/src/test/java/com/samhap/kokomen/member/service/MemberServiceTest.java index fd61af41..3470cb91 100644 --- a/src/test/java/com/samhap/kokomen/member/service/MemberServiceTest.java +++ b/src/test/java/com/samhap/kokomen/member/service/MemberServiceTest.java @@ -7,8 +7,8 @@ import com.samhap.kokomen.global.fixture.interview.InterviewFixtureBuilder; import com.samhap.kokomen.global.fixture.interview.RootQuestionFixtureBuilder; import com.samhap.kokomen.global.fixture.member.MemberFixtureBuilder; -import com.samhap.kokomen.interview.entity.InterviewState; -import com.samhap.kokomen.interview.entity.RootQuestion; +import com.samhap.kokomen.interview.domain.InterviewState; +import com.samhap.kokomen.interview.domain.RootQuestion; import com.samhap.kokomen.interview.repository.InterviewRepository; import com.samhap.kokomen.interview.repository.RootQuestionRepository; import com.samhap.kokomen.member.domain.Member;