Skip to content

Conversation

@Sangwook02
Copy link
Member

@Sangwook02 Sangwook02 commented Sep 9, 2025

🌱 관련 이슈

📌 작업 내용 및 특이사항

  • 기존애 현장신청 api에서 사용하던 dto들의 이름을 수정했습니다. 중간에 Manual을 넣어서 구분할 수 있게 했습니다

📝 참고사항

📚 기타

Summary by CodeRabbit

  • 신기능
    • 참가자용 이벤트 신청 API 추가: POST /event-participations/apply. 이벤트 ID와 애프터파티 신청 상태(필수), 참가자 정보(선택)를 받아 유효성 검증 후 신청 처리.
  • 리팩터링
    • 관리자 수동 신청 관련 요청 형식 명칭을 일원화하여 일관성 향상. 외부 연동 시 요청 스키마 이름 변경에 따른 영향 가능성에 유의.

@Sangwook02 Sangwook02 requested a review from a team as a code owner September 9, 2025 13:02
@coderabbitai
Copy link

coderabbitai bot commented Sep 9, 2025

📝 Walkthrough

Walkthrough

사용자용 이벤트 참여 신청 API가 추가되었고, 이를 처리하는 서비스 로직이 도입되었습니다. 관리자 수동 신청 관련 DTO가 ManualApplyRequest로 명시적으로 개명되며, 관련 컨트롤러/서비스 메서드 시그니처가 변경되었습니다. 신규 EventApplyRequest DTO가 추가되었습니다.

Changes

Cohort / File(s) Summary of Changes
Controllers
src/main/java/.../api/AdminEventParticipationController.java, src/main/java/.../api/ParticipantEventParticipationController.java
관리자 수동 신청 메서드 파라미터 DTO를 ManualApplyRequest로 변경. 신규 ParticipantEventParticipationController 추가 및 POST /event-participations/apply 엔드포인트 구현.
Service
src/main/java/.../application/EventParticipationService.java
applyEventParticipation(EventApplyRequest) 신설: 이벤트 로드, 참가자/회원 분기 처리 후 등록/비등록 신청 위임 및 저장. 수동 신청 메서드 파라미터를 ManualApplyRequest로 변경.
DTOs (Add/Rename)
src/main/java/.../dto/request/EventApplyRequest.java, src/main/java/.../dto/request/EventRegisteredManualApplyRequest.java, src/main/java/.../dto/request/EventUnregisteredManualApplyRequest.java
신규 EventApplyRequest 레코드 추가. EventRegisteredApplyRequestEventRegisteredManualApplyRequest로, EventUnregisteredApplyRequestEventUnregisteredManualApplyRequest로 개명(시그니처 유지).

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

토끼는 폼을 톡, 신청을 쏙 넣고
컨트롤러 문 두드려, 서비스로 폴짝!
회원이면 이쪽, 비회원이면 저쪽—분기는 깔끔
매뉴얼 DTO는 새 이름으로 반짝✨
저장 완료! 당근 케이크로 축하해요 🥕🎉

Pre-merge checks (2 passed, 2 warnings, 1 inconclusive)

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning Manual 적용용 DTO 이름 변경은 이벤트 참여 신청 폼 제출 API 구현 이슈의 범위를 벗어난 작업으로 보이며 PR 설명에서도 별도 연관성이 언급되지 않았습니다. 수동 신청 DTO 이름 변경은 별도 PR로 분리하거나 PR 설명에 해당 변경 이유를 명확히 추가하여 범위에 대한 오해를 방지해 주세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ❓ Inconclusive PR 설명이 이슈 닫기(close #1191)만을 언급하고 있으며, 작업 내용 및 특이사항, 참고사항, 기타 섹션에 구체적인 설명이 전혀 포함되어 있지 않아 변경점에 대한 정보를 파악하기 어려워 매우 일반적이고 모호합니다. PR 설명에 추가된 API 엔드포인트와 DTO 이름 변경, 서비스 로직 업데이트 등 주요 변경 사항을 요약하여 구체적으로 작성해 주시고, 각 섹션에 작업 배경과 의도를 명확히 기술해 주세요.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed 현재 제목은 주요 변경사항인 이벤트 참여 신청 폼 제출 API 구현을 명확히 요약하고 있어 PR 내용과 일치합니다.
Linked Issues Check ✅ Passed 코드에 신규 참가 신청 API 엔드포인트와 서비스 로직, DTO가 구현되어 있어 이슈 #1191의 “이벤트 참여 신청 폼 제출 API 구현” 요구사항을 충족합니다.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/1191-event-participation-form-apply-api

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot changed the title feat: 이벤트 참여 신청 폼 제출 api 구현 feat: 이벤트 참여 신청 폼 제출 API 구현 Sep 9, 2025
@github-actions
Copy link

github-actions bot commented Sep 9, 2025

Job Summary for Gradle

Check Style and Test to Develop :: build-test
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
gdsc check 8.5 Build Scan published

@github-actions
Copy link

github-actions bot commented Sep 9, 2025

Job Summary for Gradle

Check Style and Test to Develop :: build-test
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
gdsc check 8.5 Build Scan published

@github-actions
Copy link

github-actions bot commented Sep 9, 2025

Job Summary for Gradle

Check Style and Test to Develop :: build-test
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
gdsc check 8.5 Build Scan published

Copy link

@coderabbitai coderabbitai bot left a 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)를 요청 모델로 직접 받으면 도메인 규칙/필드가 외부 입력에 노출됩니다. 전용 ParticipantRequest DTO를 두고, 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

📥 Commits

Reviewing files that changed from the base of the PR and between fa9a57d and c6a368c.

📒 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에 대한 참조가 전혀 발견되지 않았습니다.

Comment on lines +281 to +297
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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

신규 신청: 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.

Comment on lines +8 to +11
public record EventApplyRequest(
@NotNull @Positive Long eventId,
Participant participant,
@NotNull AfterPartyApplicationStatus afterPartyApplicationStatus) {}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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) {}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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).

Copy link
Member

@kimsh1017 kimsh1017 left a 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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Participant얘는 왜 @NotNull 이 없나요?
제가 놓치고 있는 이유가 있을까요?

Copy link
Member

@uwoobeat uwoobeat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@Sangwook02 Sangwook02 merged commit 3a23891 into develop Sep 9, 2025
4 checks passed
@Sangwook02 Sangwook02 deleted the feature/1191-event-participation-form-apply-api branch September 9, 2025 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ 이벤트 참여 신청 폼 제출 API 구현

4 participants