Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| 코호트 / 파일(s) | 설명 |
|---|---|
엔티티 및 DTO backend/src/main/java/moadong/club/entity/PromotionArticle.java, backend/src/main/java/moadong/club/payload/dto/PromotionArticleDto.java, backend/src/main/java/moadong/club/payload/request/PromotionArticleCreateRequest.java, backend/src/main/java/moadong/club/payload/response/PromotionArticleResponse.java |
MongoDB 문서 엔티티 및 요청/응답 데이터 모델 추가. PromotionArticle은 clubId, 제목, 위치, 이벤트 기간, 설명, 이미지 목록을 포함하고, 생성일시는 기본값으로 설정됨. 요청 DTO는 필드 유효성 검사 포함. |
리포지토리 backend/src/main/java/moadong/club/repository/PromotionArticleRepository.java |
MongoDB 리포지토리 인터페이스 추가. 전체 홍보 게시물 조회 및 clubId 기반 필터링 메서드 포함. 조회 결과는 생성일시 역순으로 정렬됨. |
서비스 backend/src/main/java/moadong/club/service/PromotionArticleService.java |
비즈니스 로직 서비스 추가. 홍보 게시물 조회 및 생성 기능 구현. 생성 시 clubId 변환, 클럽 존재 여부 검증, 게시물 저장 처리. |
컨트롤러 backend/src/main/java/moadong/club/controller/PromotionArticleController.java |
REST API 엔드포인트 추가. GET /api/promotion (전체 조회), POST /api/promotion (생성, 인증 필수). Swagger/OpenAPI 주석 및 보안 요구사항 포함. |
Sequence Diagram(s)
sequenceDiagram
actor Client
participant Controller as PromotionArticleController
participant Service as PromotionArticleService
participant ClubRepo as ClubRepository
participant PromotionRepo as PromotionArticleRepository
Client->>Controller: POST /api/promotion<br/>(PromotionArticleCreateRequest)
Controller->>Service: createPromotionArticle(request)
Service->>ClubRepo: findById(clubId)
alt Club exists
ClubRepo-->>Service: Club entity
Service->>PromotionRepo: save(PromotionArticle)
PromotionRepo-->>Service: saved entity
Service-->>Controller: void
Controller-->>Client: 200 OK
else Club not found
ClubRepo-->>Service: empty
Service-->>Controller: RestApiException(CLUB_NOT_FOUND)
Controller-->>Client: 400/404 error
end
sequenceDiagram
actor Client
participant Controller as PromotionArticleController
participant Service as PromotionArticleService
participant PromotionRepo as PromotionArticleRepository
Client->>Controller: GET /api/promotion
Controller->>Service: getPromotionArticles()
Service->>PromotionRepo: findAllProjectedBy()
PromotionRepo-->>Service: List<PromotionArticleDto>
Service->>Service: wrap in PromotionArticleResponse
Service-->>Controller: PromotionArticleResponse
Controller-->>Client: 200 OK (JSON response)
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related issues
- MOA-585 "홍보 게시판 CR API 추가": 이 PR은 요청된 CREATE 및 READ API를 모두 구현하며, 홍보 게시판의 컨트롤러, 서비스, 리포지토리, 엔티티 및 DTO를 완벽하게 제공합니다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% 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 |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | PR 제목 '[feat] 홍보게시판 API 구현'은 변경 사항의 핵심을 명확하게 요약하고 있으며, 추가된 모든 파일과 엔드포인트가 홍보게시판 API 구현과 직접 관련되어 있습니다. |
| Linked Issues check | ✅ Passed | PR은 MOA-585 이슈의 모든 요구사항을 충족합니다: CREATE API [POST /api/promotion]와 READ API [GET /api/promotion] 모두 구현되었으며, MongoDB 기반 데이터 영속성과 필요한 모든 엔티티, DTO, 리포지토리, 서비스가 포함되어 있습니다. |
| Out of Scope Changes check | ✅ Passed | 모든 변경 사항은 홍보게시판 API 구현이라는 PR 범위 내에 있으며, 추가된 모든 파일(PromotionArticleController, PromotionArticle, 관련 DTO, 리포지토리, 서비스)은 직접적으로 CREATE/READ API 기능에 필요한 구성 요소들입니다. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
feature/#1122-event-bbs-cr-api-MOA-585
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.
Test Results75 tests 70 ✅ 14s ⏱️ For more details on these failures, see this check. Results for commit 6d65a11. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In
`@backend/src/main/java/moadong/club/payload/request/PromotionArticleCreateRequest.java`:
- Around line 14-15: Add validation to ensure eventEndDate is not before
eventStartDate; in the service method
PromotionArticleService.createPromotionArticle() check request.eventEndDate()
against request.eventStartDate() and throw a RestApiException (e.g.,
ErrorCode.INVALID_DATE_RANGE) when end is before start, or implement an
equivalent custom validator on PromotionArticleCreateRequest that enforces the
same rule before persisting.
In
`@backend/src/main/java/moadong/club/repository/PromotionArticleRepository.java`:
- Line 17: The repository interface PromotionArticleRepository currently
declares an unused method findByClubIdOrderByCreatedAtDesc; remove this unused
method from PromotionArticleRepository to avoid dead API surface (or if it's
intended for future use, add a short Javadoc above
findByClubIdOrderByCreatedAtDesc explaining the planned usage and a TODO with a
ticket/issue reference). Ensure any callers are updated if you choose removal
and run tests/compile to verify no references remain.
In `@backend/src/main/java/moadong/club/service/PromotionArticleService.java`:
- Around line 33-36: The createPromotionArticle method currently only looks up
Club by ID; add an authorization check to ensure the authenticated user is a
member of that Club before creating the article: after converting
request.clubId() and loading Club via clubRepository.findClubById(...) (as
shown) obtain the current user's id (via your existing auth helper/service or
SecurityContext), then verify membership (e.g., check Club.getMembers() or call
membershipRepository.existsByClubIdAndUserId(...)); if the check fails throw a
RestApiException with an appropriate ErrorCode (e.g., ErrorCode.FORBIDDEN or a
new CLUB_MEMBERSHIP_REQUIRED) to block creation. Ensure you reference
createPromotionArticle, PromotionArticleCreateRequest, clubRepository, Club and
RestApiException when implementing.
🧹 Nitpick comments (5)
backend/src/main/java/moadong/club/entity/PromotionArticle.java (2)
23-23:clubId필드에 인덱스 추가를 고려하세요.
PromotionArticleRepository에서findByClubIdOrderByCreatedAtDesc(String clubId)메서드를 사용하고 있습니다.clubId로 검색하는 쿼리 성능 최적화를 위해 인덱스 추가를 권장합니다.♻️ 인덱스 추가 제안
+import org.springframework.data.mongodb.core.index.Indexed; + `@Document`("promotion_articles") `@Getter` `@Builder` `@AllArgsConstructor` `@NoArgsConstructor` public class PromotionArticle { `@Id` private String id; + `@Indexed` private String clubId;
37-37:images필드의 null 안전성을 고려하세요.
images필드가 Builder를 통해 설정되지 않으면null이 될 수 있습니다. API 응답에서 예기치 않은 null 값을 방지하려면 빈 리스트로 기본값을 설정하는 것이 좋습니다.♻️ 기본값 설정 제안
+import java.util.ArrayList; + `@Builder.Default` - private List<String> images; + private List<String> images = new ArrayList<>();backend/src/main/java/moadong/club/repository/PromotionArticleRepository.java (1)
14-15: 페이지네이션 추가를 고려하세요.
findAllProjectedBy()메서드가 모든 게시글을 반환합니다. 데이터가 많아지면 성능 문제가 발생할 수 있으므로,Pageable파라미터를 추가하여 페이지네이션을 지원하는 것을 권장합니다.♻️ 페이지네이션 지원 메서드 추가 예시
+import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + `@Repository` public interface PromotionArticleRepository extends MongoRepository<PromotionArticle, String> { `@Query`(value = "{}", sort = "{ 'createdAt': -1 }") List<PromotionArticleDto> findAllProjectedBy(); + `@Query`(value = "{}") + Page<PromotionArticleDto> findAllProjectedBy(Pageable pageable); + List<PromotionArticle> findByClubIdOrderByCreatedAtDesc(String clubId); }backend/src/main/java/moadong/club/service/PromotionArticleService.java (1)
27-30: 읽기 전용 트랜잭션 설정을 고려하세요.
getPromotionArticles()메서드는 읽기 전용 작업이므로@Transactional(readOnly = true)를 추가하면 성능 최적화에 도움이 됩니다.♻️ 읽기 전용 트랜잭션 추가
+ `@Transactional`(readOnly = true) public PromotionArticleResponse getPromotionArticles() { List<PromotionArticleDto> articles = promotionArticleRepository.findAllProjectedBy(); return new PromotionArticleResponse(articles); }backend/src/main/java/moadong/club/controller/PromotionArticleController.java (1)
35-43: 리소스 생성 시 HTTP 201 Created 응답을 고려하세요.현재
Response.ok()는 HTTP 200을 반환합니다. REST 규칙에 따르면 리소스 생성 성공 시 HTTP 201 Created를 반환하는 것이 더 적절합니다.♻️ HTTP 201 응답으로 변경 예시
public ResponseEntity<?> createPromotionArticle( `@RequestBody` `@Validated` PromotionArticleCreateRequest request) { promotionArticleService.createPromotionArticle(request); - return Response.ok("홍보 게시글이 생성되었습니다."); + return Response.created("홍보 게시글이 생성되었습니다."); }
Response클래스에created()메서드가 없다면:- return Response.ok("홍보 게시글이 생성되었습니다."); + return ResponseEntity.status(HttpStatus.CREATED).body("홍보 게시글이 생성되었습니다.");
backend/src/main/java/moadong/club/payload/request/PromotionArticleCreateRequest.java
Show resolved
Hide resolved
backend/src/main/java/moadong/club/repository/PromotionArticleRepository.java
Show resolved
Hide resolved
flanky한 테스트라 머지에는 신경을 쓸꺼같진 않습니다. 개선이 필요하다 생각이들네요 |
#️⃣연관된 이슈
#1122
📝작업 내용
홍보게시판 API 엔드포인트 구현
추가된 엔드포인트
/api/promotion/api/promotion구조
promotion_articles컬렉션)Instant사용 (eventStartDate,eventEndDate)Request/Response 예시
GET Response:
{ "articles": [ { "clubName": "WAP", "clubId": "1230badsf", "title": "WAP 최종전시..", "location": "향파관", "eventStartDate": "2025-12-01T00:00:00Z", "eventEndDate": "2025-12-02T00:00:00Z", "description": "홍보 설명", "images": ["https://cdn.moadong.com","https://cdn.moadong.com~~~"] } ] }POST Request:
{ "clubId": "1230badsf", "title": "WAP 최종전시..", "location": "향파관", "eventStartDate": "2025-12-01T00:00:00Z", "eventEndDate": "2025-12-02T00:00:00Z", "description": "홍보 설명", "images": ["https://cdn.moadong.com","https://cdn.moadong.com~~~"] }Summary by CodeRabbit
릴리스 노트
✏️ Tip: You can customize this high-level summary in your review settings.