From a6085392ff2a895d281e2593be4fe80e0f6609f4 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sat, 23 Nov 2024 00:32:25 +0900 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20=EC=95=BC=EA=B0=84=EC=9E=94?= =?UTF-8?q?=EB=A5=98=20=EC=8B=A0=EC=B2=AD=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Application 엔티티에 컬럼 추가 * ApplicationController에서 ApiResponse를 이용한 응답 및 에러 처리 * ApplicationRequest에서 요청 DTO 구현 * ApplicationResponse에서 응답 DTO 구현 * ApplicationRepository와 MemberRepository 생성 * ApplicationService 구현 Ref: #21 --- build.gradle | 2 +- .../controller/ApplicationController.java | 49 ++++++++ .../application/domain/Application.java | 24 ++-- .../application/dto/ApplicationRequest.java | 41 +++++++ .../application/dto/ApplicationResponse.java | 43 +++++++ .../repository/ApplicationRepository.java | 7 ++ .../service/ApplicationService.java | 30 +++++ .../member/repository/MemberRepository.java | 7 ++ .../teampu/global/config/SecurityConfig.java | 116 +++++++++--------- .../teampu/global/response/ApiResponse.java | 2 +- src/main/resources/application.yml | 4 + 11 files changed, 254 insertions(+), 71 deletions(-) create mode 100644 src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java create mode 100644 src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java create mode 100644 src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java create mode 100644 src/main/java/com/kyonggi/teampu/domain/application/repository/ApplicationRepository.java create mode 100644 src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java create mode 100644 src/main/java/com/kyonggi/teampu/domain/member/repository/MemberRepository.java diff --git a/build.gradle b/build.gradle index 0c365a2..9241de2 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { dependencies { implementation 'com.h2database:h2' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-security' +// implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' diff --git a/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java new file mode 100644 index 0000000..169df20 --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java @@ -0,0 +1,49 @@ +package com.kyonggi.teampu.domain.application.controller; + +import com.kyonggi.teampu.domain.application.dto.ApplicationRequest; +import com.kyonggi.teampu.domain.application.dto.ApplicationResponse; +import com.kyonggi.teampu.domain.application.service.ApplicationService; +import com.kyonggi.teampu.global.response.ApiResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/apply") +public class ApplicationController { + private final ApplicationService applicationService; + + @PostMapping + public ResponseEntity> createApplication(@RequestBody ApplicationRequest applicationRequest) { + // 400 에러 처리 + if (applicationRequest.getMemberId() == null || applicationRequest.getStartTime() == null || applicationRequest.getEndTime() == null) { + return ResponseEntity + .status(HttpStatus.BAD_REQUEST) + .body(new ApiResponse<>( + new ApiResponse.Status(HttpStatus.BAD_REQUEST, "필수 값이 누락되었습니다"), + null + )); + } + + try { + ApplicationResponse applicationResponse = applicationService.createApplication(applicationRequest); + return ResponseEntity.ok(new ApiResponse<>( + new ApiResponse.Status(HttpStatus.CREATED, "신청이 완료되었습니다"), + applicationResponse + )); + } catch (IllegalArgumentException e) { + // 401 에러 처리 + return ResponseEntity + .status(HttpStatus.UNAUTHORIZED) + .body(new ApiResponse<>( + new ApiResponse.Status(HttpStatus.UNAUTHORIZED, "권한이 없습니다"), + null + )); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java b/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java index 1c729e5..5fcf914 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java @@ -1,17 +1,7 @@ package com.kyonggi.teampu.domain.application.domain; import com.kyonggi.teampu.domain.member.domain.Member; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -20,6 +10,8 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity @Getter @@ -46,6 +38,16 @@ public class Application { @Column(name = "status", nullable = false) private ApplicationStatus status; + @Column(name = "participant_count") + private Integer participantCount; + + @ElementCollection // JPA에서 값 타입 컬렉션을 매핑할 때 사용하는 어노테이션 + @Column(name = "co_participant_names") + private List coParticipantNames = new ArrayList<>(); + + @Column(name = "privacy_agreement") + private Boolean privacyAgreement; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; diff --git a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java new file mode 100644 index 0000000..8e23cb7 --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java @@ -0,0 +1,41 @@ +package com.kyonggi.teampu.domain.application.dto; + +import com.kyonggi.teampu.domain.application.domain.Application; +import com.kyonggi.teampu.domain.application.domain.ApplicationStatus; +import com.kyonggi.teampu.domain.member.domain.Member; +import com.kyonggi.teampu.domain.member.domain.MemberType; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@NoArgsConstructor +public class ApplicationRequest { + private String name; + private MemberType type; + private Long memberId; + private String loginId; + private String phoneNumber; + private String email; + private Integer participantCount; + private List coParticipantNames; + private Boolean privacyAgreement; + private LocalDateTime startTime; + private LocalDateTime endTime; + + public Application toEntity(Member member) { + return Application.builder() + .member(member) + .participantCount(participantCount) + .coParticipantNames(coParticipantNames) + .privacyAgreement(privacyAgreement) + .startTime(startTime) + .endTime(endTime) + .appliedDate(LocalDate.now()) + .status(ApplicationStatus.PENDING) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java new file mode 100644 index 0000000..b869801 --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java @@ -0,0 +1,43 @@ +package com.kyonggi.teampu.domain.application.dto; + +import com.kyonggi.teampu.domain.application.domain.Application; +import com.kyonggi.teampu.domain.member.domain.MemberType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +public class ApplicationResponse { + private String loginId; + private String name; + private MemberType type; + private Long memberId; + private String phoneNumber; + private String email; + private Integer participantCount; + private List coParticipantNames; + private Boolean privacyAgreement; + private LocalDateTime startTime; + private LocalDateTime endTime; + + public static ApplicationResponse of(Application application) { + return ApplicationResponse.builder() + .loginId(application.getMember().getLoginId()) + .name(application.getMember().getName()) + .type(application.getMember().getType()) + .memberId(application.getMember().getId()) + .phoneNumber(application.getMember().getPhoneNumber()) + .email(application.getMember().getEmail()) + .participantCount(application.getParticipantCount()) + .coParticipantNames(application.getCoParticipantNames()) + .privacyAgreement(application.getPrivacyAgreement()) + .startTime(application.getStartTime()) + .endTime(application.getEndTime()) + .build(); + } +} diff --git a/src/main/java/com/kyonggi/teampu/domain/application/repository/ApplicationRepository.java b/src/main/java/com/kyonggi/teampu/domain/application/repository/ApplicationRepository.java new file mode 100644 index 0000000..601a5c6 --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/application/repository/ApplicationRepository.java @@ -0,0 +1,7 @@ +package com.kyonggi.teampu.domain.application.repository; + +import com.kyonggi.teampu.domain.application.domain.Application; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ApplicationRepository extends JpaRepository { +} diff --git a/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java new file mode 100644 index 0000000..ebcde43 --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java @@ -0,0 +1,30 @@ +package com.kyonggi.teampu.domain.application.service; + +import com.kyonggi.teampu.domain.application.domain.Application; +import com.kyonggi.teampu.domain.application.dto.ApplicationRequest; +import com.kyonggi.teampu.domain.application.dto.ApplicationResponse; +import com.kyonggi.teampu.domain.application.repository.ApplicationRepository; +import com.kyonggi.teampu.domain.member.domain.Member; +import com.kyonggi.teampu.domain.member.repository.MemberRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ApplicationService { + private final ApplicationRepository applicationRepository; + private final MemberRepository memberRepository; + + @Transactional + public ApplicationResponse createApplication(ApplicationRequest request) { + Member member = memberRepository.findById(request.getMemberId()) + .orElseThrow(() -> new IllegalArgumentException("회원을 찾을 수 없습니다")); + + Application application = request.toEntity(member); + Application savedApplication = applicationRepository.save(application); + ApplicationResponse applicationResponse = ApplicationResponse.of(savedApplication); + + return ApplicationResponse.of(applicationRepository.save(application)); + } +} \ No newline at end of file diff --git a/src/main/java/com/kyonggi/teampu/domain/member/repository/MemberRepository.java b/src/main/java/com/kyonggi/teampu/domain/member/repository/MemberRepository.java new file mode 100644 index 0000000..d4c46ee --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/member/repository/MemberRepository.java @@ -0,0 +1,7 @@ +package com.kyonggi.teampu.domain.member.repository; + +import com.kyonggi.teampu.domain.member.domain.Member; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberRepository extends JpaRepository { +} diff --git a/src/main/java/com/kyonggi/teampu/global/config/SecurityConfig.java b/src/main/java/com/kyonggi/teampu/global/config/SecurityConfig.java index 180839f..54e308e 100644 --- a/src/main/java/com/kyonggi/teampu/global/config/SecurityConfig.java +++ b/src/main/java/com/kyonggi/teampu/global/config/SecurityConfig.java @@ -1,58 +1,58 @@ -package com.kyonggi.teampu.global.config; - -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.web.cors.CorsConfiguration; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -@Configuration -@EnableWebSecurity -@RequiredArgsConstructor -public class SecurityConfig { - private static final String[] PUBLIC_URLS = { - "/**" - }; - - @Bean - public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { - return configuration.getAuthenticationManager(); - } - - @Bean - public BCryptPasswordEncoder bCryptPasswordEncoder() { - return new BCryptPasswordEncoder(); - } - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - //CORS 설정 - http.cors((cors) -> cors - .configurationSource(request -> { - CorsConfiguration configuration = new CorsConfiguration(); - configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000", "http://localhost:8080")); - configuration.setAllowedMethods(Collections.singletonList("*")); - configuration.setAllowCredentials(true); - configuration.setAllowedHeaders(Collections.singletonList("*")); - configuration.setMaxAge(3600L); - configuration.setExposedHeaders(List.of("Authorization")); - return configuration; - })); - - http.csrf(AbstractHttpConfigurer::disable); - http.formLogin(AbstractHttpConfigurer::disable); - http.httpBasic(AbstractHttpConfigurer::disable); - - return http.build(); - } -} +//package com.kyonggi.teampu.global.config; +// +//import lombok.RequiredArgsConstructor; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.security.authentication.AuthenticationManager; +//import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +//import org.springframework.security.config.annotation.web.builders.HttpSecurity; +//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +//import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +//import org.springframework.security.web.SecurityFilterChain; +//import org.springframework.web.cors.CorsConfiguration; +// +//import java.util.Arrays; +//import java.util.Collections; +//import java.util.List; +// +//@Configuration +//@EnableWebSecurity +//@RequiredArgsConstructor +//public class SecurityConfig { +// private static final String[] PUBLIC_URLS = { +// "/**" +// }; +// +// @Bean +// public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { +// return configuration.getAuthenticationManager(); +// } +// +// @Bean +// public BCryptPasswordEncoder bCryptPasswordEncoder() { +// return new BCryptPasswordEncoder(); +// } +// +// @Bean +// public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { +// //CORS 설정 +// http.cors((cors) -> cors +// .configurationSource(request -> { +// CorsConfiguration configuration = new CorsConfiguration(); +// configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000", "http://localhost:8080")); +// configuration.setAllowedMethods(Collections.singletonList("*")); +// configuration.setAllowCredentials(true); +// configuration.setAllowedHeaders(Collections.singletonList("*")); +// configuration.setMaxAge(3600L); +// configuration.setExposedHeaders(List.of("Authorization")); +// return configuration; +// })); +// +// http.csrf(AbstractHttpConfigurer::disable); +// http.formLogin(AbstractHttpConfigurer::disable); +// http.httpBasic(AbstractHttpConfigurer::disable); +// +// return http.build(); +// } +//} diff --git a/src/main/java/com/kyonggi/teampu/global/response/ApiResponse.java b/src/main/java/com/kyonggi/teampu/global/response/ApiResponse.java index 038dbb2..bbd87e4 100644 --- a/src/main/java/com/kyonggi/teampu/global/response/ApiResponse.java +++ b/src/main/java/com/kyonggi/teampu/global/response/ApiResponse.java @@ -19,7 +19,7 @@ public static ApiResponse ok(T body) { @Getter @AllArgsConstructor - private static class Status { + public static class Status { private HttpStatus httpStatus; private String message; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index dc1a63d..75a93db 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,4 +1,8 @@ spring: + h2: + console: + enabled: true + path: /h2-console datasource: url: jdbc:h2:mem:test username: sa From 2cdb954ab7df6c3035581069363c9fd520c7bb3d Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sat, 23 Nov 2024 15:38:06 +0900 Subject: [PATCH 02/20] =?UTF-8?q?refactor:=20ApplicationController=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=B0=98=ED=99=98=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ResponseEntity를 ApiResponse로 통일 * ApiResponse.exception을 활용해 응답 --- .../controller/ApplicationController.java | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java index 169df20..bc9df00 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java @@ -3,10 +3,9 @@ import com.kyonggi.teampu.domain.application.dto.ApplicationRequest; import com.kyonggi.teampu.domain.application.dto.ApplicationResponse; import com.kyonggi.teampu.domain.application.service.ApplicationService; +import com.kyonggi.teampu.global.exception.ErrorCode; import com.kyonggi.teampu.global.response.ApiResponse; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -19,31 +18,20 @@ public class ApplicationController { private final ApplicationService applicationService; @PostMapping - public ResponseEntity> createApplication(@RequestBody ApplicationRequest applicationRequest) { + public ApiResponse createApplication(@RequestBody ApplicationRequest applicationRequest) { // 400 에러 처리 - if (applicationRequest.getMemberId() == null || applicationRequest.getStartTime() == null || applicationRequest.getEndTime() == null) { - return ResponseEntity - .status(HttpStatus.BAD_REQUEST) - .body(new ApiResponse<>( - new ApiResponse.Status(HttpStatus.BAD_REQUEST, "필수 값이 누락되었습니다"), - null - )); + if (applicationRequest.getMemberId() == null || + applicationRequest.getStartTime() == null || + applicationRequest.getEndTime() == null) { + return ApiResponse.exception(ErrorCode.INVALID_REQUEST); } - try { - ApplicationResponse applicationResponse = applicationService.createApplication(applicationRequest); - return ResponseEntity.ok(new ApiResponse<>( - new ApiResponse.Status(HttpStatus.CREATED, "신청이 완료되었습니다"), - applicationResponse - )); - } catch (IllegalArgumentException e) { + // 201 응답 처리 + ApplicationResponse aplApplicationResponse = applicationService.createApplication(applicationRequest); + return ApiResponse.ok(aplApplicationResponse); + }catch (IllegalArgumentException e){ // 401 에러 처리 - return ResponseEntity - .status(HttpStatus.UNAUTHORIZED) - .body(new ApiResponse<>( - new ApiResponse.Status(HttpStatus.UNAUTHORIZED, "권한이 없습니다"), - null - )); + return ApiResponse.exception(ErrorCode.NOT_ENOUGH_PERMISSION); } } } \ No newline at end of file From 85f0e2516969f3f45d7e247251368cfb5657f423 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sat, 23 Nov 2024 16:22:50 +0900 Subject: [PATCH 03/20] =?UTF-8?q?ApplicationRequest=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../teampu/domain/application/dto/ApplicationRequest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java index 8e23cb7..ce89bd4 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java @@ -3,7 +3,6 @@ import com.kyonggi.teampu.domain.application.domain.Application; import com.kyonggi.teampu.domain.application.domain.ApplicationStatus; import com.kyonggi.teampu.domain.member.domain.Member; -import com.kyonggi.teampu.domain.member.domain.MemberType; import lombok.Getter; import lombok.NoArgsConstructor; @@ -14,12 +13,6 @@ @Getter @NoArgsConstructor public class ApplicationRequest { - private String name; - private MemberType type; - private Long memberId; - private String loginId; - private String phoneNumber; - private String email; private Integer participantCount; private List coParticipantNames; private Boolean privacyAgreement; From d04b67538a5d598fe8ca944f4c60c1b31abb97ca Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sat, 23 Nov 2024 16:24:07 +0900 Subject: [PATCH 04/20] =?UTF-8?q?refactor:=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=ED=95=9C=20=ED=9A=8C=EC=9B=90=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Spring Security 도입하여 코드 리팩토링 * ApplicationController에서 Authentication을 이용해 loginId 가져옴 * ApplicationService에서 findByLoginId 적용 --- .../controller/ApplicationController.java | 12 ++++++++---- .../application/service/ApplicationService.java | 7 +++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java index bc9df00..88e916a 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java @@ -6,6 +6,8 @@ import com.kyonggi.teampu.global.exception.ErrorCode; import com.kyonggi.teampu.global.response.ApiResponse; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -19,15 +21,17 @@ public class ApplicationController { @PostMapping public ApiResponse createApplication(@RequestBody ApplicationRequest applicationRequest) { + // 현재 로그인한 회원 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String loginId = authentication.getName(); // 로그인 ID 가져오기 + // 400 에러 처리 - if (applicationRequest.getMemberId() == null || - applicationRequest.getStartTime() == null || - applicationRequest.getEndTime() == null) { + if (applicationRequest.getStartTime() == null || applicationRequest.getEndTime() == null) { return ApiResponse.exception(ErrorCode.INVALID_REQUEST); } try { // 201 응답 처리 - ApplicationResponse aplApplicationResponse = applicationService.createApplication(applicationRequest); + ApplicationResponse aplApplicationResponse = applicationService.createApplication(loginId, applicationRequest); return ApiResponse.ok(aplApplicationResponse); }catch (IllegalArgumentException e){ // 401 에러 처리 diff --git a/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java index ebcde43..46c3935 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java @@ -17,14 +17,13 @@ public class ApplicationService { private final MemberRepository memberRepository; @Transactional - public ApplicationResponse createApplication(ApplicationRequest request) { - Member member = memberRepository.findById(request.getMemberId()) + public ApplicationResponse createApplication(String loginId, ApplicationRequest request) { + Member member = memberRepository.findByLoginId(loginId) .orElseThrow(() -> new IllegalArgumentException("회원을 찾을 수 없습니다")); Application application = request.toEntity(member); Application savedApplication = applicationRepository.save(application); - ApplicationResponse applicationResponse = ApplicationResponse.of(savedApplication); - return ApplicationResponse.of(applicationRepository.save(application)); + return ApplicationResponse.of(savedApplication); } } \ No newline at end of file From 4586e4f44635f424a0ed6f5c4a53c0412188858e Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sat, 23 Nov 2024 16:55:42 +0900 Subject: [PATCH 05/20] =?UTF-8?q?feat:=20CoParticipantResponse=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20DTO=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/dto/CoParticipantResponse.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java diff --git a/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java b/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java new file mode 100644 index 0000000..b6d7618 --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java @@ -0,0 +1,15 @@ +package com.kyonggi.teampu.domain.member.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +public class CoParticipantResponse { + private final Long userId; + private final String loginId; + private final String name; + +} From 8f40ecfbc78d1f939dd8aa075880f599b27d74be Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sat, 23 Nov 2024 17:20:01 +0900 Subject: [PATCH 06/20] =?UTF-8?q?feat:=20CoParticipantRequest=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20DTO=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/dto/CoParticipantRequest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java diff --git a/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java b/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java new file mode 100644 index 0000000..dfe817c --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java @@ -0,0 +1,15 @@ +package com.kyonggi.teampu.domain.member.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +public class CoParticipantRequest { + private final Long userId; + private final String loginId; + private final String name; + +} From 7e6af98dd59bf94ecd9e33a616cc3a504a480c85 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sat, 23 Nov 2024 17:53:15 +0900 Subject: [PATCH 07/20] =?UTF-8?q?refactor:=20MemberInfoResponse=EC=97=90?= =?UTF-8?q?=20@Builder,=20@AllArgsConstructor=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kyonggi/teampu/domain/member/dto/MemberInfoResponse.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/kyonggi/teampu/domain/member/dto/MemberInfoResponse.java b/src/main/java/com/kyonggi/teampu/domain/member/dto/MemberInfoResponse.java index 1a43b9e..522dbc5 100644 --- a/src/main/java/com/kyonggi/teampu/domain/member/dto/MemberInfoResponse.java +++ b/src/main/java/com/kyonggi/teampu/domain/member/dto/MemberInfoResponse.java @@ -1,9 +1,13 @@ package com.kyonggi.teampu.domain.member.dto; import com.kyonggi.teampu.domain.member.domain.Member; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; @Getter +@Builder +@AllArgsConstructor public class MemberInfoResponse { private final Long userId; private final String loginId; @@ -26,4 +30,5 @@ public MemberInfoResponse(Member member) { this.type = member.getType().name(); this.isAdmin = member.getIsAdmin(); } + } From dfaf8ae62cde732a8d6319dc1d39bf17c11a1889 Mon Sep 17 00:00:00 2001 From: jae woo Jung Date: Sat, 23 Nov 2024 18:31:42 +0900 Subject: [PATCH 08/20] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=EB=90=9C=20memb?= =?UTF-8?q?erRepository=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/myPage/repository/MemberRepository.java | 10 ---------- .../teampu/domain/myPage/service/MyPageService.java | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java diff --git a/src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java b/src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java deleted file mode 100644 index 28ecc05..0000000 --- a/src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.kyonggi.teampu.domain.myPage.repository; - -import com.kyonggi.teampu.domain.member.domain.Member; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface MemberRepository extends JpaRepository { - Optional findByLoginId(String loginId); -} diff --git a/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java b/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java index ad33642..38a29f9 100644 --- a/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java +++ b/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java @@ -1,9 +1,9 @@ package com.kyonggi.teampu.domain.myPage.service; import com.kyonggi.teampu.domain.member.domain.Member; +import com.kyonggi.teampu.domain.member.repository.MemberRepository; import com.kyonggi.teampu.domain.myPage.dto.MyPageRequest; import com.kyonggi.teampu.domain.myPage.dto.MyPageResponse.MyPageDTO; -import com.kyonggi.teampu.domain.myPage.repository.MemberRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; From d679f527c4a6f7dfa4597a866431b952d46cfa8b Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 16:45:37 +0900 Subject: [PATCH 09/20] =?UTF-8?q?refactor:=20ApplicationController=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=ED=83=80=EC=9E=85=EC=9D=84=20void?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ApplicationController.java | 32 ++++++-------- .../application/dto/ApplicationResponse.java | 43 ------------------- .../member/dto/CoParticipantResponse.java | 15 ------- .../myPage/repository/MemberRepository.java | 10 ----- 4 files changed, 12 insertions(+), 88 deletions(-) delete mode 100644 src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java delete mode 100644 src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java delete mode 100644 src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java diff --git a/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java index 88e916a..da5a0db 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/controller/ApplicationController.java @@ -1,13 +1,11 @@ package com.kyonggi.teampu.domain.application.controller; import com.kyonggi.teampu.domain.application.dto.ApplicationRequest; -import com.kyonggi.teampu.domain.application.dto.ApplicationResponse; import com.kyonggi.teampu.domain.application.service.ApplicationService; -import com.kyonggi.teampu.global.exception.ErrorCode; +import com.kyonggi.teampu.domain.auth.domain.CustomMemberDetails; import com.kyonggi.teampu.global.response.ApiResponse; import lombok.RequiredArgsConstructor; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -19,23 +17,17 @@ public class ApplicationController { private final ApplicationService applicationService; + /** + * 신청서 작성 API + * */ @PostMapping - public ApiResponse createApplication(@RequestBody ApplicationRequest applicationRequest) { - // 현재 로그인한 회원 정보 가져오기 - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String loginId = authentication.getName(); // 로그인 ID 가져오기 + public ApiResponse createApplication(@RequestBody ApplicationRequest applicationRequest, + @AuthenticationPrincipal CustomMemberDetails customMemberDetails) { + // @AuthenticationPrincipal 스프링 시큐리티 활용해서 사용자 정보 받아옴 - // 400 에러 처리 - if (applicationRequest.getStartTime() == null || applicationRequest.getEndTime() == null) { - return ApiResponse.exception(ErrorCode.INVALID_REQUEST); - } - try { - // 201 응답 처리 - ApplicationResponse aplApplicationResponse = applicationService.createApplication(loginId, applicationRequest); - return ApiResponse.ok(aplApplicationResponse); - }catch (IllegalArgumentException e){ - // 401 에러 처리 - return ApiResponse.exception(ErrorCode.NOT_ENOUGH_PERMISSION); - } + applicationService.createApplication(applicationRequest, customMemberDetails); + + return ApiResponse.ok(); // POST에 대해서 리턴 값 필요없음 >> Void } + } \ No newline at end of file diff --git a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java deleted file mode 100644 index b869801..0000000 --- a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationResponse.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.kyonggi.teampu.domain.application.dto; - -import com.kyonggi.teampu.domain.application.domain.Application; -import com.kyonggi.teampu.domain.member.domain.MemberType; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; - -import java.time.LocalDateTime; -import java.util.List; - -@Getter -@Builder -@AllArgsConstructor -public class ApplicationResponse { - private String loginId; - private String name; - private MemberType type; - private Long memberId; - private String phoneNumber; - private String email; - private Integer participantCount; - private List coParticipantNames; - private Boolean privacyAgreement; - private LocalDateTime startTime; - private LocalDateTime endTime; - - public static ApplicationResponse of(Application application) { - return ApplicationResponse.builder() - .loginId(application.getMember().getLoginId()) - .name(application.getMember().getName()) - .type(application.getMember().getType()) - .memberId(application.getMember().getId()) - .phoneNumber(application.getMember().getPhoneNumber()) - .email(application.getMember().getEmail()) - .participantCount(application.getParticipantCount()) - .coParticipantNames(application.getCoParticipantNames()) - .privacyAgreement(application.getPrivacyAgreement()) - .startTime(application.getStartTime()) - .endTime(application.getEndTime()) - .build(); - } -} diff --git a/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java b/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java deleted file mode 100644 index b6d7618..0000000 --- a/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.kyonggi.teampu.domain.member.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -@AllArgsConstructor -public class CoParticipantResponse { - private final Long userId; - private final String loginId; - private final String name; - -} diff --git a/src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java b/src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java deleted file mode 100644 index 28ecc05..0000000 --- a/src/main/java/com/kyonggi/teampu/domain/myPage/repository/MemberRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.kyonggi.teampu.domain.myPage.repository; - -import com.kyonggi.teampu.domain.member.domain.Member; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface MemberRepository extends JpaRepository { - Optional findByLoginId(String loginId); -} From f940741fb3ebe78194bf132f1f2ef78e42247ee1 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 16:48:00 +0900 Subject: [PATCH 10/20] =?UTF-8?q?refactor:=20Application=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=EC=9D=98=20=EB=82=A0=EC=A7=9C=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20Member=20=EB=A7=A4?= =?UTF-8?q?=ED=95=91=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/application/domain/Application.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java b/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java index 5fcf914..e439053 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java @@ -9,7 +9,6 @@ import lombok.NoArgsConstructor; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -25,11 +24,8 @@ public class Application { @Column(name = "application_id") private Long id; - @Column(name = "start_time", nullable = false) - private LocalDateTime startTime; - - @Column(name = "end_time", nullable = false) - private LocalDateTime endTime; + @Column(name = "date", nullable = false) + private LocalDate date; @Column(name = "applied_date", nullable = false) private LocalDate appliedDate; @@ -43,7 +39,7 @@ public class Application { @ElementCollection // JPA에서 값 타입 컬렉션을 매핑할 때 사용하는 어노테이션 @Column(name = "co_participant_names") - private List coParticipantNames = new ArrayList<>(); + private List coParticipants = new ArrayList<>(); @Column(name = "privacy_agreement") private Boolean privacyAgreement; @@ -51,4 +47,10 @@ public class Application { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; + + private String applicantName; // Member의 name + private String applicantLoginId; // Member의 loginId + private String applicantPhone; // Member의 phoneNumber + private String applicantEmail; // Member의 email + } From 6845361a064cfb1bbeead05713f59915b0dfbcbf Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 16:50:49 +0900 Subject: [PATCH 11/20] =?UTF-8?q?refactor:=20ApplicationRequest=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=82=A0=EC=A7=9C=20=EB=B3=80=EC=88=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20builder=20=ED=8C=A8=ED=84=B4=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/dto/ApplicationRequest.java | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java index ce89bd4..d161cf3 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java @@ -1,34 +1,26 @@ package com.kyonggi.teampu.domain.application.dto; - -import com.kyonggi.teampu.domain.application.domain.Application; -import com.kyonggi.teampu.domain.application.domain.ApplicationStatus; -import com.kyonggi.teampu.domain.member.domain.Member; +import com.kyonggi.teampu.domain.member.dto.CoParticipantRequest; +import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.List; +/** + * 예약 제출 페이지에서 + * 사용자의 정보(이름, 학번, 전화번호, 이메일)를 자동으로 받아옴 >> 로그인 정보에서 가져옴 + * 날짜 >> 사용자가 직접 입력 + * 공동 참여자 목록(이름, 전화번호) >> 사용자가 직접 입력 + * 인원 >> 공동 참여자 목록 + 1으로 신청자 포함한 사용 인원 자동 계산 + * 개인정보 동의 여부 >> 사용자가 직접 체크 + */ + @Getter -@NoArgsConstructor +@AllArgsConstructor public class ApplicationRequest { - private Integer participantCount; - private List coParticipantNames; - private Boolean privacyAgreement; - private LocalDateTime startTime; - private LocalDateTime endTime; + // 로그인 정보를 통해 이름, 학번, 전화번호, 이메일 받아옴 + private LocalDate date; // 날짜 + private List coParticipants; // 공동 참여자 목록 (이름, 전화번호) + private Boolean privacyAgreement; // 개인정보 동의 여부 - public Application toEntity(Member member) { - return Application.builder() - .member(member) - .participantCount(participantCount) - .coParticipantNames(coParticipantNames) - .privacyAgreement(privacyAgreement) - .startTime(startTime) - .endTime(endTime) - .appliedDate(LocalDate.now()) - .status(ApplicationStatus.PENDING) - .build(); - } } \ No newline at end of file From a1c780764ad33daa1cb41f64d40ab4db0291e665 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 16:53:50 +0900 Subject: [PATCH 12/20] =?UTF-8?q?fix:=20MyPageService=EC=9D=98=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=EB=90=9C=20import=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/kyonggi/teampu/domain/myPage/service/MyPageService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java b/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java index ad33642..28157d4 100644 --- a/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java +++ b/src/main/java/com/kyonggi/teampu/domain/myPage/service/MyPageService.java @@ -3,7 +3,7 @@ import com.kyonggi.teampu.domain.member.domain.Member; import com.kyonggi.teampu.domain.myPage.dto.MyPageRequest; import com.kyonggi.teampu.domain.myPage.dto.MyPageResponse.MyPageDTO; -import com.kyonggi.teampu.domain.myPage.repository.MemberRepository; +import com.kyonggi.teampu.domain.member.repository.MemberRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; From 3e889daddbc812f789124f1146add05926cb45b9 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 16:55:52 +0900 Subject: [PATCH 13/20] =?UTF-8?q?fix:=20=EA=B3=B5=EB=8F=99=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/dto/CoParticipantRequest.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java b/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java index dfe817c..027079b 100644 --- a/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java +++ b/src/main/java/com/kyonggi/teampu/domain/member/dto/CoParticipantRequest.java @@ -4,12 +4,21 @@ import lombok.Builder; import lombok.Getter; +import java.util.List; + @Getter @Builder @AllArgsConstructor public class CoParticipantRequest { - private final Long userId; - private final String loginId; - private final String name; + // CoParticipantRequest: 공동 참여자 정보를 서버로 전송할 때 사용하는 객체 + private String name; // 이름 + private String phoneNumber; // 전화번호 + + // CoParticipantRequest에서 이름과 전화번호를 리스트로 변환하려면, CoParticipantRequest 클래스에 변환 메서드를 추가 + public static List toNameList(List coParticipantRequests) { + return coParticipantRequests.stream() + .map(CoParticipantRequest::getName) + .toList(); + } } From 0deb19c4cd7594af5e346cfade3aa38857b101a6 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 16:58:04 +0900 Subject: [PATCH 14/20] =?UTF-8?q?fix:=20builder=20=ED=8C=A8=ED=84=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=ED=95=98=EC=97=AC=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=A0=95=EB=B3=B4=EC=99=80=20=EC=A7=81=EC=A0=91=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=ED=95=9C=20=EC=A0=95=EB=B3=B4=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ApplicationService.java | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java index 46c3935..2574402 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java @@ -2,10 +2,9 @@ import com.kyonggi.teampu.domain.application.domain.Application; import com.kyonggi.teampu.domain.application.dto.ApplicationRequest; -import com.kyonggi.teampu.domain.application.dto.ApplicationResponse; import com.kyonggi.teampu.domain.application.repository.ApplicationRepository; -import com.kyonggi.teampu.domain.member.domain.Member; -import com.kyonggi.teampu.domain.member.repository.MemberRepository; +import com.kyonggi.teampu.domain.auth.domain.CustomMemberDetails; +import com.kyonggi.teampu.domain.member.dto.CoParticipantRequest; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -14,16 +13,31 @@ @RequiredArgsConstructor public class ApplicationService { private final ApplicationRepository applicationRepository; - private final MemberRepository memberRepository; @Transactional - public ApplicationResponse createApplication(String loginId, ApplicationRequest request) { - Member member = memberRepository.findByLoginId(loginId) - .orElseThrow(() -> new IllegalArgumentException("회원을 찾을 수 없습니다")); + public void createApplication(ApplicationRequest applicationRequest, CustomMemberDetails customMemberDetails) { + // GET 메서드를 별도로 구현할 예정이라 void 처리 - Application application = request.toEntity(member); - Application savedApplication = applicationRepository.save(application); + /** + * 1. 사용자의 정보(이름, 학번, 전화번호, 이메일) 추출 + * 2. 사용자가 직접 정보 입력(날짜, 명단: 이름, 전화번호, 개인정보 동의) + * 3. 사용 인원 계산 + */ - return ApplicationResponse.of(savedApplication); + // Application.builder()를 사용하여 로그인한 사용자 정보와 입력받은 정보를 결합 + Application application = Application.builder() + .applicantName(customMemberDetails.getMember().getName()) // 이름 + .applicantLoginId(customMemberDetails.getMember().getLoginId()) // 학번 + .applicantPhone(customMemberDetails.getMember().getPhoneNumber()) // 전화번호 + .applicantEmail(customMemberDetails.getMember().getEmail()) // 이메일 + + .date(applicationRequest.getDate()) // 날짜 + .coParticipants(CoParticipantRequest.toNameList(applicationRequest.getCoParticipants())) // 명단(이름, 전화번호) + .participantCount(applicationRequest.getCoParticipants().size() + 1) // 사용 인원 자동 계산 + .privacyAgreement(applicationRequest.getPrivacyAgreement()) // 개인정보 동의 + .build(); + + applicationRepository.save(application); } + } \ No newline at end of file From 32ab2e2212281fa710e3f905922c9b1e13d3a0e6 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 17:27:33 +0900 Subject: [PATCH 15/20] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=20=EC=B6=A9?= =?UTF-8?q?=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 36566b2..8328c63 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,8 +1,4 @@ spring: - h2: - console: - enabled: true - path: /h2-console datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root From 691dbaee5d027726629dcbcd5fef7b53ef06fe4c Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 23:24:52 +0900 Subject: [PATCH 16/20] =?UTF-8?q?feat:=20CoParticipant=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/domain/CoParticipant.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/com/kyonggi/teampu/domain/member/domain/CoParticipant.java diff --git a/src/main/java/com/kyonggi/teampu/domain/member/domain/CoParticipant.java b/src/main/java/com/kyonggi/teampu/domain/member/domain/CoParticipant.java new file mode 100644 index 0000000..46abc80 --- /dev/null +++ b/src/main/java/com/kyonggi/teampu/domain/member/domain/CoParticipant.java @@ -0,0 +1,32 @@ +package com.kyonggi.teampu.domain.member.domain; + +import com.kyonggi.teampu.domain.member.dto.CoParticipantRequest; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * 공동 사용자 정보를 별도의 엔티티로 관리함 + */ +@Embeddable +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class CoParticipant { + @Column(name = "name") + private String name; + + @Column(name = "phone_number") + private String phoneNumber; + + // DTO를 값 타입으로 변환하는 메서드 + public static CoParticipant from(CoParticipantRequest request) { + return new CoParticipant( + request.getName(), + request.getPhoneNumber() + ); + } + +} \ No newline at end of file From 441e3f9a428bfdf6a0daaad6bab4a4399f8ff153 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 23:26:34 +0900 Subject: [PATCH 17/20] =?UTF-8?q?fix:=20date=EB=A5=BC=20appliedDate?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20coParticipants=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../teampu/domain/application/domain/Application.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java b/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java index e439053..e10b1e2 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/domain/Application.java @@ -1,5 +1,6 @@ package com.kyonggi.teampu.domain.application.domain; +import com.kyonggi.teampu.domain.member.domain.CoParticipant; import com.kyonggi.teampu.domain.member.domain.Member; import jakarta.persistence.*; import lombok.AccessLevel; @@ -24,9 +25,6 @@ public class Application { @Column(name = "application_id") private Long id; - @Column(name = "date", nullable = false) - private LocalDate date; - @Column(name = "applied_date", nullable = false) private LocalDate appliedDate; @@ -38,8 +36,11 @@ public class Application { private Integer participantCount; @ElementCollection // JPA에서 값 타입 컬렉션을 매핑할 때 사용하는 어노테이션 - @Column(name = "co_participant_names") - private List coParticipants = new ArrayList<>(); + @CollectionTable( + name = "application_co_participants", + joinColumns = @JoinColumn(name = "application_id") + ) + private List coParticipants = new ArrayList<>(); @Column(name = "privacy_agreement") private Boolean privacyAgreement; From 04cbe5cbad2e96c4087775b1276a983f538f5655 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 23:28:20 +0900 Subject: [PATCH 18/20] =?UTF-8?q?fix:=20ApplicationRequest=EC=97=90=20stat?= =?UTF-8?q?us=20=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../teampu/domain/application/dto/ApplicationRequest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java index d161cf3..4256747 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/dto/ApplicationRequest.java @@ -1,4 +1,5 @@ package com.kyonggi.teampu.domain.application.dto; +import com.kyonggi.teampu.domain.application.domain.ApplicationStatus; import com.kyonggi.teampu.domain.member.dto.CoParticipantRequest; import lombok.AllArgsConstructor; import lombok.Getter; @@ -19,8 +20,9 @@ @AllArgsConstructor public class ApplicationRequest { // 로그인 정보를 통해 이름, 학번, 전화번호, 이메일 받아옴 - private LocalDate date; // 날짜 + private LocalDate appliedDate; // 날짜 private List coParticipants; // 공동 참여자 목록 (이름, 전화번호) private Boolean privacyAgreement; // 개인정보 동의 여부 + private ApplicationStatus status; } \ No newline at end of file From 06b219e47e90961b9de5c6b2ca9a3c33a78aa225 Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 23:29:04 +0900 Subject: [PATCH 19/20] =?UTF-8?q?refactor:=20ApplicationStatus=EC=9D=98=20?= =?UTF-8?q?enum=20=EA=B0=92=EC=9D=84=20json=EC=9C=BC=EB=A1=9C=20=EC=A7=81?= =?UTF-8?q?=EB=A0=AC=ED=99=94/=EC=97=AD=EC=A7=81=EB=A0=AC=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/domain/ApplicationStatus.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/domain/ApplicationStatus.java b/src/main/java/com/kyonggi/teampu/domain/application/domain/ApplicationStatus.java index 13b9a08..51bfcb7 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/domain/ApplicationStatus.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/domain/ApplicationStatus.java @@ -1,7 +1,21 @@ package com.kyonggi.teampu.domain.application.domain; +import com.fasterxml.jackson.annotation.JsonValue; + public enum ApplicationStatus { - PENDING, - APPROVED, - REJECTED + PENDING("pending"), + APPROVED("approved"), + REJECTED("rejected"); + + private final String code; + + ApplicationStatus(String code) { + this.code = code; + } + + @JsonValue + public String getCode() { + return this.code; + } + } From 506cd43f89e14082af5bf356353620a6d4e76e7f Mon Sep 17 00:00:00 2001 From: ahyeonkong Date: Sun, 24 Nov 2024 23:30:49 +0900 Subject: [PATCH 20/20] =?UTF-8?q?fix:=20Builder=20=ED=8C=A8=ED=84=B4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=97=90=20memberId,=20coParticipants,=20sta?= =?UTF-8?q?tus=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/service/ApplicationService.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java index 2574402..d1fe7f1 100644 --- a/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java +++ b/src/main/java/com/kyonggi/teampu/domain/application/service/ApplicationService.java @@ -4,11 +4,15 @@ import com.kyonggi.teampu.domain.application.dto.ApplicationRequest; import com.kyonggi.teampu.domain.application.repository.ApplicationRepository; import com.kyonggi.teampu.domain.auth.domain.CustomMemberDetails; -import com.kyonggi.teampu.domain.member.dto.CoParticipantRequest; +import com.kyonggi.teampu.domain.member.domain.CoParticipant; +import com.kyonggi.teampu.domain.member.domain.Member; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.stream.Collectors; + @Service @RequiredArgsConstructor public class ApplicationService { @@ -24,17 +28,24 @@ public void createApplication(ApplicationRequest applicationRequest, CustomMembe * 3. 사용 인원 계산 */ + Member member = customMemberDetails.getMember(); + List coParticipants = applicationRequest.getCoParticipants().stream() + .map(CoParticipant::from) + .collect(Collectors.toList()); + // Application.builder()를 사용하여 로그인한 사용자 정보와 입력받은 정보를 결합 Application application = Application.builder() + .member(member) // memberId .applicantName(customMemberDetails.getMember().getName()) // 이름 .applicantLoginId(customMemberDetails.getMember().getLoginId()) // 학번 .applicantPhone(customMemberDetails.getMember().getPhoneNumber()) // 전화번호 .applicantEmail(customMemberDetails.getMember().getEmail()) // 이메일 - .date(applicationRequest.getDate()) // 날짜 - .coParticipants(CoParticipantRequest.toNameList(applicationRequest.getCoParticipants())) // 명단(이름, 전화번호) + .appliedDate(applicationRequest.getAppliedDate()) // 날짜 + .coParticipants(coParticipants) // 명단(이름, 전화번호) .participantCount(applicationRequest.getCoParticipants().size() + 1) // 사용 인원 자동 계산 .privacyAgreement(applicationRequest.getPrivacyAgreement()) // 개인정보 동의 + .status(applicationRequest.getStatus()) .build(); applicationRepository.save(application);