-
Notifications
You must be signed in to change notification settings - Fork 2
feat: 이벤트 참여 신청 폼 제출 API 구현 #1199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 이벤트 참여 신청 폼 제출 API 구현 #1199
Conversation
📝 WalkthroughWalkthrough사용자용 이벤트 참여 신청 API가 추가되었고, 이를 처리하는 서비스 로직이 도입되었습니다. 관리자 수동 신청 관련 DTO가 ManualApplyRequest로 명시적으로 개명되며, 관련 컨트롤러/서비스 메서드 시그니처가 변경되었습니다. 신규 EventApplyRequest DTO가 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as User (Participant)
participant API as ParticipantEventParticipationController
participant SVC as EventParticipationService
participant Repo as EventRepository
participant MRepo as MemberRepository
participant Domain as EventParticipationDomainService
participant PRepo as EventParticipationRepository
User->>API: POST /event-participations/apply<br/>body: EventApplyRequest
API->>SVC: applyEventParticipation(request)
SVC->>Repo: findById(request.eventId)
Repo-->>SVC: Event
SVC->>MRepo: findByStudentId(request.participant.studentId)
alt 회원 존재 & 기본정보 충족
SVC->>Domain: applyEventForRegistered(member, afterPartyStatus, now)
else 비회원 또는 정보 미충족
SVC->>Domain: applyEventForUnregistered(participant, afterPartyStatus, now)
end
Domain-->>SVC: EventParticipation
SVC->>PRepo: save(EventParticipation)
PRepo-->>SVC: saved
SVC-->>API: void
API-->>User: 200 OK
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Pre-merge checks (2 passed, 2 warnings, 1 inconclusive)❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✨ 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. Comment |
Job Summary for GradleCheck Style and Test to Develop :: build-test
|
Job Summary for GradleCheck Style and Test to Develop :: build-test
|
Job Summary for GradleCheck Style and Test to Develop :: build-test
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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/gdschongik/gdsc/domain/event/application/EventParticipationService.java (2)
220-235: 비회원 수동 신청: participant null 시 NPE
request.participant().getStudentId()접근 전 null 가능성이 있습니다. DTO에@NotNull/@Valid추가(별도 코멘트)로 해결하거나, 서비스단 방어 로직을 추가해 주세요.
231-234: 로그에 PII 전체 노출 위험
participant={}는 개인정보 전체가 로그에 남을 수 있습니다. 식별 최소 정보(예: studentId)만 로그로 남기세요.적용 diff:
- log.info( - "[EventParticipationService] 행사 수동 신청 (비회원): eventId={}, participant={}", - request.eventId(), - request.participant()); + log.info( + "[EventParticipationService] 행사 수동 신청 (비회원): eventId={}, participantStudentId={}", + request.eventId(), + request.participant().getStudentId());
🧹 Nitpick comments (4)
src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventUnregisteredManualApplyRequest.java (1)
7-7: 요청 DTO에서 도메인 타입 직접 노출 자제 권장
Participant(domain)를 요청 모델로 직접 받으면 도메인 규칙/필드가 외부 입력에 노출됩니다. 전용ParticipantRequestDTO를 두고, Service/Domain에서 변환하는 구조를 고려해 주세요.src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventApplyRequest.java (1)
8-11: 요청 DTO에서 도메인 타입 직접 사용
Participant를 그대로 받기보다ParticipantRequest로 분리 후 Domain 변환을 권장합니다. 외부 입력에 안전합니다.src/main/java/com/gdschongik/gdsc/domain/event/api/ParticipantEventParticipationController.java (1)
23-28: 생성성 작업에는 201 Created가 더 적합리소스 생성 의미라면 200 OK 대신 201 Created(또는 204 No Content) 반환을 고려해 주세요.
적용 diff:
- return ResponseEntity.ok().build(); + return ResponseEntity.status(HttpStatus.CREATED).build();추가 import:
import org.springframework.http.HttpStatus;src/main/java/com/gdschongik/gdsc/domain/event/application/EventParticipationService.java (1)
4-4: static import 와일드카드 사용 지양
now()만 쓰이므로 와일드카드 대신 명시적 import가 깔끔합니다.적용 diff:
-import static java.time.LocalDateTime.*; +import static java.time.LocalDateTime.now;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/com/gdschongik/gdsc/domain/event/api/AdminEventParticipationController.java(3 hunks)src/main/java/com/gdschongik/gdsc/domain/event/api/ParticipantEventParticipationController.java(1 hunks)src/main/java/com/gdschongik/gdsc/domain/event/application/EventParticipationService.java(5 hunks)src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventApplyRequest.java(1 hunks)src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventRegisteredManualApplyRequest.java(1 hunks)src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventUnregisteredManualApplyRequest.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventApplyRequest.java (1)
src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventUnregisteredApplyRequest.java (1)
EventUnregisteredApplyRequest(7-7)
⏰ 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)
- GitHub Check: build-test
🔇 Additional comments (5)
src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventRegisteredManualApplyRequest.java (1)
6-6: 리네임 및 제약 조건 적절수동 신청 DTO 네이밍 일관성 좋아요. 필드 제약도 합리적입니다.
src/main/java/com/gdschongik/gdsc/domain/event/api/ParticipantEventParticipationController.java (1)
23-28: EventParticipation 엔티티에 DB 중복 제약 존재 확인
EventParticipation엔티티의@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"event_id","member_id"})})로 동일 참가자의 중복 신청이 DB 레벨에서 방지됩니다.src/main/java/com/gdschongik/gdsc/domain/event/api/AdminEventParticipationController.java (3)
126-127: 리네이밍 반영 OK (회원 수동 신청)시그니처/타입 교체 적절합니다.
136-137: 리네이밍 반영 OK (비회원 수동 신청)시그니처/타입 교체 적절합니다.
10-11: 구 DTO 참조 제거 확인됨
실행한rg검색 결과EventRegisteredApplyRequest/EventUnregisteredApplyRequest에 대한 참조가 전혀 발견되지 않았습니다.
| public void applyEventParticipation(EventApplyRequest request) { | ||
| Event event = | ||
| eventRepository.findById(request.eventId()).orElseThrow(() -> new CustomException(EVENT_NOT_FOUND)); | ||
|
|
||
| Participant participant = request.participant(); | ||
| Optional<Member> optionalMember = memberRepository.findByStudentId(participant.getStudentId()); | ||
|
|
||
| EventParticipation eventParticipation; | ||
| if (optionalMember.isPresent() | ||
| && optionalMember.get().getAssociateRequirement().isInfoSatisfied()) { | ||
| eventParticipation = eventParticipationDomainService.applyEventForRegistered( | ||
| optionalMember.get(), request.afterPartyApplicationStatus(), event, now()); | ||
| } else { | ||
| eventParticipation = eventParticipationDomainService.applyEventForUnregistered( | ||
| participant, request.afterPartyApplicationStatus(), event, now()); | ||
| } | ||
| eventParticipationRepository.save(eventParticipation); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
신규 신청: participant 필드 null 처리 필요
participant가 null이면 member 조회/로그에서 NPE 발생합니다. EventApplyRequest.participant에 @NotNull/@Valid 추가(별도 코멘트)를 반영해 주세요.
🤖 Prompt for AI Agents
In
src/main/java/com/gdschongik/gdsc/domain/event/application/EventParticipationService.java
around lines 281 to 297, the code assumes request.participant() is non-null and
can NPE; add an explicit null check at the start of applyEventParticipation and
if participant is null throw a suitable CustomException (e.g., CUSTOM_ERROR_CODE
for invalid request or participant missing) before any memberRepository lookup
or logging, and optionally log a clear message about the missing participant;
this prevents NPEs and keeps validation defense-in-depth until @NotNull/@Valid
is enforced on the DTO.
| public record EventApplyRequest( | ||
| @NotNull @Positive Long eventId, | ||
| Participant participant, | ||
| @NotNull AfterPartyApplicationStatus afterPartyApplicationStatus) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
participant에 @NotNull/@Valid 누락 → 신규 신청 플로우에서도 NPE 가능
applyEventParticipation에서 request.participant().getStudentId()를 사용하므로 null 입력 시 NPE가 납니다. 필드에 @NotNull과 @Valid를 추가해 주세요.
적용 diff:
-public record EventApplyRequest(
- @NotNull @Positive Long eventId,
- Participant participant,
- @NotNull AfterPartyApplicationStatus afterPartyApplicationStatus) {}
+public record EventApplyRequest(
+ @NotNull @Positive Long eventId,
+ @NotNull @Valid Participant participant,
+ @NotNull AfterPartyApplicationStatus afterPartyApplicationStatus) {}추가 import:
import jakarta.validation.Valid;🤖 Prompt for AI Agents
In
src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventApplyRequest.java
around lines 8 to 11, the participant field is missing @NotNull and @Valid which
allows nulls and can cause an NPE when calling
request.participant().getStudentId(); add the annotations to the participant
parameter (annotate it with @NotNull @Valid) and add the import statement import
jakarta.validation.Valid; so the record becomes public record
EventApplyRequest(@NotNull @Positive Long eventId, @NotNull @Valid Participant
participant, @NotNull AfterPartyApplicationStatus afterPartyApplicationStatus)
{} ensuring validation prevents null participant values.
| import jakarta.validation.constraints.Positive; | ||
|
|
||
| public record EventUnregisteredApplyRequest(@NotNull @Positive Long eventId, Participant participant) {} | ||
| public record EventUnregisteredManualApplyRequest(@NotNull @Positive Long eventId, Participant participant) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
participant에 @NotNull/@Valid 누락 → NPE 가능
Service에서 request.participant().getStudentId()를 즉시 호출합니다. participant가 null이면 NPE가 발생합니다. 필드에 @NotNull과 중첩 검증을 위한 @Valid를 추가해 주세요.
적용 diff:
-public record EventUnregisteredManualApplyRequest(@NotNull @Positive Long eventId, Participant participant) {}
+public record EventUnregisteredManualApplyRequest(
+ @NotNull @Positive Long eventId,
+ @NotNull @Valid Participant participant) {}추가 import:
import jakarta.validation.Valid;🤖 Prompt for AI Agents
In
src/main/java/com/gdschongik/gdsc/domain/event/dto/request/EventUnregisteredManualApplyRequest.java
around line 7, the participant field can be null causing an NPE when service
calls request.participant().getStudentId(); add @NotNull and @Valid annotations
to the participant parameter to enforce presence and trigger nested validation,
and add the import jakarta.validation.Valid at the top of the file (keep
existing @NotNull import as-is).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
신청 API 요청에 Participant 그대로 쓸거면, Period처럼 @JsonCreator 추가해야 할 것 같습니다.
이름, 학번, 전화번호에 null 입력해도 그대로 받네요
|
|
||
| public record EventApplyRequest( | ||
| @NotNull @Positive Long eventId, | ||
| Participant participant, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Participant얘는 왜 @NotNull 이 없나요?
제가 놓치고 있는 이유가 있을까요?
uwoobeat
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
🌱 관련 이슈
📌 작업 내용 및 특이사항
📝 참고사항
📚 기타
Summary by CodeRabbit