feat: 추천 일정에 Gemini AI 한 줄 맥락 해설 추가 - #119
Conversation
모임 일정 취합 결과(추천 시간 + 참여자 가용시간)를 Gemini로 요약해 "왜 이 시간이 좋은지" 설명하는 한국어 한 문장 해설을 결과 화면에 노출한다. - src/lib/gemini/insight.ts: Gemini REST(generateContent) 직접 호출 클라이언트. 키 미설정·실패·타임아웃 시 null 반환(graceful degradation, SDK 의존성 없음) - src/app/api/schedules/[id]/insight: 집계 결과로 해설을 생성하는 GET 라우트 - ScheduleRoomClient: 추천 시간 위에 "Gemini AI" 배지 해설 카드 렌더링 - .env.example: GEMINI_MODEL(선택, 기본 gemini-2.5-flash) 문서화 Close #118 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
More reviews will be available in 46 minutes and 2 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
WalkthroughGemini API를 사용해 추천 일정에 한국어 한 줄 해설을 생성하는 기능을 추가한다. ChangesGemini AI 일정 해설 기능
🎯 3 (Moderate) | ⏱️ ~25 minutesSuggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- gemini-2.5+ thinking 모델이 출력 토큰을 추론에 소비해 한 줄 해설이 잘리던 문제 수정: thinkingConfig.thinkingBudget=0으로 thinking 비활성화, maxOutputTokens 120→256 상향 - GEMINI_API_KEY 앞뒤 공백/개행 trim 처리(붙여넣기 실수 방어) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/api/schedules/`[id]/insight/route.ts:
- Around line 32-40: Replace the actual participant names being sent to the
Gemini API with ordinal-based pseudonyms to minimize personal information
exposure to external services. In the participants array mapping within the
generateScheduleInsight call, instead of passing p.name directly, substitute it
with a pseudonym (such as "Participant 1", "Participant 2", etc.) based on each
participant's index position in the array. This preserves the context needed for
insight generation while preventing real names from being transmitted to and
logged by the external Google API service.
In `@src/app/schedule/`[id]/ScheduleRoomClient.tsx:
- Around line 1124-1144: The useEffect dependency array in
ScheduleRoomClient.tsx only tracks schedule.id and commonSlotsCount, but it
should use actual slot content instead of just the count, so that recommendation
changes are detected even if the count remains the same. Additionally, when the
fetch fails or returns null data, the previous insight value is not cleared,
causing stale explanations to remain visible. To fix this: change the dependency
array from [schedule.id, commonSlotsCount] to include a content-based key or
hash of the actual commonSlots data to properly track changes, and explicitly
call setInsight(null) both at the start of the effect (before the fetch) and in
the catch block to ensure stale insights are always cleared when the request
fails or returns invalid data.
In `@src/lib/gemini/insight.ts`:
- Around line 135-139: The error logging in the Gemini API response handling
block is exposing potentially sensitive data from the API response body (such as
participant names and available times from the prompt) to server logs. Remove
the response body retrieval and logging to address the privacy concern.
Specifically, eliminate the line that calls response.text() to capture the
response body details, and update the console.error call to only include the
response status code for error reporting, matching the consistency of error
handling elsewhere in the function (such as at lines 152 and 154 where other
errors are logged without response body details).
- Around line 99-133: The generateScheduleInsight function has two issues: (1)
it directly accesses process.env and calls fetch, making it untestable for error
paths and timeouts, and (2) it likely logs detailed API error responses which
exposes sensitive information like quota and auth state. To fix this, refactor
the function to accept optional dependency parameters (for environment variables
like apiKey and model, and for the fetch implementation) with defaults that
preserve current behavior, allowing tests to inject mock implementations.
Additionally, change error logging to record only the HTTP status code instead
of the full API response body, reducing information disclosure risk while
maintaining debugging capability.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a2c2f68a-7f54-4901-9759-e18107bdad88
📒 Files selected for processing (4)
.env.examplesrc/app/api/schedules/[id]/insight/route.tssrc/app/schedule/[id]/ScheduleRoomClient.tsxsrc/lib/gemini/insight.ts
- insight 해설 stale 방지: 추천 슬롯 내용 기반 키로 재요청, 요청 시작/실패 시 setInsight(null)로 초기화, AbortController로 중복 요청 취소 - generateScheduleInsight에 의존성 주입(fetcher/apiKey/model) 추가해 단위 테스트 용이화 - Gemini 에러 응답 본문 로깅 제거(참여자명·가용시간 로그 유출 방지), 상태코드만 기록 참여자 실명은 이름 멘트가 기능 핵심이고 결과 링크에서 이미 공개되는 값이라 의도적으로 유지. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🚀 작업 내용 (What)
src/lib/gemini/insight.ts: Gemini REST(generateContent) 직접 호출 클라이언트. 키 미설정·호출 실패·타임아웃(8초) 시null반환(SDK 의존성 없음)GET /api/schedules/[id]/insight: 집계 결과(추천 시간 + 참여자 가용시간)로 해설을 생성하는 라우트ScheduleRoomClient: 추천 시간 목록 위에 해설 카드 렌더링, 추천 시간 변경 시 재요청.env.example:GEMINI_MODEL(선택, 기본gemini-2.5-flash) 문서화📣 핵심 변경 이유 (Why)
📸 스크린샷 (Visuals, 선택)
🔗 관련 이슈 (Issue)
Close #118