diff --git a/src/main/kotlin/com/dobby/backend/application/mapper/SignupMapper.kt b/src/main/kotlin/com/dobby/backend/application/mapper/SignupMapper.kt index f6e4db2e..c6fe4f2d 100644 --- a/src/main/kotlin/com/dobby/backend/application/mapper/SignupMapper.kt +++ b/src/main/kotlin/com/dobby/backend/application/mapper/SignupMapper.kt @@ -3,51 +3,8 @@ import com.dobby.backend.application.usecase.member.CreateResearcherUseCase import com.dobby.backend.application.usecase.member.CreateParticipantUseCase import com.dobby.backend.domain.model.member.Participant import com.dobby.backend.domain.model.member.Researcher -import com.dobby.backend.infrastructure.database.entity.member.MemberEntity -import com.dobby.backend.infrastructure.database.entity.member.ParticipantEntity -import com.dobby.backend.presentation.api.dto.request.signup.ParticipantSignupRequest -import com.dobby.backend.infrastructure.database.entity.member.AddressInfo -import com.dobby.backend.infrastructure.database.entity.member.ResearcherEntity -import com.dobby.backend.presentation.api.dto.request.signup.AddressInfo as DtoAddressInfo object SignupMapper { - fun toAddressInfo(dto: DtoAddressInfo): AddressInfo { - return AddressInfo( - dto.region, - dto.area - ) - } - - fun toParticipant( - member: MemberEntity, - req: ParticipantSignupRequest - ): ParticipantEntity { - return ParticipantEntity( - id = 0, - member = member, - basicAddressInfo = toAddressInfo(req.basicAddressInfo), - additionalAddressInfo = req.additionalAddressInfo?.let { toAddressInfo(it) }, - preferType = req.preferType, - gender = req.gender, - birthDate = req.birthDate - ) - } - - fun toResearcher( - member: MemberEntity, - req: CreateResearcherUseCase.Input - ): ResearcherEntity { - return ResearcherEntity( - id = 0, - member = member, - univEmail = req.univEmail, - emailVerified = req.emailVerified, - univName = req.univName, - major = req.major, - labInfo = req.labInfo - ) - } - fun modelToResearcherRes(newResearcher: Researcher) : CreateResearcherUseCase.MemberResponse { return CreateResearcherUseCase.MemberResponse( diff --git a/src/main/kotlin/com/dobby/backend/application/service/MemberService.kt b/src/main/kotlin/com/dobby/backend/application/service/MemberService.kt index 03722482..cdddc72f 100644 --- a/src/main/kotlin/com/dobby/backend/application/service/MemberService.kt +++ b/src/main/kotlin/com/dobby/backend/application/service/MemberService.kt @@ -1,9 +1,6 @@ package com.dobby.backend.application.service -import com.dobby.backend.application.usecase.member.GetResearcherInfoUseCase -import com.dobby.backend.application.usecase.member.CreateParticipantUseCase -import com.dobby.backend.application.usecase.member.CreateResearcherUseCase -import com.dobby.backend.application.usecase.member.VerifyResearcherEmailUseCase +import com.dobby.backend.application.usecase.member.* import com.dobby.backend.domain.exception.SignupOauthEmailDuplicateException import com.dobby.backend.domain.gateway.member.MemberGateway import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus @@ -16,7 +13,8 @@ class MemberService( private val createParticipantUseCase: CreateParticipantUseCase, private val createResearcherUseCase: CreateResearcherUseCase, private val verifyResearcherEmailUseCase: VerifyResearcherEmailUseCase, - private val getResearcherInfoUseCase: GetResearcherInfoUseCase + private val getResearcherInfoUseCase: GetResearcherInfoUseCase, + private val getParticipantInfoUseCase: GetParticipantInfoUseCase ) { @Transactional fun participantSignup(input: CreateParticipantUseCase.Input): CreateParticipantUseCase.Output { @@ -32,7 +30,11 @@ class MemberService( return createResearcherUseCase.execute(input) } - fun getDefaultInfo(input: GetResearcherInfoUseCase.Input): GetResearcherInfoUseCase.Output { + fun getResearcherInfo(input: GetResearcherInfoUseCase.Input): GetResearcherInfoUseCase.Output { return getResearcherInfoUseCase.execute(input) } + + fun getParticipantInfo(input: GetParticipantInfoUseCase.Input): GetParticipantInfoUseCase.Output { + return getParticipantInfoUseCase.execute(input) + } } diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/member/CreateParticipantUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/member/CreateParticipantUseCase.kt index 9d5b702b..03657350 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/member/CreateParticipantUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/member/CreateParticipantUseCase.kt @@ -26,7 +26,7 @@ class CreateParticipantUseCase ( val birthDate: LocalDate, var basicAddressInfo: AddressInfo, var additionalAddressInfo: AddressInfo?, - var preferType: MatchType, + var matchType: MatchType, ) data class AddressInfo( val region: Region, @@ -89,7 +89,7 @@ class CreateParticipantUseCase ( additionalAddressInfo = input.additionalAddressInfo?.let { Participant.AddressInfo(region = it.region, area = it.area) }, - preferType = input.preferType + matchType = input.matchType ) } } diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/member/GetParticipantInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/member/GetParticipantInfoUseCase.kt new file mode 100644 index 00000000..5b3636e3 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/application/usecase/member/GetParticipantInfoUseCase.kt @@ -0,0 +1,45 @@ +package com.dobby.backend.application.usecase.member + +import com.dobby.backend.application.usecase.UseCase +import com.dobby.backend.domain.exception.ParticipantNotFoundException +import com.dobby.backend.domain.gateway.member.MemberGateway +import com.dobby.backend.domain.gateway.member.ParticipantGateway +import com.dobby.backend.domain.model.member.Member +import com.dobby.backend.domain.model.member.Participant +import com.dobby.backend.infrastructure.database.entity.enum.GenderType +import com.dobby.backend.infrastructure.database.entity.enum.MatchType +import java.time.LocalDate + +class GetParticipantInfoUseCase( + private val memberGateway: MemberGateway, + private val participantGateway: ParticipantGateway +) : UseCase{ + data class Input( + val memberId: Long, + ) + + data class Output( + val member: Member, + val gender: GenderType, + val birthDate: LocalDate, + val basicAddressInfo: Participant.AddressInfo, + val additionalAddressInfo: Participant.AddressInfo?, + val matchType: MatchType? + ) + + override fun execute(input: Input): Output { + val memberId = input.memberId + val member = memberGateway.getById(memberId) + val participant = participantGateway.findByMemberId(memberId) + ?: throw ParticipantNotFoundException() + + return Output( + member = member, + gender = participant.gender, + birthDate = participant.birthDate, + basicAddressInfo = participant.basicAddressInfo, + additionalAddressInfo = participant.additionalAddressInfo, + matchType = participant.matchType + ) + } +} diff --git a/src/main/kotlin/com/dobby/backend/domain/exception/ErrorCode.kt b/src/main/kotlin/com/dobby/backend/domain/exception/ErrorCode.kt index 512b6136..c3442241 100644 --- a/src/main/kotlin/com/dobby/backend/domain/exception/ErrorCode.kt +++ b/src/main/kotlin/com/dobby/backend/domain/exception/ErrorCode.kt @@ -73,6 +73,11 @@ enum class ErrorCode( */ RESEARCHER_NOT_FOUND("RE001", "Researcher Not Found.", HttpStatus.NOT_FOUND), + /** + * Participant error codes + */ + PARTICIPANT_NOT_FOUND("PA001", "Participant Not Found.", HttpStatus.NOT_FOUND), + /** * Experiment Post error codes */ diff --git a/src/main/kotlin/com/dobby/backend/domain/exception/ParticipantException.kt b/src/main/kotlin/com/dobby/backend/domain/exception/ParticipantException.kt new file mode 100644 index 00000000..7fa52c82 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/domain/exception/ParticipantException.kt @@ -0,0 +1,6 @@ +package com.dobby.backend.domain.exception + +open class ParticipantException ( + errorCode: ErrorCode, +) : DomainException(errorCode) +class ParticipantNotFoundException : ParticipantException(ErrorCode.PARTICIPANT_NOT_FOUND) diff --git a/src/main/kotlin/com/dobby/backend/domain/gateway/member/ParticipantGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/member/ParticipantGateway.kt index c9eea33c..4b604fc2 100644 --- a/src/main/kotlin/com/dobby/backend/domain/gateway/member/ParticipantGateway.kt +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/member/ParticipantGateway.kt @@ -4,4 +4,5 @@ import com.dobby.backend.domain.model.member.Participant interface ParticipantGateway { fun save(participant: Participant): Participant + fun findByMemberId(memberId: Long): Participant? } diff --git a/src/main/kotlin/com/dobby/backend/domain/model/member/Participant.kt b/src/main/kotlin/com/dobby/backend/domain/model/member/Participant.kt index 5c9b37c8..0f09810b 100644 --- a/src/main/kotlin/com/dobby/backend/domain/model/member/Participant.kt +++ b/src/main/kotlin/com/dobby/backend/domain/model/member/Participant.kt @@ -13,7 +13,7 @@ data class Participant( val birthDate: LocalDate, val basicAddressInfo: AddressInfo, val additionalAddressInfo: AddressInfo?, - val preferType: MatchType? + val matchType: MatchType? ) { data class AddressInfo( @@ -28,7 +28,7 @@ data class Participant( birthDate: LocalDate, basicAddressInfo: AddressInfo, additionalAddressInfo: AddressInfo?, - preferType: MatchType? + matchType: MatchType? ) = Participant( id = 0, member = member, @@ -36,7 +36,7 @@ data class Participant( birthDate = birthDate, basicAddressInfo = basicAddressInfo, additionalAddressInfo = additionalAddressInfo, - preferType = preferType + matchType = matchType ) } } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/converter/ParticipantConverter.kt b/src/main/kotlin/com/dobby/backend/infrastructure/converter/ParticipantConverter.kt index c4bec24e..eaf536c3 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/converter/ParticipantConverter.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/converter/ParticipantConverter.kt @@ -26,7 +26,7 @@ object ParticipantConverter { birthDate = entity.birthDate, basicAddressInfo = entity.basicAddressInfo.toModel(), additionalAddressInfo = entity.additionalAddressInfo?.toModel(), - preferType = entity.preferType + matchType = entity.matchType ) } @@ -46,7 +46,7 @@ object ParticipantConverter { member = memberEntity, gender = participant.gender, birthDate = participant.birthDate, - preferType = participant.preferType, + matchType = participant.matchType, basicAddressInfo = participant.basicAddressInfo.toEntity(), additionalAddressInfo = participant.additionalAddressInfo?.toEntity() ) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/ParticipantEntity.kt b/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/ParticipantEntity.kt index b44ba2a4..664a8c2a 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/ParticipantEntity.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/ParticipantEntity.kt @@ -1,8 +1,8 @@ package com.dobby.backend.infrastructure.database.entity.member +import com.dobby.backend.domain.model.member.Participant import com.dobby.backend.infrastructure.database.entity.enum.GenderType import com.dobby.backend.infrastructure.database.entity.enum.MatchType -import com.dobby.backend.infrastructure.database.entity.enum.RoleType import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Area import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Region import jakarta.persistence.* @@ -41,10 +41,35 @@ class ParticipantEntity ( ) val additionalAddressInfo: AddressInfo?, - @Column(name = "prefer_type", nullable = true) + @Column(name = "match_type", nullable = true) @Enumerated(EnumType.STRING) - var preferType: MatchType?, -) + var matchType: MatchType?, +) { + + fun toDomain() = Participant( + id = id, + member = member.toDomain(), + gender = gender, + birthDate = birthDate, + basicAddressInfo = basicAddressInfo.toDomain(), + additionalAddressInfo = additionalAddressInfo?.toDomain(), + matchType = matchType + ) + + companion object { + fun fromDomain(participant: Participant) = with(participant) { + ParticipantEntity( + id = id, + member = MemberEntity.fromDomain(member), + gender = gender, + birthDate = birthDate, + basicAddressInfo = AddressInfo.fromDomain(basicAddressInfo), // 수정: AddressInfo.fromDomain() 사용 + additionalAddressInfo = additionalAddressInfo?.let { AddressInfo.fromDomain(it) }, // 수정 + matchType = matchType + ) + } + } +} @Embeddable data class AddressInfo( @@ -55,4 +80,16 @@ data class AddressInfo( @Enumerated(EnumType.STRING) @Column(name = "area", nullable = false) val area: Area -) +) { + fun toDomain() = Participant.AddressInfo( + region = region, + area = area + ) + + companion object { + fun fromDomain(addressInfo: Participant.AddressInfo) = AddressInfo( + region = addressInfo.region, + area = addressInfo.area + ) + } +} diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/database/repository/ParticipantRepository.kt b/src/main/kotlin/com/dobby/backend/infrastructure/database/repository/ParticipantRepository.kt index 6bb12821..8a9fa135 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/database/repository/ParticipantRepository.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/database/repository/ParticipantRepository.kt @@ -4,4 +4,5 @@ import com.dobby.backend.infrastructure.database.entity.member.ParticipantEntity import org.springframework.data.jpa.repository.JpaRepository interface ParticipantRepository: JpaRepository { + fun findByMemberId(memberId: Long): ParticipantEntity? } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/ParticipantGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/ParticipantGatewayImpl.kt index 289f61a9..2f434be8 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/ParticipantGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/ParticipantGatewayImpl.kt @@ -3,6 +3,7 @@ package com.dobby.backend.infrastructure.gateway.member import com.dobby.backend.domain.gateway.member.ParticipantGateway import com.dobby.backend.domain.model.member.Participant import com.dobby.backend.infrastructure.converter.ParticipantConverter +import com.dobby.backend.infrastructure.database.entity.member.ParticipantEntity import com.dobby.backend.infrastructure.database.repository.ParticipantRepository import org.springframework.stereotype.Component @@ -15,4 +16,10 @@ class ParticipantGatewayImpl( val savedEntity = participantRepository.save(entity) return ParticipantConverter.toModel(savedEntity) } + + override fun findByMemberId(memberId: Long): Participant? { + return participantRepository + .findByMemberId(memberId) + ?.let(ParticipantEntity::toDomain) + } } diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt index 28f56a32..3865b51d 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt @@ -3,7 +3,7 @@ package com.dobby.backend.presentation.api.controller import com.dobby.backend.application.service.AuthService import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest +import com.dobby.backend.presentation.api.dto.request.auth.GoogleOauthLoginRequest import com.dobby.backend.presentation.api.dto.request.auth.MemberRefreshTokenRequest import com.dobby.backend.presentation.api.dto.request.auth.NaverOauthLoginRequest import com.dobby.backend.presentation.api.dto.response.member.MemberResponse diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt b/src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt index dfd19096..2e525798 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/controller/ExperimentPostController.kt @@ -3,7 +3,6 @@ package com.dobby.backend.presentation.api.controller import com.dobby.backend.application.service.ExperimentPostService import com.dobby.backend.presentation.api.dto.request.expirement.CreateExperimentPostRequest import com.dobby.backend.presentation.api.dto.response.expirement.CreateExperimentPostResponse -import com.dobby.backend.presentation.api.dto.response.expirement.DefaultInfoResponse import com.dobby.backend.presentation.api.dto.response.expirement.ExperimentPostApplyMethodResponse import com.dobby.backend.presentation.api.dto.response.expirement.ExperimentPostCountsResponse import com.dobby.backend.presentation.api.dto.response.expirement.ExperimentPostDetailResponse diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt b/src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt index 2ddf3d15..34d9cb19 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt @@ -3,7 +3,8 @@ package com.dobby.backend.presentation.api.controller import com.dobby.backend.application.service.MemberService import com.dobby.backend.presentation.api.dto.request.signup.ParticipantSignupRequest import com.dobby.backend.presentation.api.dto.request.signup.ResearcherSignupRequest -import com.dobby.backend.presentation.api.dto.response.expirement.DefaultInfoResponse +import com.dobby.backend.presentation.api.dto.response.member.ParticipantInfoResponse +import com.dobby.backend.presentation.api.dto.response.member.ResearcherInfoResponse import com.dobby.backend.presentation.api.dto.response.member.SignupResponse import com.dobby.backend.presentation.api.mapper.MemberMapper import io.swagger.v3.oas.annotations.Operation @@ -48,14 +49,26 @@ class MemberController( } @PreAuthorize("hasRole('RESEARCHER')") - @GetMapping("/default-info/researcher") + @GetMapping("/researchers/me") @Operation( summary = "연구자 기본 정보 렌더링", description = "연구자의 기본 정보 [학교 + 전공 + 랩실 정보 + 이름]를 반환합니다." ) - fun getDefaultInfo(): DefaultInfoResponse { - val input = MemberMapper.toDefaultInfoUseCaseInput() - val output = memberService.getDefaultInfo(input) - return MemberMapper.toDefaultInfoResponse(output) + fun getResearcherInfo(): ResearcherInfoResponse { + val input = MemberMapper.toGetResearcherInfoUseCaseInput() + val output = memberService.getResearcherInfo(input) + return MemberMapper.toResearcherInfoResponse(output) + } + + @PreAuthorize("hasRole('PARTICIPANT')") + @GetMapping("/participants/me") + @Operation( + summary = "참여자 회원 기본 정보 렌더링", + description = "참여자의 기본 정보를 반환합니다." + ) + fun getParticipantInfo(): ParticipantInfoResponse { + val input = MemberMapper.toGetParticipantInfoUseCaseInput() + val output = memberService.getParticipantInfo(input) + return MemberMapper.toParticipantInfoResponse(output) } } diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/OauthLoginRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/GoogleOauthLoginRequest.kt similarity index 100% rename from src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/OauthLoginRequest.kt rename to src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/GoogleOauthLoginRequest.kt diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/MemberRefreshTokenRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/MemberRefreshTokenRequest.kt index 63094fc5..32a011fc 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/MemberRefreshTokenRequest.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/MemberRefreshTokenRequest.kt @@ -5,7 +5,7 @@ import jakarta.validation.constraints.NotBlank @Schema(description = "토큰 갱신 요청 DTO") data class MemberRefreshTokenRequest( - @field:NotBlank + @NotBlank @Schema(description = "리프레시 토큰", example = "") val refreshToken: String, ) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/NaverOauthLoginRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/NaverOauthLoginRequest.kt index 72d52a5e..79e6a3ea 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/NaverOauthLoginRequest.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/NaverOauthLoginRequest.kt @@ -1,11 +1,14 @@ package com.dobby.backend.presentation.api.dto.request.auth +import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.NotBlank data class NaverOauthLoginRequest( @NotBlank(message = "authorizationCode는 공백일 수 없습니다.") + @Schema(description = "인가 코드") val authorizationCode: String, @NotBlank(message = "state는 공백일 수 없습니다.") + @Schema(description = "state") val state: String, ) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/NaverTokenRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/NaverTokenRequest.kt deleted file mode 100644 index 932092f2..00000000 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/NaverTokenRequest.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.dobby.backend.presentation.api.dto.request.auth - -import com.fasterxml.jackson.annotation.JsonProperty - -data class NaverTokenRequest ( - @JsonProperty("grant_type") - val grantType: String = "authorization_code", - - @JsonProperty("client_id") - val clientId: String, - - @JsonProperty("client_secret") - val clientSecret: String, - - @JsonProperty("code") - val code: String, - - @JsonProperty("state") - val state: String -) \ No newline at end of file diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/google/GoogleOauthLoginRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/google/GoogleOauthLoginRequest.kt deleted file mode 100644 index 2dc90527..00000000 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/google/GoogleOauthLoginRequest.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.dobby.backend.presentation.api.dto.request.auth.google - -import jakarta.validation.constraints.NotBlank - -data class GoogleOauthLoginRequest( - @NotBlank(message = "authorizationCode는 공백일 수 없습니다.") - val authorizationCode: String -) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/google/GoogleTokenRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/google/GoogleTokenRequest.kt deleted file mode 100644 index 9fddc59c..00000000 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/auth/google/GoogleTokenRequest.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.dobby.backend.presentation.api.dto.request.auth.google - -import com.fasterxml.jackson.annotation.JsonProperty -data class GoogleTokenRequest ( - @JsonProperty("code") - val code: String, - - @JsonProperty("client_id") - val clientId: String, - - @JsonProperty("client_secret") - val clientSecret: String, - - @JsonProperty("redirect_uri") - val redirectUri: String, - - @JsonProperty("grant_type") - val grantType: String = "authorization_code" -) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailSendRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailSendRequest.kt index abf1c493..4be8c6bd 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailSendRequest.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailSendRequest.kt @@ -1,10 +1,12 @@ package com.dobby.backend.presentation.api.dto.request.signup +import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.Email import jakarta.validation.constraints.NotNull data class EmailSendRequest ( @Email(message = "학교 이메일이 유효하지 않습니다.") @NotNull(message = "학교 이메일은 공백일 수 없습니다.") + @Schema(description = "대학교 이메일") val univEmail : String, ) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailVerificationRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailVerificationRequest.kt index 30e2d8a8..59313aac 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailVerificationRequest.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/EmailVerificationRequest.kt @@ -1,13 +1,16 @@ package com.dobby.backend.presentation.api.dto.request.signup +import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.Email import jakarta.validation.constraints.NotNull data class EmailVerificationRequest ( @Email(message = "학교 이메일이 유효하지 않습니다.") @NotNull(message = "학교 이메일은 공백일 수 없습니다.") + @Schema(description = "대학교 이메일") val univEmail : String, @NotNull(message = "인증 코드는 공백일 수 없습니다.") + @Schema(description = "인증 코드") val inputCode: String, ) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ParticipantSignupRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ParticipantSignupRequest.kt index 3712cbff..be268ccb 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ParticipantSignupRequest.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ParticipantSignupRequest.kt @@ -3,8 +3,8 @@ package com.dobby.backend.presentation.api.dto.request.signup import com.dobby.backend.infrastructure.database.entity.enum.GenderType import com.dobby.backend.infrastructure.database.entity.enum.MatchType import com.dobby.backend.infrastructure.database.entity.enum.ProviderType -import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Area -import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Region +import com.dobby.backend.presentation.api.dto.response.member.AddressInfoResponse +import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.Email import jakarta.validation.constraints.NotBlank import jakarta.validation.constraints.NotNull @@ -15,39 +15,38 @@ import java.time.LocalDate data class ParticipantSignupRequest( @Email(message = "OAuth 이메일이 유효하지 않습니다.") @NotBlank(message = "OAuth 이메일은 공백일 수 없습니다.") + @Schema(description = "OAuth 이메일") val oauthEmail: String, @NotBlank(message = "OAuth provider은 공백일 수 없습니다.") + @Schema(description = "OAuth provider") val provider: ProviderType, @Email(message= "연락 받을 이메일이 유효하지 않습니다.") @NotBlank(message = "연락 받을 이메일은 공백일 수 없습니다.") + @Schema(description = "연락 받을 이메일") val contactEmail: String, @NotBlank(message = "이름은 공백일 수 없습니다.") + @Schema(description = "이름") val name : String, @NotBlank(message = "성별은 공백일 수 없습니다.") + @Schema(description = "성별") val gender: GenderType, @Past @NotNull(message = "생년월일은 공백일 수 없습니다.") @DateTimeFormat(pattern = "yyyy-MM-dd") + @Schema(description = "생년월일") val birthDate: LocalDate, @NotBlank(message = "거주 지역은 공백일 수 없습니다.") - var basicAddressInfo: AddressInfo, + @Schema(description = "기본 주소 정보") + var basicAddressInfo: AddressInfoResponse, - // 추가 활동 정보 - var additionalAddressInfo: AddressInfo?, + @Schema(description = "추가 주소 정보") + var additionalAddressInfo: AddressInfoResponse?, - // 선호 실험 진행 방식 - var preferType: MatchType, -) - -data class AddressInfo( - @NotBlank(message = "시/도 정보는 공백일 수 없습니다.") - val region: Region, - - @NotBlank(message = "시/군/구 정보는 공백일 수 없습니다.") - val area: Area + @Schema(description = "선호 실험 진행 방식") + var matchType: MatchType, ) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ResearcherSignupRequest.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ResearcherSignupRequest.kt index b5a02de7..92c9d085 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ResearcherSignupRequest.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/request/signup/ResearcherSignupRequest.kt @@ -1,6 +1,7 @@ package com.dobby.backend.presentation.api.dto.request.signup import com.dobby.backend.infrastructure.database.entity.enum.ProviderType +import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.Email import jakarta.validation.constraints.NotBlank import jakarta.validation.constraints.NotNull @@ -8,30 +9,39 @@ import jakarta.validation.constraints.NotNull data class ResearcherSignupRequest( @Email(message = "OAuth 이메일이 유효하지 않습니다.") @NotBlank(message = "OAuth 이메일은 공백일 수 없습니다.") + @Schema(description = "OAuth 이메일") val oauthEmail: String, @NotBlank(message = "OAuth provider은 공백일 수 없습니다.") + @Schema(description = "OAuth provider") val provider: ProviderType, @Email(message= "연락 받을 이메일이 유효하지 않습니다.") @NotBlank(message = "연락 받을 이메일은 공백일 수 없습니다.") + @Schema(description = "연락 받을 이메일") val contactEmail: String, @Email(message = "학교 이메일이 유효하지 않습니다.") @NotBlank(message = "학교 이메일은 공백일 수 없습니다.") + @Schema(description = "대학교 이메일") val univEmail : String, @NotNull(message = "이메일 인증 여부는 공백일 수 없습니다.") + @Schema(description = "이메일 인증 여부") var emailVerified: Boolean, @NotBlank(message = "이름은 공백일 수 없습니다.") + @Schema(description = "이름") val name: String, @NotBlank(message = "학교명은 공백일 수 없습니다.") + @Schema(description = "학교명") val univName: String, @NotBlank(message = "전공명은 공백일 수 없습니다.") + @Schema(description = "전공명") val major: String, + @Schema(description = "연구실 정보") val labInfo: String? ) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/AddressInfoResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/AddressInfoResponse.kt new file mode 100644 index 00000000..d7e57131 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/AddressInfoResponse.kt @@ -0,0 +1,24 @@ +package com.dobby.backend.presentation.api.dto.response.member + +import com.dobby.backend.domain.model.member.Participant +import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Area +import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Region +import io.swagger.v3.oas.annotations.media.Schema + +@Schema(description = "주소 정보 반환 DTO") +data class AddressInfoResponse( + @Schema(description = "지역") + val region: Region, + + @Schema(description = "지역 상세") + val area: Area +) { + companion object { + fun fromDomain(basicAddressInfo: Participant.AddressInfo): AddressInfoResponse { + return AddressInfoResponse( + region = basicAddressInfo.region, + area = basicAddressInfo.area + ) + } + } +} diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/ParticipantInfoResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/ParticipantInfoResponse.kt new file mode 100644 index 00000000..bc20eda8 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/ParticipantInfoResponse.kt @@ -0,0 +1,27 @@ +package com.dobby.backend.presentation.api.dto.response.member + +import com.dobby.backend.infrastructure.database.entity.enum.GenderType +import com.dobby.backend.infrastructure.database.entity.enum.MatchType +import io.swagger.v3.oas.annotations.media.Schema +import java.time.LocalDate + +@Schema(description = "공고 등록 시, 자동 입력에 필요한 연구자 정보 반환 DTO") +data class ParticipantInfoResponse( + @Schema(description = "사용자 기본 정보") + val memberInfo: MemberResponse, + + @Schema(description = "성별") + val gender: GenderType, + + @Schema(description = "생년월일") + val birthDate: LocalDate, + + @Schema(description = "기본 주소 정보") + val basicAddressInfo: AddressInfoResponse, + + @Schema(description = "추가 주소 정보") + val additionalAddressInfo: AddressInfoResponse?, + + @Schema(description = "매칭 선호 타입") + val matchType: MatchType?, +) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/expirement/DefaultInfoResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/ResearcherInfoResponse.kt similarity index 75% rename from src/main/kotlin/com/dobby/backend/presentation/api/dto/response/expirement/DefaultInfoResponse.kt rename to src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/ResearcherInfoResponse.kt index 00c0324a..2da3edb4 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/expirement/DefaultInfoResponse.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/member/ResearcherInfoResponse.kt @@ -1,9 +1,9 @@ -package com.dobby.backend.presentation.api.dto.response.expirement +package com.dobby.backend.presentation.api.dto.response.member import io.swagger.v3.oas.annotations.media.Schema @Schema(description = "공고 등록 시, 자동 입력에 필요한 연구자 정보 반환 DTO") -data class DefaultInfoResponse( +data class ResearcherInfoResponse( @Schema(description = "연구 책임") val leadResearcher: String, diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt b/src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt index e3f57bce..ef0fd872 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt @@ -3,11 +3,10 @@ package com.dobby.backend.presentation.api.mapper import com.dobby.backend.application.usecase.member.GetResearcherInfoUseCase import com.dobby.backend.application.usecase.member.CreateResearcherUseCase import com.dobby.backend.application.usecase.member.CreateParticipantUseCase +import com.dobby.backend.application.usecase.member.GetParticipantInfoUseCase import com.dobby.backend.presentation.api.dto.request.signup.ParticipantSignupRequest import com.dobby.backend.presentation.api.dto.request.signup.ResearcherSignupRequest -import com.dobby.backend.presentation.api.dto.response.expirement.DefaultInfoResponse -import com.dobby.backend.presentation.api.dto.response.member.MemberResponse -import com.dobby.backend.presentation.api.dto.response.member.SignupResponse +import com.dobby.backend.presentation.api.dto.response.member.* import com.dobby.backend.util.getCurrentMemberId object MemberMapper { @@ -48,7 +47,7 @@ object MemberMapper { additionalAddressInfo = req.additionalAddressInfo?.let { CreateParticipantUseCase.AddressInfo(region = it.region, area = it.area) }, - preferType = req.preferType + matchType = req.matchType ) } @@ -84,16 +83,33 @@ object MemberMapper { } } - fun toDefaultInfoUseCaseInput(): GetResearcherInfoUseCase.Input { + fun toGetResearcherInfoUseCaseInput(): GetResearcherInfoUseCase.Input { return GetResearcherInfoUseCase.Input( memberId = getCurrentMemberId() ) } - fun toDefaultInfoResponse(response: GetResearcherInfoUseCase.Output): DefaultInfoResponse { - return DefaultInfoResponse( + fun toResearcherInfoResponse(response: GetResearcherInfoUseCase.Output): ResearcherInfoResponse { + return ResearcherInfoResponse( leadResearcher = response.leadResearcher, univName = response.univName ) } + + fun toGetParticipantInfoUseCaseInput(): GetParticipantInfoUseCase.Input { + return GetParticipantInfoUseCase.Input( + memberId = getCurrentMemberId() + ) + } + + fun toParticipantInfoResponse(output: GetParticipantInfoUseCase.Output): ParticipantInfoResponse { + return ParticipantInfoResponse( + memberInfo = MemberResponse.fromDomain(output.member), + gender = output.gender, + birthDate = output.birthDate, + basicAddressInfo = AddressInfoResponse.fromDomain(output.basicAddressInfo), + additionalAddressInfo = output.additionalAddressInfo?.let { AddressInfoResponse.fromDomain(it) }, + matchType = output.matchType + ) + } } diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/member/GetParticipantInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/member/GetParticipantInfoUseCaseTest.kt new file mode 100644 index 00000000..d53d8593 --- /dev/null +++ b/src/test/kotlin/com/dobby/backend/application/usecase/member/GetParticipantInfoUseCaseTest.kt @@ -0,0 +1,74 @@ +package com.dobby.backend.application.usecase.member + +import com.dobby.backend.domain.exception.ParticipantNotFoundException +import com.dobby.backend.domain.exception.PermissionDeniedException +import com.dobby.backend.domain.gateway.member.MemberGateway +import com.dobby.backend.domain.gateway.member.ParticipantGateway +import com.dobby.backend.domain.model.member.Member +import com.dobby.backend.domain.model.member.Participant +import com.dobby.backend.infrastructure.database.entity.enum.GenderType +import com.dobby.backend.infrastructure.database.entity.enum.MatchType +import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Area +import com.dobby.backend.infrastructure.database.entity.enum.areaInfo.Region +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.shouldBe +import io.kotest.assertions.throwables.shouldThrow +import io.mockk.every +import io.mockk.mockk +import java.time.LocalDate + +class GetParticipantInfoUseCaseTest : BehaviorSpec({ + val memberGateway = mockk() + val participantGateway = mockk() + val useCase = GetParticipantInfoUseCase(memberGateway, participantGateway) + + given("유효한 memberId가 주어졌을 때") { + val memberId = 1L + + val member = mockk() + val participant = mockk() + val basicAddressInfo = Participant.AddressInfo(region = Region.SEOUL, area = Area.GWANGJINGU) + val additionalAddressInfo = Participant.AddressInfo(region = Region.INCHEON, area = Area.SEOGU) + + every { memberGateway.getById(memberId) } returns member + every { participantGateway.findByMemberId(memberId) } returns participant + every { participant.gender } returns GenderType.FEMALE + every { participant.birthDate } returns LocalDate.of(2000, 7, 8) + every { participant.basicAddressInfo } returns basicAddressInfo + every { participant.additionalAddressInfo } returns additionalAddressInfo + every { participant.matchType } returns MatchType.HYBRID + + `when`("useCase의 execute가 호출되면") { + val input = GetParticipantInfoUseCase.Input(memberId) + val result = useCase.execute(input) + + then("정상적으로 participant 정보가 반환된다") { + result.member shouldBe member + result.gender shouldBe GenderType.FEMALE + result.birthDate shouldBe LocalDate.of(2000, 7, 8) + result.basicAddressInfo shouldBe basicAddressInfo + result.additionalAddressInfo shouldBe additionalAddressInfo + result.matchType shouldBe MatchType.HYBRID + } + } + } + + given("존재하지 않는 participantId가 주어졌을 때") { + val memberId = 1L + + val member = mockk() + + every { memberGateway.getById(memberId) } returns member + every { participantGateway.findByMemberId(memberId) } returns null + + `when`("useCase의 execute가 호출되면") { + val input = GetParticipantInfoUseCase.Input(memberId) + + then("ParticipantNotFoundException이 발생한다") { + shouldThrow { + useCase.execute(input) + } + } + } + } +})