Skip to content

Commit

Permalink
Merge pull request #13 from Kusitms-29th-Meetup-TeamE/feat/11/onboarding
Browse files Browse the repository at this point in the history
Feat: 온보딩 API 구현
  • Loading branch information
nohy6630 authored May 6, 2024
2 parents e9de027 + ce364f5 commit f10dd57
Show file tree
Hide file tree
Showing 16 changed files with 167 additions and 32 deletions.
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,18 @@ dependencies {

//swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

//Querydsl 추가
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}

tasks.named('test') {
useJUnitPlatform()
}

clean {
delete file('src/main/generated')
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

import com.fasterxml.jackson.annotation.JsonFormat;
import com.meetup.teame.backend.domain.activity.entity.Activity;
import com.meetup.teame.backend.domain.activity.entity.Personality;
import com.meetup.teame.backend.domain.personality.Personality;
import lombok.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.meetup.teame.backend.domain.activity.entity;

import com.meetup.teame.backend.domain.like.entity.ActivityLike;
import com.meetup.teame.backend.domain.user.entity.User;
import com.meetup.teame.backend.domain.personality.Personality;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.Comment;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.meetup.teame.backend.domain.activity.repository;

import com.meetup.teame.backend.domain.activity.entity.Activity;
import com.meetup.teame.backend.domain.activity.repository.custom.ActivityRepositoryCustom;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ActivityRepository extends JpaRepository<Activity, Long> {
public interface ActivityRepository extends JpaRepository<Activity, Long>, ActivityRepositoryCustom {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.meetup.teame.backend.domain.activity.repository.custom;

import com.meetup.teame.backend.domain.activity.entity.Activity;
import com.meetup.teame.backend.domain.user.entity.User;

import java.util.List;

public interface ActivityRepositoryCustom {
List<Activity> findActivitiesForUser(User user);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.meetup.teame.backend.domain.activity.repository.custom;

import com.meetup.teame.backend.domain.activity.entity.Activity;
import com.meetup.teame.backend.domain.activity.entity.QActivity;
import com.meetup.teame.backend.domain.user.entity.User;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;

import java.util.List;

import static com.meetup.teame.backend.domain.activity.entity.QActivity.activity;

@RequiredArgsConstructor
public class ActivityRepositoryImpl implements ActivityRepositoryCustom {
private final JPAQueryFactory jpaQueryFactory;

@Override
public List<Activity> findActivitiesForUser(User user) {
return jpaQueryFactory
.select(activity)
.from(activity)
.where(activity.personalities.any().in(user.getPersonalities()))
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.anyRequest().permitAll())
.cors(c -> c.configurationSource(request -> {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("http://localhost:3000"));
config.setAllowedOrigins(List.of("http://localhost:3000", "https://api.yeongjin.site", "https://ddoba.vercel.app"));
config.setAllowedMethods(List.of("*"));
config.setAllowCredentials(true);
config.setAllowedHeaders(List.of("*"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.meetup.teame.backend.domain.personality;

import com.meetup.teame.backend.global.exception.CustomException;
import com.meetup.teame.backend.global.exception.ExceptionContent;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.Arrays;

@Getter
@RequiredArgsConstructor
public enum Personality {
WINDLESS("잔잔한"),
ACTIVE("활발한"),
PEACEFUL("평화로운"),
NATURE_FRIENDLY("자연친화적인"),
CREATIVE("창의적인"),
ACADEMIC("학문적인"),
ARTISTIC("예술적인"),
LEARNABLE("배울 수 있는");

private final String description;

public static Personality des2enum(String description) {
return Arrays.stream(Personality.values())
.filter(personality -> personality.getDescription().equals(description))
.findFirst()
.orElseThrow(() -> new CustomException(ExceptionContent.NOT_FOUND_PERSONALITY));
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.meetup.teame.backend.domain.user.controller;

import com.meetup.teame.backend.domain.user.dto.request.OnboardingReq;
import com.meetup.teame.backend.domain.user.dto.response.ReadMainRes;
import com.meetup.teame.backend.domain.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand All @@ -19,14 +19,32 @@ public class UserController {

@Operation(summary = "메인 페이지 조회", description = """
현재 로그인한 유저의 메인 페이지를 조회합니다.
아직 로그인이 없어서 임시로 고정된 더미 유저의 데이터를 전달하는 식으로 구현되어 있습니다.
추후 로그인 적용 시에는 jwt토큰도 같이 전달해서 요청해주셔야 합니다.
""")
@GetMapping("/main")
public ResponseEntity<ReadMainRes> readMainPage() {
return ResponseEntity
.ok(userService.readMainPage());
}

@Operation(summary = "온보딩 정보 등록", description = """
유저의 온보딩 정보를 등록합니다.
아직 로그인이 없어서 임시로 고정된 더미 유저의 온보딩 정보를 등록하는 식으로 구현되어 있습니다.
추후 로그인 적용 시에는 jwt토큰도 같이 전달해서 요청해주셔야 합니다.
현재 온보딩 정보로 입력 가능한 성격 유형
("잔잔한", "활발한", "평화로운", "자연친화적인", "창의적인", "학문적인", "예술적인", "배울 수 있는")
위 유형들 중 최소 1개 이상을 선택해서 Request Body에 담아 전송해주세요.
""")
@PatchMapping("/onboarding")
public ResponseEntity<Void> setUserPersonality(@RequestBody @Valid OnboardingReq onboardingReq){
userService.setUserPersonality(onboardingReq);
return ResponseEntity
.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.meetup.teame.backend.domain.user.dto.request;

import jakarta.validation.constraints.Size;
import lombok.*;

import java.util.List;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class OnboardingReq {
@Size(min = 1, message = "at least one personality must be selected")
private List<String> personalities;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.meetup.teame.backend.domain.user.entity;

import com.meetup.teame.backend.domain.activity.entity.Activity;
import com.meetup.teame.backend.domain.personality.Personality;
import com.meetup.teame.backend.domain.experience.entity.Experience;
import com.meetup.teame.backend.domain.like.entity.ActivityLike;
import jakarta.persistence.*;
Expand Down Expand Up @@ -45,4 +45,12 @@ public class User {

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<ActivityLike> activityLikes;

@ElementCollection
@Enumerated(EnumType.STRING)
private List<Personality> personalities;

public void setPersonalities(List<Personality> personalities) {
this.personalities = personalities;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@

import com.meetup.teame.backend.domain.activity.repository.ActivityRepository;
import com.meetup.teame.backend.domain.experience.repository.ExperienceRepository;
import com.meetup.teame.backend.domain.personality.Personality;
import com.meetup.teame.backend.domain.user.dto.request.OnboardingReq;
import com.meetup.teame.backend.domain.user.dto.response.ReadMainRes;
import com.meetup.teame.backend.domain.user.entity.User;
import com.meetup.teame.backend.domain.user.repository.UserRepository;
import com.meetup.teame.backend.global.exception.CustomException;
import com.meetup.teame.backend.global.exception.ExceptionContent;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
Expand All @@ -17,10 +24,24 @@ public class UserService {
private final ExperienceRepository experienceRepository;

public ReadMainRes readMainPage() {
//todo 현재는 더미 유저지만 추후에는 SecurityContextHolder 정보를 조회해서 유저 정보를 가져와야 함
User user = userRepository.findById(5L)
.orElseThrow(() -> new CustomException(ExceptionContent.NOT_FOUND_USER));
return ReadMainRes.of(
activityRepository.findAll(),
activityRepository.findActivitiesForUser(user),
experienceRepository.findAll(),
2500
);
}

@Transactional
public void setUserPersonality(OnboardingReq onboardingReq) {
//todo 현재는 더미 유저지만 추후에는 SecurityContextHolder 정보를 조회해서 유저 정보를 가져와야 함
User user = userRepository.findById(5L)
.orElseThrow(() -> new CustomException(ExceptionContent.NOT_FOUND_USER));
List<Personality> personalities = onboardingReq.getPersonalities().stream()
.map(Personality::des2enum)
.toList();
user.setPersonalities(personalities);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.meetup.teame.backend.global.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QueryDslConfig {
@Autowired
private EntityManager entityManager;

@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum ExceptionContent {
BAD_REQUEST_SIGNUP(BAD_REQUEST, "회원가입에 실패했습니다. 이미 가입한 이메일입니다."),

NOT_FOUND_USER(NOT_FOUND, "존재하지 않는 사용자입니다."),
NOT_FOUND_PERSONALITY(NOT_FOUND, "존재하지 않는 성격입니다."),
;

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.meetup.teame.backend.domain.activity.entity.Activity;
import com.meetup.teame.backend.domain.activity.entity.Personality;
import com.meetup.teame.backend.domain.personality.Personality;
import com.meetup.teame.backend.domain.experience.entity.Experience;
import com.meetup.teame.backend.domain.experience.entity.ExperienceType;
import com.meetup.teame.backend.domain.user.dto.response.ReadMainRes;
Expand All @@ -17,14 +17,11 @@
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.time.LocalDateTime;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand Down

0 comments on commit f10dd57

Please sign in to comment.