[FEAT] 레포지토리 분석 결과 조회 API 구현#25
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthrough레포지토리 분석 결과 조회 API를 구현합니다. QueryDSL 기반 데이터 접근, 다중 응답 DTO, 심각도 필터링 및 페이지네이션, 사용자별 권한 검증을 추가하여 3개 엔드포인트(이슈 목록, 취약 파일, 이슈 상세)를 제공합니다. ChangesRepository Analysis Query API
Sequence DiagramsequenceDiagram
participant Client
participant RepositoryIssueController
participant RepositoryIssueService
participant AnalysisResultRepository
participant ProjectRepositoryRepository
participant Database
Client->>RepositoryIssueController: GET /api/repositories/{repositoryId}/analysis/issues?severity=CRITICAL&page=1&size=20
RepositoryIssueController->>RepositoryIssueService: getRepositoryIssues(repositoryId, userId, severity, page, size)
RepositoryIssueService->>ProjectRepositoryRepository: existsByRepositoryIdAndUserUserIdAndDeletedFalse(repositoryId, userId)
ProjectRepositoryRepository->>Database: SELECT EXISTS(...)
Database-->>ProjectRepositoryRepository: true/false
RepositoryIssueService->>AnalysisResultRepository: findRepositoryIssues(repositoryId, userId, severity, pageable)
AnalysisResultRepository->>Database: QueryDSL SELECT (joins, groupBy, aggregation)
Database-->>AnalysisResultRepository: result set
AnalysisResultRepository-->>RepositoryIssueService: RepositoryIssueListResponse (paged)
RepositoryIssueService-->>RepositoryIssueController: RepositoryIssueListResponse
RepositoryIssueController-->>Client: ApiResponse<RepositoryIssueListResponse>
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related PRs
Poem
🚥 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 |
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/SeCause/SeCause_be/domain/projectRepository/service/RepositoryIssueService.java`:
- Around line 71-74: The validatePageRequest method currently only checks for
page < 1 or size < 1; add an upper bound for size (e.g., define a constant
MAX_PAGE_SIZE = 100) and throw
ProjectRepositoryException(ProjectRepositoryErrorCode.INVALID_PAGE_REQUEST) when
size > MAX_PAGE_SIZE; update validatePageRequest to compare against
MAX_PAGE_SIZE and include the constant near the top of RepositoryIssueService
(or as a private static final field) so callers of validatePageRequest will be
protected from excessively large page sizes.
In `@src/main/resources/schema.sql`:
- Around line 1-34: Remove the stray marker lines "^^^ END OF SCRIPT ^^^" and
terminate statements properly: add a semicolon after "CREATE EXTENSION IF NOT
EXISTS vector" and ensure each DO $$ ... END $$ block ends with "END $$;" so the
type creations (file_type_enum, analysis_status_enum, severity_enum,
reference_type_enum) are valid; keep the CREATE TYPE names as-is and only adjust
the trailing markers and semicolons so the SQL executes.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: dfa3c9f4-5e1e-49b4-b2d2-5a63c5e1d4ce
📒 Files selected for processing (22)
build.gradlesrc/main/java/SeCause/SeCause_be/domain/analysis/code/AnalysisErrorCode.javasrc/main/java/SeCause/SeCause_be/domain/analysis/exception/AnalysisException.javasrc/main/java/SeCause/SeCause_be/domain/analysis/repository/AnalysisResultRepository.javasrc/main/java/SeCause/SeCause_be/domain/analysis/repository/AnalysisResultRepositoryCustom.javasrc/main/java/SeCause/SeCause_be/domain/analysis/repository/AnalysisResultRepositoryImpl.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/code/ProjectRepositoryErrorCode.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/controller/RepositoryIssueApi.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/controller/RepositoryIssueController.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/dto/RepositoryIssueDetailResponse.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/dto/RepositoryIssueListResponse.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/dto/RepositoryIssueSeverity.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/dto/RepositoryIssueSummaryResponse.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/dto/SecurityReferenceResponse.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/dto/VulnerableFileListResponse.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/dto/VulnerableFileSummaryResponse.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/exception/ProjectRepositoryException.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/repository/ProjectRepositoryRepository.javasrc/main/java/SeCause/SeCause_be/domain/projectRepository/service/RepositoryIssueService.javasrc/main/java/SeCause/SeCause_be/domain/user/controller/UserController.javasrc/main/java/SeCause/SeCause_be/global/config/QueryDslConfig.javasrc/main/resources/schema.sql
boogiewooki02
left a comment
There was a problem hiding this comment.
전체적으로 QueryDSL을 활용해서 조회 API에 필요한 데이터만 조인하는 구조가 잘 잡혀 있는 것 같습니다.
고생하셨습니다!
| private void validatePageRequest(int page, int size) { | ||
| if (page < 1 || size < 1) { | ||
| throw new ProjectRepositoryException(ProjectRepositoryErrorCode.INVALID_PAGE_REQUEST); | ||
| } |
There was a problem hiding this comment.
페이지 size에 상한이 없어서 큰 값 요청 시 한 번에 과도한 조회가 발생할 수 있어 보입니다. 최대 size를 제한하는 방어 로직이 있으면 좋겠습니다!
| @Tag(name = "Repository Issue", description = "레포지토리 분석 이슈 API") | ||
| public interface RepositoryIssueApi { |
There was a problem hiding this comment.
이런식으로 스웨거 문서 내용을 따로 분리해서 관리할 수 있군요! 덕분에 컨트롤러 코드가 훨씬 깔끔해지는 것 같아요!
close #19
🔎 개요
레포지토리 분석 결과의 보안 이슈를 조회하는 API를 구현했습니다.
📝 작업 내용
severity필터링 및 페이지네이션 응답 적용Vulnerability상속 구조 기준으로 함께 조회ProjectRepositoryErrorCode,ProjectRepositoryExceptionAnalysisErrorCode,AnalysisException현재 PR 단위가 커져서, 스웨거로 간단한 테스트만 진행했으며 테스트 코드는 확인해본 후 다음 PR때 올리겠습니다
👀 변경 사항
domain.projectRepository하위에 추가되었습니다.analysis_results -> vulnerability -> analysis/repositoryFile구조를 기준으로 동작합니다.lineStart,lineEnd는 코드 취약점인 경우에만 내려가며, 인프라 취약점은null일 수 있습니다.COMMON404대신 도메인별 에러 코드가 반환됩니다.PROJECT_REPOSITORY404ANALYSIS_RESULT404📸 스크린샷 (Optional)
레포지토리 이슈 목록 조회
취약점 파일 목록 조회
이슈 상세 조회
관련 에러 응답
✅ 체크리스트
💬 고민사항 및 리뷰 요구사항 (Optional)
analysis_results -> vulnerability -> analysis -> repository,vulnerability -> repositoryFile조인이 사용됩니다.CodeVulnerability는 left join으로 처리했습니다.analysis_results.vulnerability_id,vulnerabilities.analysis_id,vulnerabilities.repository_file_id기준 인덱스를 추가해 최적화할 수 있습니다.Summary by CodeRabbit
릴리스 노트
New Features
Documentation
Chores