-
Notifications
You must be signed in to change notification settings - Fork 35
Spring Batch 기반 집계 서비스 구현 #240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6ead99e
8e06929
5569bf6
ee02ce7
e1d3f05
b399fde
a143f91
0096dae
7f05b54
ca1fed1
d5280ea
05b7b2a
227d932
003b543
00498cd
1ad67da
4a13366
bc962b2
0605dc4
f1d94ed
a51021c
a946ac0
33c0ab8
b73c2c6
8d5e90a
d6711cf
7a56684
ded9e38
5b83c03
3158c2b
e287600
9c5e6ea
3774002
8e5643a
ef3eebd
d738654
b06e034
6c48755
d9ae7ad
5bb8d33
d505115
624b780
a97d77b
55f8c8b
592a4e5
4faa67e
86a8205
d06a0d0
5042c22
4fda674
25b423e
04ff345
7e0ac82
1087ea2
3e2e0f4
5db5c36
aa374c3
c74e6ad
c80ed47
c5754ff
deda1e2
617746d
be18c88
0074ea9
b84525a
52b62bd
34df8d5
4ca321e
339132b
d321b49
caec6fa
da195a3
6c87e71
9f4552a
d447d48
7f3a2d7
9121d96
1034b98
d894a11
139cbc3
2dffa78
d1693f0
2c8e554
e5128b7
78ead14
7218ff9
5863915
6aee58a
2be7a2f
c02335e
9c26225
6508dad
e162dad
20b19fc
16bb063
34b6871
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| name: PR Agent | ||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize] | ||
| jobs: | ||
| pr_agent_job: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: PR Agent action step | ||
| uses: Codium-ai/pr-agent@main | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 액션 버전을 고정하여 보안을 강화하세요.
🔎 권장 수정 사항- - name: PR Agent action step
- uses: Codium-ai/pr-agent@main
+ - name: PR Agent action step
+ uses: Codium-ai/pr-agent@v1.2.3 # 또는 특정 커밋 SHA 사용최신 안정 버전을 확인하려면 Codium-ai/pr-agent 릴리스 페이지를 참조하세요.
🤖 Prompt for AI Agents |
||
| env: | ||
| OPENAI_KEY: ${{ secrets.OPENAI_KEY }} | ||
| GITHUB_TOKEN: ${{ secrets.G_TOKEN }} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's examine the workflow file to understand the context around line 13
cd .github/workflows && ls -laRepository: Loopers-dev-lab/loopers-spring-java-template Length of output: 253 🏁 Script executed: # Read the main.yml workflow file to understand the pr-agent action setup
cat -n main.yml | head -30Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 128 🌐 Web query:
💡 Result: Short answer: pr-agent (the GitHub Action) requires a GITHUB_TOKEN with permissions:
You can use the automatically provided secrets.GITHUB_TOKEN (recommended). Use a repo-scoped PAT (repo scope) only when you need cross-repo/fork behaviors or to trigger downstream workflows. [1][2][3] Sources:
🏁 Script executed: cat -n .github/workflows/main.ymlRepository: Loopers-dev-lab/loopers-spring-java-template Length of output: 487 🏁 Script executed: # Also check if there's any documentation or comments in the workflow explaining the token choice
cat .github/workflows/main.ymlRepository: Loopers-dev-lab/loopers-spring-java-template Length of output: 396 🏁 Script executed: # Search for references to G_TOKEN in the repository to understand if this is intentional
rg "G_TOKEN" --type yaml --type yml --type mdRepository: Loopers-dev-lab/loopers-spring-java-template Length of output: 115 🏁 Script executed: # Check for any GitHub repository settings or documentation about token usage
fd README -type f | head -5 | xargs cat 2>/dev/null | grep -i "token\|G_TOKEN" -A 2 -B 2Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 258 🏁 Script executed: # Search for any GitHub Actions documentation or setup guides in the repository
fd -e md -e txt | xargs rg "GITHUB_TOKEN\|G_TOKEN\|secrets\|github.*token" -i 2>/dev/null | head -20Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 70 🏁 Script executed: # Search for G_TOKEN references in the entire repository
rg "G_TOKEN"Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 70 🏁 Script executed: # Search for any documentation about token setup
find . -type f \( -name "*.md" -o -name "*.txt" \) -exec grep -l "token\|TOKEN" {} \;Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 70 🏁 Script executed: # Check if there's any GitHub documentation or setup instructions
cat README.md 2>/dev/null | head -50Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 1242 🏁 Script executed: # Search for GitHub secrets configuration or environment setup files
find . -type f \( -name "*.md" -o -name ".env*" -o -name "*.properties" \) | head -20Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 695 내장된 GITHUB_TOKEN 사용으로 변경하세요. pr-agent 액션은 공식적으로
🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package com.loopers.application.ranking; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.PageImpl; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import com.loopers.domain.ranking.MonthlyRankEntity; | ||
| import com.loopers.domain.ranking.MonthlyRankRepository; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
||
| /** | ||
| * 월간 랭킹 조회 서비스 | ||
| */ | ||
| @Service | ||
| @RequiredArgsConstructor | ||
| @Slf4j | ||
| @Transactional(readOnly = true) | ||
| public class MonthlyRankingService { | ||
|
|
||
| private final MonthlyRankRepository monthlyRankRepository; | ||
|
|
||
| /** | ||
| * 특정 월의 랭킹을 페이지네이션하여 조회합니다. | ||
| * | ||
| * @param yearMonth 조회할 월 (예: "2024-12") | ||
| * @param pageable 페이징 정보 | ||
| * @return 월간 랭킹 페이지 | ||
| */ | ||
| public Page<MonthlyRankEntity> getMonthlyRanking(String yearMonth, Pageable pageable) { | ||
| log.debug("월간 랭킹 조회: yearMonth={}, page={}, size={}", | ||
| yearMonth, pageable.getPageNumber(), pageable.getPageSize()); | ||
|
|
||
| // 1. 전체 랭킹 조회 (순위 순으로 정렬됨) | ||
| Page<MonthlyRankEntity> pagedRankings = monthlyRankRepository.findByYearMonth(yearMonth, pageable); | ||
|
|
||
|
|
||
| log.debug("월간 랭킹 조회 완료: yearMonth={}, 전체={}, 페이지={}", | ||
| yearMonth, pagedRankings.getTotalPages(), pagedRankings.getNumber()); | ||
|
|
||
| return pagedRankings; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| package com.loopers.application.ranking; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.PageImpl; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import com.loopers.domain.ranking.WeeklyRankEntity; | ||
| import com.loopers.domain.ranking.WeeklyRankRepository; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
||
| /** | ||
| * 주간 랭킹 조회 서비스 | ||
| */ | ||
| @Service | ||
| @RequiredArgsConstructor | ||
| @Slf4j | ||
| @Transactional(readOnly = true) | ||
| public class WeeklyRankingService { | ||
|
|
||
| private final WeeklyRankRepository weeklyRankRepository; | ||
|
|
||
| /** | ||
| * 특정 주차의 랭킹을 페이지네이션하여 조회합니다. | ||
| * | ||
| * @param yearWeek 조회할 주차 (예: "2024-W52") | ||
| * @param pageable 페이징 정보 | ||
| * @return 주간 랭킹 페이지 | ||
| */ | ||
| public Page<WeeklyRankEntity> getWeeklyRanking(String yearWeek, Pageable pageable) { | ||
| log.debug("주간 랭킹 조회: yearWeek={}, page={}, size={}", | ||
| yearWeek, pageable.getPageNumber(), pageable.getPageSize()); | ||
|
|
||
| // 1. 전체 랭킹 조회 (순위 순으로 정렬됨) | ||
| Page<WeeklyRankEntity> pagedRankings = weeklyRankRepository.findByYearWeek(yearWeek , pageable); | ||
|
|
||
| if (pagedRankings.isEmpty()) { | ||
| log.debug("주간 랭킹 데이터 없음: yearWeek={}", yearWeek); | ||
| return Page.empty(pageable); | ||
| } | ||
|
|
||
| return pagedRankings; | ||
| } | ||
|
|
||
| /** | ||
| * 특정 주차의 전체 랭킹 개수를 조회합니다. | ||
| * | ||
| * @param yearWeek 조회할 주차 | ||
| * @return 랭킹 개수 | ||
| */ | ||
| public long getWeeklyRankingCount(String yearWeek) { | ||
| List<WeeklyRankEntity> rankings = weeklyRankRepository.findByYearWeek(yearWeek); | ||
| return rankings.size(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.loopers.domain.ranking; | ||
|
|
||
| /** | ||
| * 랭킹 조회 기간 타입 | ||
| */ | ||
| public enum RankingPeriod { | ||
| /** | ||
| * 일간 랭킹 (Redis ZSET 기반) | ||
| */ | ||
| DAILY, | ||
|
|
||
| /** | ||
| * 주간 랭킹 (mv_product_rank_weekly 기반) | ||
| */ | ||
| WEEKLY, | ||
|
|
||
| /** | ||
| * 월간 랭킹 (mv_product_rank_monthly 기반) | ||
| */ | ||
| MONTHLY | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
명시적 권한 설정을 추가하세요.
최소 권한 원칙에 따라 워크플로우에 필요한 권한을 명시적으로 설정하는 것이 보안 모범 사례입니다. PR Agent는 PR 코멘트 작성 및 저장소 읽기 권한이 필요합니다.
🔎 권장 수정 사항
jobs: pr_agent_job: runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps:📝 Committable suggestion
🤖 Prompt for AI Agents