Refactor like feature and add member nickname field#15
Refactor like feature and add member nickname field#15kminseok-dev wants to merge 4 commits intomainfrom
Conversation
Walkthrough레포의 README 내용이 수정되었고, 멤버 엔티티/DTO에 닉네임 필드가 추가되었으며, 좋아요 기능이 Redis 캐싱을 활용하도록 서비스 레이어가 리팩토링되고 컨트롤러의 API 경로가 재구성되었습니다. 또한 HTTP 테스트 시나리오 파일이 신규 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant LikeController
participant LikeService
participant LikeRepository
participant Redis
Client->>LikeController: POST /api/boards/{boardId}/like (userId)
LikeController->>LikeService: toggleLike(boardId, userId)
alt not liked
LikeService->>LikeRepository: save LikeEntity(boardId, userId)
LikeRepository-->>LikeService: persisted
LikeService->>Redis: INCR like:count:{boardId}
Redis-->>LikeService: newCount
LikeService->>Redis: SETEX like:user:{boardId}:{userId} true (TTL)
Redis-->>LikeService: ok
LikeService-->>LikeController: true (liked)
else already liked
LikeService->>LikeRepository: delete By(boardId, userId)
LikeRepository-->>LikeService: deleted
LikeService->>Redis: DECR like:count:{boardId}
Redis-->>LikeService: newCount
LikeService->>Redis: DEL like:user:{boardId}:{userId}
Redis-->>LikeService: ok
LikeService-->>LikeController: false (unliked)
end
LikeController-->>Client: 200 {message, likeCount}
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
src/main/java/com/kms/springboard/member/entity/MemberEntity.java (1)
17-23:⚠️ Potential issue | 🟠 Major
@Index의columnList가 변경된 컬럼명과 불일치
@Column(name = "user_id")로 컬럼명이 변경되었지만@Index의columnList = "userId"는 이전 camelCase 이름을 그대로 참조합니다. JPA/Hibernate가 스키마 생성 또는 검증 시 존재하지 않는 컬럼명으로 인덱스를 생성하려 하여 오류가 발생할 수 있습니다.🐛 제안 수정
`@Table`( name="members", indexes = { - `@Index`(name = "uk_members_userId", columnList = "userId",unique = true), + `@Index`(name = "uk_members_user_id", columnList = "user_id", unique = true), `@Index`(name = "uk_members_email", columnList = "email", unique = true) } )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/member/entity/MemberEntity.java` around lines 17 - 23, The `@Index` columnList entries in MemberEntity reference the old camelCase property name ("userId") but the actual DB column is renamed via `@Column`(name = "user_id"); update the `@Index` annotations in the `@Table` on MemberEntity to use the physical column names (e.g., change "userId" to "user_id") and verify the "email" index matches the `@Column`(name=...) for the email field so JPA/Hibernate creates/validates indexes against the correct column names.src/main/java/com/kms/springboard/member/service/MemberServiceImpl.java (1)
36-43:⚠️ Potential issue | 🟡 Minor닉네임 중복 검사 누락
userId와existsBy*)를 수행하지만nickname은 생략되어 있습니다.MemberEntity의unique = trueDB 제약으로 인해 중복 시DataIntegrityViolationException이 발생하며, 사용자에게 비친화적인 500 에러가 반환됩니다.
MemberRepository에existsByNickname을 추가하고 서비스 레이어에서도 일관되게 검사하세요.🛡️ 제안 수정
+ if(memberRepository.existsByNickname(memberDto.getNickname())) { + throw new IllegalStateException("이미 존재하는 닉네임입니다"); + } String encoded = passwordEncoder.encode(memberDto.getPassword());🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/member/service/MemberServiceImpl.java` around lines 36 - 43, The service is missing a pre-save uniqueness check for nickname causing DB constraint violations; add an existsByNickname(String nickname) method to MemberRepository and call it from MemberServiceImpl (before building/saving the MemberEntity) to throw a controlled exception (e.g., DuplicateMemberException or IllegalArgumentException) when memberDto.getNickname() already exists, mirroring the existing existsByUserId/existsByEmail checks and preventing memberRepository.save(member) from triggering DataIntegrityViolationException for MemberEntity.nickname.src/main/java/com/kms/springboard/like/service/LikeServiceImpl.java (3)
78-104:⚠️ Potential issue | 🟠 Major트랜잭션 롤백 시 Redis 상태 불일치
addLike/removeLike는@Transactional컨텍스트 안에서 실행되지만, Redis 연산(incrementLikeCount,cacheUserLiked등)은 JPA 트랜잭션의 롤백 대상이 아닙니다. DB 저장이 롤백되더라도 Redis 카운트와 캐시된 상태는 그대로 남아 최대 24시간 동안 불일치 상태가 유지됩니다.DB 커밋 성공 이후에만 Redis 연산이 실행되도록
TransactionSynchronizationManager를 활용한afterCommit콜백 방식을 고려하세요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/like/service/LikeServiceImpl.java` around lines 78 - 104, The DB/Redis inconsistency occurs because addLike and removeLike call Redis helpers (incrementLikeCount, decrementLikeCount, cacheUserLiked) inside the transactional method so Redis updates aren't rolled back with the DB; change both addLike and removeLike to register a TransactionSynchronizationManager.afterCommit callback that performs the Redis operations (incrementLikeCount/decrementLikeCount and cacheUserLiked) only after the transaction successfully commits, i.e., replace the direct calls in addLike/removeLike with a TransactionSynchronizationManager.registerSynchronization(...) that invokes those specific methods (incrementLikeCount, decrementLikeCount, cacheUserLiked) on afterCommit and handle any exceptions there to avoid affecting DB commit flow.
106-121:⚠️ Potential issue | 🟠 Major캐시 키 미초기화 시
increment/decrement가 잘못된 카운트를 기록Redis에 해당 키가 존재하지 않을 때
increment()는 0에서 시작해 1로 설정합니다.getLikeCount()를 한 번도 호출하지 않아 캐시가 비어 있는 상태에서addLike가 실행되면, DB의 실제 좋아요 수(예: 50)와 무관하게 Redis에 1이 기록됩니다. 이후getLikeCount()는 캐시 히트로 인해 잘못된 값을 반환합니다.
increment/decrement전에 키 존재 여부를 확인하거나, 키가 없을 경우 DB에서 읽어 초기화하는 로직을 추가하세요.🐛 제안 수정
private void incrementLikeCount(Long boardId){ String cacheKey = LIKE_COUNT_PREFIX + boardId; - redisTemplate.opsForValue().increment(cacheKey); + Boolean keyExists = redisTemplate.hasKey(cacheKey); + if (Boolean.TRUE.equals(keyExists)) { + redisTemplate.opsForValue().increment(cacheKey); + } else { + long count = likeRepository.countByBoardId(boardId); + redisTemplate.opsForValue().set(cacheKey, String.valueOf(count), CACHE_TTL); + return; + } redisTemplate.expire(cacheKey,CACHE_TTL); } private void decrementLikeCount(Long boardId){ String cacheKey = LIKE_COUNT_PREFIX + boardId; - Long count = redisTemplate.opsForValue().decrement(cacheKey); - if(count != null && count < 0){ - redisTemplate.opsForValue().set(cacheKey, "0", CACHE_TTL); + Boolean keyExists = redisTemplate.hasKey(cacheKey); + if (Boolean.TRUE.equals(keyExists)) { + Long count = redisTemplate.opsForValue().decrement(cacheKey); + if(count != null && count < 0){ + redisTemplate.opsForValue().set(cacheKey, "0", CACHE_TTL); + } + redisTemplate.expire(cacheKey, CACHE_TTL); + } else { + long count = likeRepository.countByBoardId(boardId); + redisTemplate.opsForValue().set(cacheKey, String.valueOf(count), CACHE_TTL); } - log.debug("like count decremented in Redis: boardId={}", boardId); + log.debug("like count decremented in Redis: boardId={}", boardId); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/like/service/LikeServiceImpl.java` around lines 106 - 121, incrementLikeCount and decrementLikeCount can create incorrect counts when the Redis key is missing; modify both methods to first check whether the key (LIKE_COUNT_PREFIX + boardId) exists and if not, load the current like count from the database (e.g., via the repository method used by getLikeCount or a countLikesByBoardId) and set that value into Redis with CACHE_TTL, then perform the increment()/decrement() and reset the TTL; also ensure decrement handles negative results by clamping to 0 after decrement. Use the existing symbols incrementLikeCount, decrementLikeCount, LIKE_COUNT_PREFIX, CACHE_TTL, redisTemplate.opsForValue(), and the service/repository method that reads DB counts (the same one getLikeCount uses) to initialize the cache before mutating.
38-48:⚠️ Potential issue | 🟠 Major
USER_LIKED_PREFIX캐시가 쓰기만 하고 읽지 않음
cacheUserLiked()는 사용자별 좋아요 상태를 Redis에 기록하지만,toggleLike()의 존재 확인은 여전히likeRepository.existsByBoardIdAndUserId()(DB 쿼리)를 사용합니다. Redis 캐시가 전혀 활용되지 않아 캐싱 효과가 없고 불필요한 쓰기 연산만 발생합니다.Redis 캐시를 실제로 읽도록
toggleLike를 수정하거나, 사용되지 않는cacheUserLiked호출을 제거하세요.
🧹 Nitpick comments (4)
src/main/java/com/kms/springboard/like/controller/LikeController.java (1)
27-34: 변수명isliked→isLiked(Java 네이밍 컨벤션)✏️ 제안 수정
- boolean isliked = likeService.toggleLike(boardId, userId); - - String message; - if(isliked){ + boolean isLiked = likeService.toggleLike(boardId, userId); + + String message; + if(isLiked){🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/like/controller/LikeController.java` around lines 27 - 34, Rename the local boolean variable isliked to isLiked in LikeController (the variable that captures the return value of likeService.toggleLike(boardId, userId)) to follow Java camelCase convention, and update all references in the method (including the if(isliked) conditional and any further usages) to use isLiked instead.src/main/java/com/kms/springboard/like/repository/LikeRepository.java (1)
5-5: 사용되지 않는Optional임포트
java.util.Optional이 임포트되었으나 인터페이스 내 어떤 메서드에서도 사용되지 않습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/like/repository/LikeRepository.java` at line 5, The import java.util.Optional at the top of LikeRepository.java is unused; remove that unused import from the interface (LikeRepository) to clean up warnings and keep imports accurate—no code changes beyond deleting the Optional import line are needed.src/main/java/com/kms/springboard/like/service/LikeServiceImpl.java (1)
73-76:getUserLikeBoards에@Transactional(readOnly = true)누락
getLikeUsers(Line 66)에는@Transactional(readOnly = true)가 적용되어 있지만 동일한 조회 성격의getUserLikeBoards에는 누락되어 있습니다. 클래스 레벨의@Transactional이 적용되어 쓰기 가능 트랜잭션으로 실행됩니다.♻️ 제안 수정
+ `@Transactional`(readOnly = true) public Page<LikeDto> getUserLikeBoards(String userId, Pageable pageable) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/like/service/LikeServiceImpl.java` around lines 73 - 76, The getUserLikeBoards method in LikeServiceImpl is missing `@Transactional`(readOnly = true) and is currently running under the class-level writable transaction; annotate the getUserLikeBoards method with `@Transactional`(readOnly = true) so its read-only repository call (likeRepository.findByUserId) executes in a read-only transaction consistent with getLikeUsers.src/main/java/com/kms/springboard/member/entity/MemberEntity.java (1)
27-34: 컬럼명 변경(memberId→member_id,userId→user_id)은 DB 마이그레이션 필요기존 운영 DB가 있다면 컬럼명 변경을 위한 DDL 마이그레이션 스크립트(Flyway 또는 Liquibase)가 없으면 애플리케이션 구동 시 스키마 불일치 오류가 발생합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/kms/springboard/member/entity/MemberEntity.java` around lines 27 - 34, The Entity MemberEntity now maps fields id -> column "member_id" and userId -> "user_id", so add a DB migration (Flyway or Liquibase) that renames the existing columns to these new names (preserving data and constraints) before deploying; create a migration script that uses ALTER TABLE ... RENAME COLUMN (or the DB-specific equivalent) for memberId -> member_id and userId -> user_id, include any index/constraint/name adjustments and test it against the existing production schema, and ensure the migration file is versioned and picked up by the project's migration runner so MemberEntity.id and MemberEntity.userId mappings match the DB at startup.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/com/kms/springboard/like/controller/LikeController.java`:
- Around line 45-66: The two controller methods getLikeUsers and getLikeBoards
currently share the same GET mapping pattern ("/like/{...}") causing ambiguous
handler errors; change the mappings to distinct paths (e.g.,
`@GetMapping`("/like/board/{boardId}") for getLikeUsers and
`@GetMapping`("/like/user/{userId}") for getLikeBoards), update any clients/tests
to call the new endpoints, and keep the existing method signatures and calls to
likeService.getLikeUsers(...) and likeService.getUserLikeBoards(...) unchanged.
In `@src/main/java/com/kms/springboard/member/dto/MemberDto.java`:
- Around line 25-26: The MemberDto.nickname field is missing a `@Size`(max=...)
constraint and the corresponding entity column has no length limit, allowing
excessively long nicknames; add a `@Size`(max=XX, message="...") annotation to the
nickname field in MemberDto (choose the same max as other fields or a sensible
limit like 30), and update the corresponding Member entity's nickname column
annotation (e.g., `@Column`(length=XX)) to enforce the same maximum at the
DB/model level so DTO validation and the entity schema match.
In `@src/main/resources/http/RequestTest.http`:
- Around line 7-13: The test request JSON contains real PII in the fields
username, email, userId, and nickname and a weak password; replace these with
clearly synthetic values (e.g., username: "Test User", email:
"user@example.test", userId: "testuser123", nickname: "tester") and use a
non-trivial test password (e.g., "TestPass!234") so the data is obviously fake
and no real personal information is committed; update the JSON object in
RequestTest.http replacing the values for username, email, userId, password, and
nickname accordingly.
---
Outside diff comments:
In `@src/main/java/com/kms/springboard/like/service/LikeServiceImpl.java`:
- Around line 78-104: The DB/Redis inconsistency occurs because addLike and
removeLike call Redis helpers (incrementLikeCount, decrementLikeCount,
cacheUserLiked) inside the transactional method so Redis updates aren't rolled
back with the DB; change both addLike and removeLike to register a
TransactionSynchronizationManager.afterCommit callback that performs the Redis
operations (incrementLikeCount/decrementLikeCount and cacheUserLiked) only after
the transaction successfully commits, i.e., replace the direct calls in
addLike/removeLike with a
TransactionSynchronizationManager.registerSynchronization(...) that invokes
those specific methods (incrementLikeCount, decrementLikeCount, cacheUserLiked)
on afterCommit and handle any exceptions there to avoid affecting DB commit
flow.
- Around line 106-121: incrementLikeCount and decrementLikeCount can create
incorrect counts when the Redis key is missing; modify both methods to first
check whether the key (LIKE_COUNT_PREFIX + boardId) exists and if not, load the
current like count from the database (e.g., via the repository method used by
getLikeCount or a countLikesByBoardId) and set that value into Redis with
CACHE_TTL, then perform the increment()/decrement() and reset the TTL; also
ensure decrement handles negative results by clamping to 0 after decrement. Use
the existing symbols incrementLikeCount, decrementLikeCount, LIKE_COUNT_PREFIX,
CACHE_TTL, redisTemplate.opsForValue(), and the service/repository method that
reads DB counts (the same one getLikeCount uses) to initialize the cache before
mutating.
In `@src/main/java/com/kms/springboard/member/entity/MemberEntity.java`:
- Around line 17-23: The `@Index` columnList entries in MemberEntity reference the
old camelCase property name ("userId") but the actual DB column is renamed via
`@Column`(name = "user_id"); update the `@Index` annotations in the `@Table` on
MemberEntity to use the physical column names (e.g., change "userId" to
"user_id") and verify the "email" index matches the `@Column`(name=...) for the
email field so JPA/Hibernate creates/validates indexes against the correct
column names.
In `@src/main/java/com/kms/springboard/member/service/MemberServiceImpl.java`:
- Around line 36-43: The service is missing a pre-save uniqueness check for
nickname causing DB constraint violations; add an existsByNickname(String
nickname) method to MemberRepository and call it from MemberServiceImpl (before
building/saving the MemberEntity) to throw a controlled exception (e.g.,
DuplicateMemberException or IllegalArgumentException) when
memberDto.getNickname() already exists, mirroring the existing
existsByUserId/existsByEmail checks and preventing memberRepository.save(member)
from triggering DataIntegrityViolationException for MemberEntity.nickname.
---
Nitpick comments:
In `@src/main/java/com/kms/springboard/like/controller/LikeController.java`:
- Around line 27-34: Rename the local boolean variable isliked to isLiked in
LikeController (the variable that captures the return value of
likeService.toggleLike(boardId, userId)) to follow Java camelCase convention,
and update all references in the method (including the if(isliked) conditional
and any further usages) to use isLiked instead.
In `@src/main/java/com/kms/springboard/like/repository/LikeRepository.java`:
- Line 5: The import java.util.Optional at the top of LikeRepository.java is
unused; remove that unused import from the interface (LikeRepository) to clean
up warnings and keep imports accurate—no code changes beyond deleting the
Optional import line are needed.
In `@src/main/java/com/kms/springboard/like/service/LikeServiceImpl.java`:
- Around line 73-76: The getUserLikeBoards method in LikeServiceImpl is missing
`@Transactional`(readOnly = true) and is currently running under the class-level
writable transaction; annotate the getUserLikeBoards method with
`@Transactional`(readOnly = true) so its read-only repository call
(likeRepository.findByUserId) executes in a read-only transaction consistent
with getLikeUsers.
In `@src/main/java/com/kms/springboard/member/entity/MemberEntity.java`:
- Around line 27-34: The Entity MemberEntity now maps fields id -> column
"member_id" and userId -> "user_id", so add a DB migration (Flyway or Liquibase)
that renames the existing columns to these new names (preserving data and
constraints) before deploying; create a migration script that uses ALTER TABLE
... RENAME COLUMN (or the DB-specific equivalent) for memberId -> member_id and
userId -> user_id, include any index/constraint/name adjustments and test it
against the existing production schema, and ensure the migration file is
versioned and picked up by the project's migration runner so MemberEntity.id and
MemberEntity.userId mappings match the DB at startup.
| @GetMapping("/like/{boardId}") | ||
| public ResponseEntity<ApiResponse<Page<LikeDto>>> getLikeUsers( | ||
| @PathVariable Long boardId, | ||
| @RequestParam(defaultValue = "0") int page, | ||
| @RequestParam(defaultValue = "20")int size, | ||
| Authentication auth){ | ||
|
|
||
|
|
||
| @RequestParam(defaultValue = "20")int size){ | ||
| Pageable pageable = PageRequest.of(page, size); | ||
| Page<LikeDto> users = likeService.getLikeUsers(boardId, pageable); | ||
|
|
||
| return ResponseEntity.ok(ApiResponse.success("좋아요 누른 사람 목록 조회", users)); | ||
|
|
||
| } | ||
|
|
||
| @GetMapping("/like/{userId}") | ||
| public ResponseEntity<ApiResponse<Page<LikeDto>>> getLikeBoards( | ||
| @PathVariable String userId, | ||
| @RequestParam(defaultValue = "0") int page, | ||
| @RequestParam(defaultValue = "20") int size){ | ||
| Pageable pageable = PageRequest.of(page, size); | ||
| Page<LikeDto> userLikeBoards = likeService.getUserLikeBoards(userId, pageable); | ||
|
|
||
| return ResponseEntity.ok(ApiResponse.success("사용자가 좋아요 누른 게시글", userLikeBoards)); | ||
| } |
There was a problem hiding this comment.
/like/{boardId}와 /like/{userId}가 동일한 URL 패턴 → 애플리케이션 구동 불가
두 엔드포인트의 경로가 모두 GET /api/boards/like/{variable}로 동일합니다. Spring MVC는 경로 변수의 타입(Long vs String)으로 라우팅을 구분하지 않으며, 이 경우 IllegalStateException: Ambiguous handler methods 예외가 발생합니다. 애플리케이션이 정상적으로 시작되지 않습니다.
두 엔드포인트를 구분 가능한 경로로 분리하세요.
🐛 제안 수정
- `@GetMapping`("/like/{boardId}")
+ `@GetMapping`("/{boardId}/like/users")
public ResponseEntity<ApiResponse<Page<LikeDto>>> getLikeUsers(
`@PathVariable` Long boardId,
`@RequestParam`(defaultValue = "0") int page,
- `@RequestParam`(defaultValue = "20")int size){
+ `@RequestParam`(defaultValue = "20") int size){
Pageable pageable = PageRequest.of(page, size);
Page<LikeDto> users = likeService.getLikeUsers(boardId, pageable);
return ResponseEntity.ok(ApiResponse.success("좋아요 누른 사람 목록 조회", users));
}
- `@GetMapping`("/like/{userId}")
+ `@GetMapping`("/users/{userId}/like")
public ResponseEntity<ApiResponse<Page<LikeDto>>> getLikeBoards(
`@PathVariable` String userId,
`@RequestParam`(defaultValue = "0") int page,
`@RequestParam`(defaultValue = "20") int size){
Pageable pageable = PageRequest.of(page, size);
Page<LikeDto> userLikeBoards = likeService.getUserLikeBoards(userId, pageable);
return ResponseEntity.ok(ApiResponse.success("사용자가 좋아요 누른 게시글", userLikeBoards));
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/kms/springboard/like/controller/LikeController.java` around
lines 45 - 66, The two controller methods getLikeUsers and getLikeBoards
currently share the same GET mapping pattern ("/like/{...}") causing ambiguous
handler errors; change the mappings to distinct paths (e.g.,
`@GetMapping`("/like/board/{boardId}") for getLikeUsers and
`@GetMapping`("/like/user/{userId}") for getLikeBoards), update any clients/tests
to call the new endpoints, and keep the existing method signatures and calls to
likeService.getLikeUsers(...) and likeService.getUserLikeBoards(...) unchanged.
| @NotBlank(message = "닉네임을 입력해주세요") | ||
| private String nickname; |
There was a problem hiding this comment.
nickname 필드에 @Size 제약 누락
userId, email, password에는 모두 @Size 최댓값이 지정되어 있지만 nickname에는 없습니다. 대응하는 엔티티 컬럼에도 length 지정이 없어, 비정상적으로 긴 문자열이 입력될 수 있습니다.
✏️ 제안 수정
- `@NotBlank`(message = "닉네임을 입력해주세요")
+ `@NotBlank`(message = "닉네임을 입력해주세요")
+ `@Size`(min = 2, max = 30, message = "닉네임은 2~30자여야 합니다")
private String nickname;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/kms/springboard/member/dto/MemberDto.java` around lines 25
- 26, The MemberDto.nickname field is missing a `@Size`(max=...) constraint and
the corresponding entity column has no length limit, allowing excessively long
nicknames; add a `@Size`(max=XX, message="...") annotation to the nickname field
in MemberDto (choose the same max as other fields or a sensible limit like 30),
and update the corresponding Member entity's nickname column annotation (e.g.,
`@Column`(length=XX)) to enforce the same maximum at the DB/model level so DTO
validation and the entity schema match.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
README.md (1)
1-5: README에 기술 스택 및 실행 방법 추가를 권장합니다.현재 내용은 프로젝트를 간략히 소개하는 수준에서 적절합니다. 다만, 이번 PR에서 Redis 캐싱, 닉네임 필드, HTTP 테스트 등 의미 있는 기술적 변경이 이루어졌으므로, 아래와 같이 기술 스택과 실행 방법을 함께 기술하면 프로젝트의 가독성과 재현 가능성이 높아집니다.
📝 README 보강 예시
# 프로젝트 - 개인 프로젝트 - spring으로 게시판 만들기 - 새로운 기술 적용해 계속 발전시키는 중 + +## 기술 스택 + +- Java / Spring Boot +- Spring Data JPA +- Redis (좋아요 캐싱) +- MySQL + +## 실행 방법 + +```bash +# Redis 및 MySQL이 실행 중인 상태에서 +./gradlew bootRun +```🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 1 - 5, Update README.md to include a concise "Tech Stack" section listing core technologies used (e.g., Spring Boot, MySQL, Redis, Gradle) and an "Running Locally" section with exact prerequisites and commands; mention that Redis and MySQL must be running and show the command to start the app (e.g., ./gradlew bootRun) and any environment variables or ports to set, and add a brief note about running HTTP tests and the new nickname field so reviewers can reproduce the Redis caching and nickname behavior locally.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@README.md`:
- Around line 1-5: Update README.md to include a concise "Tech Stack" section
listing core technologies used (e.g., Spring Boot, MySQL, Redis, Gradle) and an
"Running Locally" section with exact prerequisites and commands; mention that
Redis and MySQL must be running and show the command to start the app (e.g.,
./gradlew bootRun) and any environment variables or ports to set, and add a
brief note about running HTTP tests and the new nickname field so reviewers can
reproduce the Redis caching and nickname behavior locally.
Summary by CodeRabbit
릴리스 노트
새 기능
테스트
문서