Conversation
Walkthrough사용자가 매칭을 떠나는 기능을 추가합니다. 새로운 leave 엔드포인트, MatchRoom과 MatchParticipant 엔티티의 메서드 추가, joinMatch 메서드의 재참여 로직 개선, 관련 DTO 및 저장소 쿼리를 포함합니다. Changes
Sequence DiagramsequenceDiagram
actor User
participant Controller
participant Service
participant Repository
participant Entity
rect rgba(100, 150, 200, 0.5)
note over User,Entity: 매칭 떠나기 (leaveMatch)
User->>Controller: DELETE /api/matches/{matchId}/leave
Controller->>Service: leaveMatch(matchId, userId)
Service->>Repository: findById(matchId)
Repository-->>Service: MatchRoom
Service->>Repository: findByUser(userId)
Repository-->>Service: User
Service->>Repository: findByMatchRoomAndUserAndStatus(room, user, JOINED)
Repository-->>Service: Optional<MatchParticipant>
Service->>Entity: participant.leave()
Entity->>Entity: status = LEFT, leftAt = now
Service->>Entity: matchRoom.leave()
Entity->>Entity: curMembers--, status 업데이트
Service-->>Controller: void
Controller-->>User: 200 OK
end
rect rgba(150, 200, 100, 0.5)
note over User,Entity: 매칭 참여/재참여 (joinMatch)
User->>Controller: POST /api/matches/{matchId}/join
Controller->>Service: joinMatch(matchId, userId)
Service->>Repository: findByMatchRoomAndUser(room, user)
Repository-->>Service: Optional<MatchParticipant>
alt 기존 참여자 존재
Service->>Entity: participant.rejoin()
Entity->>Entity: status = JOINED, joinedAt = now, leftAt = null
else 새로운 참여자
Service->>Repository: save(new MatchParticipant)
end
Service->>Entity: matchRoom.join()
Entity->>Entity: curMembers++, status 업데이트
Service-->>Controller: void
Controller-->>User: 200 OK
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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 (2)
src/main/java/com/be/sportizebe/domain/match/service/MatchServiceImpl.java (2)
35-49:⚠️ Potential issue | 🟠 Major
createMatch에서matchRoom.join()미호출로curMembers가 0으로 남는 문제
joinMatch는 이번 PR에서 추가된matchRoom.join()을 호출하여curMembers를 1씩 증가시키지만,createMatch는 창설자 참가자를 저장하고도join()을 호출하지 않아curMembers=0으로 시작합니다. 이후 다른 유저가joinMatch로 참가하면curMembers=1이 되지만 실제 JOINED 인원은 2명입니다.MatchResponse.from(savedRoom)에서 반환하는curMembers도 0으로 잘못 표시됩니다.🐛 수정 제안
// 3) 생성자 자동 참여 처리 matchParticipantRepository.save(new MatchParticipant(savedRoom, user)); + // 4) 생성자 참여로 인한 인원/상태 갱신 + savedRoom.join(); return MatchResponse.from(savedRoom);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/be/sportizebe/domain/match/service/MatchServiceImpl.java` around lines 35 - 49, createMatch currently saves the creator as a MatchParticipant but never calls matchRoom.join(), leaving curMembers at 0; to fix, invoke the room join logic (matchRoom.join() or savedRoom.join()) so curMembers increments for the creator before persisting/returning: call join() on the MatchRoom instance after creating it (or on the savedRoom), then persist the participant with matchParticipantRepository.save(new MatchParticipant(...)), ensure the updated MatchRoom is saved/returned so MatchResponse.from(savedRoom) reflects the correct curMembers.
62-92:⚠️ Potential issue | 🟠 Major
joinMatch— 정원 초과를 허용하는 TOCTOU 레이스 컨디션
countByMatchRoomAndStatus(3단계)와 실제 참가자 저장(5단계) 사이는 단일 트랜잭션 내에서 직렬화되지 않습니다. 두 요청이 동시에 3단계를 통과하면 둘 다 남은 1자리를 차지하여 정원을 초과할 수 있습니다.
MatchRoom에@Version을 추가하여 낙관적 잠금을 활성화하는 것이 권장 해결책입니다. JPA 엔티티의@Version어노테이션을 추가하면 동시 수정을 방지할 수 있습니다. 충돌 발생 시OptimisticLockException이 발생하므로, 서비스 레이어에서 도메인 예외로 전환 처리가 필요합니다.🔒 낙관적 잠금 적용 제안 (MatchRoom.java에 적용)
`@Enumerated`(EnumType.STRING) `@Column`(nullable = false) private MatchStatus status; +@Version +private int version;
MatchServiceImpl.joinMatch에서OptimisticLockException을 잡아 도메인 예외로 전환:+import org.springframework.dao.OptimisticLockingFailureException; ... + } catch (OptimisticLockingFailureException e) { + throw new CustomException(MatchErrorCode.MATCH_FULL); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/be/sportizebe/domain/match/service/MatchServiceImpl.java` around lines 62 - 92, joinMatch currently has a TOCTOU race between countByMatchRoomAndStatus and persisting participants; add optimistic locking to prevent concurrent overfill by adding a version field annotated with `@Version` to the MatchRoom entity (e.g., private Long version) and ensure MatchRoom is used/merged in the same transactional context (joinMatch in MatchServiceImpl should be `@Transactional`). Catch javax.persistence.OptimisticLockException (or Spring's ObjectOptimisticLockingFailureException) in MatchServiceImpl.joinMatch and translate it into a domain CustomException (e.g., MATCH_FULL or a new CONCURRENT_MODIFICATION error) so callers receive a clear domain-level error when a concurrent modification occurs.
🧹 Nitpick comments (5)
src/main/java/com/be/sportizebe/domain/match/dto/request/MatchCreateRequest.java (1)
17-26:maxMembers(Integer 박싱 타입)와durationMinutes,entryFee(int 원시 타입) 간의 타입 불일치
Integer maxMembers는 JSON에서 누락 시null이 되며, Jakarta Validation의@Min/@Max는null을 유효한 것으로 간주해 제약이 무시됩니다.int durationMinutes,int entryFee는 누락 시0으로 기본값 처리됩니다.필드 간 타입을 통일하거나,
maxMembers에도@NotNull을 추가해 일관된 검증 동작을 보장하는 것을 권장합니다.♻️ 제안 수정 (타입 통일 예시)
- Integer maxMembers, + `@NotNull`(message = "최대 인원은 필수입니다.") + Integer maxMembers,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/be/sportizebe/domain/match/dto/request/MatchCreateRequest.java` around lines 17 - 26, MatchCreateRequest has inconsistent types: Integer maxMembers is nullable so `@Min/`@Max are skipped when null while durationMinutes and entryFee are primitive ints defaulting to 0; make validation consistent by either converting maxMembers to primitive int or adding `@NotNull` to maxMembers, and/or change durationMinutes and entryFee to Integer if you want null-checks; update the annotations accordingly (e.g., add `@NotNull` on maxMembers or change its type) so `@Min/`@Max/@NotNull apply uniformly to maxMembers, durationMinutes, and entryFee.src/main/java/com/be/sportizebe/domain/match/entity/MatchParticipantStatus.java (1)
4-5: 포매팅 변경만 포함되어 있어 기능상 문제는 없습니다.다만 연결된 이슈
#57에서는"LEFT 상태를 대체하거나 보완할 새로운 상태값 추가"를 요구했습니다. 현재 구현에서는 자발적 탈퇴와 매칭 취소 모두LEFT를 사용하므로, 두 케이스를 구분할 수 없습니다. 추후 이력 추적이나 취소/탈퇴 통계가 필요해질 경우CANCELLED등의 상태를 분리하는 것을 고려할 수 있습니다.♻️ 제안 예시
public enum MatchParticipantStatus { JOINED, - LEFT + LEFT, + CANCELLED // 매칭 취소(사용자 요청 또는 시스템에 의해 참가 철회된 경우) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/be/sportizebe/domain/match/entity/MatchParticipantStatus.java` around lines 4 - 5, MatchParticipantStatus currently only has JOINED and LEFT which mixes voluntary leaves and match cancellations; add a distinct enum value (e.g., CANCELLED) to MatchParticipantStatus to represent match-initiated cancellation and leave LEFT for voluntary departures, then update all code paths that set or interpret MatchParticipantStatus (construction/mutation sites, persistence mapping, JSON serialization/deserialization, and any business logic or tests referencing LEFT) to use CANCELLED where appropriate so the two cases can be distinguished in history/stats.src/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.java (2)
42-46:NOT NULL컬럼 추가 시 기존 데이터 마이그레이션 주의
durationMinutes와entryFee모두@Column(nullable = false)로 선언되어 있습니다. 기존match_rooms레코드가 있는 환경에서 Flyway/Liquibase 또는 Hibernate DDL auto로 컬럼을 추가할 경우, 기본값 없이 NOT NULL 컬럼을 추가하면 마이그레이션이 실패합니다. 마이그레이션 스크립트에DEFAULT 0등 기본값을 지정하거나, 필요에 따라 기존 데이터 백필(backfill) 처리를 포함해야 합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.java` around lines 42 - 46, The new NOT NULL fields on MatchRoom (durationMinutes and entryFee) will break migrations for existing match_rooms rows; update the migration strategy to supply safe defaults or backfill values: modify the schema migration script (Flyway/Liquibase) that adds these columns to set a DEFAULT (e.g., DEFAULT 0) and/or perform an UPDATE backfill before making them NOT NULL, and then adjust/remove the default if desired; ensure the JPA entity annotations (`@Column`(nullable = false) on MatchRoom.durationMinutes and MatchRoom.entryFee) remain consistent with the migration.
68-71:join()— 엔티티 레벨의 정원 초과 방어 로직 누락서비스 레이어에서 이미 정원 체크를 수행하지만, 엔티티 메서드 자체는 이미
FULL인 상태에서 호출되어도curMembers를 초과 증가시킵니다.leave()와 일관성을 맞추는 차원에서 방어 로직을 추가하는 것을 권장합니다.♻️ 수정 제안
public void join() { + if (isFull()) { + throw new IllegalStateException("매칭방이 이미 정원입니다."); + } this.curMembers++; if (isFull()) this.status = MatchStatus.FULL; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.java` around lines 68 - 71, The join() method currently increments curMembers even when the room is already FULL; add defensive logic in MatchRoom.join() to first check isFull() (and/or compare curMembers against capacity) and prevent incrementing when full (either no-op or throw an IllegalStateException to match your domain behavior), and only increment and set status = MatchStatus.FULL when the increment is allowed; mirror the defensive pattern used in leave() so curMembers cannot exceed capacity and status remains consistent.src/main/java/com/be/sportizebe/domain/match/dto/response/MatchNearResponse.java (1)
7-18:MatchNearResponse레코드 필드에@Schema어노테이션 누락
MatchResponse,MatchDetailResponse와 달리 이 레코드에는 어떤 필드에도@Schema어노테이션이 없습니다.durationMinutes,entryFee를 포함한 전체 필드에@Schema(description = ..., example = ...)어노테이션을 추가하여 Swagger 문서 품질을 맞추는 것을 권장합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/be/sportizebe/domain/match/dto/response/MatchNearResponse.java` around lines 7 - 18, The MatchNearResponse record is missing `@Schema` annotations on its fields; add io.swagger.v3.oas.annotations.media.Schema to each component of the record (e.g., matchId, sportsName, facilityId, facilityName, curMembers, maxMembers, status, distanceM, durationMinutes, entryFee) with a brief description and an example value for each (for instance durationMinutes: description "Estimated match duration in minutes", example "90"; entryFee: description "Entry fee in cents or currency unit", example "5000"), placing the annotation immediately before each record component in the MatchNearResponse declaration so Swagger/OpenAPI picks up the field metadata.
🤖 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/be/sportizebe/domain/match/controller/MatchController.java`:
- Line 72: The Swagger `@Operation` summary "매칭 취소" in MatchController is
ambiguous; update the annotation on the relevant controller method in class
MatchController (the method annotated with `@Operation`(summary = "...")) to a
clearer phrase such as "매칭 참여 취소" or "매칭 나가기" so it explicitly indicates
withdrawing participation rather than deleting the match; ensure only the
summary string is changed in the `@Operation` annotation for that method.
In
`@src/main/java/com/be/sportizebe/domain/match/dto/request/MatchCreateRequest.java`:
- Around line 21-22: The durationMinutes field in MatchCreateRequest currently
uses a primitive int and has no validation, allowing missing or negative values;
change the field to an Integer and add validation annotations (e.g., `@NotNull`
and `@Positive` or `@Min`(1)) on durationMinutes in the MatchCreateRequest DTO so a
missing or non-positive value fails validation before persisting.
In `@src/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.java`:
- Around line 72-75: In MatchRoom.leave(), add defensive logic to prevent
curMembers from going negative: check if this.curMembers <= 0 and throw an
IllegalStateException (or return early) with a clear message referencing
MatchRoom.leave; otherwise decrement this.curMembers and if (this.status ==
MatchStatus.FULL) set this.status = MatchStatus.OPEN. Update any callers/tests
accordingly to expect the new guard.
---
Outside diff comments:
In `@src/main/java/com/be/sportizebe/domain/match/service/MatchServiceImpl.java`:
- Around line 35-49: createMatch currently saves the creator as a
MatchParticipant but never calls matchRoom.join(), leaving curMembers at 0; to
fix, invoke the room join logic (matchRoom.join() or savedRoom.join()) so
curMembers increments for the creator before persisting/returning: call join()
on the MatchRoom instance after creating it (or on the savedRoom), then persist
the participant with matchParticipantRepository.save(new MatchParticipant(...)),
ensure the updated MatchRoom is saved/returned so MatchResponse.from(savedRoom)
reflects the correct curMembers.
- Around line 62-92: joinMatch currently has a TOCTOU race between
countByMatchRoomAndStatus and persisting participants; add optimistic locking to
prevent concurrent overfill by adding a version field annotated with `@Version` to
the MatchRoom entity (e.g., private Long version) and ensure MatchRoom is
used/merged in the same transactional context (joinMatch in MatchServiceImpl
should be `@Transactional`). Catch javax.persistence.OptimisticLockException (or
Spring's ObjectOptimisticLockingFailureException) in MatchServiceImpl.joinMatch
and translate it into a domain CustomException (e.g., MATCH_FULL or a new
CONCURRENT_MODIFICATION error) so callers receive a clear domain-level error
when a concurrent modification occurs.
---
Nitpick comments:
In
`@src/main/java/com/be/sportizebe/domain/match/dto/request/MatchCreateRequest.java`:
- Around line 17-26: MatchCreateRequest has inconsistent types: Integer
maxMembers is nullable so `@Min/`@Max are skipped when null while durationMinutes
and entryFee are primitive ints defaulting to 0; make validation consistent by
either converting maxMembers to primitive int or adding `@NotNull` to maxMembers,
and/or change durationMinutes and entryFee to Integer if you want null-checks;
update the annotations accordingly (e.g., add `@NotNull` on maxMembers or change
its type) so `@Min/`@Max/@NotNull apply uniformly to maxMembers, durationMinutes,
and entryFee.
In
`@src/main/java/com/be/sportizebe/domain/match/dto/response/MatchNearResponse.java`:
- Around line 7-18: The MatchNearResponse record is missing `@Schema` annotations
on its fields; add io.swagger.v3.oas.annotations.media.Schema to each component
of the record (e.g., matchId, sportsName, facilityId, facilityName, curMembers,
maxMembers, status, distanceM, durationMinutes, entryFee) with a brief
description and an example value for each (for instance durationMinutes:
description "Estimated match duration in minutes", example "90"; entryFee:
description "Entry fee in cents or currency unit", example "5000"), placing the
annotation immediately before each record component in the MatchNearResponse
declaration so Swagger/OpenAPI picks up the field metadata.
In
`@src/main/java/com/be/sportizebe/domain/match/entity/MatchParticipantStatus.java`:
- Around line 4-5: MatchParticipantStatus currently only has JOINED and LEFT
which mixes voluntary leaves and match cancellations; add a distinct enum value
(e.g., CANCELLED) to MatchParticipantStatus to represent match-initiated
cancellation and leave LEFT for voluntary departures, then update all code paths
that set or interpret MatchParticipantStatus (construction/mutation sites,
persistence mapping, JSON serialization/deserialization, and any business logic
or tests referencing LEFT) to use CANCELLED where appropriate so the two cases
can be distinguished in history/stats.
In `@src/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.java`:
- Around line 42-46: The new NOT NULL fields on MatchRoom (durationMinutes and
entryFee) will break migrations for existing match_rooms rows; update the
migration strategy to supply safe defaults or backfill values: modify the schema
migration script (Flyway/Liquibase) that adds these columns to set a DEFAULT
(e.g., DEFAULT 0) and/or perform an UPDATE backfill before making them NOT NULL,
and then adjust/remove the default if desired; ensure the JPA entity annotations
(`@Column`(nullable = false) on MatchRoom.durationMinutes and MatchRoom.entryFee)
remain consistent with the migration.
- Around line 68-71: The join() method currently increments curMembers even when
the room is already FULL; add defensive logic in MatchRoom.join() to first check
isFull() (and/or compare curMembers against capacity) and prevent incrementing
when full (either no-op or throw an IllegalStateException to match your domain
behavior), and only increment and set status = MatchStatus.FULL when the
increment is allowed; mirror the defensive pattern used in leave() so curMembers
cannot exceed capacity and status remains consistent.
ℹ️ Review info
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/main/java/com/be/sportizebe/domain/match/controller/MatchController.javasrc/main/java/com/be/sportizebe/domain/match/dto/request/MatchCreateRequest.javasrc/main/java/com/be/sportizebe/domain/match/dto/request/MatchNearRequest.javasrc/main/java/com/be/sportizebe/domain/match/dto/response/MatchNearResponse.javasrc/main/java/com/be/sportizebe/domain/match/entity/MatchParticipant.javasrc/main/java/com/be/sportizebe/domain/match/entity/MatchParticipantStatus.javasrc/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.javasrc/main/java/com/be/sportizebe/domain/match/exception/MatchErrorCode.javasrc/main/java/com/be/sportizebe/domain/match/repository/MatchParticipantRepository.javasrc/main/java/com/be/sportizebe/domain/match/repository/MatchRoomRepository.javasrc/main/java/com/be/sportizebe/domain/match/repository/projection/MatchNearProjection.javasrc/main/java/com/be/sportizebe/domain/match/service/MatchService.javasrc/main/java/com/be/sportizebe/domain/match/service/MatchServiceImpl.java
| } | ||
|
|
||
| @Operation(summary = "내 주변 매칭 목록 조회") | ||
| @Operation(summary = "매칭 취소") |
There was a problem hiding this comment.
@Operation summary가 의미상 불명확합니다.
"매칭 취소"는 매칭 자체를 취소(삭제)하는 것으로 오해될 수 있습니다. 참여를 철회한다는 의도를 명확히 하려면 "매칭 참여 취소" 또는 "매칭 나가기"로 수정을 권장합니다.
✏️ 수정 제안
- `@Operation`(summary = "매칭 취소")
+ `@Operation`(summary = "매칭 참여 취소", description = "현재 참여 중인 매칭에서 나갑니다.")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @Operation(summary = "매칭 취소") | |
| `@Operation`(summary = "매칭 참여 취소", description = "현재 참여 중인 매칭에서 나갑니다.") |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/be/sportizebe/domain/match/controller/MatchController.java`
at line 72, The Swagger `@Operation` summary "매칭 취소" in MatchController is
ambiguous; update the annotation on the relevant controller method in class
MatchController (the method annotated with `@Operation`(summary = "...")) to a
clearer phrase such as "매칭 참여 취소" or "매칭 나가기" so it explicitly indicates
withdrawing participation rather than deleting the match; ensure only the
summary string is changed in the `@Operation` annotation for that method.
| @Schema(description = "몇 분동안 진행되는 매칭인지", example = "120") | ||
| int durationMinutes, |
There was a problem hiding this comment.
durationMinutes에 유효성 검증 제약 조건이 없습니다.
int 원시 타입이므로 JSON 요청에서 해당 필드가 누락되면 기본값 0이 사용되며, 음수 값도 아무런 오류 없이 허용됩니다. 0 또는 음수 매칭 시간은 유효하지 않은 비즈니스 데이터로 DB에 저장됩니다.
🛡️ 제안 수정
+ `@Schema`(description = "몇 분동안 진행되는 매칭인지", example = "120")
+ `@Min`(value = 1, message = "매칭 시간은 1분 이상이어야 합니다.")
+ `@Max`(value = 1440, message = "매칭 시간은 1440분(24시간) 이하이어야 합니다.")
int durationMinutes,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/com/be/sportizebe/domain/match/dto/request/MatchCreateRequest.java`
around lines 21 - 22, The durationMinutes field in MatchCreateRequest currently
uses a primitive int and has no validation, allowing missing or negative values;
change the field to an Integer and add validation annotations (e.g., `@NotNull`
and `@Positive` or `@Min`(1)) on durationMinutes in the MatchCreateRequest DTO so a
missing or non-positive value fails validation before persisting.
| public void leave() { | ||
| this.curMembers--; | ||
| if (this.status == MatchStatus.FULL) this.status = MatchStatus.OPEN; | ||
| } |
There was a problem hiding this comment.
leave() — curMembers가 음수가 될 수 있습니다
서비스 레이어에서 JOINED 참가자를 먼저 조회하므로 정상 흐름에서는 이 문제가 발생하지 않지만, 엔티티 메서드 자체에 방어 로직이 없어 잘못된 호출 시 curMembers가 음수가 됩니다.
🛡️ 수정 제안
public void leave() {
- this.curMembers--;
+ if (this.curMembers <= 0) {
+ throw new IllegalStateException("curMembers가 이미 0입니다.");
+ }
+ this.curMembers--;
if (this.status == MatchStatus.FULL) this.status = MatchStatus.OPEN;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public void leave() { | |
| this.curMembers--; | |
| if (this.status == MatchStatus.FULL) this.status = MatchStatus.OPEN; | |
| } | |
| public void leave() { | |
| if (this.curMembers <= 0) { | |
| throw new IllegalStateException("curMembers가 이미 0입니다."); | |
| } | |
| this.curMembers--; | |
| if (this.status == MatchStatus.FULL) this.status = MatchStatus.OPEN; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/be/sportizebe/domain/match/entity/MatchRoom.java` around
lines 72 - 75, In MatchRoom.leave(), add defensive logic to prevent curMembers
from going negative: check if this.curMembers <= 0 and throw an
IllegalStateException (or return early) with a clear message referencing
MatchRoom.leave; otherwise decrement this.curMembers and if (this.status ==
MatchStatus.FULL) set this.status = MatchStatus.OPEN. Update any callers/tests
accordingly to expect the new guard.
#️⃣ Issue Number
📝 요약(Summary)
🛠️ PR 유형
어떤 변경 사항이 있나요?
📸스크린샷 (선택)
💬 공유사항 to 리뷰어
✅ PR Checklist
PR이 다음 요구 사항을 충족하는지 확인하세요.
Summary by CodeRabbit
릴리스 노트