From 0273b19a99723c31ad87e8fea32eefa4aa7dd592 Mon Sep 17 00:00:00 2001 From: minmin02 Date: Wed, 18 Feb 2026 11:49:31 +0900 Subject: [PATCH 1/4] =?UTF-8?q?Fix=20:=20prompt=20=EA=B0=84=EB=B3=84?= =?UTF-8?q?=ED=99=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IdeaAnalysisRequestConverter.java | 2 +- nect-api/src/main/resources/application.yml | 5 --- .../main/resources/prompts/idea-analysis.txt | 32 +++++++++---------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisRequestConverter.java b/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisRequestConverter.java index ce768d3a..3813fe13 100644 --- a/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisRequestConverter.java +++ b/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisRequestConverter.java @@ -39,7 +39,7 @@ public OpenAiResponseRequest toOpenAiRequest(IdeaAnalysisRequestDto dto) { .input(prompt) .text(text) .temperature(0.7) - .maxOutputTokens(4000) + .maxOutputTokens(20000) .metadata(Map.of( "promptVersion", "v1.0", "feature", "idea-analysis" diff --git a/nect-api/src/main/resources/application.yml b/nect-api/src/main/resources/application.yml index eda992b4..9dad4511 100644 --- a/nect-api/src/main/resources/application.yml +++ b/nect-api/src/main/resources/application.yml @@ -57,11 +57,6 @@ spring: org.hibernate.orm.jdbc.bind: TRACE org.hibernate.tool.schema: DEBUG # DDL 생성 로그 확인용 - servlet: - multipart: - max-file-size: 10MB - max-request-size: 10MB - jwt: secret: ${JWT_SECRET:test-jwt-secret-key-for-testing-minimum-256-bits-required-for-hs256-algorithm-security} access-token-expiration: ${JWT_ACCESS_TOKEN_EXPIRATION:3600000} diff --git a/nect-api/src/main/resources/prompts/idea-analysis.txt b/nect-api/src/main/resources/prompts/idea-analysis.txt index eecf8eac..dc829816 100644 --- a/nect-api/src/main/resources/prompts/idea-analysis.txt +++ b/nect-api/src/main/resources/prompts/idea-analysis.txt @@ -11,11 +11,11 @@ **⚠️ 매우 중요: weekly_roadmap 배열의 길이는 반드시 project_duration.total_weeks와 정확히 일치해야 합니다!** { - "description": "<아이디어 분석을 바탕으로 이 프로젝트의 핵심 가치, 목표 및 기대효과를 전문적인 어조로 기술 (1문장)>", + "description": "<아이디어 분석을 바탕으로 이 프로젝트의 핵심 가치, 목표 및 기대효과를 전문적인 어조로 기술 (2문장)>", "recommended_project_names": [ - "실제 프로젝트에 어울리는 이름1", - "실제 프로젝트에 어울리는 이름2", - "실제 프로젝트에 어울리는 이름3" + "프로젝트의 핵심 가치와 목적을 반영한 브랜드명, + "타겟 사용자와 서비스 특성을 담은 브랜드명", + "직관적이고 기억하기 쉬운 브랜드명" ], "project_duration": { "total_weeks": <실제 필요한 주차 수> @@ -31,19 +31,18 @@ { "order": 1, "title": "<구체적인 개선점 제목>", - "description": "<간결한 설명 (1-2문장, 50자 이내)>" - + "description": "개선이 필요한 구체적인 이유, 현재 문제점, 개선 후 기대 효과를 포함하여 최소 100자 이상 200자 이내로 서술" }, { "order": 2, "title": "<구체적인 개선점 제목>", - "description": "<간결한 설명 (1-2문장, 50자 이내)>" + "description": "개선이 필요한 구체적인 이유, 현재 문제점, 개선 후 기대 효과를 포함하여 최소 100자 이상 200자 이내로 서술" }, { "order": 3, "title": "<구체적인 개선점 제목>", - "description": "<간결한 설명 (1-2문장, 50자 이내)>" + "description": "개선이 필요한 구체적인 이유, 현재 문제점, 개선 후 기대 효과를 포함하여 최소 100자 이상 200자 이내로 서술" } ], "weekly_roadmap": [ @@ -54,8 +53,8 @@ { "role_field": "", "role_field_display_name": "<역할의 한글명>", - "tasks": "<해당 역할의 구체적인 작업 목록>" - } + "tasks": "<이번 주차 목표에 맞는 해당 역할의 작업을 단계별로 나누어 각 작업의 목적과 방법을 포함하여 최소 100자 이상 구체적으로 작성. 단순한 나열이 아닌 왜 하는지, 어떻게 하는지까지 서술>" + } ] }, { @@ -79,11 +78,11 @@ - role_field는 위에 제시된 7개 역할 코드만 사용 - "이름1", "제목1", "..." 같은 플레이스홀더를 절대 사용하지 마세요 - 모든 내용은 프로젝트 정보를 기반으로 구체적으로 작성 -- tasks는 반드시 구체적인 작업 내용을 포함 (최소 3-5개) +- tasks는 반드시 최소 100자 이상 작성하며 각 작업의 목적과 수행 방법을 포함 - 각 주차의 role_tasks는 team_composition의 모든 역할을 포함 + **모든 텍스트 필드(description, week_title, tasks, title 등)는 반드시 한글로 작성** + **role_field, role_field_display_name을 제외한 모든 값은 한글로 출력** -+ **텍스트 길이 제한: week_title 20자 이내, tasks 항목당 15자 이내, improvement_points description 50자 이내** ++ **텍스트 길이 제한: week_title 20자 이내, tasks 항목당 100자 이상 200자 이내, improvement_points description 100자 이상 200자 이내** **⚠️ weekly_roadmap 생성 필수 규칙 (매우 중요!):** 1. **weekly_roadmap 배열의 길이 = project_duration.total_weeks** (정확히 일치해야 함!) @@ -93,10 +92,9 @@ 5. **total_weeks가 8이라면 반드시 8개의 로드맵 객체를 생성하세요** **주차별 내용 구성 가이드**: -- **1-2주차**: 프로젝트 계획, 환경 설정, 초기 설계 -- **3-4주차**: 기본 기능 개발 시작 -- **중반부 (5주차~total_weeks-3주차)**: 핵심 기능 구현 및 고도화 -- **후반부 (마지막 3주차)**: 테스트, 버그 수정, 최적화, 배포 준비 -- **마지막 주차**: 최종 점검, 문서화, 출시 +- 프로젝트의 플랫폼, 핵심 기능, 팀 구성을 기반으로 각 주차 내용을 독자적으로 구성하세요. +- 단순히 개발 단계를 나누는 것이 아니라, 해당 프로젝트에서 실제로 필요한 작업 흐름을 반영하세요. +- 각 주차의 week_title은 그 주차에서 가장 중요한 산출물이나 목표를 기준으로 작성하세요. +- 역할별 tasks는 해당 주차의 목표에 맞는 구체적인 작업을 작성하세요. **검증 방법**: 응답 생성 후 `weekly_roadmap.length === project_duration.total_weeks` 인지 반드시 확인하세요! \ No newline at end of file From 75661db2f7a78e92cd849c0654f13b90a56e77ed Mon Sep 17 00:00:00 2001 From: minmin02 Date: Wed, 18 Feb 2026 11:52:15 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=20Fix=20:=20develop=20yml=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nect-api/src/main/resources/application.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nect-api/src/main/resources/application.yml b/nect-api/src/main/resources/application.yml index 9dad4511..eda992b4 100644 --- a/nect-api/src/main/resources/application.yml +++ b/nect-api/src/main/resources/application.yml @@ -57,6 +57,11 @@ spring: org.hibernate.orm.jdbc.bind: TRACE org.hibernate.tool.schema: DEBUG # DDL 생성 로그 확인용 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB + jwt: secret: ${JWT_SECRET:test-jwt-secret-key-for-testing-minimum-256-bits-required-for-hs256-algorithm-security} access-token-expiration: ${JWT_ACCESS_TOKEN_EXPIRATION:3600000} From 380e8f40d0270e8e3570214246d7a03736730ff6 Mon Sep 17 00:00:00 2001 From: minmin02 Date: Wed, 18 Feb 2026 23:04:27 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Fix=20:=20RoleField=20OTHER=20=ED=8C=8C?= =?UTF-8?q?=ED=8A=B8=20=ED=95=84=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/analysis/converter/IdeaAnalysisSchemaBuilder.java | 2 ++ .../main/java/com/nect/core/entity/user/enums/RoleField.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisSchemaBuilder.java b/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisSchemaBuilder.java index b0ae4936..dd69d426 100644 --- a/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisSchemaBuilder.java +++ b/nect-api/src/main/java/com/nect/api/domain/analysis/converter/IdeaAnalysisSchemaBuilder.java @@ -1,5 +1,6 @@ package com.nect.api.domain.analysis.converter; +import com.nect.core.entity.user.enums.Role; import com.nect.core.entity.user.enums.RoleField; import org.springframework.stereotype.Component; @@ -15,6 +16,7 @@ public Map buildIdeaAnalysisSchema() { List allRoleFields = Arrays.stream(RoleField.values()) .filter(rf -> rf != RoleField.CUSTOM) + .filter(rf -> rf.getRole() != Role.OTHER) .map(Enum::name) .collect(Collectors.toList()); diff --git a/nect-core/src/main/java/com/nect/core/entity/user/enums/RoleField.java b/nect-core/src/main/java/com/nect/core/entity/user/enums/RoleField.java index c6d480c9..5a303f44 100644 --- a/nect-core/src/main/java/com/nect/core/entity/user/enums/RoleField.java +++ b/nect-core/src/main/java/com/nect/core/entity/user/enums/RoleField.java @@ -39,8 +39,8 @@ public enum RoleField { AD_VIRAL("광고/바이럴", "Ads/Viral", Role.MARKETER), LIVE_COMMERCE("라이브커머스", "Live Commerce", Role.MARKETER), DATA_ANALYSIS("데이터 분석", "Data Analysis", Role.MARKETER), -// MARKETING_OTHER("기타", "Other", Role.MARKETER), +// MARKETING_OTHER("기타", "Other", Role.MARKETER), OPERATIONS_CS("운영/CS", "Operations/CS", Role.OTHER), SALES_PARTNERSHIP("영업/제휴", "Sales/Partnership", Role.OTHER), VIDEO_MUSIC_DIRECTING("영상/음악 감독", "Video/Music Directing", Role.OTHER), From c39e8e9dfeae80ffca9b507101b881f28818a7dd Mon Sep 17 00:00:00 2001 From: minmin02 Date: Thu, 19 Feb 2026 00:30:52 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Fix=20:=20Project=20description=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20length=20255=20=EC=88=98=EC=A0=95=20&=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EB=94=94=EC=96=B4=20=EB=B6=84=EC=84=9D=20=ED=94=84?= =?UTF-8?q?=EB=A1=AC=ED=94=84=ED=8A=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/analysis/util/PromptLoader.java | 5 +++-- .../project/enums/code/ProjectErrorCode.java | 3 ++- .../team/project/service/ProjectService.java | 19 +++++++++++++++---- .../main/resources/prompts/idea-analysis.txt | 16 ++++++++++++++++ .../entity/analysis/ProjectIdeaAnalysis.java | 1 - .../com/nect/core/entity/team/Project.java | 2 +- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/nect-api/src/main/java/com/nect/api/domain/analysis/util/PromptLoader.java b/nect-api/src/main/java/com/nect/api/domain/analysis/util/PromptLoader.java index 528d481d..a5a14396 100644 --- a/nect-api/src/main/java/com/nect/api/domain/analysis/util/PromptLoader.java +++ b/nect-api/src/main/java/com/nect/api/domain/analysis/util/PromptLoader.java @@ -1,6 +1,7 @@ package com.nect.api.domain.analysis.util; +import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; @@ -10,7 +11,7 @@ import java.nio.file.Files; import java.util.Map; - +@Slf4j @Component public class PromptLoader { @@ -27,7 +28,7 @@ public String loadPrompt(String promptPath, Map variables) { String value = entry.getValue() != null ? entry.getValue() : ""; result = result.replace(placeholder, value); } - + log.info("빌드된 프롬프트 앞부분: {}", result.substring(0, Math.min(500, result.length()))); return result; } catch (IOException e) { diff --git a/nect-api/src/main/java/com/nect/api/domain/team/project/enums/code/ProjectErrorCode.java b/nect-api/src/main/java/com/nect/api/domain/team/project/enums/code/ProjectErrorCode.java index 2e6a8df7..b8009fa1 100644 --- a/nect-api/src/main/java/com/nect/api/domain/team/project/enums/code/ProjectErrorCode.java +++ b/nect-api/src/main/java/com/nect/api/domain/team/project/enums/code/ProjectErrorCode.java @@ -23,7 +23,8 @@ public enum ProjectErrorCode implements ResponseCode { PROJECT_PART_NOT_FOUND("P400_9", "해당 프로젝트 파트(팀 역할)를 찾을 수 없습니다."), DUPLICATE_PART("P400_10", "이미 존재하는 파트입니다."), INVALID_CUSTOM_PART_NAME("P400_11", "CUSTOM 파트 이름이 올바르지 않습니다."), - + TITLE_TOO_LONG("P400_12", "프로젝트 제목이 너무 깁니다."), + DESCRIPTION_TOO_LONG("P400_13", "프로젝트 설명이 너무 깁니다."), PROJECT_MEMBER_FORBIDDEN("P403_0", "프로젝트 멤버만 접근할 수 있습니다."), LEADER_ONLY_ACTION("P403_1", "리더만 할 수 있는 요청입니다."), diff --git a/nect-api/src/main/java/com/nect/api/domain/team/project/service/ProjectService.java b/nect-api/src/main/java/com/nect/api/domain/team/project/service/ProjectService.java index 2691308f..97f5a951 100644 --- a/nect-api/src/main/java/com/nect/api/domain/team/project/service/ProjectService.java +++ b/nect-api/src/main/java/com/nect/api/domain/team/project/service/ProjectService.java @@ -114,7 +114,7 @@ public ProjectCreateResponseDto createProjectFromAnalysis(Long userId, ProjectCr addProjectLeader(project, userId, leaderRole); // 4. 팀 구성 복사 saveTeamRoles(project.getId(), analysis); - //TODO : 리팩토링 + saveUserTeamRoles(project, analysis); // 5. 주차별 로드맵 복사 @@ -147,18 +147,29 @@ private void validateAnalysisData(ProjectIdeaAnalysis analysis) { */ private Project createProject(ProjectIdeaAnalysis analysis) { try { + String title = analysis.getRecommendedProjectName1(); + String description = analysis.getDescription(); + + if (title != null && title.length() > 255) { + throw new ProjectException(ProjectErrorCode.TITLE_TOO_LONG); + } + if (description != null && description.length() > 255) { + throw new ProjectException(ProjectErrorCode.DESCRIPTION_TOO_LONG); + } + Project project = Project.builder() - .title(analysis.getRecommendedProjectName1()) - .description(analysis.getDescription()) + .title(title) + .description(description) .status(ProjectStatus.ACTIVE) .build(); project.setProjectPeriod(analysis.getProjectStartDate(), analysis.getProjectEndDate()); - setRecruitmentStatus(project, RecruitmentStatus.OPEN); Project savedProject = projectRepository.save(project); saveDefaultInterestFields(savedProject); return savedProject; + } catch (ProjectException e) { + throw e; } catch (Exception e) { throw new ProjectException(ProjectErrorCode.INVALID_ANALYSIS_DATA); } diff --git a/nect-api/src/main/resources/prompts/idea-analysis.txt b/nect-api/src/main/resources/prompts/idea-analysis.txt index dc829816..1ae7e065 100644 --- a/nect-api/src/main/resources/prompts/idea-analysis.txt +++ b/nect-api/src/main/resources/prompts/idea-analysis.txt @@ -1,3 +1,19 @@ +다음 프로젝트 정보를 분석하여 아래 형식에 맞게 응답하세요. + +## 프로젝트 정보 +- 프로젝트명: {{projectName}} +- 프로젝트 요약: {{projectSummary}} +- 타겟 사용자: {{targetUsers}} +- 해결할 문제: {{problemStatement}} +- 핵심 기능 1: {{coreFeature1}} +- 핵심 기능 2: {{coreFeature2}} +- 핵심 기능 3: {{coreFeature3}} +- 플랫폼: {{platform}} +- 레퍼런스 서비스: {{referenceServices}} +- 기술적 도전: {{technicalChallenges}} +- 목표 완료일: {{targetCompletionDate}} + +--- 5. **주차별 로드맵**: - **⚠️ 중요: total_weeks 값만큼 정확히 모든 주차의 로드맵을 생성해야 합니다.** - **예: total_weeks가 12라면 week_number 1부터 12까지 총 12개의 로드맵 객체를 생성하세요.** diff --git a/nect-core/src/main/java/com/nect/core/entity/analysis/ProjectIdeaAnalysis.java b/nect-core/src/main/java/com/nect/core/entity/analysis/ProjectIdeaAnalysis.java index e4d1027b..76e6bb2b 100644 --- a/nect-core/src/main/java/com/nect/core/entity/analysis/ProjectIdeaAnalysis.java +++ b/nect-core/src/main/java/com/nect/core/entity/analysis/ProjectIdeaAnalysis.java @@ -29,7 +29,6 @@ public class ProjectIdeaAnalysis extends BaseEntity { @Column(name = "description", columnDefinition = "TEXT", nullable = false) private String description; - //TODO : 정규화 위반이긴하지만 추천명 3개를 담겠다고 별도의 엔티티를 만드는게 성능적으로 더 별로라 생각해서 별도 필드로 구현했습니다. @Column(name = "recommended_project_name_1", length = 100, nullable = false) private String recommendedProjectName1; diff --git a/nect-core/src/main/java/com/nect/core/entity/team/Project.java b/nect-core/src/main/java/com/nect/core/entity/team/Project.java index 53783f07..5aeb40b6 100644 --- a/nect-core/src/main/java/com/nect/core/entity/team/Project.java +++ b/nect-core/src/main/java/com/nect/core/entity/team/Project.java @@ -21,7 +21,7 @@ public class Project extends BaseEntity { @Column(name = "title", length = 50, nullable = false) private String title; - @Column(name = "description", length = 100) + @Column(name = "description", length = 255) private String description; @Column(name = "information", columnDefinition = "TEXT")