Conversation
|
""" Walkthrough이 변경사항은 투표(Poll) 기능의 도메인, 서비스, 컨트롤러, 저장소 계층을 신규로 도입하고, 이에 대한 테스트 및 DB 마이그레이션, 예외 코드 확장, 테스트 픽스처 생성기를 추가합니다. Poll 생성, 조회, 완료 처리 API와 관련 도메인 객체, JPA 엔티티, 리포지토리, 서비스 레이어, REST 컨트롤러, 그리고 통합/단위 테스트가 포함됩니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant PollController
participant PollService
participant PollDomainRepository
participant VoteDomainRepository
participant CustomizeTableDomainRepository
Client->>PollController: POST /api/polls/{tableId}
PollController->>PollService: create(tableId, member)
PollService->>CustomizeTableDomainRepository: getByIdAndMember(tableId, member)
PollService->>PollDomainRepository: create(Poll)
PollService-->>PollController: PollCreateResponse
PollController-->>Client: 201 Created
Client->>PollController: GET /api/polls/{pollId}
PollController->>PollService: readPollInfo(pollId, member)
PollService->>PollDomainRepository: getByIdAndMemberId(pollId, member.id)
PollService->>VoteDomainRepository: findVoteInfoByPollId(pollId)
PollService-->>PollController: PollInfoResponse
PollController-->>Client: 200 OK
Client->>PollController: PATCH /api/polls/{pollId}
PollController->>PollService: updateToDone(pollId, member)
PollService->>PollDomainRepository: updateToDone(pollId, member.id)
PollService->>VoteDomainRepository: findVoteInfoByPollId(pollId)
PollService-->>PollController: PollInfoResponse
PollController-->>Client: 200 OK
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40분 Suggested labels
Suggested reviewers
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: .coderabbit.yaml 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
Test Results105 files 105 suites 13s ⏱️ Results for commit 486abf1. ♻️ This comment has been updated with latest results. |
📝 Test Coverage Report
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (10)
src/main/java/com/debatetimer/domain/poll/ParticipateCode.java (1)
17-21: 메서드 명명 개선 제안검증 로직은 적절하지만
validateName메서드명이 실제로 참여 코드를 검증하는 것과 맞지 않습니다.validateCode또는validateParticipateCode로 변경하는 것이 더 명확합니다.- private void validateName(String value) { + private void validateCode(String value) { if (value == null || value.isBlank()) { throw new DTClientErrorException(ClientErrorCode.INVALID_POLL_PARTICIPANT_CODE); } }그리고 생성자에서 호출하는 부분도 함께 수정:
public ParticipateCode(String value) { - validateName(value); + validateCode(value); this.value = value; }src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java (1)
24-30: null 안전성 개선을 고려해보세요.현재
voteEntities가 null일 경우 NPE가 발생할 수 있습니다. 방어적 프로그래밍을 위해 null 체크를 추가하는 것을 고려해보세요.private VoteInfo resolveVoteInfo(long pollId, List<VoteEntity> voteEntities) { + if (voteEntities == null || voteEntities.isEmpty()) { + return new VoteInfo(pollId, 0L, 0L); + } Map<VoteTeam, Long> teamCount = voteEntities.stream() .collect(Collectors.groupingBy(VoteEntity::getTeam, Collectors.counting())); long prosCount = teamCount.getOrDefault(VoteTeam.PROS, 0L); long consCount = teamCount.getOrDefault(VoteTeam.CONS, 0L); return new VoteInfo(pollId, prosCount, consCount); }src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java (1)
25-42: 추가 테스트 케이스 고려해보세요.현재는 기본적인 성공 케이스만 테스트하고 있습니다. 다음과 같은 엣지 케이스들도 테스트하면 더 견고한 코드가 될 것 같습니다:
- 투표가 없는 경우
- 한 팀만 투표한 경우
- 존재하지 않는 pollId로 조회하는 경우
추가 테스트 메서드 예시:
@Test void 투표가_없는_경우_0을_반환한다() { Member member = memberGenerator.generate("email@email.com"); CustomizeTableEntity table = customizeTableGenerator.generate(member); PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); VoteInfo voteInfo = voteDomainRepository.findVoteInfoByPollId(pollEntity.getId()); assertAll( () -> assertThat(voteInfo.getPollId()).isEqualTo(pollEntity.getId()), () -> assertThat(voteInfo.getTotalCount()).isEqualTo(0L), () -> assertThat(voteInfo.getProsCount()).isEqualTo(0L), () -> assertThat(voteInfo.getConsCount()).isEqualTo(0L) ); }src/test/java/com/debatetimer/fixture/PollGenerator.java (2)
20-29: 하드코딩된 값들의 상수화를 고려해보세요."찬성", "반대", "주제" 같은 하드코딩된 값들이 여러 테스트에서 일관되게 사용되려면 상수로 관리하는 것이 좋겠습니다.
@Component public class PollGenerator { + private static final String DEFAULT_PROS_TEAM_NAME = "찬성"; + private static final String DEFAULT_CONS_TEAM_NAME = "반대"; + private static final String DEFAULT_AGENDA = "주제"; private final PollRepository pollRepository; public PollGenerator(final PollRepository pollRepository) { this.pollRepository = pollRepository; } public PollEntity generate(CustomizeTableEntity customizeTableEntity, PollStatus status) { Poll poll = new Poll( null, customizeTableEntity.getId(), customizeTableEntity.getMember().getId(), status, - "찬성", - "반대", - "주제" + DEFAULT_PROS_TEAM_NAME, + DEFAULT_CONS_TEAM_NAME, + DEFAULT_AGENDA ); return pollRepository.save(new PollEntity(poll)); } }
19-30: 메서드 오버로딩으로 유연성을 높여보세요.테스트에서 다양한 팀명이나 주제가 필요한 경우를 대비해 추가 메서드를 제공하는 것을 고려해보세요.
public PollEntity generate(CustomizeTableEntity customizeTableEntity, PollStatus status, String prosTeamName, String consTeamName, String agenda) { Poll poll = new Poll( null, customizeTableEntity.getId(), customizeTableEntity.getMember().getId(), status, prosTeamName, consTeamName, agenda ); return pollRepository.save(new PollEntity(poll)); }src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java (1)
17-30: BaseServiceTest와의 코드 중복을 고려해보세요.BaseServiceTest에도 동일한 fixture generator들과 repository들이 주입되어 있습니다. 공통 부모 클래스를 만들거나 컴포지션 패턴을 활용하여 중복을 줄이는 것을 고려해볼 수 있습니다.
예를 들어, 공통 테스트 의존성을 관리하는 클래스를 만들어볼 수 있습니다:
@TestComponent public class TestFixtures { @Autowired protected MemberGenerator memberGenerator; @Autowired protected CustomizeTableGenerator customizeTableGenerator; @Autowired protected PollGenerator pollGenerator; @Autowired protected VoteGenerator voteGenerator; // 기타 공통 fixture들... }그리고 각 기본 테스트 클래스에서 이를 주입받아 사용하는 방식으로 중복을 줄일 수 있습니다.
src/test/java/com/debatetimer/service/poll/PollServiceTest.java (1)
24-37: Poll 생성 테스트선거 생성 테스트가 기본적인 동작을 검증합니다. 하지만 생성된 Poll의 세부 속성(상태, 팀명 등)까지 검증하면 더 완전한 테스트가 될 것입니다.
다음과 같이 생성된 Poll의 세부 속성까지 검증하는 것을 고려해보세요:
PollCreateResponse createdPoll = pollService.create(table.getId(), member); Optional<PollEntity> foundPoll = pollRepository.findById(createdPoll.id()); -assertThat(foundPoll).isPresent(); +assertAll( + () -> assertThat(foundPoll).isPresent(), + () -> assertThat(foundPoll.get().getStatus()).isEqualTo(PollStatus.PROGRESS), + () -> assertThat(foundPoll.get().getMemberId()).isEqualTo(member.getId()) +);src/test/java/com/debatetimer/controller/poll/PollControllerTest.java (1)
21-37: Poll 생성 API 테스트선거 생성 API 테스트가 기본적인 성공 시나리오를 다룹니다. 하지만 응답 본문의 내용도 검증하면 더 완전한 테스트가 될 것입니다.
다음과 같이 응답 본문도 검증하는 것을 고려해보세요:
- given() - .contentType(ContentType.JSON) - .headers(headers) - .pathParam("tableId", table.getId()) - .when().post("/api/polls/{tableId}") - .then().statusCode(HttpStatus.CREATED.value()); + PollCreateResponse response = given() + .contentType(ContentType.JSON) + .headers(headers) + .pathParam("tableId", table.getId()) + .when().post("/api/polls/{tableId}") + .then().statusCode(HttpStatus.CREATED.value()) + .extract().as(PollCreateResponse.class); + + assertThat(response.id()).isNotNull();src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java (1)
37-53: 투표 조회 테스트의 검증 로직을 개선해보세요.
assertAll을 사용한 다중 검증이 좋습니다. 다만 도메인 객체와 엔티티 간의 변환 로직을 더 명확하게 검증할 수 있도록 개선을 제안합니다.assertAll( () -> assertThat(foundPoll.getId()).isEqualTo(pollEntity.getId()), + () -> assertThat(foundPoll.getTableId()).isEqualTo(pollEntity.getTableId()), () -> assertThat(foundPoll.getAgenda().getValue()).isEqualTo(pollEntity.getAgenda()), () -> assertThat(foundPoll.getStatus()).isEqualTo(pollEntity.getStatus()), () -> assertThat(foundPoll.getMemberId()).isEqualTo(pollEntity.getMemberId()), () -> assertThat(foundPoll.getProsTeamName().getValue()).isEqualTo(pollEntity.getProsTeamName()), () -> assertThat(foundPoll.getConsTeamName().getValue()).isEqualTo(pollEntity.getConsTeamName()) );src/main/java/com/debatetimer/service/poll/PollService.java (1)
41-46: 상태 업데이트 메서드의 일관성을 개선할 수 있습니다.
updateToDone메서드에서 두 번의 데이터베이스 호출이 발생합니다:
pollDomainRepository.updateToDone()- 상태 업데이트voteDomainRepository.findVoteInfoByPollId()- 투표 정보 조회성능 최적화를 위해 다음을 고려해보세요:
- 업데이트된 Poll 객체에서 필요한 정보를 직접 사용하거나
- 단일 트랜잭션에서 두 작업을 효율적으로 처리하는 방법
또한
readPollInfo메서드와 코드 중복이 있어 리팩토링을 고려할 수 있습니다:@Transactional public PollInfoResponse updateToDone(long pollId, Member member) { Poll poll = pollDomainRepository.updateToDone(pollId, member.getId()); return buildPollInfoResponse(poll.getId(), poll); } private PollInfoResponse buildPollInfoResponse(long pollId, Poll poll) { VoteInfo voteInfo = voteDomainRepository.findVoteInfoByPollId(pollId); return new PollInfoResponse(poll, voteInfo); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (33)
src/main/java/com/debatetimer/controller/poll/PollController.java(1 hunks)src/main/java/com/debatetimer/domain/poll/ParticipantName.java(1 hunks)src/main/java/com/debatetimer/domain/poll/ParticipateCode.java(1 hunks)src/main/java/com/debatetimer/domain/poll/Poll.java(1 hunks)src/main/java/com/debatetimer/domain/poll/Vote.java(1 hunks)src/main/java/com/debatetimer/domain/poll/VoteInfo.java(1 hunks)src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java(1 hunks)src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java(1 hunks)src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java(1 hunks)src/main/java/com/debatetimer/dto/poll/response/PollCreateResponse.java(1 hunks)src/main/java/com/debatetimer/dto/poll/response/PollInfoResponse.java(1 hunks)src/main/java/com/debatetimer/entity/poll/PollEntity.java(4 hunks)src/main/java/com/debatetimer/entity/poll/VoteEntity.java(3 hunks)src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java(1 hunks)src/main/java/com/debatetimer/repository/poll/PollRepository.java(1 hunks)src/main/java/com/debatetimer/repository/poll/VoteRepository.java(1 hunks)src/main/java/com/debatetimer/service/poll/PollService.java(1 hunks)src/main/resources/db/migration/V11__add_memberId_into_poll.sql(1 hunks)src/test/java/com/debatetimer/controller/BaseControllerTest.java(2 hunks)src/test/java/com/debatetimer/controller/BaseDocumentTest.java(2 hunks)src/test/java/com/debatetimer/controller/Tag.java(1 hunks)src/test/java/com/debatetimer/controller/poll/PollControllerTest.java(1 hunks)src/test/java/com/debatetimer/controller/poll/PollDocumentTest.java(1 hunks)src/test/java/com/debatetimer/domain/poll/ParticipantNameTest.java(1 hunks)src/test/java/com/debatetimer/domain/poll/ParticipateCodeTest.java(1 hunks)src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java(1 hunks)src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java(1 hunks)src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java(1 hunks)src/test/java/com/debatetimer/fixture/PollGenerator.java(1 hunks)src/test/java/com/debatetimer/fixture/VoteGenerator.java(1 hunks)src/test/java/com/debatetimer/repository/BaseRepositoryTest.java(1 hunks)src/test/java/com/debatetimer/service/BaseServiceTest.java(3 hunks)src/test/java/com/debatetimer/service/poll/PollServiceTest.java(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/main/java/com/debatetimer/entity/poll/VoteEntity.java (1)
Learnt from: coli-geonwoo
PR: #196
File: src/main/java/com/debatetimer/entity/poll/VoteEntity.java:19-0
Timestamp: 2025-07-10T01:01:08.967Z
Learning: VoteEntity와 같은 JPA 엔티티에서 getter/setter 메서드는 필요할 때 점진적으로 추가하는 방식을 선호함. 초기 엔티티 설정 단계에서는 최소한의 구조만 유지하고 기능을 점진적으로 확장하는 개발 방식을 사용함.
🧬 Code Graph Analysis (13)
src/main/java/com/debatetimer/domain/poll/Vote.java (2)
src/main/java/com/debatetimer/domain/poll/ParticipantName.java (1)
Getter(7-22)src/main/java/com/debatetimer/domain/poll/ParticipateCode.java (1)
Getter(7-22)
src/test/java/com/debatetimer/fixture/VoteGenerator.java (1)
src/test/java/com/debatetimer/fixture/PollGenerator.java (1)
Component(10-31)
src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java (2)
src/test/java/com/debatetimer/DataBaseCleaner.java (1)
DataBaseCleaner(11-47)src/test/java/com/debatetimer/service/BaseServiceTest.java (1)
ExtendWith(21-68)
src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java (3)
src/main/java/com/debatetimer/exception/custom/DTClientErrorException.java (1)
DTClientErrorException(5-10)src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java (1)
Repository(13-31)src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java (1)
Repository(12-24)
src/main/java/com/debatetimer/domain/poll/ParticipantName.java (3)
src/main/java/com/debatetimer/exception/custom/DTClientErrorException.java (1)
DTClientErrorException(5-10)src/main/java/com/debatetimer/domain/poll/ParticipateCode.java (1)
Getter(7-22)src/main/java/com/debatetimer/domain/poll/Vote.java (1)
Getter(6-19)
src/main/java/com/debatetimer/domain/poll/VoteInfo.java (1)
src/main/java/com/debatetimer/domain/poll/Poll.java (1)
Getter(8-24)
src/main/java/com/debatetimer/domain/poll/Poll.java (1)
src/main/java/com/debatetimer/domain/poll/VoteInfo.java (1)
Getter(5-19)
src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java (2)
src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java (1)
Nested(22-43)src/test/java/com/debatetimer/service/poll/PollServiceTest.java (3)
Nested(24-37)Nested(39-63)Nested(65-78)
src/test/java/com/debatetimer/domain/poll/ParticipantNameTest.java (2)
src/main/java/com/debatetimer/exception/custom/DTClientErrorException.java (1)
DTClientErrorException(5-10)src/test/java/com/debatetimer/domain/poll/ParticipateCodeTest.java (1)
Nested(14-25)
src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java (1)
src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java (1)
Nested(22-65)
src/test/java/com/debatetimer/fixture/PollGenerator.java (1)
src/test/java/com/debatetimer/fixture/VoteGenerator.java (1)
Component(10-23)
src/test/java/com/debatetimer/domain/poll/ParticipateCodeTest.java (2)
src/main/java/com/debatetimer/exception/custom/DTClientErrorException.java (1)
DTClientErrorException(5-10)src/test/java/com/debatetimer/domain/poll/ParticipantNameTest.java (1)
Nested(14-25)
src/main/java/com/debatetimer/entity/poll/PollEntity.java (3)
src/main/java/com/debatetimer/domain/poll/Poll.java (1)
Getter(8-24)src/main/java/com/debatetimer/domain/poll/ParticipantName.java (1)
Getter(7-22)src/main/java/com/debatetimer/entity/poll/VoteEntity.java (1)
Entity(22-51)
🔇 Additional comments (60)
src/main/java/com/debatetimer/domain/poll/Poll.java (2)
20-23: 생성자 위임 패턴이 올바르게 구현되었습니다.문자열 파라미터를 받는 편의 생성자가 도메인 객체 생성자로 적절히 위임하고 있어, 코드 중복을 방지하고 일관성을 유지합니다.
8-18: 도메인 모델 설계가 잘 되어 있습니다.불변 객체로 설계되어 있고, 값 객체(TeamName, Agenda)를 활용하여 도메인 로직을 캡슐화했습니다. 필드명도 명확하고 적절합니다.
src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java (2)
18-23: 도메인 저장소 구현이 올바른 패턴을 따르고 있습니다.읽기 전용 트랜잭션 어노테이션, 적절한 예외 처리, 엔티티-도메인 변환 등 모든 부분이 잘 구현되어 있습니다.
12-16: 생성자 주입과 Spring 어노테이션이 적절히 사용되었습니다.
@Repository와@RequiredArgsConstructor를 사용한 의존성 주입이 Spring Boot 모범 사례를 따르고 있습니다.src/test/java/com/debatetimer/repository/BaseRepositoryTest.java (1)
17-17: 후행 쉼표 추가로 코드 일관성이 개선되었습니다.배열의 마지막 요소 뒤에 쉼표를 추가하는 것은 향후 요소 추가 시 diff를 깔끔하게 유지하는 좋은 관례입니다.
src/test/java/com/debatetimer/controller/Tag.java (1)
9-9: 새로운 Poll API 태그가 일관된 패턴으로 추가되었습니다.기존 API 태그들과 동일한 명명 규칙을 따르며, 새로운 투표 기능을 위한 적절한 태그입니다.
src/test/java/com/debatetimer/controller/BaseDocumentTest.java (2)
15-15: PollService import가 올바르게 추가되었습니다.새로운 투표 기능을 위한 서비스 임포트가 적절히 추가되었습니다.
66-67: PollService 목 빈이 일관된 패턴으로 추가되었습니다.기존 서비스들과 동일한 방식으로
@MockitoBean어노테이션을 사용하여 테스트 인프라에 적절히 통합되었습니다.src/test/java/com/debatetimer/controller/BaseControllerTest.java (1)
15-17: 새로운 픽스처 제너레이터 추가가 적절합니다투표 관련 기능 테스트를 위한
PollGenerator와VoteGenerator추가가 기존 패턴과 일치하며 적절합니다. 모든 컨트롤러 테스트에서 재사용 가능하도록 베이스 클래스에 추가된 것이 좋은 설계입니다.Also applies to: 50-54
src/main/java/com/debatetimer/repository/poll/VoteRepository.java (1)
7-10: 깔끔한 리포지토리 인터페이스 구현Spring Data JPA 규칙을 잘 따르고 있으며, 메서드 명명 규칙도 적절합니다.
findAllByPollId메서드는 자동으로 구현되어 특정 투표에 속한 모든 투표 엔티티를 조회할 수 있습니다.src/main/java/com/debatetimer/repository/poll/PollRepository.java (1)
7-10: 보안을 고려한 우수한 리포지토리 설계
findByIdAndMemberId메서드는 투표 ID와 회원 ID를 함께 검증하여 접근 제어를 강화하는 좋은 설계입니다.Optional반환 타입 사용으로 null 안전성도 확보했습니다.src/main/java/com/debatetimer/domain/poll/ParticipateCode.java (1)
7-15: 우수한 값 객체 설계불변성을 보장하고 생성자에서 유효성 검증을 수행하는 도메인 모델링 모범 사례를 잘 따르고 있습니다. 적절한 예외 처리와 함께 깔끔한 구현입니다.
src/main/java/com/debatetimer/dto/poll/response/PollCreateResponse.java (1)
5-10: 깔끔한 DTO 설계입니다.Record 타입을 사용한 불변 DTO와 도메인 객체로부터 편리하게 생성할 수 있는 생성자가 잘 구현되어 있습니다. API 응답용 DTO로서 적절한 설계입니다.
src/main/java/com/debatetimer/domain/poll/ParticipantName.java (1)
7-22: 적절한 값 객체(Value Object) 구현입니다.참가자 이름의 유효성 검증을 생성자에서 수행하고, 불변성을 보장하는 설계가 잘 되어 있습니다. ParticipateCode와 동일한 패턴을 따라 일관성도 좋습니다.
src/main/java/com/debatetimer/domain/poll/VoteInfo.java (1)
5-19: 투표 집계 정보를 잘 표현한 도메인 객체입니다.불변 설계와 생성자에서 총 투표 수를 계산하는 로직이 명확하고 적절합니다. 투표 통계 정보를 캡슐화하는 용도로 잘 설계되었습니다.
src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java (1)
51-57: 투표 기능을 위한 적절한 에러 코드 추가입니다.새로 추가된 에러 코드들이 적절한 HTTP 상태 코드와 명확한 한국어 오류 메시지를 가지고 있으며, 기존 패턴과 일관성을 유지하고 있습니다. 투표 참가자 검증과 투표 조회 실패에 대한 적절한 에러 처리를 지원합니다.
src/test/java/com/debatetimer/service/BaseServiceTest.java (1)
8-9: 테스트 인프라 확장이 적절합니다.투표 기능 테스트를 위한 PollRepository, PollGenerator, VoteGenerator가 기존 패턴과 일관성 있게 추가되었습니다. 새로운 투표 관련 기능 테스트를 위한 필수 의존성들이 잘 구성되어 있습니다.
Also applies to: 14-14, 37-39, 52-57
src/main/java/com/debatetimer/entity/poll/VoteEntity.java (2)
23-26: Lombok 어노테이션 추가가 적절합니다.
@Getter와@AllArgsConstructor추가로 코드 간소화가 잘 이루어졌습니다. 점진적 개발 방식에 맞게 필요한 기능만 추가한 점이 좋습니다.
48-50: 도메인 변환 메서드 구현이 올바릅니다.
toDomain()메서드가 엔티티를 도메인 객체로 올바르게 변환하고 있습니다.poll.getId()를 통해 연관된 Poll의 ID를 추출하는 방식도 적절합니다.src/test/java/com/debatetimer/domain/poll/ParticipantNameTest.java (1)
14-25: 검증 테스트가 포괄적이고 적절합니다.매개변수화된 테스트를 사용하여 null, 빈 문자열, 공백 문자열에 대한 검증을 모두 다루고 있습니다. 예외 타입과 메시지 검증도 정확합니다.
src/test/java/com/debatetimer/domain/poll/ParticipateCodeTest.java (1)
14-25: 일관된 테스트 패턴으로 잘 구현되었습니다.
ParticipantNameTest와 동일한 구조로 일관성이 있고,INVALID_POLL_PARTICIPANT_CODE에러 코드를 올바르게 사용하고 있습니다.src/main/java/com/debatetimer/domain/poll/Vote.java (2)
6-14: 불변 도메인 객체 설계가 우수합니다.모든 필드를
final로 선언하여 불변성을 보장하고,ParticipantName과ParticipateCode값 객체를 사용하여 도메인 규칙이 잘 캡슐화되어 있습니다.
16-18: 편의 생성자가 올바르게 구현되었습니다.String 매개변수를 받아 값 객체로 변환하는 편의 생성자가 주 생성자에 올바르게 위임하고 있습니다. 이는 엔티티에서 도메인 객체로 변환할 때 유용합니다.
src/test/java/com/debatetimer/fixture/VoteGenerator.java (2)
10-17: 테스트 픽스처 설계가 적절합니다.Spring 컴포넌트로 구현하여 의존성 주입을 활용하고, 생성자 주입 방식을 사용한 점이 좋습니다.
19-22: UUID를 참여 코드로 사용하는 것이 적절합니다.
UUID.randomUUID().toString()을 사용하여 고유한 참여 코드를 생성하는 방식이 테스트 환경에서 충돌을 방지하는 좋은 접근법입니다.src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java (1)
1-31: 코드 구조와 집계 로직이 잘 구현되었습니다.도메인 저장소 패턴을 적절히 활용하여 투표 정보 집계 기능을 깔끔하게 구현했습니다. 스트림 API를 사용한 집계 로직도 효율적입니다.
src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java (1)
17-44: 테스트 구조가 잘 정리되어 있습니다.중첩 클래스를 활용한 테스트 그룹화와 fixture generator를 사용한 테스트 데이터 생성이 적절합니다. assertAll을 사용한 다중 검증도 효과적입니다.
src/main/java/com/debatetimer/dto/poll/response/PollInfoResponse.java (2)
7-28: Record를 활용한 깔끔한 DTO 설계입니다.불변 데이터 클래스로 적절하게 설계되었고, 도메인 객체에서 DTO로의 변환 로직도 명확합니다. 편의 생성자를 통한 객체 생성 방식도 효율적입니다.
17-27: PollInfoResponse에 agenda 필드 누락 확인 필요
- com.debatetimer.domain.poll.Poll 클래스에
· private final Agenda agenda;
· @Getter로 getAgenda() 자동 생성됨- com.debatetimer.dto.poll.response.PollInfoResponse record 선언부에 agenda 관련 필드·생성자 파라미터가 없음
- agenda 값을 포함하려면
- record 정의에
String agenda추가- 레코드 보조 생성자에서
poll.getAgenda().getValue()전달- PollService, PollController, JSON 매핑 스펙 업데이트
- PollServiceTest, PollControllerTest, PollDocumentTest 등 테스트 코드 수정 필요
- agenda 제외가 의도된 설계인지 확인 부탁드립니다.
src/test/java/com/debatetimer/fixture/PollGenerator.java (1)
10-31: 테스트 픽스처로서 적절한 구현입니다.VoteGenerator와 일관된 패턴으로 구현되었고, 테스트 데이터 생성 목적에 부합합니다. Spring 컴포넌트로 등록하여 재사용성도 확보했습니다.
src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java (1)
13-31: 도메인 저장소 테스트를 위한 잘 구성된 기본 클래스입니다.BaseServiceTest와 일관된 패턴으로 구현되었고, 웹 환경을 제외하여 테스트 성능을 최적화했습니다. DataBaseCleaner를 통한 테스트 격리도 적절합니다.
src/main/java/com/debatetimer/entity/poll/PollEntity.java (6)
3-3: 도메인 객체 import 추가 확인Poll 도메인 객체를 import하여 엔티티-도메인 간 변환을 위한 준비가 완료되었습니다.
6-6: JPA 어노테이션과 Lombok 설정 확인@column 어노테이션과 @Getter 어노테이션이 적절히 추가되어 필드 매핑과 접근성이 개선되었습니다.
Also applies to: 17-17, 21-21
30-34: 데이터베이스 컬럼명 명시적 매핑 개선tableId와 memberId 필드에 @column 어노테이션으로 데이터베이스 컬럼명을 명시적으로 매핑한 것이 좋습니다. 이는 코드의 가독성과 유지보수성을 향상시킵니다.
48-56: 도메인 객체로부터 엔티티 생성 생성자 구현Poll 도메인 객체로부터 PollEntity를 생성하는 생성자가 잘 구현되었습니다. 도메인의 값 객체(TeamName, Agenda)에서 실제 값을 추출하여 엔티티 필드에 할당하는 방식이 적절합니다.
58-60: 상태 변경 메서드 캡슐화updateToDone() 메서드를 통해 Poll 상태를 DONE으로 변경하는 로직이 엔티티 내부에 캡슐화되어 있어 좋습니다. 이는 도메인 로직의 응집성을 높입니다.
62-64: 엔티티에서 도메인 객체로의 변환 메서드toDomain() 메서드가 엔티티를 도메인 객체로 변환하는 역할을 적절히 수행합니다. Poll 도메인 객체의 생성자를 활용하여 문자열 값들을 값 객체로 자동 변환하는 방식이 효율적입니다.
src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java (5)
1-16: 도메인 리포지토리 클래스 구조 설정패키지 구조와 필요한 의존성 import가 적절히 구성되었습니다. @repository와 @requiredargsconstructor 어노테이션을 통한 Spring 빈 등록과 의존성 주입 설정이 올바릅니다.
18-23: Poll 생성 메서드 구현create 메서드가 도메인 객체를 엔티티로 변환하여 저장 후 다시 도메인 객체로 반환하는 패턴이 일관되게 적용되었습니다. @transactional 어노테이션으로 트랜잭션 관리도 적절합니다.
25-29: Poll 조회 메서드 구현getByIdAndMemberId 메서드에 @transactional(readOnly = true)를 사용하여 읽기 전용 트랜잭션으로 최적화한 것이 좋습니다. findPoll 헬퍼 메서드를 활용하여 코드 중복을 방지한 점도 훌륭합니다.
31-36: Poll 상태 업데이트 메서드 구현updateToDone 메서드가 엔티티의 updateToDone() 메서드를 호출하여 상태를 변경하는 방식이 도메인 로직 캡슐화 원칙에 부합합니다. 변경된 엔티티를 도메인 객체로 반환하는 것도 적절합니다.
38-41: 예외 처리를 위한 헬퍼 메서드findPoll 헬퍼 메서드가 코드 중복을 줄이고 일관된 예외 처리를 제공합니다. POLL_NOT_FOUND 에러 코드를 사용한 예외 처리가 명확합니다.
src/test/java/com/debatetimer/service/poll/PollServiceTest.java (3)
1-22: 테스트 클래스 구조 설정필요한 import와 테스트 클래스 구조가 적절히 설정되었습니다. BaseServiceTest를 상속받아 공통 테스트 설정을 활용하고, @Autowired로 테스트 대상 서비스를 주입받는 방식이 올바릅니다.
39-63: Poll 정보 조회 테스트선거 정보 조회 테스트가 매우 포괄적으로 구현되었습니다. 투표 데이터 설정부터 응답의 모든 필드 검증까지 완전히 다루고 있어 훌륭합니다. assertAll을 사용하여 여러 assertion을 그룹화한 것도 좋습니다.
65-78: Poll 상태 업데이트 테스트선거 완료 상태 변경 테스트가 핵심 동작을 적절히 검증합니다. 상태 변경 전후를 명확히 구분하여 테스트하는 것이 좋습니다.
src/main/java/com/debatetimer/controller/poll/PollController.java (4)
1-21: 컨트롤러 클래스 구조 설정필요한 import와 어노테이션이 적절히 구성되었습니다. @RestController와 @requiredargsconstructor를 통한 설정이 Spring Boot 모범 사례를 따르고 있습니다.
23-30: Poll 생성 엔드포인트POST /api/polls/{tableId} 엔드포인트가 RESTful 설계 원칙에 부합합니다. HTTP 201 Created 상태 코드 사용이 적절하고, @AuthMember를 통한 인증 처리도 올바릅니다.
32-39: Poll 정보 조회 엔드포인트GET /api/polls/{pollId} 엔드포인트가 리소스 조회에 적합한 설계입니다. HTTP 200 OK 상태 코드 사용이 적절합니다.
41-48: Poll 상태 업데이트 엔드포인트PATCH /api/polls/{pollId} 엔드포인트가 부분 업데이트에 적합한 HTTP 메서드를 사용했습니다. 상태 변경이라는 특정 작업에 맞는 의미론적 설계가 잘 되어있습니다.
src/test/java/com/debatetimer/controller/poll/PollControllerTest.java (3)
1-19: 컨트롤러 테스트 클래스 구조필요한 import와 BaseControllerTest 상속이 적절히 설정되었습니다. RestAssured와 AssertJ를 활용한 테스트 환경 구성이 좋습니다.
39-70: Poll 정보 조회 API 테스트선거 정보 조회 API 테스트가 매우 포괄적으로 구현되었습니다. 투표 데이터 설정, HTTP 요청, 응답 검증까지 모든 단계가 완벽하게 다뤄졌습니다. assertAll을 사용한 다중 assertion도 훌륭합니다.
72-93: Poll 상태 업데이트 API 테스트선거 완료 상태 변경 API 테스트가 핵심 기능을 적절히 검증합니다. PATCH 요청과 응답 상태 확인이 올바르게 구현되었습니다.
src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java (2)
25-35: 투표 생성 테스트가 잘 구현되었습니다.도메인 객체 생성 후 영속성 확인이 적절하게 이루어지고 있습니다. 테스트 로직이 명확하고 검증도 충분합니다.
55-64: 투표 상태 업데이트 테스트가 적절합니다.상태 변경 로직이 올바르게 테스트되고 있으며, 반환된 도메인 객체의 상태를 적절히 검증하고 있습니다.
src/test/java/com/debatetimer/controller/poll/PollDocumentTest.java (2)
45-61: 투표 생성 API 문서화 테스트가 잘 구성되어 있습니다.요청 헤더, 경로 파라미터, 응답 필드에 대한 문서화가 적절하고, 테스트 시나리오도 명확합니다.
88-112: 투표 정보 조회 API 문서화가 포괄적입니다.모든 응답 필드에 대한 설명이 잘 되어 있고, 투표 상태에 대한 설명도 명확합니다.
src/main/java/com/debatetimer/service/poll/PollService.java (4)
1-16: 패키지 구조와 임포트가 잘 정리되어 있습니다.임포트가 논리적으로 그룹화되어 있고 불필요한 임포트가 없어 보입니다.
17-24: 서비스 클래스 구조가 적절합니다.Spring 어노테이션과 의존성 주입이 올바르게 구성되어 있습니다.
34-39: 읽기 전용 메서드가 적절하게 구현되었습니다.
@Transactional(readOnly = true)어노테이션이 올바르게 적용되어 있고, 비즈니스 로직이 간결합니다.
25-32: Poll 생성 시 null ID 전달은 의도된 동작입니다.도메인
Poll클래스의id필드는Long타입의 최종 필드로, 영속화 레이어(JPA 등)에서 식별자를 생성하도록 설계되어 있습니다. 따라서 서비스 계층에서 새Poll객체를 생성할 때null을 넘겨 초기화하는 것은 정상적인 흐름입니다.
- 추가 개선(선택 사항):
null전달을 숨기고 가독성을 높이기 위해Poll.createNew(…)같은 정적 팩토리 메서드를 도입할 수 있습니다.
| ALTER TABLE poll | ||
| ADD COLUMN member_id BIGINT NOT NULL |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
기존 데이터가 있는 테이블에 NOT NULL 컬럼 추가 시 주의 필요
기존 poll 테이블에 데이터가 있다면 NOT NULL 제약조건이 있는 member_id 컬럼을 추가할 때 마이그레이션이 실패할 수 있습니다. 기존 데이터 처리를 위한 전략이 필요합니다.
다음 중 하나의 방법을 고려해보세요:
- 기본값을 설정한 후 별도 마이그레이션에서 실제 값으로 업데이트
- 기존 데이터가 없음을 확신할 수 있는 경우 현재 방식 유지
기존 poll 테이블에 데이터가 있는지 확인하는 스크립트를 실행해보겠습니다:
🏁 Script executed:
#!/bin/bash
# Description: Check if there are existing records in poll table by looking at previous migrations
# Expected: Find references to poll table creation and any existing data
# Search for poll table creation and any INSERT statements
rg -A 5 -B 5 "CREATE TABLE.*poll|INSERT INTO.*poll" --type sqlLength of output: 675
기존 데이터가 있는 테이블에 NOT NULL 컬럼 추가 시 데이터 백필 전략 필요
V9 마이그레이션(V9__create_poll_and_vote_table.sql)에서는 poll 테이블만 생성되고 INSERT 구문은 없습니다. 운영 중인 DB에 기존 레코드가 있을 경우, member_id BIGINT NOT NULL 컬럼 추가 시 마이그레이션이 실패할 수 있습니다.
다음 중 하나를 적용해 주세요:
- 컬럼을 NULL 허용으로 추가
기존 레코드에 적절한 값 배정
ALTER TABLE poll ADD COLUMN member_id BIGINT;
NOT NULL 제약조건 추가UPDATE poll SET member_id = /* 기본 member ID */;
ALTER TABLE poll ALTER COLUMN member_id SET NOT NULL;
NOT NULL DEFAULT옵션으로 추가 후 기본값으로 백필, 이후 DEFAULT 제거ALTER TABLE poll ADD COLUMN member_id BIGINT NOT NULL DEFAULT /*기본값*/; ALTER TABLE poll ALTER COLUMN member_id DROP DEFAULT;
- 운영 DB에 레코드가 전혀 없음을 확신할 경우 현 방식 유지
파일: src/main/resources/db/migration/V11__add_memberId_into_poll.sql
🤖 Prompt for AI Agents
In src/main/resources/db/migration/V11__add_memberId_into_poll.sql at lines 1-2,
adding a NOT NULL column member_id directly to the poll table can cause
migration failures if existing data is present. To fix this, either add the
column as nullable first, update existing rows with appropriate member_id
values, then set the column to NOT NULL; or add the column with NOT NULL and a
DEFAULT value to backfill existing rows, then drop the DEFAULT constraint;
alternatively, keep the current approach only if you are certain the table has
no existing records.
There was a problem hiding this comment.
운영중인 DB에 아직 포함안되어서 괜찮아
There was a problem hiding this comment.
@coli-geonwoo 알겠습니다! 운영 DB에 아직 poll 테이블 데이터가 없다면 현재 마이그레이션 방식이 안전합니다. 감사합니다.
(\ /)
( ._. )
o_("_")("_")
understanding nod
✏️ Learnings added
Learnt from: coli-geonwoo
PR: debate-timer/debate-timer-be#203
File: src/main/resources/db/migration/V11__add_memberId_into_poll.sql:1-2
Timestamp: 2025-07-24T03:12:25.193Z
Learning: debate-timer 프로젝트에서 poll 관련 테이블들은 아직 운영 환경에 배포되지 않았으므로, NOT NULL 컬럼 추가 시 기존 데이터 백필 전략을 고려할 필요가 없음.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
leegwichan
left a comment
There was a problem hiding this comment.
/noti @coli-geonwoo
코멘트 많이 달긴 달았는데, 구조적인 문제보다는 저와 다른 사소한 네이밍 이슈가 많은 것 같아요! 반영은 금방 끝날테니 코멘트 많이 달았다고 뭐라하지 마십쇼.
콜리 고생했고~ 추가적인 의견 있으면 더 남겨주세요!
| @Transactional | ||
| public Poll updateToDone(long pollId, long memberId) { | ||
| PollEntity pollEntity = findPoll(pollId, memberId); | ||
| pollEntity.updateToDone(); | ||
| return pollEntity.toDomain(); | ||
| } |
There was a problem hiding this comment.
updateToDone()은 너무 내부 구현 노출하는 것 같은데, finishPoll() 정도는 어떨까요?
There was a problem hiding this comment.
✅ 반영완료
사실 그 네이밍이 더 좋기는 해요. 저도 추상화 준위 신경을 쓰는 편이라.
그런데 궁금한점은 예전에 debate api 만들 때 커찬이 updateXXX를 썼던 기억이 있어서요. 그때 아무래도 내부 변경에 대한 트래킹을 쉽게 하기 위해 해당 네이밍을 썼다고 한걸로 기억하는데, 이번 케이스는 다른 기준을 제시하는 이유가 있는지 궁금해요.
There was a problem hiding this comment.
만약에 특정 필드 값등을 바꾸는 것이라면 updateXXX() 라는 용어를 사용할 것 같은데, 도메인 로직이라면 그렇게 사용하지 않을 것 같아요.
해당 업데이트 로직은 Entity에 있는 것은 맞지만 도메인 로직이라고 생각해요. 그래서 finishPoll()을 말씀드렸습니다.
만약에 도메인 로직으로 변경하고 싶다면 아래와 같은 방법도 있겠죠.
// PollService
public finishPoll(long pollId) {
Poll poll = pollDomainRepository.getById(long pollId);
poll.finishPoll();
pollDomainRepository.update(poll); // pollDomainRepository에서 Entity를 조회해서 값을 바꿔 놓기
}
src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java
Outdated
Show resolved
Hide resolved
src/main/java/com/debatetimer/dto/poll/response/PollCreateResponse.java
Outdated
Show resolved
Hide resolved
| @Test | ||
| void 선거를_생성할_수_있다() { | ||
| Member member = memberGenerator.generate("email@email.com"); | ||
| CustomizeTableEntity table = customizeTableGenerator.generate(member); | ||
| Headers headers = headerGenerator.generateAccessTokenHeader(member); | ||
|
|
||
| given() | ||
| .contentType(ContentType.JSON) | ||
| .headers(headers) | ||
| .pathParam("tableId", table.getId()) | ||
| .when().post("/api/polls/{tableId}") | ||
| .then().statusCode(HttpStatus.CREATED.value()); | ||
| } |
There was a problem hiding this comment.
- 아래와 같이 안한 이유가 있나요? (아래 코드가 마음에 든다면, 다른 PollControllerTest, PollDocumentTest 에 반영 부탁드립니다)
| @Test | |
| void 선거를_생성할_수_있다() { | |
| Member member = memberGenerator.generate("email@email.com"); | |
| CustomizeTableEntity table = customizeTableGenerator.generate(member); | |
| Headers headers = headerGenerator.generateAccessTokenHeader(member); | |
| given() | |
| .contentType(ContentType.JSON) | |
| .headers(headers) | |
| .pathParam("tableId", table.getId()) | |
| .when().post("/api/polls/{tableId}") | |
| .then().statusCode(HttpStatus.CREATED.value()); | |
| } | |
| @Test | |
| void 선거를_생성할_수_있다() { | |
| Member member = memberGenerator.generate("email@email.com"); | |
| CustomizeTableEntity table = customizeTableGenerator.generate(member); | |
| given() | |
| .contentType(ContentType.JSON) | |
| .header(HttpHeaders.AUTHORIZATION, accessToken()) | |
| .pathParam("tableId", table.getId()) | |
| .when().post("/api/polls/{tableId}") | |
| .then().statusCode(HttpStatus.CREATED.value()); | |
| } |
There was a problem hiding this comment.
[의견]
이건 일단 보류, CustomizeControllerTest에서 작성한 방식으로 맞춘거라 만약 필요하다면 전부 개선할 필요가 있음
- 헤더에 넣는 값을 명확히 한다는 점에서 좋으나,
- 반복되는 코드를 감추려고 headerGenerator를 쓰는 거고 의미상으로 안읽히진 않아서 지금도 나쁘지 않다고 생각
src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java
Show resolved
Hide resolved
| @Nested | ||
| class CRUDTest { | ||
|
|
There was a problem hiding this comment.
Hey Man 이거 클래스 이름을 메서드 이름으로 통일하기로 했던 것 같은데?
| @Component | ||
| public class VoteGenerator { | ||
|
|
||
| private final VoteRepository voteRepository; | ||
|
|
||
| public VoteGenerator(VoteRepository voteRepository) { | ||
| this.voteRepository = voteRepository; | ||
| } |
There was a problem hiding this comment.
[나중에 제안] Generator 이름들을 전부 XXXEntityGenerator로 바꿔야 하나 생각중...
이번 PR에 반영하면 사이즈가 너무 커지니까, 의견만 달아주세요!
There was a problem hiding this comment.
저장된 객체를 반환한다는 점에서 그게 좋을 것 같긴 해요.
| Optional<PollEntity> findByIdAndMemberId(long id, long memberId); | ||
|
|
| @ParameterizedTest | ||
| @NullAndEmptySource | ||
| @ValueSource(strings = {" ", " "}) | ||
| void 투표참여자_이름은_널이거나_빈_값_일_수_없다(String name) { |
There was a problem hiding this comment.
이거 제가 만든 @NullAndEmptyAndBlankSource를 안쓴 이유가 있나요?
There was a problem hiding this comment.
✅ 반영 완료
좋은 걸 만들어놓으셨군요
| @ParameterizedTest | ||
| @NullAndEmptySource | ||
| @ValueSource(strings = {" ", " "}) | ||
| void 투표_참여_코드는_널이거나_빈_값_일_수_없다(String participatecode) { | ||
| assertThatThrownBy(() -> new ParticipateCode(participatecode)) | ||
| .isInstanceOf(DTClientErrorException.class) | ||
| .hasMessage(ClientErrorCode.INVALID_POLL_PARTICIPANT_CODE.getMessage()); | ||
| } |
| private final long totalCount; | ||
| private final long prosCount; | ||
| private final long consCount; |
There was a problem hiding this comment.
여기는 서비스에서 검증해서 따로 검증로직이 없는 건가요?
There was a problem hiding this comment.
[질문 ✋ ]
음.. 검증로직을 원래 넣었었는데 서로 시각이 다른 부분이 있을 것 같아 비토랑 커찬 시각이 궁금하네요.
해당 count 값은 애플리케이션 서버 로직 내에서 완전히 통제되는 값이에요. 즉, 외부 변인에 의해 수정될 여지가 크게 없다고 판단했어요.
또, 만약 검증로직을 넣는다면 ClientError인지, Server Error로 처리해야할지가 애매했습니다.
- 검증로직 필요하다고 보는가?
- 만약 양수 검증을 한다면 Server Error인가, Client Error인가?
There was a problem hiding this comment.
저는 "DB에 있는 값을 보여주기 위한 객체"에는 유효성 검사를 잘 안하는 것 같아요.차라리 동작 안하는 것보다는 뭐라도 어떻게는 동작하게 하자는 느낌?
만약에 이 객체가 유저가 입력을 위한 객체로도 쓰인다고 하면, 그 때 추가하지 않을까 싶네요.
There was a problem hiding this comment.
개인적으로 저는 넣는 편이긴 합니다. 다만 그 검증은 사용자에게 보여주기보단 다른 개발자의 실수 방지 용도에 더 가깝긴 할 것 같아요.
There was a problem hiding this comment.
일단 voter api를 만들기 위해 놔두겠습니다. 백엔드 회의 때 논의해보시죵
|
/noti 리뷰 반영했으니 한번 확인 부탁합니다 |
leegwichan
left a comment
There was a problem hiding this comment.
/noti @coli-geonwoo
미안해요. 심신미약 상태라 리뷰해야된다는 사실을 까먹었네요;; 모든 내용 전반적으로 반영해줘서 고맙고 Approve 누르겠습니다!
unifolio0
left a comment
There was a problem hiding this comment.
/noti
@coli-geonwoo
리뷰 2개 남겼어요~
| private final long totalCount; | ||
| private final long prosCount; | ||
| private final long consCount; |
There was a problem hiding this comment.
개인적으로 저는 넣는 편이긴 합니다. 다만 그 검증은 사용자에게 보여주기보단 다른 개발자의 실수 방지 용도에 더 가깝긴 할 것 같아요.
| void 선거를_생성한다() { | ||
| Member member = memberGenerator.generate("email@email.com"); | ||
| CustomizeTableEntity table = customizeTableGenerator.generate(member); | ||
| Poll poll = new Poll(null, table.getId(), member.getId(), PollStatus.PROGRESS, "찬성", "반대", "주제"); |
There was a problem hiding this comment.
여기에는 null이 안들어가는 생성자를 안쓴 이유가 있나요?
There was a problem hiding this comment.
나중에 추가된 거라 test까지 신경 못썼어요 비꼼(비토 꼼꼼이라는 뜻) 👍
coli-geonwoo
left a comment
There was a problem hiding this comment.
/noti
비토 리뷰까지 반영해서 merge 하겠습니다~
몇가지 논의할 부분은 커찬이 파놓은 회의록에 정리해놓았어요!
| private final long totalCount; | ||
| private final long prosCount; | ||
| private final long consCount; |
There was a problem hiding this comment.
일단 voter api를 만들기 위해 놔두겠습니다. 백엔드 회의 때 논의해보시죵
| void 선거를_생성한다() { | ||
| Member member = memberGenerator.generate("email@email.com"); | ||
| CustomizeTableEntity table = customizeTableGenerator.generate(member); | ||
| Poll poll = new Poll(null, table.getId(), member.getId(), PollStatus.PROGRESS, "찬성", "반대", "주제"); |
There was a problem hiding this comment.
나중에 추가된 거라 test까지 신경 못썼어요 비꼼(비토 꼼꼼이라는 뜻) 👍
🚩 연관 이슈
closed #199
🗣️ 리뷰 요구사항 (선택)
관련 API 스펙은 다음 노션 링크를 참고하세요
Summary by CodeRabbit
신규 기능
버그 수정
문서화
테스트
기타