[Feat] 컬렉션 기본 CRUD API 구현 - #17
Conversation
- CollectionRepository, CollectionDocumentRepository, DocumentRepository(읽기 전용) 추가
- CollectionConverter, CollectionCommandService, CollectionQueryService 구현
- CollectionController: POST /collections, GET /collections/{id}, POST /collections/{collectionId}/documents
- ErrorCode: COLLECTION_NOT_FOUND, DOCUMENT_NOT_FOUND, COLLECTION_DOCUMENT_ALREADY_EXISTS 추가
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CollectionFixture: User, DocumentCollection, Document 팩토리 메서드 - CollectionQueryServiceTest: 정상 조회, COLLECTION_NOT_FOUND - CollectionCommandServiceTest: 컬렉션 생성(정상/기본값/상위컬렉션/상위없음), 문서 추가(정상/COLLECTION_NOT_FOUND/PERMISSION_DENIED/DOCUMENT_NOT_FOUND/중복) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 53 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough컬렉션 생성·단건 조회·문서 추가 REST API와 요청·응답 DTO, 저장소, 변환기, 서비스, 오류 코드 및 단위 테스트가 추가되었습니다. Changes컬렉션 API 기능
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant CollectionController
participant CollectionCommandService
participant CollectionRepository
participant DocumentRepository
participant CollectionDocumentRepository
CollectionController->>CollectionCommandService: 문서 추가 요청 전달
CollectionCommandService->>CollectionRepository: 컬렉션 조회
CollectionCommandService->>DocumentRepository: 문서 조회
CollectionCommandService->>CollectionDocumentRepository: 중복 조합 확인
CollectionCommandService->>CollectionDocumentRepository: 컬렉션 문서 저장
CollectionCommandService-->>CollectionController: 문서 응답 반환
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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.
🧹 Nitpick comments (3)
src/main/java/com/opensource/docgrid/domain/collection/service/command/CollectionCommandService.java (1)
77-80: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value유니크 제약 조건을 통한 동시성(TOCTOU) 방지 권장
현재 로직은 애플리케이션 레벨에서 문서가 컬렉션에 존재하는지 먼저 확인(
existsBy...)한 후 저장(save)합니다. 동일한 사용자가 동시에 같은 문서를 추가하려고 시도할 경우, 두 요청이 거의 동시에 인입되어 둘 다 존재 여부 검사를 통과하고 중복 데이터가 저장되는 시간차 공격(TOCTOU) 위험이 발생할 수 있습니다.데이터 무결성을 보장하기 위해 데이터베이스의
collection_documents테이블 레벨에서collection_id와document_id조합에 대해 유니크 인덱스(Unique Index)가 설정되어 있는지 확인하시기를 권장합니다.🤖 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/opensource/docgrid/domain/collection/service/command/CollectionCommandService.java` around lines 77 - 80, Ensure the collection_documents database table has a unique constraint or index on the collection_id and document_id combination, using the schema or migration configuration for this entity. Keep the existing CollectionCommandService existence check, and ensure duplicate-key violations from concurrent saves are handled consistently with COLLECTION_DOCUMENT_ALREADY_EXISTS.src/main/java/com/opensource/docgrid/domain/collection/repository/CollectionDocumentRepository.java (1)
9-9: 🗄️ Data Integrity & Integration | 🔵 Trivial데이터베이스 레벨의 유니크 제약조건 확인
애플리케이션 레벨에서 이 쿼리 메서드를 사용해 문서 중복 추가를 방지하고 있지만, 런타임 동시성 요청이 발생할 경우 경쟁 조건(Race Condition)으로 인해
exists검증을 우회하여 중복 데이터가 삽입될 위험이 있습니다.데이터 정합성을 확실히 보장하기 위해, 데이터베이스의
collection_documents(또는 관련 매핑 테이블)에collection_id와document_id를 묶는 유니크 인덱스(Unique Index)나 제약조건이 구성되어 있는지 함께 확인하시기를 권장합니다.🤖 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/opensource/docgrid/domain/collection/repository/CollectionDocumentRepository.java` at line 9, Ensure the database schema for the collection_documents mapping table enforces uniqueness on the combined collection_id and document_id columns, using the project’s migration or entity configuration mechanism. Keep existsByCollectionIdAndDocumentId for application-level checks, but add or verify the composite unique index/constraint so concurrent requests cannot insert duplicate mappings.src/test/java/com/opensource/docgrid/domain/collection/service/command/CollectionCommandServiceTest.java (1)
73-73: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
ArgumentCaptor를 활용한 엔티티 상태 검증 고려현재
save()메서드에 전달되는 인자를any(DocumentCollection.class)로 모킹하여 호출 여부만 검증하고 있습니다.저장되는 엔티티에 이름, 설명, 소유자 등의 상태가 DTO로부터 의도한 대로 정확히 매핑되었는지 한 단계 더 정밀하게 확인하고 싶다면,
ArgumentCaptor를 사용하여 캡처된 엔티티의 필드 값을 검증하는 방법을 고려해 볼 수 있습니다.💡 ArgumentCaptor 적용 예시
import org.mockito.ArgumentCaptor; // ... ArgumentCaptor<DocumentCollection> captor = ArgumentCaptor.forClass(DocumentCollection.class); then(collectionRepository).should().save(captor.capture()); DocumentCollection savedCollection = captor.getValue(); assertThat(savedCollection.getName()).isEqualTo(request.name()); // 필요한 필드 추가 검증...🤖 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/test/java/com/opensource/docgrid/domain/collection/service/command/CollectionCommandServiceTest.java` at line 73, Update the test around the collection command service save verification to capture the DocumentCollection passed to collectionRepository.save(...) with an ArgumentCaptor, then assert that its mapped fields such as name, description, and owner match the request DTO. Preserve the existing save invocation verification while adding precise entity-state assertions.
🤖 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.
Nitpick comments:
In
`@src/main/java/com/opensource/docgrid/domain/collection/repository/CollectionDocumentRepository.java`:
- Line 9: Ensure the database schema for the collection_documents mapping table
enforces uniqueness on the combined collection_id and document_id columns, using
the project’s migration or entity configuration mechanism. Keep
existsByCollectionIdAndDocumentId for application-level checks, but add or
verify the composite unique index/constraint so concurrent requests cannot
insert duplicate mappings.
In
`@src/main/java/com/opensource/docgrid/domain/collection/service/command/CollectionCommandService.java`:
- Around line 77-80: Ensure the collection_documents database table has a unique
constraint or index on the collection_id and document_id combination, using the
schema or migration configuration for this entity. Keep the existing
CollectionCommandService existence check, and ensure duplicate-key violations
from concurrent saves are handled consistently with
COLLECTION_DOCUMENT_ALREADY_EXISTS.
In
`@src/test/java/com/opensource/docgrid/domain/collection/service/command/CollectionCommandServiceTest.java`:
- Line 73: Update the test around the collection command service save
verification to capture the DocumentCollection passed to
collectionRepository.save(...) with an ArgumentCaptor, then assert that its
mapped fields such as name, description, and owner match the request DTO.
Preserve the existing save invocation verification while adding precise
entity-state assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: a5759218-3647-47da-ae9a-d666cccceb33
📒 Files selected for processing (15)
src/main/java/com/opensource/docgrid/domain/collection/controller/CollectionController.javasrc/main/java/com/opensource/docgrid/domain/collection/converter/CollectionConverter.javasrc/main/java/com/opensource/docgrid/domain/collection/dto/request/AddDocumentRequest.javasrc/main/java/com/opensource/docgrid/domain/collection/dto/request/CreateCollectionRequest.javasrc/main/java/com/opensource/docgrid/domain/collection/dto/response/CollectionDocumentResponse.javasrc/main/java/com/opensource/docgrid/domain/collection/dto/response/CollectionResponse.javasrc/main/java/com/opensource/docgrid/domain/collection/repository/CollectionDocumentRepository.javasrc/main/java/com/opensource/docgrid/domain/collection/repository/CollectionRepository.javasrc/main/java/com/opensource/docgrid/domain/collection/service/command/CollectionCommandService.javasrc/main/java/com/opensource/docgrid/domain/collection/service/query/CollectionQueryService.javasrc/main/java/com/opensource/docgrid/domain/document/repository/DocumentRepository.javasrc/main/java/com/opensource/docgrid/global/exception/ErrorCode.javasrc/test/java/com/opensource/docgrid/domain/collection/fixture/CollectionFixture.javasrc/test/java/com/opensource/docgrid/domain/collection/service/command/CollectionCommandServiceTest.javasrc/test/java/com/opensource/docgrid/domain/collection/service/query/CollectionQueryServiceTest.java
저장되는 엔티티의 name, description, owner 필드가 요청 DTO와 일치하는지 검증 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🔍️작업 내용
✨ 상세 설명
구현 내용
POST /collections— 컬렉션 생성 (생성자가 owner로 설정, visibility 미입력 시 PRIVATE 기본값)GET /collections/{id}— 컬렉션 단건 조회POST /collections/{collectionId}/documents— 컬렉션에 문서 추가구조
CollectionCommandService/CollectionQueryService(CQRS 분리)CollectionConverter— Entity → DTO 변환DocumentRepository— A담당자documents테이블 읽기 전용 참조용으로 추가COLLECTION_NOT_FOUND,DOCUMENT_NOT_FOUND,COLLECTION_DOCUMENT_ALREADY_EXISTS참고
🛠 추후 리팩토링 및 고도화 계획
POST /collections/{collectionId}/documents의 write 권한 체크가 현재 owner 여부만 확인함→ 이슈 3
PermissionService.canWriteDocument()완성 후 대체 예정 (코드에 TODO 마킹)📸 스크린샷 (선택)
💬 리뷰 요구사항
DocumentRepository를 B담당자 쪽에서 추가한 것이 A담당자와 충돌 여지가 있는지 확인 부탁드립니다Summary by CodeRabbit
새로운 기능
버그 수정
테스트