From 666960972bc457d85f4da1fd31439744bcb1546f Mon Sep 17 00:00:00 2001 From: jmj Date: Thu, 4 Jun 2026 14:30:43 +0900 Subject: [PATCH] =?UTF-8?q?feat(session):=20=EC=A0=9C=EB=AA=A9=20=EB=AF=B8?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EB=AA=A8=EB=93=9C+=EC=A7=81?= =?UTF-8?q?=EA=B5=B0=20=EA=B7=9C=EC=B9=99=20=EC=A0=9C=EB=AA=A9=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 히스토리에서 "면접 #id" 대신 의미 있는 제목을 보이도록, 세션 생성 시 제목이 비어 있으면 "{직군} {모드}"(예: "백엔드 기술 면접")로 채운다. SessionMode/JobCategory 에 koreanLabel() 추가. 부수: StackupApplicationTests 에 누락됐던 SessionQuestionPoolRepository @MockitoBean 추가 (질문 풀 도입 PR에서 빠져 컨텍스트 로드가 깨져 있던 것 복구). Co-Authored-By: Claude Opus 4.8 --- .../session/application/SessionService.java | 13 ++++++++- .../stackup/session/domain/JobCategory.java | 11 +++++++- .../stackup/session/domain/SessionMode.java | 10 ++++++- .../stackup/StackupApplicationTests.java | 4 +++ .../application/SessionServiceTest.java | 28 +++++++++++++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/com/stackup/stackup/session/application/SessionService.java b/backend/src/main/java/com/stackup/stackup/session/application/SessionService.java index 53a6d479..dafd7a75 100644 --- a/backend/src/main/java/com/stackup/stackup/session/application/SessionService.java +++ b/backend/src/main/java/com/stackup/stackup/session/application/SessionService.java @@ -43,9 +43,10 @@ public class SessionService { @Transactional public SessionResult create(Long userId, SessionCreateCommand command) { User user = loadUser(userId); + String title = resolveTitle(command); InterviewSession session = sessionRepository.save(InterviewSession.create( user, - command.title(), + title, command.memo(), command.mode(), command.jobCategory(), @@ -145,6 +146,16 @@ public SessionResult updateMeta(Long userId, Long sessionId, String title, Strin return SessionResult.of(session, contextDocumentIds(sessionId)); } + // 제목 미입력 시 모드+직군으로 규칙 기반 제목 생성 (예: "백엔드 기술 면접"). + // 히스토리에서 "면접 #id" 대신 의미 있는 제목을 보이게 한다. + private String resolveTitle(SessionCreateCommand command) { + String title = command.title(); + if (title != null && !title.isBlank()) { + return title; + } + return command.jobCategory().koreanLabel() + " " + command.mode().koreanLabel(); + } + private User loadUser(Long userId) { return userRepository.findByIdAndDeletedFalse(userId) .orElseThrow(() -> new DomainException(ApiErrorCode.USER_NOT_FOUND)); diff --git a/backend/src/main/java/com/stackup/stackup/session/domain/JobCategory.java b/backend/src/main/java/com/stackup/stackup/session/domain/JobCategory.java index a976cd34..d32d6835 100644 --- a/backend/src/main/java/com/stackup/stackup/session/domain/JobCategory.java +++ b/backend/src/main/java/com/stackup/stackup/session/domain/JobCategory.java @@ -4,5 +4,14 @@ public enum JobCategory { FRONTEND, BACKEND, INFRA, - DBA + DBA; + + public String koreanLabel() { + return switch (this) { + case FRONTEND -> "프론트엔드"; + case BACKEND -> "백엔드"; + case INFRA -> "인프라"; + case DBA -> "DBA"; + }; + } } diff --git a/backend/src/main/java/com/stackup/stackup/session/domain/SessionMode.java b/backend/src/main/java/com/stackup/stackup/session/domain/SessionMode.java index 868130fa..b9c6fd47 100644 --- a/backend/src/main/java/com/stackup/stackup/session/domain/SessionMode.java +++ b/backend/src/main/java/com/stackup/stackup/session/domain/SessionMode.java @@ -3,5 +3,13 @@ public enum SessionMode { TECHNICAL, PERSONALITY, - INTEGRATED + INTEGRATED; + + public String koreanLabel() { + return switch (this) { + case TECHNICAL -> "기술 면접"; + case PERSONALITY -> "인성 면접"; + case INTEGRATED -> "종합 면접"; + }; + } } diff --git a/backend/src/test/java/com/stackup/stackup/StackupApplicationTests.java b/backend/src/test/java/com/stackup/stackup/StackupApplicationTests.java index d6a17090..54fd016f 100644 --- a/backend/src/test/java/com/stackup/stackup/StackupApplicationTests.java +++ b/backend/src/test/java/com/stackup/stackup/StackupApplicationTests.java @@ -13,6 +13,7 @@ import com.stackup.stackup.session.domain.MessageVoiceAnalysisRepository; import com.stackup.stackup.session.domain.SessionContextRepository; import com.stackup.stackup.session.domain.SessionFeedbackRepository; +import com.stackup.stackup.session.domain.SessionQuestionPoolRepository; import com.stackup.stackup.user.domain.UserRepository; import com.stackup.stackup.user.domain.consent.UserConsentRepository; import org.junit.jupiter.api.Test; @@ -61,6 +62,9 @@ class StackupApplicationTests { @MockitoBean private SessionFeedbackRepository sessionFeedbackRepository; + @MockitoBean + private SessionQuestionPoolRepository sessionQuestionPoolRepository; + @MockitoBean private MessageVoiceAnalysisRepository messageVoiceAnalysisRepository; diff --git a/backend/src/test/java/com/stackup/stackup/session/application/SessionServiceTest.java b/backend/src/test/java/com/stackup/stackup/session/application/SessionServiceTest.java index d550ef9e..675d8dfb 100644 --- a/backend/src/test/java/com/stackup/stackup/session/application/SessionServiceTest.java +++ b/backend/src/test/java/com/stackup/stackup/session/application/SessionServiceTest.java @@ -63,6 +63,34 @@ void create_savesSessionAndPublishesEvent() { verify(events).publishEvent(any(SessionCreatedEvent.class)); } + @Test + void create_generatesTitleFromModeAndJobWhenBlank() { + User user = userFixture(1L); + when(userRepository.findByIdAndDeletedFalse(1L)).thenReturn(Optional.of(user)); + when(sessionRepository.save(any(InterviewSession.class))).thenAnswer(inv -> inv.getArgument(0)); + + SessionResult result = service.create(1L, new SessionCreateCommand( + " ", null, SessionMode.TECHNICAL, JobCategory.BACKEND, + 5, 30, null, null, List.of() + )); + + assertThat(result.title()).isEqualTo("백엔드 기술 면접"); + } + + @Test + void create_keepsProvidedTitle() { + User user = userFixture(1L); + when(userRepository.findByIdAndDeletedFalse(1L)).thenReturn(Optional.of(user)); + when(sessionRepository.save(any(InterviewSession.class))).thenAnswer(inv -> inv.getArgument(0)); + + SessionResult result = service.create(1L, new SessionCreateCommand( + "내가 정한 제목", null, SessionMode.INTEGRATED, JobCategory.FRONTEND, + 5, 30, null, null, List.of() + )); + + assertThat(result.title()).isEqualTo("내가 정한 제목"); + } + @Test void create_linksAnalyzedContextDocuments() { User user = userFixture(1L);