diff --git a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRules.java b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRules.java index e6bea6ea..60c7b24b 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRules.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRules.java @@ -39,7 +39,8 @@ public final class AnalysisSanitizationRules { private static final String[] FABRICATED_DIRECT_CONFLICT_TERMS = { "직접 충돌", "명시적 사실과 충돌", "사실과 충돌", "조건과 충돌", "요건과 충돌", "서로 충돌", "상충", "하지 않았다고", "수행하지 않았다고", "경험이 없다고", - "없다고 밝혔", "실제로 하지 않았" + "없다고 밝혔", "실제로 하지 않았", "모순", "불일치", "일치하지 않", "앞뒤가 맞지", + "다르게 서술" }; private static final Set STOP_WORDS = Set.of( "경험", "역량", "업무", "관련", "가능", "보유", "필수", "우대", "자격", "요건", @@ -181,7 +182,16 @@ public static boolean hasFabricatedDirectConflictReason(String reason) { return true; } } - return false; + return containsTeamAndIndividualProjectConflict(normalized); + } + + private static boolean containsTeamAndIndividualProjectConflict(String normalizedReason) { + boolean teamClaim = normalizedReason.contains(normalize("팀 프로젝트")) + || normalizedReason.contains(normalize("팀으로 진행")); + boolean individualClaim = normalizedReason.contains(normalize("개인 프로젝트")) + || normalizedReason.contains(normalize("혼자 수행")) + || normalizedReason.contains(normalize("혼자 진행")); + return teamClaim && individualClaim; } public static boolean isStructuredQualificationKeyword(String keyword) { diff --git a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/core/AnalysisServiceTest.java b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/core/AnalysisServiceTest.java index f35c3e1b..9d089d03 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/core/AnalysisServiceTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/core/AnalysisServiceTest.java @@ -661,7 +661,7 @@ void analyzeKeepsTwoValidQuestionAnalyses() { question.getId(), "두 번째 문장입니다.", "fabricated", - "확인된 사실과 직접 충돌합니다.", + "팀 프로젝트로 진행했으나 개인 프로젝트라고 주장함", null ) ) diff --git a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRulesTest.java b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRulesTest.java index a46e1dc3..3862f301 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRulesTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/analysis/service/sanitization/AnalysisSanitizationRulesTest.java @@ -34,6 +34,23 @@ void detectsContradictoryProvenReasonByDefectPhrase() { .isTrue(); } + @Test + @DisplayName("FABRICATED reason은 명시적 충돌 표현과 팀·개인 프로젝트의 대조를 인정한다") + void detectsFabricatedReasonByConflictMeaning() { + assertThat(AnalysisSanitizationRules.hasFabricatedDirectConflictReason( + "팀 프로젝트로 진행했으나 개인 프로젝트라고 주장함" + )).isTrue(); + assertThat(AnalysisSanitizationRules.hasFabricatedDirectConflictReason( + "앞뒤 설명이 불일치합니다." + )).isTrue(); + assertThat(AnalysisSanitizationRules.hasFabricatedDirectConflictReason( + "팀 프로젝트 경험을 설명했습니다." + )).isFalse(); + assertThat(AnalysisSanitizationRules.hasFabricatedDirectConflictReason( + "팀 프로젝트와 개인의 역할이 혼재되어 있습니다." + )).isFalse(); + } + @Test @DisplayName("unsafe improvement를 제거한다") void removesUnsafeImprovement() {