From cb71594a50488b80095da113cce9f5dd14ae6633 Mon Sep 17 00:00:00 2001 From: jiwonkim Date: Wed, 12 Feb 2025 17:19:24 +0900 Subject: [PATCH 1/5] =?UTF-8?q?fix=20:=20Swagger=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .gradle/buildOutputCleanup/outputFiles.bin | Bin 19019 -> 19415 bytes .gradle/file-system.probe | Bin 8 -> 8 bytes .../giftidea/configuration/SwaggerConfig.java | 39 ++++++++++++++++++ .../giftidea/controller/GptController.java | 38 +++++++++-------- 5 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/team4/giftidea/configuration/SwaggerConfig.java diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 84c852e5aa20622aff89eb9b27e1c2b86f65d394..c9492340d1a7e2f435d9e0e8ed2f1e736a37828d 100644 GIT binary patch literal 17 VcmZRc_VA=6%hWql8Nh&72mm*(1cm?r literal 17 VcmZRc_VA=6%hWql8Nh(&9soFa1yKM1 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index 8a2a32d4154cda1da3b81a3eb09aa8d587775c2b..8801f00868ba200ddf03747865a6a0f497e96359 100644 GIT binary patch delta 571 zcmX>-h4K1y#tkMCn#LX6ce3tzr@AtLfv4?%DCl0Z^V_=nQOOW-?}d|HB`gG{#yvQd zb$sa*h@e;gPFm@~RG~cq~lfQ}2RwR)snts5#1$Yb6^rc(P7d z$5@6fhYB8rDdv0bv%#Q9{WH{%rIWu(DrjghnmJs*+HDF|YzkAX@%u>N*Q(nmpo%9? z=9N+qunD>JC_Y)C2ddb8vZ|DVhNlJF+qOq*|3d})VJ3JUH{;kh{iib2gtwDzfhPFP z^|$NSt$jTicQ~bx|OFZKm@&OVTxfi n0|U#=jfy|SHyStyZ+7(HVw$|)!+COo$D+vsUe=TEd*%QD3UmA0 delta 97 zcmcaUo$>S(#tkMCg0dalce3tzr@AtLfv4@{SP6^CYb8ERJ}W6P*;T4y@>?m1$)?g0 qlT(3sEfC)YVpW-h$!BFGc>Y5H0|V2^jfy|SHyQ+pZg%wGVgdlo)Fq<; diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index 9395b2d8d2cd5c836c7c72dc76817c3a58963ff8..8f8dc91631fbee545e90dabc8d086eea49f6b8b7 100644 GIT binary patch literal 8 PcmZQzV4U*PM%4@e2nqrw literal 8 PcmZQzV4U*6c(wrm2yp^* diff --git a/src/main/java/com/team4/giftidea/configuration/SwaggerConfig.java b/src/main/java/com/team4/giftidea/configuration/SwaggerConfig.java new file mode 100644 index 0000000..1c0ac77 --- /dev/null +++ b/src/main/java/com/team4/giftidea/configuration/SwaggerConfig.java @@ -0,0 +1,39 @@ +package com.team4.giftidea.configuration; + +import io.swagger.v3.oas.models.ExternalDocumentation; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.servers.Server; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI giftIdeaOpenAPI() { + return new OpenAPI() + .info(new Info() + .title("🎁 GiftIdea API λ¬Έμ„œ") + .description("GPT 기반 μ„ λ¬Ό μΆ”μ²œ API") + .version("1.0.0") + .contact(new Contact() + .name("νŒ€4") + .email("team4@giftidea.com") + .url("https://presentalk.store")) + .license(new License() + .name("Apache 2.0") + .url("https://www.apache.org/licenses/LICENSE-2.0"))) + .externalDocs(new ExternalDocumentation() + .description("GitHub Repository") + .url("https://github.com/team4/giftidea")) + .servers(List.of( + new Server().url("https://app.presentalk.store").description("πŸš€ 배포 ν™˜κ²½"), + new Server().url("http://localhost:8080").description("πŸ› οΈ 둜컬 개발 ν™˜κ²½") + )); + } +} \ No newline at end of file diff --git a/src/main/java/com/team4/giftidea/controller/GptController.java b/src/main/java/com/team4/giftidea/controller/GptController.java index 970db40..5595227 100644 --- a/src/main/java/com/team4/giftidea/controller/GptController.java +++ b/src/main/java/com/team4/giftidea/controller/GptController.java @@ -22,7 +22,7 @@ import java.nio.charset.StandardCharsets; import java.util.*; -@Tag(name = "GPT μΆ”μ²œ API", description = "GPTλ₯Ό μ΄μš©ν•˜μ—¬ μ‚¬μš©μž 맞좀 μ„ λ¬Ό μΆ”μ²œμ„ μ œκ³΅ν•˜λŠ” API") +@Tag(name = "🎁 GPT μΆ”μ²œ API", description = "μΉ΄μΉ΄μ˜€ν†‘ λŒ€ν™”λ₯Ό λΆ„μ„ν•˜μ—¬ GPTλ₯Ό 톡해 μΆ”μ²œ 선물을 μ œκ³΅ν•˜λŠ” API") @RestController @RequestMapping("/api/gpt") @Slf4j @@ -49,39 +49,41 @@ public GptController(RestTemplate restTemplate, GptConfig gptConfig, ProductServ * @param theme μ„ λ¬Ό ν…Œλ§ˆ (예: "birthday", "valentine") * @return μΆ”μ²œλœ μƒν’ˆ λͺ©λ‘ */ - @Operation(summary = "λŒ€ν™” 뢄석 ν›„ μΆ”μ²œ μƒν’ˆ λ°˜ν™˜", description = "μΉ΄μΉ΄μ˜€ν†‘ λŒ€ν™”λ₯Ό λΆ„μ„ν•˜μ—¬ GPT APIλ₯Ό 톡해 ν‚€μ›Œλ“œλ₯Ό μΆ”μΆœν•˜κ³ , ν•΄λ‹Ή ν‚€μ›Œλ“œμ— λ§žλŠ” μΆ”μ²œ μƒν’ˆμ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.") + @Operation( + summary = "카톑 λŒ€ν™” 뢄석 ν›„ μ„ λ¬Ό μΆ”μ²œ", + description = "μΉ΄μΉ΄μ˜€ν†‘ λŒ€ν™” νŒŒμΌμ„ λΆ„μ„ν•˜μ—¬ GPT APIλ₯Ό μ΄μš©ν•΄ ν‚€μ›Œλ“œλ₯Ό μΆ”μΆœν•˜κ³ , 이에 λ§žλŠ” μΆ”μ²œ μƒν’ˆμ„ λ°˜ν™˜ν•©λ‹ˆλ‹€." + ) @ApiResponses({ @ApiResponse(responseCode = "200", description = "μΆ”μ²œ μƒν’ˆ λͺ©λ‘ λ°˜ν™˜"), @ApiResponse(responseCode = "400", description = "잘λͺ»λœ μš”μ²­ νŒŒλΌλ―Έν„°"), + @ApiResponse(responseCode = "415", description = "μ§€μ›λ˜μ§€ μ•ŠλŠ” 파일 ν˜•μ‹"), @ApiResponse(responseCode = "500", description = "μ„œλ²„ λ‚΄λΆ€ 였λ₯˜ λ°œμƒ") }) - @PostMapping("/process") + @PostMapping(value = "/process", consumes = "multipart/form-data", produces = "application/json") public List processFileAndRecommend( - @RequestParam("file") @Parameter(description = "μΉ΄μΉ΄μ˜€ν†‘ λŒ€ν™” λ‚΄μš©μ΄ ν¬ν•¨λœ 파일", required = true) MultipartFile file, - @RequestParam("targetName") @Parameter(description = "λŒ€μƒ 이름", required = true) String targetName, - @RequestParam("relation") @Parameter(description = "λŒ€μƒκ³Όμ˜ 관계", required = true) String relation, - @RequestParam("sex") @Parameter(description = "λŒ€μƒ 성별", required = true) String sex, - @RequestParam("theme") @Parameter(description = "μ„ λ¬Όμ˜ 주제", required = true) String theme) { + @RequestParam("file") @Parameter(description = "μΉ΄μΉ΄μ˜€ν†‘ λŒ€ν™” 파일 (.txt)", required = true) MultipartFile file, + @RequestParam("targetName") @Parameter(description = "뢄석 λŒ€μƒ 이름 (예: 'μ—¬μžμΉœκ΅¬')", required = true) String targetName, + @RequestParam("relation") @Parameter(description = "λŒ€μƒκ³Όμ˜ 관계 (couple, friend, parent λ“±)", required = true) String relation, + @RequestParam("sex") @Parameter(description = "λŒ€μƒ 성별 (male λ˜λŠ” female)", required = true) String sex, + @RequestParam("theme") @Parameter(description = "μ„ λ¬Ό 주제 (birthday, valentine λ“±)", required = true) String theme + ) { + log.info("λŒ€ν™” 뢄석 μ‹œμž‘ - λŒ€μƒ: {}, 관계: {}, 성별: {}, ν…Œλ§ˆ: {}", targetName, relation, sex, theme); // 1. 파일 μ „μ²˜λ¦¬ List processedMessages = preprocessKakaoFile(file, targetName); // 2. GPT API 호좜: μ „μ²˜λ¦¬λœ λ©”μ‹œμ§€λ‘œ ν‚€μ›Œλ“œ λ°˜ν™˜ - String categories = generatePrompt(processedMessages, relation, sex, theme); // 이미 ν‚€μ›Œλ“œλ₯Ό μΆ”μΆœν–ˆμŒ + String categories = generatePrompt(processedMessages, relation, sex, theme); - // 3. ν‚€μ›Œλ“œ 리슀트둜 λ³€ν™˜λœ κ°’ κ·ΈλŒ€λ‘œ μ‚¬μš© + // 3. ν‚€μ›Œλ“œ 리슀트 λ³€ν™˜ 및 μƒν’ˆ 검색 List keywords = Arrays.asList(categories.split(",")); - keywords.replaceAll(String::trim); // 곡백 제거 + keywords.replaceAll(String::trim); + log.debug("πŸ” μΆ”μΆœλœ ν‚€μ›Œλ“œ λͺ©λ‘: {}", keywords); - log.debug("μΆ”μΆœλœ ν‚€μ›Œλ“œ λͺ©λ‘: {}", keywords); - - // 4. μƒν’ˆ 검색 (DBμ—μ„œ ν‚€μ›Œλ“œ 기반으둜 μΆ”μ²œ μƒν’ˆ 검색) List products = productService.searchByKeywords(keywords); + log.debug("🎁 μΆ”μ²œλœ μƒν’ˆ: {}", products); - // κ²€μƒ‰λœ μƒν’ˆ 확인 둜그 - log.debug("κ²€μƒ‰λœ μƒν’ˆ: {}", products); - - return products; // μƒν’ˆ λͺ©λ‘ λ°˜ν™˜ + return products; } private static final int MAX_TOKENS = 15000; // 15000 토큰 μ œν•œ From 4c5a14d490d8643d2bc87690ed90cbd9c28edc78 Mon Sep 17 00:00:00 2001 From: jiwonkim Date: Wed, 12 Feb 2025 17:21:32 +0900 Subject: [PATCH 2/5] =?UTF-8?q?hotfix=20:=20securityconfig=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../buildOutputCleanup/buildOutputCleanup.lock | Bin 17 -> 17 bytes .../giftidea/configuration/SecurityConfig.java | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index c9492340d1a7e2f435d9e0e8ed2f1e736a37828d..303b46a8bf0e4c05336c7e6e3a25cb58b0599279 100644 GIT binary patch literal 17 VcmZRc_VA=6%hWql8Nh&70RT6=1e5>( literal 17 VcmZRc_VA=6%hWql8Nh&72mm*(1cm?r diff --git a/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java b/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java index 993d918..ffe0ca7 100644 --- a/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java +++ b/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java @@ -47,7 +47,7 @@ public CorsConfigurationSource corsConfigurationSource() { // ν—ˆμš©ν•  좜처 μ„€μ • configuration.setAllowedOrigins(List.of( - "http://localhost:5174", + "http://localhost:5173", "http://localhost:3000", "https://presentalk.store", "https://app.presentalk.store" From 35cbe5b9c0e42e30110341b556895fa3aeedfed2 Mon Sep 17 00:00:00 2001 From: jiwonkim Date: Wed, 12 Feb 2025 17:37:28 +0900 Subject: [PATCH 3/5] =?UTF-8?q?hotfix=20:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EA=B8=B4=EA=B8=89=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../giftidea/controller/GptController.java | 30 ++++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 303b46a8bf0e4c05336c7e6e3a25cb58b0599279..b32e8c548bed768a1cbe3e2a2803628007842cb2 100644 GIT binary patch literal 17 VcmZRc_VA=6%hWql8Nh&74*)mH1fl={ literal 17 VcmZRc_VA=6%hWql8Nh&70RT6=1e5>( diff --git a/src/main/java/com/team4/giftidea/controller/GptController.java b/src/main/java/com/team4/giftidea/controller/GptController.java index 5595227..a91cad9 100644 --- a/src/main/java/com/team4/giftidea/controller/GptController.java +++ b/src/main/java/com/team4/giftidea/controller/GptController.java @@ -180,21 +180,23 @@ private int detectFormatType(MultipartFile file) { private String generatePrompt(List processedMessages, String relation, String sex, String theme) { String combinedMessages = String.join("\n", processedMessages); // List을 ν•˜λ‚˜μ˜ String으둜 ν•©μΉ¨ - switch (relation) { - case "couple": - return sex.equals("male") ? extractKeywordsAndReasonsCoupleMan(theme, combinedMessages) - : extractKeywordsAndReasonsCoupleWoman(theme, combinedMessages); - case "parent": - return extractKeywordsAndReasonsParents(theme, combinedMessages); - case "friend": - return extractKeywordsAndReasonsFriend(theme, combinedMessages); - case "housewarming": - return extractKeywordsAndReasonsHousewarming(combinedMessages); - case "valentine": - return extractKeywordsAndReasonsSeasonal(theme, combinedMessages); - default: - return "쑰건에 λ§žλŠ” μ„ λ¬Ό μΆ”μ²œμ΄ μ—†μŠ΅λ‹ˆλ‹€."; + if ("couple".equals(relation)) { + if ("male".equals(sex)) { + return extractKeywordsAndReasonsCoupleMan(theme, combinedMessages); + } else if ("female".equals(sex)) { + return extractKeywordsAndReasonsCoupleWoman(theme, combinedMessages); + } + } else if ("parent".equals(relation)) { + return extractKeywordsAndReasonsParents(theme, combinedMessages); + } else if ("friend".equals(relation)) { + return extractKeywordsAndReasonsFriend(theme, combinedMessages); + } else if ("housewarming".equals(theme)) { + return extractKeywordsAndReasonsHousewarming(combinedMessages); + } else if ("valentine".equals(theme)) { + return extractKeywordsAndReasonsSeasonal(theme, combinedMessages); } + + return "쑰건에 λ§žλŠ” μ„ λ¬Ό μΆ”μ²œ κΈ°λŠ₯이 μ—†μŠ΅λ‹ˆλ‹€."; } private String generateText(String prompt) { From eaedf7392f53ad84d08d8ddb9b25586d9ae920ab Mon Sep 17 00:00:00 2001 From: jiwonkim Date: Thu, 13 Feb 2025 00:55:18 +0900 Subject: [PATCH 4/5] fix : add origin --- .../java/com/team4/giftidea/configuration/SecurityConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java b/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java index ffe0ca7..74bfcbc 100644 --- a/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java +++ b/src/main/java/com/team4/giftidea/configuration/SecurityConfig.java @@ -50,7 +50,8 @@ public CorsConfigurationSource corsConfigurationSource() { "http://localhost:5173", "http://localhost:3000", "https://presentalk.store", - "https://app.presentalk.store" + "https://app.presentalk.store", + "http://presentalk.s3-website.ap-northeast-2.amazonaws.com" )); // ν—ˆμš©ν•  HTTP λ©”μ„œλ“œ μ„€μ • From c464a23ea5f4b86ea1d59d20fcbba3ee6b3a2267 Mon Sep 17 00:00:00 2001 From: jiwonkim Date: Thu, 13 Feb 2025 16:10:50 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix=20:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A1=9C=EA=B7=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/team4/giftidea/controller/GptController.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/com/team4/giftidea/controller/GptController.java b/src/main/java/com/team4/giftidea/controller/GptController.java index a91cad9..126a7e4 100644 --- a/src/main/java/com/team4/giftidea/controller/GptController.java +++ b/src/main/java/com/team4/giftidea/controller/GptController.java @@ -67,7 +67,6 @@ public List processFileAndRecommend( @RequestParam("sex") @Parameter(description = "λŒ€μƒ 성별 (male λ˜λŠ” female)", required = true) String sex, @RequestParam("theme") @Parameter(description = "μ„ λ¬Ό 주제 (birthday, valentine λ“±)", required = true) String theme ) { - log.info("λŒ€ν™” 뢄석 μ‹œμž‘ - λŒ€μƒ: {}, 관계: {}, 성별: {}, ν…Œλ§ˆ: {}", targetName, relation, sex, theme); // 1. 파일 μ „μ²˜λ¦¬ List processedMessages = preprocessKakaoFile(file, targetName); @@ -78,10 +77,8 @@ public List processFileAndRecommend( // 3. ν‚€μ›Œλ“œ 리슀트 λ³€ν™˜ 및 μƒν’ˆ 검색 List keywords = Arrays.asList(categories.split(",")); keywords.replaceAll(String::trim); - log.debug("πŸ” μΆ”μΆœλœ ν‚€μ›Œλ“œ λͺ©λ‘: {}", keywords); List products = productService.searchByKeywords(keywords); - log.debug("🎁 μΆ”μ²œλœ μƒν’ˆ: {}", products); return products; } @@ -202,12 +199,9 @@ private String generatePrompt(List processedMessages, String relation, S private String generateText(String prompt) { GptRequestDTO request = new GptRequestDTO(gptConfig.getModel(), prompt); try { - log.info("GPT μš”μ²­ μ‹œμž‘ - λͺ¨λΈ: {}", gptConfig.getModel()); - log.debug("μš”μ²­ λ‚΄μš©: {}", prompt); // HTTP μš”μ²­ 전에 request 객체 λ‘œκΉ… ObjectMapper mapper = new ObjectMapper(); - log.debug("전체 μš”μ²­ λ°”λ””: {}", mapper.writeValueAsString(request)); GptResponseDTO response = restTemplate.postForObject(gptConfig.getApiUrl(), request, GptResponseDTO.class); @@ -218,12 +212,10 @@ private String generateText(String prompt) { // 응닡에 'choices'κ°€ 있고, κ·Έ 쀑 첫 번째 ν•­λͺ©μ΄ μ‘΄μž¬ν•˜λŠ”μ§€ 확인 if (response.getChoices() != null && !response.getChoices().isEmpty()) { String content = response.getChoices().get(0).getMessage().getContent(); - log.debug("μΆ”μΆœλœ μ½˜ν…μΈ : {}", content); // ν•„μš”ν•œ ν˜•νƒœλ‘œ μΉ΄ν…Œκ³ λ¦¬ μΆ”μΆœ (예: "1. [무선이어폰, μŠ€λ§ˆνŠΈμ›ŒμΉ˜, ν–₯수]" ν˜•νƒœ) if (content.contains("1.")) { String categories = content.split("1.")[1].split("\n")[0]; // 첫 번째 μΉ΄ν…Œκ³ λ¦¬ 라인 μΆ”μΆœ - log.debug("GPT μ‘λ‹΅μ—μ„œ μΆ”μΆœλœ μΉ΄ν…Œκ³ λ¦¬: {}", categories); // κ΄„ν˜Έ μ•ˆμ˜ ν•­λͺ©λ“€μ„ μΆ”μΆœν•˜κ³ , μ‰Όν‘œλ‘œ κ΅¬λΆ„ν•˜μ—¬ ν‚€μ›Œλ“œ 리슀트 λ§Œλ“€κΈ° String[] categoryArray = categories.split("\\[|\\]")[1].split(","); @@ -244,7 +236,6 @@ private String generateText(String prompt) { return "GPT 응닡 였λ₯˜ λ°œμƒ"; } catch (Exception e) { log.error("GPT μš”μ²­ 쀑 였λ₯˜ λ°œμƒ: ", e); - log.error("상세 였λ₯˜ λ©”μ‹œμ§€: {}", e.getMessage()); if (e.getCause() != null) { log.error("원인 μ˜ˆμ™Έ: {}", e.getCause().getMessage()); }