From 20bfdd7576ee49f8bd24b561b17b5c80217e41d9 Mon Sep 17 00:00:00 2001 From: sb Date: Sat, 11 Jul 2026 22:14:41 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20AI=20=EC=B6=94=EC=B2=9C=EC=97=90=20?= =?UTF-8?q?=EC=A4=91=EC=84=B1=ED=99=94=20=EC=A1=B0=EA=B1=B4=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20(neutered)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GET /api/spots/{id}/ai-mates?dogId=&neutered=true|false — 해당 중성화 여부 강아지 중에서만 추천. 미지정 시 전체. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/main/java/com/dog/dognation/api/SpotController.java | 9 ++++++--- .../com/dog/dognation/domain/spot/MateAiService.java | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/dog/dognation/api/SpotController.java b/src/main/java/com/dog/dognation/api/SpotController.java index 2f631f7..a693282 100644 --- a/src/main/java/com/dog/dognation/api/SpotController.java +++ b/src/main/java/com/dog/dognation/api/SpotController.java @@ -57,10 +57,13 @@ public class SpotController { return spotService.activeMates(id, userId).stream().map(MateResponse::from).toList(); } - /** AI 궁합 메이트 추천 — 내 강아지(dogId)와 사이좋게 지낼 만한 스팟 내 강아지 목록 */ + /** AI 궁합 메이트 추천 — 내 강아지(dogId)와 사이좋게 지낼 만한 스팟 내 강아지 목록. + * neutered: 중성화 조건(true/false). 미지정 시 전체. */ @GetMapping("/{id}/ai-mates") - public List aiMates(@PathVariable Long id, @RequestParam Long dogId) { - return mateAiService.compatibleMates(id, dogId); + public List aiMates(@PathVariable Long id, + @RequestParam Long dogId, + @RequestParam(required = false) Boolean neutered) { + return mateAiService.compatibleMates(id, dogId, neutered); } /** 현재 요일·시간대에 이 스팟에 자주 오는 견종(통계) */ diff --git a/src/main/java/com/dog/dognation/domain/spot/MateAiService.java b/src/main/java/com/dog/dognation/domain/spot/MateAiService.java index a35d6e0..b1d228b 100644 --- a/src/main/java/com/dog/dognation/domain/spot/MateAiService.java +++ b/src/main/java/com/dog/dognation/domain/spot/MateAiService.java @@ -56,9 +56,12 @@ public class MateAiService { this.gemini = gemini; } - /** 스팟 활성 메이트 중 내 강아지와 궁합 좋은 강아지 목록(궁합점수 내림차순). */ + /** + * 스팟 활성 메이트 중 내 강아지와 궁합 좋은 강아지 목록(궁합점수 내림차순). + * neutered 가 주어지면 해당 중성화 여부에 맞는 강아지 중에서만 추천한다. + */ @Transactional(readOnly = true) - public List compatibleMates(Long spotId, Long myDogId) { + public List compatibleMates(Long spotId, Long myDogId, Boolean neutered) { if (!gemini.isConfigured()) { throw new ApiException(HttpStatus.SERVICE_UNAVAILABLE, "AI 추천이 설정되지 않았습니다."); } @@ -71,6 +74,7 @@ public class MateAiService { return List.of(); } Map candidates = dogRepository.findWithTraitsByIdIn(activeIds).stream() + .filter(d -> neutered == null || d.isNeutered() == neutered) // 중성화 조건 필터 .collect(Collectors.toMap(Dog::getId, Function.identity())); if (candidates.isEmpty()) { return List.of();