Skip to content

Commit

Permalink
[Feature/17] 자기소개 등록하기 API를 구현한다 (#18)
Browse files Browse the repository at this point in the history
* feat: 자기소개 등록하기 api를 구현한다

* feat: 코드리뷰 반영

* feat: 코드리뷰 반영
  • Loading branch information
injoon2019 authored Jul 22, 2024
1 parent 237ea74 commit 9f6e52b
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.nexters.bottles.user.controller

import com.nexters.bottles.user.controller.dto.ProfileChoiceResponseDto
import com.nexters.bottles.user.controller.dto.RegisterProfileRequestDto
import com.nexters.bottles.user.facade.dto.ProfileChoiceResponseDto
import com.nexters.bottles.user.facade.dto.RegisterIntroductionRequestDto
import com.nexters.bottles.user.facade.dto.RegisterProfileRequestDto
import com.nexters.bottles.user.facade.UserProfileFacade
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
Expand All @@ -10,18 +11,23 @@ import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/v1")
@RequestMapping("/api/v1/profile")
class UserProfileController(
private val profileFacade: UserProfileFacade,
) {

@PostMapping("/profile/choice")
fun registerProfile(@RequestBody registerProfileRequestDto: RegisterProfileRequestDto) {
profileFacade.saveProfile(registerProfileRequestDto)
@PostMapping("/choice")
fun upsertProfile(@RequestBody registerProfileRequestDto: RegisterProfileRequestDto) {
profileFacade.upsertProfile(registerProfileRequestDto)
}

@GetMapping("/profile/choice")
@GetMapping("/choice")
fun getProfileChoiceList() : ProfileChoiceResponseDto {
return profileFacade.getProfileChoice()
}

@PostMapping("/introduction")
fun upsertIntroduction(@RequestBody registerIntroductionRequestDto: RegisterIntroductionRequestDto) {
profileFacade.upsertIntroduction(registerIntroductionRequestDto)
}
}
15 changes: 12 additions & 3 deletions src/main/kotlin/com/nexters/bottles/user/domain/UserProfile.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.nexters.bottles.user.domain

import com.nexters.bottles.user.controller.dto.InterestDto
import com.nexters.bottles.user.controller.dto.RegionDto
import com.nexters.bottles.user.facade.dto.InterestDto
import com.nexters.bottles.user.facade.dto.RegionDto
import com.nexters.bottles.user.repository.converter.QuestionAndAnswerConverter
import com.nexters.bottles.user.repository.converter.UserProfileSelectConverter
import javax.persistence.*

Expand All @@ -16,7 +17,10 @@ class UserProfile(
var user: User? = null,

@Convert(converter = UserProfileSelectConverter::class)
var profileSelect: UserProfileSelect,
var profileSelect: UserProfileSelect? = null,

@Convert(converter = QuestionAndAnswerConverter::class)
var introduction: List<QuestionAndAnswer> = arrayListOf(),
) : BaseEntity()

data class UserProfileSelect(
Expand All @@ -30,3 +34,8 @@ data class UserProfileSelect(
val region: RegionDto,
)

data class QuestionAndAnswer(
val question: String,
val answer: String,
)

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.nexters.bottles.user.facade

import com.nexters.bottles.user.controller.dto.ProfileChoiceResponseDto
import com.nexters.bottles.user.controller.dto.RegisterProfileRequestDto
import com.nexters.bottles.user.domain.UserProfile
import com.nexters.bottles.user.facade.dto.ProfileChoiceResponseDto
import com.nexters.bottles.user.facade.dto.RegisterIntroductionRequestDto
import com.nexters.bottles.user.facade.dto.RegisterProfileRequestDto
import com.nexters.bottles.user.domain.UserProfileSelect
import com.nexters.bottles.user.service.UserProfileService
import org.springframework.stereotype.Component
Expand All @@ -13,22 +13,20 @@ class UserProfileFacade(
private val profileService: UserProfileService,
) {

fun saveProfile(profileDto: RegisterProfileRequestDto) {
fun upsertProfile(profileDto: RegisterProfileRequestDto) {
validateProfile(profileDto)
val convertedProfileDto = convertProfileDto(profileDto)

profileService.saveProfile(
UserProfile(
profileSelect = UserProfileSelect(
mbti = convertedProfileDto.mbti,
keyword = convertedProfileDto.keyword,
interest = convertedProfileDto.interest,
job = convertedProfileDto.job,
smoking = convertedProfileDto.smoking,
alcohol = convertedProfileDto.alcohol,
religion = convertedProfileDto.religion,
region = convertedProfileDto.region,
)
profileService.upsertProfile(
profileSelect = UserProfileSelect(
mbti = convertedProfileDto.mbti,
keyword = convertedProfileDto.keyword,
interest = convertedProfileDto.interest,
job = convertedProfileDto.job,
smoking = convertedProfileDto.smoking,
alcohol = convertedProfileDto.alcohol,
religion = convertedProfileDto.religion,
region = convertedProfileDto.region,
)
)
}
Expand All @@ -39,17 +37,32 @@ class UserProfileFacade(
)
}

fun upsertIntroduction(registerIntroductionRequestDto: RegisterIntroductionRequestDto) {
validateIntroduction(registerIntroductionRequestDto)

profileService.saveIntroduction(registerIntroductionRequestDto.introduction)
}

private fun validateProfile(profileDto: RegisterProfileRequestDto) {
require(profileDto.keyword.size <= 5) {
"키워드는 5개 이하여야 해요"
}
val interestCount = profileDto.interest.culture.size + profileDto.interest.sports.size
+profileDto.interest.entertainment.size + profileDto.interest.etc.size
+ profileDto.interest.entertainment.size + profileDto.interest.etc.size
require(interestCount <= 5) {
"취미는 5개 이하여야 해요"
}
}

private fun validateIntroduction(introductionDto: RegisterIntroductionRequestDto) {
introductionDto.introduction.forEach {
// require(it.answer.length > 30 && it.answer.length <= 100) {
// "소개는 30자 이상 100자 이하로 써야 해요"
// }
// TODO: 개발 환경에서 빠르게 테스트 하기 위해 일단 주석 처리하고 라이브 서비스 나가기전 해제할 예정입니다.
}
}

private fun convertProfileDto(profileDto: RegisterProfileRequestDto): RegisterProfileRequestDto {
when(profileDto.smoking) {
"전혀 피우지 않아요" -> profileDto.smoking = "흡연 안해요"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.nexters.bottles.user.controller.dto
package com.nexters.bottles.user.facade.dto

data class InterestDto(
val culture: List<String> = arrayListOf(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.nexters.bottles.user.controller.dto
package com.nexters.bottles.user.facade.dto

data class ProfileChoiceResponseDto(
val regions: List<Map<String, Any>>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.nexters.bottles.user.controller.dto
package com.nexters.bottles.user.facade.dto

data class RegionDto(
val city: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.nexters.bottles.user.facade.dto

import com.nexters.bottles.user.domain.QuestionAndAnswer

data class RegisterIntroductionRequestDto(
val introduction: List<QuestionAndAnswer>
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.nexters.bottles.user.controller.dto
package com.nexters.bottles.user.facade.dto

data class RegisterProfileRequestDto(
val mbti: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ package com.nexters.bottles.user.repository
import com.nexters.bottles.user.domain.UserProfile
import org.springframework.data.jpa.repository.JpaRepository

interface UserProfileRepository : JpaRepository<UserProfile, Long>
interface UserProfileRepository : JpaRepository<UserProfile, Long> {

fun findByUserId(userId: Long): UserProfile?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.nexters.bottles.user.repository.converter

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.kotlinModule
import com.nexters.bottles.user.domain.QuestionAndAnswer
import javax.persistence.AttributeConverter
import javax.persistence.Converter

@Converter(autoApply = true)
class QuestionAndAnswerConverter : AttributeConverter<List<QuestionAndAnswer>, String> {

private val objectMapper = ObjectMapper().registerModule(kotlinModule())

override fun convertToDatabaseColumn(attribute: List<QuestionAndAnswer>?): String? {
return attribute?.let { objectMapper.writeValueAsString(it) }
}

override fun convertToEntityAttribute(dbData: String?): List<QuestionAndAnswer>? {
return dbData?.let {
objectMapper.readValue(
it,
objectMapper.typeFactory.constructCollectionType(List::class.java, QuestionAndAnswer::class.java)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.nexters.bottles.user.repository.converter

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinFeature
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.nexters.bottles.config.JacksonConfig.Companion.kotlinModule
import com.fasterxml.jackson.module.kotlin.kotlinModule
import com.nexters.bottles.user.domain.UserProfileSelect
import javax.persistence.AttributeConverter
import javax.persistence.Converter

@Converter(autoApply = true)
class UserProfileSelectConverter : AttributeConverter<UserProfileSelect, String> {

private val objectMapper = ObjectMapper().registerModule(kotlinModule)
private val objectMapper = ObjectMapper().registerModule(kotlinModule())

override fun convertToDatabaseColumn(attribute: UserProfileSelect?): String {
return try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.nexters.bottles.user.service

import com.nexters.bottles.user.domain.QuestionAndAnswer
import com.nexters.bottles.user.domain.UserProfile
import com.nexters.bottles.user.domain.UserProfileSelect
import com.nexters.bottles.user.repository.UserProfileRepository
import com.nexters.bottles.user.repository.UserRepository
import mu.KotlinLogging
Expand All @@ -17,10 +19,38 @@ class UserProfileService(
private val log = KotlinLogging.logger { }

@Transactional
fun saveProfile(userProfile: UserProfile): UserProfile {
val user = userRepository.findByIdOrNull(1L) // TODO User 회원 가입 기능 구현후 수정
fun upsertProfile(profileSelect: UserProfileSelect) {
// TODO User 회원 가입 기능 구현후 수정
val user = userRepository.findByIdOrNull(1L) ?: throw IllegalStateException("회원가입 상태를 문의해주세요")

userProfile.user = user
return profileRepository.save(userProfile)
profileRepository.findByUserId(user.id)?.let {
it.user = user
it.profileSelect = profileSelect
it.introduction = it.introduction
} ?: run {
profileRepository.save(
UserProfile(
user = user,
profileSelect = profileSelect,
)
)
}
}

@Transactional
fun saveIntroduction(introduction: List<QuestionAndAnswer>) {
// TODO User 회원 가입 기능 구현후 수정
val user = userRepository.findByIdOrNull(1L) ?: throw IllegalStateException("회원가입 상태를 문의해주세요")

profileRepository.findByUserId(user.id)?.let {
it.introduction = introduction
} ?: run {
profileRepository.save(
UserProfile(
user = user,
introduction = introduction
)
)
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/sql/table_query.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CREATE TABLE user_profile (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
profile_select JSON,
introduction JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);

0 comments on commit 9f6e52b

Please sign in to comment.