refactor: FRONTEND.md 기반 전체 API 계약 준수 리팩터링#32
Conversation
- 모든 컨트롤러 base URL /api/v1 통일 (Auth, Jwt, User, Feed, Post, Spot, Notification) - UserController /me vs /users 경로 분리 - FeedController apply → applications 경로 변경, bookmark 스텁 추가 - NotificationController PATCH→POST + read-all 스텁 추가 - SpotController /map, /search 스텁 추가 - DTO 필드명 FRONTEND.md 일치: content→text, isDone→completed, label, voterIds, uploaderNickname, authorNickname, spotId, sizeBytes 추가 - SpotService 참여자/파일/노트/투표 응답에 닉네임/voterIds 배치 조회 적용 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@coderabbitai full review |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughControllers and SecurityConfig were versioned to /api/v1; feed application role/deposit added end-to-end with migration; notification mark-as-read changed; Spot DTOs renamed/expanded and SpotService refactored to bulk-resolve nicknames and compute per-option voter-id lists; several controller stubs added. ChangesAPI Versioning, Feed, Notification, Security
Spot DTOs and Service Refactor
Sequence DiagramsequenceDiagram
participant Client
participant SpotController
participant SpotService
participant UserRepository
Client->>SpotController: GET /api/v1/spots/{id}/votes
SpotController->>SpotService: getVotes(spotId, currentUserId)
SpotService->>UserRepository: findAllByIds(userIds) (bulk nickname lookup)
SpotService->>SpotService: prefetch SpotVoteAnswer rows and compute voterIds per option
SpotService-->>SpotController: SpotVoteResponse (with option.voterIds)
SpotController-->>Client: 200 ApiResponse<SpotVoteResponse>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 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 |
✅ Actions performedFull review triggered. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
보안/회귀 리뷰 — refactor/frontend-md-complianceURL 전체가 🔴 HIGH — 서비스 전면 차단 (즉시 수정 필요)[1] SecurityConfig — permitAll 패턴이 구 경로 참조파일: 현재 코드: .requestMatchers(HttpMethod.POST,
"/api/users/exist", // ← 구 경로
"/api/users", // ← 구 경로
"/api/jwt/exchange" // ← 구 경로
).permitAll()
.requestMatchers(
"/api/auth/**", // ← 구 경로 (OAuth 엔드포인트)
"/api/spots/**", // ← 구 경로
"/api/feeds/**", // ← 구 경로
"/api/posts/**", // ← 구 경로
...
).permitAll()문제: 제안 수정: .requestMatchers(HttpMethod.POST,
"/api/v1/users/exist",
"/api/v1/users",
"/api/v1/jwt/exchange"
).permitAll()
.requestMatchers(
"/api/v1/auth/**",
"/api/v1/spots/**", // TODO: 인증 도입 후 제거
"/api/v1/feeds/**", // TODO: 인증 도입 후 제거
"/api/v1/posts/**", // TODO: 인증 도입 후 제거
"/v3/api-docs/**",
...
).permitAll()[2] LoginFilter — 로그인 경로 하드코딩파일: 현재 코드: private static final String LOGIN_PATH = "/api/auth/login";문제: 제안 수정: private static final String LOGIN_PATH = "/api/v1/auth/login";[3] SecurityConfig — logoutUrl 하드코딩파일: 현재 코드: .logoutUrl("/api/auth/logout")문제: 제안 수정: .logoutUrl("/api/v1/auth/logout")🟡 MEDIUM — 의도치 않은 접근 제어 변경[4]
|
| 체크리스트 항목 | 결과 |
|---|---|
JWTFilter shouldNotFilter / 경로 화이트리스트 |
없음 — token-absent pass-through 방식이라 경로 변경 불필요 ✅ |
NotificationController PATCH→POST + @ResponseStatus(NO_CONTENT) + void |
✅ 정상 변환됨 |
CORS allowedPaths |
/** 와일드카드 — /api/v1 포함 ✅ |
/me, /me/password 인증 필수 유지 |
.anyRequest().authenticated() 에 걸림 ✅ (단, [1] 수정 후에도 유지됨) |
요약: [1][2][3]이 동시에 존재하면 회원가입·로그인·로그아웃이 모두 차단되어 서비스가 동작하지 않습니다. 세 파일을 함께 수정한 후 머지하는 것을 권장합니다.
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
capstone-api/src/main/java/backend/feed/controller/FeedController.java (1)
53-60:⚠️ Potential issue | 🟠 Major | ⚡ Quick winReturn
201 Createdfrom the application-creation endpoint.This handler creates a feed application but currently returns 200. The PR’s contract/test plan expects 201 for
POST /applications.Suggested fix
`@Operation`(summary = "피드 신청") `@PostMapping`("/{feedId}/applications") +@ResponseStatus(HttpStatus.CREATED) public ApiResponse<FeedApplicationResponse> applyToFeed( `@PathVariable` String feedId, `@RequestBody` FeedApplyRequest request) {🤖 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 `@capstone-api/src/main/java/backend/feed/controller/FeedController.java` around lines 53 - 60, The applyToFeed handler in FeedController currently returns a 200 OK wrapped by ApiResponse; change it to return HTTP 201 Created: update the method to return ResponseEntity<ApiResponse<FeedApplicationResponse>> and return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(response)) after calling feedItemService.applyToFeed(feedId, "dummy-user-id", "황호찬", request). Ensure you import org.springframework.http.ResponseEntity and org.springframework.http.HttpStatus and keep the existing ApiResponse/FeedApplicationResponse usage.
🧹 Nitpick comments (1)
capstone-api/src/main/java/backend/feed/dto/FeedApplyRequest.java (1)
18-22: ⚡ Quick winAdd validation constraints for new request fields.
roleanddepositare new contract inputs; guarding them at DTO level prevents invalid payloads from entering service logic.Suggested fix
+import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; ... `@Schema`(description = "신청 역할 (SUPPORTER | PARTNER)", example = "SUPPORTER") - private String role; + `@NotBlank` + `@Pattern`(regexp = "SUPPORTER|PARTNER") + private String role; `@Schema`(description = "보증금", example = "10000") - private Integer deposit; + `@Min`(0) + private Integer deposit;🤖 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 `@capstone-api/src/main/java/backend/feed/dto/FeedApplyRequest.java` around lines 18 - 22, FeedApplyRequest currently exposes new fields role and deposit without validation; add bean validation annotations to ensure valid payloads: annotate role (in class FeedApplyRequest) with `@NotBlank` and restrict allowed values with `@Pattern`(regexp = "SUPPORTER|PARTNER") (or create/use an enum validator if preferred), and annotate deposit with `@NotNull` and `@Min`(0) (or `@PositiveOrZero`) to prevent negative or missing deposits; remember to import javax.validation.constraints.* and ensure controller methods are annotated with `@Valid` so these constraints are enforced.
🤖 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 `@capstone-api/src/main/java/backend/feed/controller/FeedController.java`:
- Around line 71-82: addBookmark and removeBookmark are stubs that return 204
without acting; wire in the bookmark service and call its methods to persist and
remove bookmarks using the feedId PathVariable (e.g., inject a BookmarkService
into FeedController and invoke bookmarkService.addBookmark(feedId, userId) in
addBookmark and bookmarkService.removeBookmark(feedId, userId) in
removeBookmark), handle/translate service errors to appropriate HTTP responses
(e.g., 404 if feed not found, 500 for server errors) and only return 204 after
the service call succeeds.
In `@capstone-api/src/main/java/backend/feed/dto/FeedApplicationResponse.java`:
- Around line 26-27: The FeedApplicationResponse DTO added fields appliedRole
and deposit but its static factory method from(...) never maps them, leaving
clients with nulls; update FeedApplicationResponse.from(<source>) to populate
appliedRole and deposit by reading the corresponding values from the source
object (e.g. call builder.appliedRole(source.getAppliedRole()) and
builder.deposit(source.getDeposit()) or map appropriate field names), and apply
the same mapping fix for the other newly added fields referenced around the same
block (the builder in from(...)) so all DTO fields are populated.
In
`@capstone-api/src/main/java/backend/notification/controller/NotificationController.java`:
- Around line 66-71: The endpoint NotificationController.markAllAsRead currently
returns 204 without doing anything; implement the missing behavior by adding a
method NotificationService.markAllAsRead(CustomUserDetails userDetails) (or
similar) that marks all notifications for the authenticated user as read, then
call that service from NotificationController.markAllAsRead using the injected
NotificationService and keep the `@ResponseStatus`(HttpStatus.NO_CONTENT) on
success; alternatively, if you prefer not to implement now, remove the
controller method or change its annotation to
`@ResponseStatus`(HttpStatus.NOT_IMPLEMENTED) to avoid falsely signaling success.
In `@capstone-api/src/main/java/backend/spot/controller/SpotController.java`:
- Around line 61-83: The controller methods getSpotMap and searchSpots currently
ignore their request parameters; either forward them to parameter-aware service
methods (e.g., add/rename and call spotService.getSpots(swLat, swLng, neLat,
neLng, category, type, status, page?, size?) for getSpotMap and
spotService.searchSpots(q, page, size) for searchSpots) or explicitly return 501
until implemented (use ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED) with a
clear message). Update the controller to call the new/updated SpotService
methods (or swap the successful ResponseEntity to a NOT_IMPLEMENTED response) so
the accepted parameters are actually used or the API contract is clearly
unimplemented.
In `@capstone-api/src/main/java/backend/spot/dto/SpotVoteResponse.java`:
- Around line 52-58: The convenience overloads of SpotVoteResponse.of are
dropping spotId by passing null; update both overloads (the methods public
static SpotVoteResponse of(SpotVote vote, List<SpotVoteOptionResponse> options)
and public static SpotVoteResponse of(SpotVote vote,
List<SpotVoteOptionResponse> options, List<Long> myVotedOptionIds)) to forward
the actual spotId (e.g., vote.getSpotId()) into the full factory call instead of
null so the DTO's spotId is populated; make the same change for the other
convenience overload referenced in the comment.
In `@capstone-api/src/main/java/backend/spot/service/SpotService.java`:
- Around line 578-582: The code currently treats only null currentUserId as
unauthenticated, allowing blank strings to be stored; update the uploader/author
selection logic to treat blank strings as unauthenticated by using a blank check
(e.g., currentUserId != null && !currentUserId.isBlank()) before using it;
replace the ternary that sets uploaderId for SpotFile.builder() and the similar
authorId logic in the SpotNote/other creation block (the branch around lines
629-633) to use this non-blank check and fall back to FALLBACK_USER_ID when
currentUserId is null or blank.
---
Outside diff comments:
In `@capstone-api/src/main/java/backend/feed/controller/FeedController.java`:
- Around line 53-60: The applyToFeed handler in FeedController currently returns
a 200 OK wrapped by ApiResponse; change it to return HTTP 201 Created: update
the method to return ResponseEntity<ApiResponse<FeedApplicationResponse>> and
return
ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(response))
after calling feedItemService.applyToFeed(feedId, "dummy-user-id", "황호찬",
request). Ensure you import org.springframework.http.ResponseEntity and
org.springframework.http.HttpStatus and keep the existing
ApiResponse/FeedApplicationResponse usage.
---
Nitpick comments:
In `@capstone-api/src/main/java/backend/feed/dto/FeedApplyRequest.java`:
- Around line 18-22: FeedApplyRequest currently exposes new fields role and
deposit without validation; add bean validation annotations to ensure valid
payloads: annotate role (in class FeedApplyRequest) with `@NotBlank` and restrict
allowed values with `@Pattern`(regexp = "SUPPORTER|PARTNER") (or create/use an
enum validator if preferred), and annotate deposit with `@NotNull` and `@Min`(0) (or
`@PositiveOrZero`) to prevent negative or missing deposits; remember to import
javax.validation.constraints.* and ensure controller methods are annotated with
`@Valid` so these constraints are enforced.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3785ed21-b479-4850-bf08-9ac2c1598253
📒 Files selected for processing (16)
capstone-api/src/main/java/backend/auth/controller/AuthController.javacapstone-api/src/main/java/backend/auth/controller/JwtController.javacapstone-api/src/main/java/backend/feed/controller/FeedController.javacapstone-api/src/main/java/backend/feed/dto/FeedApplicationResponse.javacapstone-api/src/main/java/backend/feed/dto/FeedApplyRequest.javacapstone-api/src/main/java/backend/notification/controller/NotificationController.javacapstone-api/src/main/java/backend/post/controller/PostController.javacapstone-api/src/main/java/backend/spot/controller/SpotController.javacapstone-api/src/main/java/backend/spot/dto/SpotChecklistResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotFileResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotNoteResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotParticipantResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotVoteOptionResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotVoteResponse.javacapstone-api/src/main/java/backend/spot/service/SpotService.javacapstone-api/src/main/java/backend/user/controller/UserController.java
hoTan35
left a comment
There was a problem hiding this comment.
SPOT 백엔드 프로젝트 PR #32 (refactor/frontend-md-compliance)에 대한 리뷰 결과입니다.
docs/FRONTEND.md 명세(v1.5, v1.6)를 기준으로 코드를 대조한 결과, 다수의 명세 불일치 및 구현 누락이 발견되었습니다.
🔍 PR 리뷰 결과 리포트
1. FRONTEND.md 섹션 1.5, 1.6 명세 불일치 (DTO)
-
ID 타입 불일치 (String vs Long)
- 파일:
capstone-api/src/main/java/backend/spot/dto/내SpotVoteResponse.java,SpotVoteOptionResponse.java,SpotChecklistResponse.java,SpotFileResponse.java,SpotNoteResponse.java - 설명:
FRONTEND.md에서는 모든 ID를string으로 정의하고 있으나, 위 DTO들에서는Long타입을 사용하고 있습니다. 프론트엔드 라이브러리(ex. Zod, TypeScript Interface)와의 호환성을 위해 타입을 맞추거나 백엔드에서 String으로 변환하여 응답해야 합니다.
- 파일:
-
Spot Collaboration (1.5) 필드 누락 및 오류
- 파일:
capstone-api/src/main/java/backend/spot/dto/SpotChecklistResponse.javaassigneeId,assigneeNickname필드가 누락되었습니다.
- 파일:
capstone-api/src/main/java/backend/spot/dto/SpotFileResponse.java(L44, L56)sizeBytes필드가null로 하드코딩되어 있습니다. 명세상 필수 값이므로 실제 파일 크기를 반영해야 합니다.
- 파일:
-
Feed (1.6) 필드 누락 및 명명 규칙 위반
- 파일:
capstone-api/src/main/java/backend/feed/dto/FeedAuthorProfile.java(L29)@JsonProperty("avatar_url")사용으로 인해 JSON 응답이avatar_url(snake_case)로 나갑니다. 명세는avatarUrl(camelCase)입니다.
- 파일:
capstone-api/src/main/java/backend/feed/dto/FeedItemResponse.javaisRentable,myApplicationRole,myApplicationDeposit필드가 누락되었습니다.
- 파일:
capstone-api/src/main/java/backend/feed/dto/FeedApplicationResponse.java(L30-36)appliedRole,deposit필드는 선언되어 있으나,from()팩토리 메서드에서 빌더에 포함되지 않아 항상null또는 기본값으로 응답됩니다.
- 파일:
2. 응답 Envelope 규격 불일치
- 파일:
capstone-api/src/main/java/backend/feed/controller/FeedController.java(L74)cancelApplication메서드가ApiResponse.success()를 반환하여data: null이 응답됩니다.- FRONTEND.md 명세:
{ data: { feedId, status: "CANCELLED" } }형태의 응답을 기대하고 있습니다.
3. 엔티티-DTO 간 불일치 및 마이그레이션 누락
- 파일:
capstone-domain/src/main/java/backend/feed/entity/FeedApplication.java- DTO(
FeedApplicationResponse)에는appliedRole,deposit이 추가되었으나, 엔티티에는 해당 필드가 없고 DB 마이그레이션 파일도 존재하지 않습니다. - 의견: 현재 DTO에서만 필드를 추가하고 매핑을 누락한 상태라 API가 불완전합니다. 후속 작업으로 분리하기보다는, **프론트엔드 명세 준수(Compliance)**가 목적인 PR인 만큼 엔티티 수정 및 마이그레이션을 이번 PR에 포함시키는 것이 아키텍처 일관성 측면에서 바람직합니다.
- DTO(
4. 스타일 및 Import 순서 위반
- Import 순서:
static→java→javax→org→com→backend순서를 준수해야 하나,FeedController.java,SpotVoteResponse.java등에서backend.*패키지가io.swagger.*나lombok.*보다 앞에 위치하고 있습니다. - Checkstyle: 실행 결과 약 6,700건의 경고(대부분 CRLF vs LF Newline 문제)가 발생합니다. 프로젝트 표준인 LF로 파일 엔딩을 일괄 조정할 필요가 있습니다.
5. SpotVoteOptionResponse.from() 위험성 확인
- 확인 결과:
SpotVoteOptionResponse.from()은 현재 프로젝트 내에서 직접 호출되고 있지 않습니다. 다만,SpotService.java(L314)에서 유사하게voterIds를List.of()로 초기화하여 반환하는 로직이 있습니다. 이는 투표 생성 직후의 응답이므로 현재로서는 정상 동작으로 판단되나, 추후from()메서드를 무분별하게 사용할 경우 기존 투표 데이터를 조회할 때 투표자 목록이 누락될 위험이 있으므로 주의가 필요합니다.
💬 종합 의견
Request Changes (❌ 수정 필요)
프론트엔드 명세 준수를 위한 리팩토링 PR임에도 불구하고, (1) 주요 필드 누락, (2) snake_case 혼용, (3) 응답 Envelope 불일치 등 명세와 상충하는 지점이 많습니다. 특히 appliedRole과 deposit은 도메인 모델까지 영향이 가는 변경사항이므로, 이를 완전히 구현하거나 혹은 명세에서 제외하는 방향으로 동기화가 필요합니다. 위 이슈들을 수정한 후 다시 리뷰 요청 부탁드립니다.
ca5tlechan 리뷰 (HIGH 보안):
- SecurityConfig permitAll/oauth/logoutUrl 경로 /api/v1 prefix로 통일
- LoginFilter LOGIN_PATH /api/auth/login → /api/v1/auth/login
CodeRabbit 리뷰:
- FeedController.applyToFeed @ResponseStatus(CREATED) 추가
- FeedController.cancelApplication 응답 envelope {feedId, status:CANCELLED}
- Feed bookmark / Notification read-all / Spot map·search 모두 501 NOT_IMPLEMENTED
- SpotVoteResponse.of() 오버로드들이 vote.getSpotId() 전달
- SpotService.resolveUserId() 도입: null + blank string 모두 fallback 처리
hoTan35 리뷰:
- FeedApplication 엔티티에 appliedRole(enum) + deposit(Integer) 컬럼 추가
- FeedApplicationRole enum 신설 (SUPPORTER, PARTNER)
- FeedApplyRequest.role 타입 String → FeedApplicationRole
- FeedApplicationResponse.from() 빌더에 appliedRole, deposit 매핑 누락 수정
- FeedAuthorProfile @JsonProperty("avatar_url") 제거 (camelCase 통일)
- FeedItemResponse 누락 필드 추가: myApplicationRole, myApplicationDeposit, isRentable
후속 작업으로 분리:
- ID Long → String 전환 (전체 도메인 영향, 별도 PR)
- SpotFile.sizeBytes, SpotChecklist.assignee* 엔티티 컬럼 + DB 마이그레이션
- markAllAsRead 실제 구현
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
capstone-api/src/main/java/backend/feed/controller/FeedController.java (1)
56-64:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRemove hardcoded caller identity from application flows.
Using
"dummy-user-id"/fixed nickname makes all users share one identity, which breaks per-user application and cancellation behavior.Proposed fix
+import org.springframework.security.core.annotation.AuthenticationPrincipal; +import backend.global.security.CustomUserDetails; ... public ApiResponse<FeedApplicationResponse> applyToFeed( `@PathVariable` String feedId, - `@RequestBody` FeedApplyRequest request) { - // 추후 인증 도입 시 실제 userId, nickname으로 교체 + `@RequestBody` FeedApplyRequest request, + `@AuthenticationPrincipal` CustomUserDetails userDetails) { FeedApplicationResponse response = feedItemService.applyToFeed( - feedId, "dummy-user-id", "황호찬", request); + feedId, userDetails.getUserId(), userDetails.getNickname(), request); return ApiResponse.success(response); } ... public ApiResponse<Map<String, String>> cancelApplication(`@PathVariable` String feedId) { - feedItemService.cancelApplication(feedId, "dummy-user-id"); +public ApiResponse<Map<String, String>> cancelApplication( + `@PathVariable` String feedId, + `@AuthenticationPrincipal` CustomUserDetails userDetails) { + feedItemService.cancelApplication(feedId, userDetails.getUserId()); return ApiResponse.success(Map.of( "feedId", feedId, "status", "CANCELLED" )); }Also applies to: 68-74
🤖 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 `@capstone-api/src/main/java/backend/feed/controller/FeedController.java` around lines 56 - 64, The controller currently hardcodes the caller identity ("dummy-user-id" and "황호찬") in FeedController.applyToFeed when calling feedItemService.applyToFeed (and similarly in the cancellation endpoint), which breaks per-user behavior; replace the hardcoded values by retrieving the authenticated user's id and nickname (e.g., from the security Principal/Authentication or a request header) and pass those values into feedItemService.applyToFeed and the cancel method (match the parameter order expected by feedItemService), or add a small adapter method to extract userId/nickname and forward them to feedItemService so each request uses the real caller identity.
🤖 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 `@capstone-api/src/main/java/backend/feed/dto/FeedItemResponse.java`:
- Around line 74-82: The DTO fields myApplicationRole, myApplicationDeposit, and
isRentable are declared but not populated in the static from(...) builder;
update FeedItemResponse.from(...) to set these three fields from the source
Feed/FeedApplication/availability data (use the same source objects used for
other fields), e.g. determine the current user's FeedApplication role and
deposit and compute rental availability, then call
builder.myApplicationRole(...), builder.myApplicationDeposit(...), and
builder.isRentable(...) before build(); reference FeedItemResponse.from, the
builder on FeedItemResponse, and the field names
myApplicationRole/myApplicationDeposit/isRentable when making the change.
---
Outside diff comments:
In `@capstone-api/src/main/java/backend/feed/controller/FeedController.java`:
- Around line 56-64: The controller currently hardcodes the caller identity
("dummy-user-id" and "황호찬") in FeedController.applyToFeed when calling
feedItemService.applyToFeed (and similarly in the cancellation endpoint), which
breaks per-user behavior; replace the hardcoded values by retrieving the
authenticated user's id and nickname (e.g., from the security
Principal/Authentication or a request header) and pass those values into
feedItemService.applyToFeed and the cancel method (match the parameter order
expected by feedItemService), or add a small adapter method to extract
userId/nickname and forward them to feedItemService so each request uses the
real caller identity.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3fb780c9-6a40-43f2-aa09-49da69a243e3
📒 Files selected for processing (14)
capstone-api/src/main/java/backend/feed/controller/FeedController.javacapstone-api/src/main/java/backend/feed/dto/FeedApplicationResponse.javacapstone-api/src/main/java/backend/feed/dto/FeedApplyRequest.javacapstone-api/src/main/java/backend/feed/dto/FeedAuthorProfile.javacapstone-api/src/main/java/backend/feed/dto/FeedItemResponse.javacapstone-api/src/main/java/backend/feed/service/FeedItemService.javacapstone-api/src/main/java/backend/global/filter/LoginFilter.javacapstone-api/src/main/java/backend/notification/controller/NotificationController.javacapstone-api/src/main/java/backend/spot/controller/SpotController.javacapstone-api/src/main/java/backend/spot/dto/SpotVoteResponse.javacapstone-api/src/main/java/backend/spot/service/SpotService.javacapstone-common/src/main/java/backend/global/config/SecurityConfig.javacapstone-domain/src/main/java/backend/feed/entity/FeedApplication.javacapstone-domain/src/main/java/backend/feed/entity/FeedApplicationRole.java
💤 Files with no reviewable changes (1)
- capstone-api/src/main/java/backend/feed/dto/FeedAuthorProfile.java
✅ Files skipped from review due to trivial changes (1)
- capstone-api/src/main/java/backend/global/filter/LoginFilter.java
🚧 Files skipped from review as they are similar to previous changes (3)
- capstone-api/src/main/java/backend/feed/dto/FeedApplyRequest.java
- capstone-api/src/main/java/backend/notification/controller/NotificationController.java
- capstone-api/src/main/java/backend/spot/service/SpotService.java
| @Schema(description = "내 신청 역할 (SUPPORTER | PARTNER)") | ||
| private FeedApplicationRole myApplicationRole; | ||
|
|
||
| @Schema(description = "내 신청 보증금") | ||
| private Integer myApplicationDeposit; | ||
|
|
||
| @Schema(description = "대여 가능 여부", example = "false") | ||
| private Boolean isRentable; | ||
|
|
There was a problem hiding this comment.
Populate newly added response fields in from(...).
myApplicationRole, myApplicationDeposit, and isRentable are declared but never set in the builder, so clients always get null for them.
Proposed fix
public static FeedItemResponse from(FeedItem feedItem, Long applicantCount, Boolean isBookmarked,
- FeedApplicationStatus myApplicationStatus, FeedAuthorProfile authorProfile) {
+ FeedApplicationStatus myApplicationStatus, FeedApplicationRole myApplicationRole,
+ Integer myApplicationDeposit, Boolean isRentable, FeedAuthorProfile authorProfile) {
return FeedItemResponse.builder()
...
.myApplicationStatus(myApplicationStatus)
+ .myApplicationRole(myApplicationRole)
+ .myApplicationDeposit(myApplicationDeposit)
+ .isRentable(isRentable)
.authorProfile(authorProfile)
...
.build();
}Also applies to: 102-127
🤖 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 `@capstone-api/src/main/java/backend/feed/dto/FeedItemResponse.java` around
lines 74 - 82, The DTO fields myApplicationRole, myApplicationDeposit, and
isRentable are declared but not populated in the static from(...) builder;
update FeedItemResponse.from(...) to set these three fields from the source
Feed/FeedApplication/availability data (use the same source objects used for
other fields), e.g. determine the current user's FeedApplication role and
deposit and compute rental availability, then call
builder.myApplicationRole(...), builder.myApplicationDeposit(...), and
builder.isRentable(...) before build(); reference FeedItemResponse.from, the
builder on FeedItemResponse, and the field names
myApplicationRole/myApplicationDeposit/isRentable when making the change.
|
@hoTan35 @ca5tlechan 코멘트 반영해서 19be0ef 푸시했습니다. 재리뷰 부탁드립니다. |
hoTan35
left a comment
There was a problem hiding this comment.
리뷰 요약
전체적으로 DTO 필드 추가 등 일부 진척은 있으나, 체크리스트의 핵심 불일치들이 아직 남아 있습니다. 아래 인라인 코멘트와 함께 확인 부탁드립니다.
미반영 항목 요약
| 항목 | 상태 |
|---|---|
| DTO 구조 불일치 (SpotSchedule, Checklist, IncludedItem, AddOn, FeedItem) | ❌ 미수정 |
cancelApplication 응답 envelope |
❌ 미수정 |
| FeedApplication 엔티티 마이그레이션 | |
| import 순서 checkstyle | |
SpotVoteOptionResponse.from() dead code |
✅ 런타임 위험 없음, 정리 권고 |
| @@ -61,10 +65,27 @@ public ApiResponse<FeedApplicationResponse> applyToFeed( | |||
| } | |||
|
|
|||
| @Operation(summary = "피드 신청 취소") | |||
There was a problem hiding this comment.
[Issue] cancelApplication 응답 envelope 불일치
FRONTEND.md 명세:
responses:
200:
application/json:
data:
feedId: string
status: CANCELLED현재 ApiResponse.success()는 body 없이 반환되어 프론트가 data.feedId를 읽을 수 없습니다.
수정 예시:
Map<String, Object> body = Map.of("feedId", feedId, "status", "CANCELLED");
return ApiResponse.success(body);| @@ -32,6 +35,8 @@ public static FeedApplicationResponse from(FeedApplication application) { | |||
| .userId(application.getUserId()) | |||
| .proposal(application.getProposal()) | |||
| .status(application.getStatus()) | |||
There was a problem hiding this comment.
[Issue] FeedApplicationResponse.from() — appliedRole, deposit 항상 null
FEENTEND.md 명세:
type FeedApplication = {
appliedRole: FeedApplicationRole; // required
deposit: number; // required
...
};from() 팩토리에서 두 필드를 설정하지 않아 항상 null 응답이 나갑니다. 근본 원인은 FeedApplication 엔티티에 appliedRole, deposit 컬럼 자체가 없기 때문입니다.
후속 작업으로 분리해도 되지만, 현재 상태에서는 명세상 required 필드가 null로 내려가므로 프론트 파싱이 깨질 수 있습니다. 엔티티 컬럼 추가 + 마이그레이션 스크립트를 별도 이슈/PR로 트래킹 해주세요.
- IncludedItem: note → value (FRONTEND.md PriceBreakdown.included_items) - AddOn: note → explanation (FRONTEND.md PriceBreakdown.optional_addons) - SpotChecklistResponse: assigneeId, assigneeNickname (nullable) 추가 - SpotVoteOptionResponse: dead code from() 제거 (호출처 없음) - SpotService, SpotController: import 순서 정리 미반영 (별도 PR로 분리): - SpotSchedule 구조 (proposedSlots / confirmedSlot / ScheduleSlot): 도메인 엔티티 scheduledAt → ScheduleSlot 전환 필요, DB 마이그레이션 동반 큰 변경 - FeedController dummy-user-id 제거: 전체 코드베이스 공통 패턴(SpotController, ChatController 동일), 인증 통합 PR에서 일괄 처리 권장 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@hoTan35 2차 리뷰 감사합니다. 항목별로 답변드립니다. 이미 반영된 항목 (19be0ef 커밋 — 재확인 부탁)
위 두 항목은 인라인 코멘트 위치(라인 67, 37)에서 실제 코드를 다시 확인 부탁드립니다. 이번 커밋(d8e5a94)에서 추가 반영
별도 PR로 분리 제안
위 분리 항목은 머지 후 follow-up 이슈로 등록하겠습니다. 추가 확인 부탁드립니다. |
2차 리뷰 — 1차 반영분 확인 + 잔여 이슈✅ 1차 리뷰 반영 확인
🔴 HIGH — 신규 발견[1]
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
capstone-api/src/main/java/backend/spot/dto/SpotVoteOptionResponse.java (1)
32-37: ⚡ Quick winNormalize
voterIdsto an empty list in the DTO factory.If
voterIdsis null at Line 37, the API can emitnullinstead of[]. Normalizing here makes the response contract safer for consumers.Proposed fix
public static SpotVoteOptionResponse of(SpotVoteOption option, List<String> voterIds) { return SpotVoteOptionResponse.builder() .id(option.getId()) .label(option.getContent()) .voteCount(option.getVoteCount()) - .voterIds(voterIds) + .voterIds(voterIds == null ? List.of() : List.copyOf(voterIds)) .build(); }🤖 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 `@capstone-api/src/main/java/backend/spot/dto/SpotVoteOptionResponse.java` around lines 32 - 37, The factory method SpotVoteOptionResponse.of currently passes voterIds through to the builder which can allow a null to be emitted; change the method to normalize voterIds to an empty List when null (e.g., replace voterIds with Collections.emptyList() or new ArrayList<>() before calling SpotVoteOptionResponse.builder().voterIds(...)) so the DTO always returns [] instead of null; update the of(...) implementation where id/label/voteCount are set and voterIds is supplied.
🤖 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 `@capstone-api/src/main/java/backend/spot/dto/SpotChecklistResponse.java`:
- Around line 29-33: The SpotChecklistResponse factory method
from(SpotChecklist) currently never sets the newly added fields assigneeId and
assigneeNickname, so populate these two fields when building the response: in
SpotChecklistResponse.from(SpotChecklist) extract the assignee ID and nickname
from the input SpotChecklist (e.g., spot.getAssigneeId() and
spot.getAssigneeNickname() or the appropriate getters) and set them on the
response builder/constructor alongside the other mapped fields; ensure both
assigneeId and assigneeNickname are assigned where other properties are mapped
so responses no longer return null for these fields.
---
Nitpick comments:
In `@capstone-api/src/main/java/backend/spot/dto/SpotVoteOptionResponse.java`:
- Around line 32-37: The factory method SpotVoteOptionResponse.of currently
passes voterIds through to the builder which can allow a null to be emitted;
change the method to normalize voterIds to an empty List when null (e.g.,
replace voterIds with Collections.emptyList() or new ArrayList<>() before
calling SpotVoteOptionResponse.builder().voterIds(...)) so the DTO always
returns [] instead of null; update the of(...) implementation where
id/label/voteCount are set and voterIds is supplied.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: b1a22b12-194f-4070-be44-a45a342f6401
📒 Files selected for processing (6)
capstone-api/src/main/java/backend/feed/dto/AddOn.javacapstone-api/src/main/java/backend/feed/dto/IncludedItem.javacapstone-api/src/main/java/backend/spot/controller/SpotController.javacapstone-api/src/main/java/backend/spot/dto/SpotChecklistResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotVoteOptionResponse.javacapstone-api/src/main/java/backend/spot/service/SpotService.java
🚧 Files skipped from review as they are similar to previous changes (2)
- capstone-api/src/main/java/backend/spot/controller/SpotController.java
- capstone-api/src/main/java/backend/spot/service/SpotService.java
| @Schema(description = "담당자 ID (선택)", nullable = true) | ||
| private String assigneeId; | ||
|
|
||
| @Schema(description = "담당자 닉네임 (선택)", nullable = true) | ||
| private String assigneeNickname; |
There was a problem hiding this comment.
Map newly added assignee fields in the factory path.
Line 29-Line 33 add assigneeId/assigneeNickname, but Line 38-Line 44 never sets them. Responses built via from(SpotChecklist) will always return these as null.
Proposed fix
public static SpotChecklistResponse from(SpotChecklist checklist) {
+ return from(checklist, null, null);
+}
+
+public static SpotChecklistResponse from(SpotChecklist checklist, String assigneeId, String assigneeNickname) {
return SpotChecklistResponse.builder()
.id(checklist.getId())
.text(checklist.getContent())
.completed(checklist.getIsDone())
+ .assigneeId(assigneeId)
+ .assigneeNickname(assigneeNickname)
.createdAt(checklist.getCreatedAt())
.build();
}Also applies to: 38-44
🤖 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 `@capstone-api/src/main/java/backend/spot/dto/SpotChecklistResponse.java`
around lines 29 - 33, The SpotChecklistResponse factory method
from(SpotChecklist) currently never sets the newly added fields assigneeId and
assigneeNickname, so populate these two fields when building the response: in
SpotChecklistResponse.from(SpotChecklist) extract the assignee ID and nickname
from the input SpotChecklist (e.g., spot.getAssigneeId() and
spot.getAssigneeNickname() or the appropriate getters) and set them on the
response builder/constructor alongside the other mapped fields; ensure both
assigneeId and assigneeNickname are assigned where other properties are mapped
so responses no longer return null for these fields.
ca5tlechan HIGH [1]: - SimulationController @RequestMapping /api/sim/runs → /api/v1/sim/runs (SecurityConfig permitAll 경로 변경으로 인한 401 회귀 차단) CodeRabbit: - SpotVoteOptionResponse.of() voterIds null-safe (null → List.of()) - SpotChecklistResponse.from() assigneeId/assigneeNickname 명시 null 매핑 ca5tlechan LOW [3]: - FeedItemResponse.from() 신규 3필드(myApplicationRole, myApplicationDeposit, isRentable) 명시 null 매핑으로 JSON 키 직렬화 보장 미반영 (의도적): - ca5tlechan [2] FeedAuthorProfile avatar_url → avatarUrl 변경: FRONTEND.md 1.1 SupporterProfile/PartnerProfile 모두 avatarUrl(camelCase) 명세이므로 의도적 변경. 프론트 동기화 필요 시 알려달라고 답글 예정. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@ca5tlechan 2차 리뷰 감사합니다. 3ce48c4 커밋에 반영했습니다. 반영 (3ce48c4)
CodeRabbit 동시 반영
🟡 [2] FeedAuthorProfile avatarUrl — 의도적 변경FRONTEND.md 1.1 SupporterProfile/PartnerProfile 모두 type SupporterProfile = {
avatarUrl?: string; // camelCase
...
};그리고 0번 공통 규칙도 camelCase가 기본이라 @coderabbitai review |
|
🐇 ✅ Actions performedReview triggered.
|
|
@ThonApple 답변 감사합니다. 확인 중 두 가지 미해결 항목을 발견했습니다. 1. FeedApplication DB 마이그레이션 파일 누락 2. |
[1] FeedApplication DB 마이그레이션 추가 - docs/migrations/2026-05-19_feed_application_role_deposit.sql - applied_role VARCHAR(20) + deposit INTEGER 컬럼 추가 - 기존 row는 NULL 유지, 신규 신청부터 채워짐 [2] SpotFile.sizeBytes 엔티티/DTO/마이그레이션 완성 - SpotFile 엔티티에 size_bytes BIGINT NULL 컬럼 추가 - UploadFileRequest.sizeBytes 필드 추가 (nullable) - SpotService.uploadFile() request 값 전달 - SpotFileResponse.from()/of() file.getSizeBytes() 매핑 (기존 null 하드코딩 제거) - docs/migrations/2026-05-19_spot_file_size_bytes.sql Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@hoTan35 두 항목 모두 ff17bfe 커밋에 반영했습니다. [1] FeedApplication 마이그레이션 ✅
[2] SpotFile.sizeBytes ✅이번 PR에서 전체 처리:
재확인 부탁드립니다. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
capstone-api/src/main/java/backend/spot/dto/UploadFileRequest.java (1)
21-22: ⚡ Quick winConsider adding validation for non-negative file size.
The
sizeBytesfield accepts anyLongvalue, including negatives. File sizes should be non-negative.✅ Proposed validation constraint
+import jakarta.validation.constraints.PositiveOrZero; + `@Schema`(description = "파일 크기 (bytes)", example = "204800", nullable = true) +@PositiveOrZero private Long sizeBytes;🤖 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 `@capstone-api/src/main/java/backend/spot/dto/UploadFileRequest.java` around lines 21 - 22, The sizeBytes field in UploadFileRequest currently accepts negative values; add a non-negative validation (e.g., annotate the sizeBytes property in class UploadFileRequest with a bean validation constraint such as `@PositiveOrZero` or `@Min`(0)) and import the corresponding javax.validation or jakarta.validation annotation so requests with negative file sizes are rejected by validation.capstone-api/src/main/java/backend/spot/dto/SpotFileResponse.java (1)
41-63: 💤 Low valueRemove the unused
from()factory method or deprecate it with clear JavaDoc guidance.The
from()method is not used anywhere in the codebase—all call sites useof()and provide a properuploaderNickname. Thefrom()method returningnullforuploaderNicknameis dead code that could mislead future developers into using it and creating incomplete responses.Either remove
from()entirely or mark it@Deprecatedwith JavaDoc explaining when (if ever) it should be used.🤖 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 `@capstone-api/src/main/java/backend/spot/dto/SpotFileResponse.java` around lines 41 - 63, Remove the unused factory method SpotFileResponse.from(SpotFile) or mark it deprecated: locate the SpotFileResponse.from(SpotFile) method and either delete it entirely (since all call sites use of(SpotFile,String)) or annotate it with `@Deprecated` and add JavaDoc explaining it returns a response with a null uploaderNickname and should not be used; ensure SpotFileResponse.of(SpotFile,String) remains the canonical factory and update JavaDoc/comments to point callers to of(...) if you keep a deprecated shim.
🤖 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 `@capstone-api/src/main/java/backend/spot/dto/SpotFileResponse.java`:
- Around line 41-63: Remove the unused factory method
SpotFileResponse.from(SpotFile) or mark it deprecated: locate the
SpotFileResponse.from(SpotFile) method and either delete it entirely (since all
call sites use of(SpotFile,String)) or annotate it with `@Deprecated` and add
JavaDoc explaining it returns a response with a null uploaderNickname and should
not be used; ensure SpotFileResponse.of(SpotFile,String) remains the canonical
factory and update JavaDoc/comments to point callers to of(...) if you keep a
deprecated shim.
In `@capstone-api/src/main/java/backend/spot/dto/UploadFileRequest.java`:
- Around line 21-22: The sizeBytes field in UploadFileRequest currently accepts
negative values; add a non-negative validation (e.g., annotate the sizeBytes
property in class UploadFileRequest with a bean validation constraint such as
`@PositiveOrZero` or `@Min`(0)) and import the corresponding javax.validation or
jakarta.validation annotation so requests with negative file sizes are rejected
by validation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bd2db293-0ef1-406e-9d43-13a0bb1c4d02
📒 Files selected for processing (10)
capstone-api/src/main/java/backend/feed/dto/FeedItemResponse.javacapstone-api/src/main/java/backend/simulation/controller/SimulationController.javacapstone-api/src/main/java/backend/spot/dto/SpotChecklistResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotFileResponse.javacapstone-api/src/main/java/backend/spot/dto/SpotVoteOptionResponse.javacapstone-api/src/main/java/backend/spot/dto/UploadFileRequest.javacapstone-api/src/main/java/backend/spot/service/SpotService.javacapstone-domain/src/main/java/backend/spot/entity/SpotFile.javadocs/migrations/2026-05-19_feed_application_role_deposit.sqldocs/migrations/2026-05-19_spot_file_size_bytes.sql
✅ Files skipped from review due to trivial changes (2)
- docs/migrations/2026-05-19_spot_file_size_bytes.sql
- docs/migrations/2026-05-19_feed_application_role_deposit.sql
🚧 Files skipped from review as they are similar to previous changes (3)
- capstone-api/src/main/java/backend/spot/dto/SpotChecklistResponse.java
- capstone-api/src/main/java/backend/spot/dto/SpotVoteOptionResponse.java
- capstone-api/src/main/java/backend/spot/service/SpotService.java
…tiveOrZero 추가 - SpotFileResponse.from(SpotFile) dead code 제거 (호출처 없음, of() 단일화) - UploadFileRequest.sizeBytes @PositiveOrZero 검증 추가 (음수 거부) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ca5tlechan
left a comment
There was a problem hiding this comment.
최종 리뷰 — Approve
3차 커밋(3ce48c4·ff17bfe·8f4b3a17)까지 확인했습니다.
반영 확인
| 항목 | 커밋 |
|---|---|
| SecurityConfig / LoginFilter / logoutUrl 경로 통일 | 19be0ef |
| SimulationController 정렬 | 3ce48c4 |
| FeedItemService appliedRole·deposit 빌더 추가 | d8e5a94 |
| FeedApplication 엔티티 + 마이그레이션 SQL | ff17bfe |
| SpotFile.sizeBytes 엔티티·서비스·마이그레이션 | ff17bfe |
| SpotFileResponse.from() dead code 제거 | 8f4b3a1 |
| FeedItemResponse / SpotChecklistResponse 미구현 필드 명시 null + TODO 주석 | 3ce48c4 |
| FeedAuthorProfile avatarUrl camelCase — FRONTEND.md 명세 기준 의도적 변경 확인 | — |
잔여 dummy-user-id placeholder는 인증 도입 전 임시값으로 이번 PR 스코프 외임을 확인했습니다.
머지해도 됩니다.
ca5tlechan
left a comment
There was a problem hiding this comment.
최종 리뷰 — Approve
3차 커밋(3ce48c4·ff17bfe·8f4b3a17)까지 확인했습니다.
반영 확인
| 항목 | 커밋 |
|---|---|
| SecurityConfig / LoginFilter / logoutUrl 경로 통일 | 19be0ef |
| SimulationController /api/v1/sim/runs 정렬 | 3ce48c4 |
| FeedItemService appliedRole·deposit 빌더 추가 | d8e5a94 |
| FeedApplication 엔티티 + 마이그레이션 SQL | ff17bfe |
| SpotFile.sizeBytes 엔티티·서비스·마이그레이션 | ff17bfe |
| SpotFileResponse.from() dead code 제거 | 8f4b3a1 |
| FeedItemResponse / SpotChecklistResponse 미구현 필드 명시 null + TODO 주석 | 3ce48c4 |
| FeedAuthorProfile avatarUrl camelCase — FRONTEND.md 명세 기준 의도적 변경 확인 | — |
잔여 dummy-user-id placeholder는 인증 도입 전 임시값으로 이번 PR 스코프 외임을 확인했습니다.
머지해도 됩니다.
|
@ThonApple 최종 확인 결과 import 순서 위반이 4개 파일에 남아 있습니다. 수정 부탁드립니다. 규칙 (CAPSTONE.md):
올바른 순서 예시: import java.*
import org.springframework.*
import io.swagger.*
import jakarta.*
import lombok.*
import backend.*이 항목만 수정되면 나머지는 모두 확인됐습니다. 반영 후 머지해도 됩니다 ✅ |
FeedController, FeedApplicationResponse, SpotVoteResponse, SpotController 4개 파일에서 backend.* 그룹을 io.swagger / jakarta / lombok 뒤로 이동.⚠️ 알려진 트레이드오프: config/checkstyle/checkstyle.xml의 ImportOrder는 Naver Hackday 표준이라 backend.*, io.swagger.*, jakarta.*, lombok.* 모두 catch-all 그룹 6에 매칭되며 ordered=true로 알파벳 정렬을 강제한다 (b < i < j < l → backend 최상단). 이번 커밋은 CAPSTONE.md 텍스트("static→java→javax→org→com→backend")를 우선해 reorder 했으나 그 결과 checkstyle warning 8건이 새로 발생한다 (BUILD는 통과, ERROR 아닌 WARN). 향후 CAPSTONE.md와 checkstyle.xml 중 어느 쪽을 정답으로 통일할지 팀 논의 필요. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@hoTan35 4개 파일 import 순서 수정해서 ef93dba 푸시했습니다.
|
This reverts commit ef93dba.
이전 문구("static→java→javax→org→com→backend")는 단순화된 표현이라
config/checkstyle/checkstyle.xml 의 ImportOrder 룰(Naver Hackday 표준,
ordered=true + catch-all regex)과 충돌했음.
실제 enforcement 기준:
- backend.*, io.*, jakarta.*, lombok.* 모두 catch-all 그룹(group 6)에 속해
알파벳 순으로 정렬됨 (b < i < j < l → backend 최상단)
기존 코드베이스(ChatService, OAuth2UserServiceImpl 등)는 이미 이 규칙을
따르고 있으며, 직전 ef93dba 의 reorder 는 checkstyle warning 8건을 신규
유발했기에 함께 revert 됨 (b1fd2a2).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@hoTan35 import 순서 항목에 대한 추가 조사 결과 보고드립니다. 결론: CAPSTONE.md 문구를 정정하는 방향으로 처리 (옵션 B)직전 커밋(ef93dba) 으로 <property name="groups" value="java., javax., org., net., /com\\.(?!nhncorp|navercorp|naver)/, /(?!java\\.|javax\\.|com\\.|org\\.|net\\.)/, com.nhncorp., com.navercorp., com.naver."/>
<property name="ordered" value="true"/>여기서 group 6 catch-all 정규식이 즉 checkstyle 관점에서는 처리
이로써 PR #32 가 도입한 import warning 은 0건이며, checkstyle/PR 본문/문서가 모두 일관됩니다. 추가 확인 부탁드립니다. |
도메인 오너 기준 12개 follow-up 이슈 분담 및 우선순위·의존성 명시. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
도메인 오너 기준 12개 follow-up 이슈 분담 및 우선순위·의존성 명시. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
@RequestMappingbase URL을/api/v1로 통일 (Auth, Jwt, User, Feed, Post, Spot, Notification)UserController—/me/**vs/users/**경로 올바르게 분리FeedController—apply→applications경로 변경, bookmark POST/DELETE 스텁 추가NotificationController—PATCH→POST+/read-all스텁 추가SpotController—/map,/search스텁 추가SpotChecklistResponse:content→text,isDone→completedSpotVoteOptionResponse:content→label,voterIds: List<String>추가SpotVoteResponse:spotId필드 추가SpotFileResponse:uploaderNickname,spotId,sizeBytes추가, 필드명 통일SpotNoteResponse:authorNickname,spotId추가SpotParticipantResponse:nickname필드 추가FeedApplyRequest:role,deposit필드 추가FeedApplicationResponse:appliedRole,deposit필드 추가SpotService— 참여자/파일/노트/투표 응답에userRepository.findAllByIdIn()배치 닉네임 조회 + voterIds 집계 적용Test plan
./gradlew compileJava빌드 통과 확인 ✅GET /api/v1/spots/{id}/participants— nickname 포함 응답 확인GET /api/v1/spots/{id}/votes— voterIds, label 필드 확인GET /api/v1/spots/{id}/checklist— text, completed 필드 확인POST /api/v1/feeds/{id}/applications— 201 반환 확인DELETE /api/v1/feeds/{id}/applications/me— 200 반환 확인GET /api/v1/notifications—/api/v1prefix 정상 동작 확인🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
API Updates
Database