Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/main/kotlin/codel/question/domain/QuestionCategory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ enum class QuestionCategory(
@Schema(description = "채팅방 그룹 정책")
val chatGroupPolicy: GroupPolicy
) {
// 회원가입 + 채팅방 양쪽 사용
@Schema(description = "가치관 관련 질문 (회원가입 + 채팅방)")
// 회원가입 전용
@Schema(description = "가치관 관련 질문 (회원가입 전용)")
VALUES(
displayName = "가치관",
description = "인생 가치관·성향",
usedInSignup = true,
usedInChat = true,
chatGroupPolicy = GroupPolicy.A_THEN_B
usedInChat = false,
chatGroupPolicy = GroupPolicy.NONE
),

// 회원가입 전용
Expand All @@ -35,11 +35,11 @@ enum class QuestionCategory(
chatGroupPolicy = GroupPolicy.NONE
),

@Schema(description = "현재 상태 관련 질문 (레거시)")
@Schema(description = "현재 상태 관련 질문")
CURRENT_ME(
displayName = "요즘 나",
description = "최근 상태·몰입한 것",
usedInSignup = false,
usedInSignup = true,
usedInChat = false,
chatGroupPolicy = GroupPolicy.NONE
),
Expand Down Expand Up @@ -81,6 +81,15 @@ enum class QuestionCategory(
),

// 채팅방 전용
@Schema(description = "가치관 코드 - 가치관으로 서로의 성격 코드 알아가기")
VALUES_CODE(
displayName = "가치관 코드",
description = "가치관으로 서로의 성격 코드 알아가기",
usedInSignup = false,
usedInChat = true,
chatGroupPolicy = GroupPolicy.A_THEN_B
),

@Schema(description = "텐션업 코드 - 가벼운 선택 질문")
TENSION_UP(
displayName = "텐션업 코드",
Expand Down
19 changes: 19 additions & 0 deletions src/main/resources/db/migration/V22__add_values_code_category.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-- VALUES_CODE 카테고리 추가 (채팅방 전용 가치관 코드)
-- Issue: #397

-- category ENUM에 VALUES_CODE 추가
ALTER TABLE question
MODIFY COLUMN category
ENUM(
'VALUES',
'VALUES_CODE',
'FAVORITE',
'CURRENT_ME',
'DATE',
'MEMORY',
'WANT_TALK',
'BALANCE_ONE',
'IF',
'TENSION_UP',
'SECRET'
) NOT NULL;
19 changes: 7 additions & 12 deletions src/main/resources/templates/questionEditForm.html
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,15 @@ <h1 class="fw-bold">질문 수정</h1>
// 용도별 카테고리 옵션
const categoryOptions = {
chatroom: [
{ value: 'VALUES', label: '가치관 코드' },
{ value: 'VALUES_CODE', label: '가치관 코드' },
{ value: 'TENSION_UP', label: '텐션업 코드' },
{ value: 'IF', label: '만약에 코드' },
{ value: 'SECRET', label: '비밀 코드 (19+)' }
],
profile: [
{ value: 'VALUES', label: '가치관' },
{ value: 'FAVORITE', label: 'favorite' },
{ value: 'CURRENT_ME', label: '요즘 나' },
{ value: 'DATE', label: '데이트' },
{ value: 'MEMORY', label: '추억' },
{ value: 'WANT_TALK', label: '이런대화해보고싶어' }
Expand All @@ -183,18 +184,20 @@ <h1 class="fw-bold">질문 수정</h1>

// 카테고리별 용도 매핑
const categoryToPurpose = {
'VALUES': 'both', // 양쪽 모두 가능
'VALUES': 'profile',
'VALUES_CODE': 'chatroom',
'TENSION_UP': 'chatroom',
'IF': 'chatroom',
'SECRET': 'chatroom',
'FAVORITE': 'profile',
'CURRENT_ME': 'profile',
'DATE': 'profile',
'MEMORY': 'profile',
'WANT_TALK': 'profile'
};

// 회원가입 전용 카테고리 (그룹 자동 RANDOM)
const signupOnlyCategories = ['FAVORITE', 'DATE', 'MEMORY', 'WANT_TALK'];
const signupOnlyCategories = ['FAVORITE', 'CURRENT_ME', 'DATE', 'MEMORY', 'WANT_TALK'];

const purposeSelect = document.getElementById('purpose');
const categorySelect = document.getElementById('category');
Expand Down Expand Up @@ -251,15 +254,7 @@ <h1 class="fw-bold">질문 수정</h1>
// 기존 카테고리로 용도 결정
const purpose = categoryToPurpose[currentCategory];

if (purpose === 'both') {
// VALUES는 채팅방 용도로 기본 설정 (채팅방에서 사용되는 경우가 더 흔함)
// 그룹이 RANDOM이면 profile, 아니면 chatroom으로 추정
if (currentGroup === 'RANDOM') {
purposeSelect.value = 'profile';
} else {
purposeSelect.value = 'chatroom';
}
} else if (purpose === 'chatroom') {
if (purpose === 'chatroom') {
purposeSelect.value = 'chatroom';
} else {
purposeSelect.value = 'profile';
Expand Down
5 changes: 3 additions & 2 deletions src/main/resources/templates/questionForm.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,22 +151,23 @@ <h1 class="fw-bold">새 질문 등록</h1>
// 용도별 카테고리 옵션
const categoryOptions = {
chatroom: [
{ value: 'VALUES', label: '가치관 코드' },
{ value: 'VALUES_CODE', label: '가치관 코드' },
{ value: 'TENSION_UP', label: '텐션업 코드' },
{ value: 'IF', label: '만약에 코드' },
{ value: 'SECRET', label: '비밀 코드 (19+)' }
],
profile: [
{ value: 'VALUES', label: '가치관' },
{ value: 'FAVORITE', label: 'favorite' },
{ value: 'CURRENT_ME', label: '요즘 나' },
{ value: 'DATE', label: '데이트' },
{ value: 'MEMORY', label: '추억' },
{ value: 'WANT_TALK', label: '이런대화해보고싶어' }
]
};

// 회원가입 전용 카테고리 (그룹 자동 RANDOM)
const signupOnlyCategories = ['FAVORITE', 'DATE', 'MEMORY', 'WANT_TALK'];
const signupOnlyCategories = ['FAVORITE', 'CURRENT_ME', 'DATE', 'MEMORY', 'WANT_TALK'];

const purposeSelect = document.getElementById('purpose');
const categorySelect = document.getElementById('category');
Expand Down
5 changes: 2 additions & 3 deletions src/main/resources/templates/questionList.html
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,15 @@ <h1 class="fw-bold">질문 관리</h1>
// 용도별 카테고리 옵션
const categoryOptions = {
chatroom: [
{ value: 'VALUES', label: '가치관 코드' },
{ value: 'VALUES_CODE', label: '가치관 코드' },
{ value: 'TENSION_UP', label: '텐션업 코드' },
{ value: 'IF', label: '만약에 코드' },
{ value: 'SECRET', label: '비밀 코드 (19+)' }
],
profile: [
{ value: 'VALUES', label: '가치관' },
{ value: 'FAVORITE', label: 'favorite' },
{ value: 'CURRENT_ME', label: '요즘 나' },
{ value: 'DATE', label: '데이트' },
{ value: 'MEMORY', label: '추억' },
{ value: 'WANT_TALK', label: '이런대화해보고싶어' }
Expand All @@ -225,8 +226,6 @@ <h1 class="fw-bold">질문 관리</h1>

html += '<optgroup label="회원가입·프로필 수정">';
categoryOptions.profile.forEach(opt => {
// VALUES는 이미 chatroom에서 추가했으므로 profile에서는 생략
if (opt.value === 'VALUES') return;
const selected = selectedCategory === opt.value ? ' selected' : '';
html += `<option value="${opt.value}"${selected}>${opt.label}</option>`;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class QuestionServiceRecommendationTest {
fun recommend_from_group_a_when_available() {
// given
val chatRoomId = 1L
val category = QuestionCategory.VALUES
val category = QuestionCategory.VALUES_CODE
val groupAQuestions = listOf(
createQuestion(1L, category, QuestionGroup.A),
createQuestion(2L, category, QuestionGroup.A)
Expand Down Expand Up @@ -82,7 +82,7 @@ class QuestionServiceRecommendationTest {
fun recommend_from_group_b_when_group_a_exhausted() {
// given
val chatRoomId = 1L
val category = QuestionCategory.VALUES
val category = QuestionCategory.VALUES_CODE
val groupBQuestions = listOf(
createQuestion(3L, category, QuestionGroup.B),
createQuestion(4L, category, QuestionGroup.B)
Expand Down Expand Up @@ -110,7 +110,7 @@ class QuestionServiceRecommendationTest {
fun return_exhausted_when_all_groups_exhausted() {
// given
val chatRoomId = 1L
val category = QuestionCategory.VALUES
val category = QuestionCategory.VALUES_CODE

`when`(questionJpaRepository.findUnusedQuestionsByChatRoomAndCategoryAndGroup(
chatRoomId, category, QuestionGroup.A
Expand Down
34 changes: 27 additions & 7 deletions src/test/kotlin/codel/question/domain/QuestionCategoryTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,32 @@ class QuestionCategoryTest {
@DisplayName("카테고리 용도 테스트")
inner class CategoryUsageTest {

@DisplayName("VALUES는 회원가입과 채팅방 양쪽에서 사용된다")
@DisplayName("VALUES는 회원가입에서만 사용된다")
@Test
fun values_used_in_both() {
fun values_used_in_signup_only() {
// given
val category = QuestionCategory.VALUES

// then
assertTrue(category.usedInSignup)
assertTrue(category.usedInChat)
assertFalse(category.usedInChat)
assertTrue(category.isSignupCategory())
assertFalse(category.isChatCategory())
assertEquals(GroupPolicy.NONE, category.chatGroupPolicy)
}

@DisplayName("VALUES_CODE는 채팅방에서만 사용된다")
@Test
fun values_code_used_in_chat_only() {
// given
val category = QuestionCategory.VALUES_CODE

// then
assertFalse(category.usedInSignup)
assertTrue(category.usedInChat)
assertFalse(category.isSignupCategory())
assertTrue(category.isChatCategory())
assertEquals(GroupPolicy.A_THEN_B, category.chatGroupPolicy)
}

@DisplayName("FAVORITE은 회원가입에서만 사용된다")
Expand Down Expand Up @@ -77,11 +92,11 @@ class QuestionCategoryTest {
@DisplayName("그룹 정책 테스트")
inner class GroupPolicyTest {

@DisplayName("VALUES는 A_THEN_B 그룹 정책을 사용한다")
@DisplayName("VALUES_CODE는 A_THEN_B 그룹 정책을 사용한다")
@Test
fun values_has_a_then_b_policy() {
fun values_code_has_a_then_b_policy() {
// given
val category = QuestionCategory.VALUES
val category = QuestionCategory.VALUES_CODE

// then
assertEquals(GroupPolicy.A_THEN_B, category.chatGroupPolicy)
Expand Down Expand Up @@ -122,7 +137,9 @@ class QuestionCategoryTest {
fun signup_only_categories_have_none_policy() {
// given
val signupOnlyCategories = listOf(
QuestionCategory.VALUES,
QuestionCategory.FAVORITE,
QuestionCategory.CURRENT_ME,
QuestionCategory.DATE,
QuestionCategory.MEMORY,
QuestionCategory.WANT_TALK
Expand All @@ -149,9 +166,11 @@ class QuestionCategoryTest {
// then
assertTrue(signupCategories.contains(QuestionCategory.VALUES))
assertTrue(signupCategories.contains(QuestionCategory.FAVORITE))
assertTrue(signupCategories.contains(QuestionCategory.CURRENT_ME))
assertTrue(signupCategories.contains(QuestionCategory.DATE))
assertTrue(signupCategories.contains(QuestionCategory.MEMORY))
assertTrue(signupCategories.contains(QuestionCategory.WANT_TALK))
assertFalse(signupCategories.contains(QuestionCategory.VALUES_CODE))
assertFalse(signupCategories.contains(QuestionCategory.TENSION_UP))
assertFalse(signupCategories.contains(QuestionCategory.IF))
assertFalse(signupCategories.contains(QuestionCategory.SECRET))
Expand All @@ -164,10 +183,11 @@ class QuestionCategoryTest {
val chatCategories = QuestionCategory.getChatCategories()

// then
assertTrue(chatCategories.contains(QuestionCategory.VALUES))
assertTrue(chatCategories.contains(QuestionCategory.VALUES_CODE))
assertTrue(chatCategories.contains(QuestionCategory.TENSION_UP))
assertTrue(chatCategories.contains(QuestionCategory.IF))
assertTrue(chatCategories.contains(QuestionCategory.SECRET))
assertFalse(chatCategories.contains(QuestionCategory.VALUES))
assertFalse(chatCategories.contains(QuestionCategory.FAVORITE))
assertFalse(chatCategories.contains(QuestionCategory.DATE))
}
Expand Down