Skip to content
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

[YS-54] feat: 실험자 공고 등록 API 구현 #24

Merged
merged 43 commits into from
Jan 11, 2025
Merged

[YS-54] feat: 실험자 공고 등록 API 구현 #24

merged 43 commits into from
Jan 11, 2025

Conversation

chock-cho
Copy link
Contributor

@chock-cho chock-cho commented Jan 10, 2025

💡 작업 내용

  • 실험자가 공고를 등록하는 API를 구현하였습니다.

공고 등록 - POST /v1/experiment-posts

image

연구자 정보 자동 완성 - GET /v1/experiment-posts/default

image

DB 저장 내역

  • target_group
    image

  • apply_method
    image

  • experiment_post
    image

✅ 셀프 체크리스트

  • PR 제목을 형식에 맞게 작성했나요?
  • 브랜치 전략에 맞는 브랜치에 PR을 올리고 있나요?
  • 테스트는 잘 통과했나요?
  • 빌드에 성공했나요?
  • 본인을 assign 해주세요.
  • 해당 PR에 맞는 label을 붙여주세요.

🙋🏻‍ 확인해주세요

  • 관련된 Discussion 등이 있다면 첨부해주세요
  • 세부 요구사항을 체크해보아야 해서, 이 PR은 HOLD합니다

🔗 Jira 티켓


https://yappsocks.atlassian.net/browse/YS-54

🔗 Jira 티켓


https://yappsocks.atlassian.net/browse/YS-54

- 참여자 회원가입 API 구현
- 구글 OAuth 에외처리 로직 일부 수정
- 테스트 커버리지 충족을 위해 테스트 코드 추가
- `SignupMapperTest` 코드 추가
- `ParticipantSignupUseCase` 코드 추가
- 실험자 회원가입 시, Authentication 중복 생성 코드 제거
architecture principal

- DB 트랜잭션 책임 관련: UseCase  → Service 계층으로 위임
- UseCase 클래스가 비즈니스 로직의 핵심 계층: 자동으로 컴포넌트 스캔
  대상에 포함되도록 어노테이션 제거
- 관리와 확장성을 고려하여 클린 아키텍처를 적용한 구현 방식
- 회원가입 API endpoint 관련하여 기존 `/join` → `/signup` 으로 개선
- 코드 컨벤션을 위한 API endpoint 개선
- 생년월일 데이터 포맷 관련: 기존: `@NotBlank` → `@NotNull` `@Past`
  `@DateTimeFormat`
- dto → entity 변환하는 용례에 따라, 기존: `toAddressInfoDto` →
  `toAddressInfo` 로 리네이밍
- dto 함수 리네이밍 반영한 `SingupMapperTest` 버그 해결
- 연구자 회원가입 기본 로직 초안 구현
- `emailVerified` 필드 값이 false이면, `EmailNotValidateException`
  반환하도록 구현
- 세부 조정사항: 기존 MemberEntity에 있던 `birthDate`  →
  ParticipantEntity 에 추가
- 이에 따른 기존 test code 수정하여 반영
- `AuthenticationUtils` 에 대한 test code 작성
- `SignupService`에 대한 test code 작성
- `CreateResearcherUsecase`,`ParticipantSignupUsecase` test code
  작성&수정
- `VerificationEntity`, `VerificationStatus` 도메인 엔티티 추가
- `VerificationRepository` 레포지토리 추가
- SMTP 활용하여 메일 인증 코드 발송 로직 구현
- 유효한 이메일 도메인인지 확인(실제 존재하는지 여부)
- 학교 이메일 여부 확인 로직 구현
- 학교 이메일 코드 전송 로직 구현
- 인증코드 만료 시에도 재요청 가능하도록 로직 수정
- 이미 승인된 대학 이메일에 대해서는 '이미 승인 완료'라고 예외 처리
- `usecase/SignUpUseCase/email` 패키지 밑에 메일 인증 관련 UseCase 재배ġ
- 테스트가 Fail하는 현상을 막기 위해, 몇 가지 조치를 취했습니다.
- `application/usecase/email/` 패키지 하위 UseCase에 대한 테스트 코드
  작성
- 연구자 회원가입 전 인증된 학교 메일에 대해서만 가입 가능하게끔 변경
- `ResearcherSignupRequest` 에서 `emailVerified=false` 인 경우, 예외
  반환
- `/v1/email`→ `/v1/emails` 로 엔드포인트 조정
- 이메일 도메인 검증 중 getter 삭제 후 인덱싱 방법으로 재조정
- MemberResponse 필드값 `isSuccess` typo 수정
- 기존 검증 로직 EmailUtils 패키지로 구조 조정
…DIP principal

- 클린 아키텍처 원칙 준수를 위한 기존 이메일 인증 로직 리팩토링
- `VerificationGateway` `VerificationGatewayImpl` 추가
- `VerificationModel` 추가
- researcherSignup 시 쿼리가 2번 날아가 정합성 깨지는 현상
- → Researcher,Participant / Member 도메인 @OnetoOne으로 맵핑 전략 수정
저장된 Researcher 및 Member 엔티티의 ID가 정상적으로 반영되지 않는
문제를 해결하였습니다.
- createResearcher에서 저장된 엔티티의 반환값을 사용하도록 수정
- researcherGateway.save 호출 시 반환 값이 최신 ID를 확인하도록 확인
- '공고 등록'의 전반적인 기능 구현 초안
- Bug 발견→ 회원가입 되었음에도 불구하고, MemberStatus가 ACTIVE이 X ▶
  해결
@chock-cho chock-cho added 🐛 BUG 버그 ✨ FEATURE 기능 추가 🔒 HOLD 홀드 labels Jan 10, 2025
@chock-cho chock-cho self-assigned this Jan 10, 2025
- 연구자 자동 완성 정보에 대한 커밋입니다.
- GET `/v1/experiment-posts/default` 를 수행하면, 연구자 기본 정보가
  반환됩니다.
@chock-cho chock-cho changed the title [YS-54] Feat: 실험자 공고 등록 API 구현 [YS-54] feat: 실험자 공고 등록 API 구현 Jan 10, 2025
@chock-cho chock-cho requested a review from Ji-soo708 January 10, 2025 10:28
- 패키지 구조 명 통일하여 수정
- controller에서 응답 형식 통일
- 이메일 인증 과정 중 인증 정보 조회 안 되는 현상 해결
- 공고 등록 필드 요구사항에 맞게 nullable 처리
- 연구 책임 변수명: `researcherName` → `leadResearcher` 변경
- `verifyResearcherEmailUseCase` 클¸° 아키텍처 원칙에 맞게 의존성 수정
- 공고 등록 기존: [실험자] → [연구자]로 스웨거 문서 수정
@chock-cho chock-cho added 📄 DOCS 문서화 ♻️ REFACTORING 리팩토링 labels Jan 11, 2025
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
30.6% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@Ji-soo708 Ji-soo708 marked this pull request as ready for review January 11, 2025 08:33
Copy link
Member

@Ji-soo708 Ji-soo708 left a comment

Choose a reason for hiding this comment

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

고려하실 부분이 많아 복잡했을텐데 잘 구현하셔서 approve합니다. 고생 많으셨습니다!

1/11 서버 회의에서 논의한 결과, 다음과 같이 결론 내렸습니다.

  1. mapper와 converter의 사용은 지양
  2. 다만, 기능 구현이 우선되어야 하므로 이전까지 구현한 코드에 대한 리팩터링은 4차 스프린트 이후(2차 MVP 시작 이전)에 진행하기로 결정
  3. 차주부터 구현되는 기능에 대해서는 협의한 부분을 지키며 구현

Comment on lines 18 to 20
class CreatePostUseCase(
private val experimentPostGateway: ExperimentPostGateway,
private val memberGateway: MemberGateway,
Copy link
Member

Choose a reason for hiding this comment

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

엔티티 이름이 ExperimentPost라 유즈케이스도 통일성있게 Post 앞에 Experiment 단어를 붙이는 건 어떨까요?
그리고 아직 프로젝트 초반이지만, 나중에 다른 유형의 Post가 등장할 수도 있어서 확장성을 생각하면 구체적으로 나타내는 거 좋다고 생각합니다!

@@ -100,7 +102,7 @@ class ExperimentPostEntity(
area = area,
detailedAddress = detailedAddress,
alarmAgree = alarmAgree,
images = images.map { it.toDomain() }
images = emptyList() // 이미지 업로드 보류
Copy link
Member

Choose a reason for hiding this comment

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

이미지 업로드 기능은 보류되었더라도, 나중에 추가될 예정이라면 emptyList() 대신 기존 상태를 유지하는 것이 더 나을 것 같습니다~

Comment on lines +33 to +36
override fun save(savedMember: Member): Member {
val entity = MemberConverter.toEntity(savedMember)
val savedEntity = memberRepository.save(entity)
return MemberConverter.toModel(savedEntity)
Copy link
Member

Choose a reason for hiding this comment

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

override fun save(member: Member): Member {
    val memberEntity = MemberEntity.fromDomain(member)
    return jpaMemberRepository
        .save(memberEntity)
        .toDomain()
}

다른 프로젝트에서 가져온 코드인데 저희 프로젝트에 있는 MemberEntity의 toDomain으로 해결 가능하지 않을까요?!

그리고 수정님의 코드를 리뷰하면서, 변환이 필요할 때마다 새로운 파일이나 변환을 위한 코드를 생성하는 패턴이 보였어요. 물론 이 부분은 코드 스타일의 차이일 수 있고, 그 방식도 저는 충분히 이해가 가요. 하지만 클린 아키텍처를 유지하려고 파일이 많이 생기는 상황에서 기존의 변환 메서드를 재사용할 수 있다면 좀 더 효율적이지 않을까 생각해요. 이런 접근이 저희 프로젝트 상황에서는 더 유리할 것 같다는 제 개인적인 의견을 드려봅니다!

이 부분에 대해서는 내일 좀 더 깊게 논의해보면 좋을 것 같습니다. 👏

@Ji-soo708 Ji-soo708 merged commit 8e2d2d4 into dev Jan 11, 2025
2 of 3 checks passed
@Ji-soo708 Ji-soo708 deleted the feat/YS-54 branch January 11, 2025 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 BUG 버그 📄 DOCS 문서화 ✨ FEATURE 기능 추가 🔒 HOLD 홀드 ♻️ REFACTORING 리팩토링
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants