Feat/#137 타임라인 - 타임라인 엔티티 AI 요약#138
Conversation
Walkthrough타임라인 AI 요약 기능이 추가됩니다. 사용자가 요약을 요청하면 트랜잭션 커밋 후 비동기로 OpenAI를 통해 요약을 생성하고 저장합니다. 동시에 타임라인 생성/수정/삭제 시 성과 데이터 검증을 강화하고 권한 검증 로직을 단순화합니다. ChangesTimeline AI Summary Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🔍 시니어 리뷰어 관점의 주요 체크포인트✅ 잘 설계된 부분
|
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | PR 제목은 주요 기능 변경(타임라인 AI 요약)을 명확하게 설명하며 이슈 번호와 함께 간결하게 표현됨. |
| Description check | ✅ Passed | PR 설명은 템플릿 구조를 따르며 개요, 작업 내용, 테스트 결과, 체크리스트, 리뷰 포인트를 포함하고 있음. |
| Linked Issues check | ✅ Passed | 모든 연결된 이슈 #137의 요구사항(데이터 쿼리, 시스템 프롬프트, 요약 저장)이 구현되었으며 PR 변경사항이 요구사항을 충족함. |
| Out of Scope Changes check | ✅ Passed | 모든 변경사항이 타임라인 AI 요약 기능과 관련된 범위 내에 있으며, 부수적인 권한 개선(MEMBER 권한 수정)과 데이터 검증(현재 데이터 확인)은 기능 구현에 필요한 변경임. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
📝 Generate docstrings
- Create stacked PR
- Commit on current branch
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
feat/#137
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 @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/main/java/com/whereyouad/WhereYouAd/domains/timeline/domain/service/TimelineAsyncServiceImpl.java`:
- Around line 32-49: Ensure the timeline belongs to the requested org before
loading metrics: in TimelineAsyncServiceImpl, after retrieving the Timeline via
timelineRepository.findById(timelineId), compare timeline.getOrgId() (or
equivalent org field on Timeline) with the provided orgId and if they differ
throw a TimelineException (use an existing error code or add
TIMELINE_ORG_MISMATCH) to stop processing; only proceed to call
metricFactRepository.findByOrgAndPeriodAndGrain(...) when the org IDs match.
In
`@src/main/java/com/whereyouad/WhereYouAd/domains/timeline/domain/service/TimelineServiceImpl.java`:
- Around line 277-281: 현재 사전 검증에서 hasData는
기간(timeline.getStartDate()~getEndDate())과 orgId만 검사하지만 비동기 생성에서는 Grain.DAILY로 다시
조회해 실제 요약 데이터가 없을 수 있으므로 검증 조건을 실제 요약 조회와 동일하게 맞추어야 합니다: 변경할 위치는 hasData를 만드는
식(metricFactRepository.existsByTimeBucketBetweenAndOrg(...))이며, 여기에 요약
grain(timeline.getGrain() 또는 상수 Grain.DAILY) 조건을 추가해 예를 들어
metricFactRepository.existsByTimeBucketBetweenAndOrgAndGrain(start, end, orgId,
timeline.getGrain()) 같은 저장소 메서드를 호출하도록 수정하세요; 저장소에 해당 exists 메서드가 없다면 리포지토리에 존재
여부 메서드를 추가해 동일한 grain 기준으로 검사하도록 구현하세요.
🪄 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: CHILL
Plan: Pro
Run ID: d23ed5e2-9b39-48b5-9f95-1065a921d4fd
📒 Files selected for processing (9)
src/main/java/com/whereyouad/WhereYouAd/domains/timeline/domain/service/TimelineAsyncService.javasrc/main/java/com/whereyouad/WhereYouAd/domains/timeline/domain/service/TimelineAsyncServiceImpl.javasrc/main/java/com/whereyouad/WhereYouAd/domains/timeline/domain/service/TimelineService.javasrc/main/java/com/whereyouad/WhereYouAd/domains/timeline/domain/service/TimelineServiceImpl.javasrc/main/java/com/whereyouad/WhereYouAd/domains/timeline/exception/code/TimelineErrorCode.javasrc/main/java/com/whereyouad/WhereYouAd/domains/timeline/presentation/TimelineController.javasrc/main/java/com/whereyouad/WhereYouAd/domains/timeline/presentation/docs/TimelineControllerDocs.javasrc/main/java/com/whereyouad/WhereYouAd/infrastructure/client/openai/prompt/PromptBuilder.javasrc/main/java/com/whereyouad/WhereYouAd/infrastructure/client/openai/service/OpenApiService.java
| boolean hasData = metricFactRepository.existsByTimeBucketBetweenAndOrg( | ||
| timeline.getStartDate().atStartOfDay(), | ||
| timeline.getEndDate().plusDays(1).atStartOfDay(), | ||
| orgId | ||
| ); |
There was a problem hiding this comment.
요약 요청 전 데이터 재검증 조건이 실제 요약 조회 조건과 다릅니다.
여기서는 기간+조직만 확인하고, 비동기 생성에서는 Grain.DAILY 조건으로 다시 조회합니다. 그래서 사전 검증은 통과했는데 실제 요약용 데이터는 비어 있는 케이스가 생길 수 있습니다. 동일한 조건(최소한 동일 grain)으로 맞춰주세요.
수정 방향 예시
- boolean hasData = metricFactRepository.existsByTimeBucketBetweenAndOrg(
- timeline.getStartDate().atStartOfDay(),
- timeline.getEndDate().plusDays(1).atStartOfDay(),
- orgId
- );
+ boolean hasData = !metricFactRepository.findByOrgAndPeriodAndGrain(
+ orgId,
+ timeline.getStartDate().atStartOfDay(),
+ timeline.getEndDate().plusDays(1).atStartOfDay(),
+ Grain.DAILY
+ ).isEmpty();🤖 Prompt for 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.
In
`@src/main/java/com/whereyouad/WhereYouAd/domains/timeline/domain/service/TimelineServiceImpl.java`
around lines 277 - 281, 현재 사전 검증에서 hasData는
기간(timeline.getStartDate()~getEndDate())과 orgId만 검사하지만 비동기 생성에서는 Grain.DAILY로 다시
조회해 실제 요약 데이터가 없을 수 있으므로 검증 조건을 실제 요약 조회와 동일하게 맞추어야 합니다: 변경할 위치는 hasData를 만드는
식(metricFactRepository.existsByTimeBucketBetweenAndOrg(...))이며, 여기에 요약
grain(timeline.getGrain() 또는 상수 Grain.DAILY) 조건을 추가해 예를 들어
metricFactRepository.existsByTimeBucketBetweenAndOrgAndGrain(start, end, orgId,
timeline.getGrain()) 같은 저장소 메서드를 호출하도록 수정하세요; 저장소에 해당 exists 메서드가 없다면 리포지토리에 존재
여부 메서드를 추가해 동일한 grain 기준으로 검사하도록 구현하세요.
ojy0903
left a comment
There was a problem hiding this comment.
P4: 고생하셨어요! 일단은 피그마상에서도 타임라인 관련 요약은 간단하게 되어있어서 지금처럼 하는 것도 괜찮아 보입니다. 요약도 비교적 짧은 내용이여서 TimeLine 엔티티 필드로 받는거 좋은 것 같아요! 지금은 이렇게 유지하고, 혹시라도 프론트 측에서 좀 더 길게 요약 제시할 필요가 있다고 하면 그때 프롬프트 쪽만 수정하면 될 거 같습니다!!
jinnieusLab
left a comment
There was a problem hiding this comment.
P4: 고생하셨습니다! 저희 예산 수정 기능 완료 되면 해당 타임라인 요약 프롬프트에 예산 수정 시점이 존재하면 해당 시점을 기준으로 유의미한 변화가 있었는지 분석하는 내용도 추후에 추가하면 좋을 것 같아요!
📌 관련 이슈
🚀 개요
타임라인 엔티티에 해당하는 데이터와 비교기간에 해당하는 데이터를 불러와 AI에게 요약을 요청하는 API 구현
📄 작업 내용
📸 스크린샷 / 테스트 결과 (선택)
✅ 체크리스트
🔍 리뷰 포인트 (Review Points)
(예: 이 로직이 최선일까요? P2)
(예: 예외 처리 누락 여부 확인 부탁드립니다. P1)
기존에 있던 조직 데이터 or 플랫폼별 데이터를 넘겨주고 분석 요청하는 프롬프트와는 결과가 좀 달라야 할 것 같아서 프롬프트는 새로 작성했습니다. 타임라인 특성상 단순 분석만 하면 될 것 같아서 2~3문장 결과 위주 요약정도만 제공하면 될 것 같은데 혹시 추가로 AI한테 더 부탁할 내용이 있을까요?? 지금은 딱히 생각나는게 없어서 분석만 넣었습니다.
마찬가지로 타임라인 요약이 여러개 있을 필요는 없을 것 같고 1개만 존재하면 될 것 같아서 TimeLine 엔티티에서 칼럼으로 관리하는 방식이고 상세 조회 시에 같이 반환되어서 타임라인 AI요청 결과보기 같은 API는 따로 만들지 않았습니다..!
Summary by CodeRabbit
Release Notes
New Features
Improvements
Documentation
릴리스 노트
새로운 기능
개선 사항
문서화