diff --git a/src/main/java/com/neighbors/tohero/application/letter/dto/GetMyLettersResponse.java b/src/main/java/com/neighbors/tohero/application/letter/dto/GetMyLettersResponse.java index f9beb09..d7e93f5 100644 --- a/src/main/java/com/neighbors/tohero/application/letter/dto/GetMyLettersResponse.java +++ b/src/main/java/com/neighbors/tohero/application/letter/dto/GetMyLettersResponse.java @@ -2,8 +2,6 @@ import com.neighbors.tohero.domain.domain.mainPage.model.Letter; -import java.text.Format; -import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; @@ -16,7 +14,8 @@ public record MyLetterInfo( String from, String createdAt, boolean isOpened, - String content + String content, + boolean isPublic ){ public static MyLetterInfo from(Letter letter){ return new MyLetterInfo( @@ -25,7 +24,9 @@ public static MyLetterInfo from(Letter letter){ letter.getWriter(), letter.getCreatedDate().format(DateTimeFormatter.ofPattern("YY.MM.dd")), letter.isOpened(), - letter.getLetterContent()); + letter.getLetterContent(), + letter.isPublic() + ); } } diff --git a/src/main/java/com/neighbors/tohero/application/user/dto/SignOutRequest.java b/src/main/java/com/neighbors/tohero/application/user/dto/SignOutRequest.java new file mode 100644 index 0000000..a592886 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/application/user/dto/SignOutRequest.java @@ -0,0 +1,16 @@ +package com.neighbors.tohero.application.user.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import jakarta.validation.constraints.NotBlank; +import org.hibernate.validator.constraints.Length; + +public record SignOutRequest( + @NotBlank + @Length(min = 1, max = 30) + String reasonCategory, + + @JsonInclude(JsonInclude.Include.NON_NULL) + @Length(min = 1, max = 500) + String opinionForService +) { +} diff --git a/src/main/java/com/neighbors/tohero/application/user/service/UserService.java b/src/main/java/com/neighbors/tohero/application/user/service/UserService.java index 3ff2cc9..7180d30 100644 --- a/src/main/java/com/neighbors/tohero/application/user/service/UserService.java +++ b/src/main/java/com/neighbors/tohero/application/user/service/UserService.java @@ -5,12 +5,14 @@ import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; import com.neighbors.tohero.application.user.dto.AuthenticateUserRequest; import com.neighbors.tohero.application.user.dto.AuthenticateUserResponse; +import com.neighbors.tohero.application.user.dto.SignOutRequest; import com.neighbors.tohero.common.enums.Role; import com.neighbors.tohero.common.jwt.AuthTokens; import com.neighbors.tohero.common.jwt.JwtProvider; import com.neighbors.tohero.common.jwt.JwtUserDetails; import com.neighbors.tohero.domain.domain.user.model.User; import com.neighbors.tohero.domain.domain.user.service.CreateUser; +import com.neighbors.tohero.domain.domain.user.service.CreateUserOpinion; import com.neighbors.tohero.domain.domain.user.service.DeleteUser; import com.neighbors.tohero.domain.domain.user.service.UpdateUser; import jakarta.servlet.http.HttpSession; @@ -25,6 +27,7 @@ public class UserService { private final CreateUser createUser; private final DeleteUser deleteUser; private final JwtProvider jwtProvider; + private final CreateUserOpinion createUserOpinion; public BaseResponse updateUserName(long userId, String nickname){ @@ -51,9 +54,10 @@ public BaseResponse logout(HttpSession httpSession){ ); } - public BaseResponse signout(JwtUserDetails jwtUserDetails, HttpSession httpSession){ + public BaseResponse signout(JwtUserDetails jwtUserDetails, HttpSession httpSession, SignOutRequest signOutRequest){ httpSession.invalidate(); + createUserOpinion.createSignOutOpinion(signOutRequest.reasonCategory(), signOutRequest.opinionForService(), jwtUserDetails.getEmail()); deleteUser.signout(jwtUserDetails.getUserId()); return new BaseResponse<>( diff --git a/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java b/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java index 904afd1..5525eae 100644 --- a/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java +++ b/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java @@ -82,6 +82,7 @@ public CorsFilter corsFilter() { List allowedOrigins = new ArrayList<>(); allowedOrigins.add("https://glittery-madeleine-215e2f.netlify.app"); allowedOrigins.add("https://tohero.co.kr"); + allowedOrigins.add("http://localhost:5173"); config.setAllowedOrigins(allowedOrigins); // 여러 도메인 추가 config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 허용할 HTTP 메서드 config.setAllowedHeaders(List.of("*")); // 모든 헤더 허용 diff --git a/src/main/java/com/neighbors/tohero/domain/domain/user/model/UserOpinion.java b/src/main/java/com/neighbors/tohero/domain/domain/user/model/UserOpinion.java new file mode 100644 index 0000000..86b728b --- /dev/null +++ b/src/main/java/com/neighbors/tohero/domain/domain/user/model/UserOpinion.java @@ -0,0 +1,13 @@ +package com.neighbors.tohero.domain.domain.user.model; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class UserOpinion { + private int opinionId; + private String signOutCategory; + private String adviceForService; + private String userEmail; +} diff --git a/src/main/java/com/neighbors/tohero/domain/domain/user/service/CreateUserOpinion.java b/src/main/java/com/neighbors/tohero/domain/domain/user/service/CreateUserOpinion.java new file mode 100644 index 0000000..cce5b7b --- /dev/null +++ b/src/main/java/com/neighbors/tohero/domain/domain/user/service/CreateUserOpinion.java @@ -0,0 +1,24 @@ +package com.neighbors.tohero.domain.domain.user.service; + +import com.neighbors.tohero.common.annotaion.DomainService; +import com.neighbors.tohero.domain.domain.user.model.UserOpinion; +import com.neighbors.tohero.domain.query.UserOpinionRepository; +import lombok.RequiredArgsConstructor; + +@DomainService +@RequiredArgsConstructor +public class CreateUserOpinion { + + private final UserOpinionRepository userOpinionRepository; + + public void createSignOutOpinion(String signOutCategory, String adviceForService, String email){ + + UserOpinion userOpinion = UserOpinion.builder() + .signOutCategory(signOutCategory) + .adviceForService(adviceForService) + .userEmail(email) + .build(); + + userOpinionRepository.createSignOutOpinion(userOpinion); + } +} diff --git a/src/main/java/com/neighbors/tohero/domain/query/UserOpinionRepository.java b/src/main/java/com/neighbors/tohero/domain/query/UserOpinionRepository.java new file mode 100644 index 0000000..3dfe015 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/domain/query/UserOpinionRepository.java @@ -0,0 +1,7 @@ +package com.neighbors.tohero.domain.query; + +import com.neighbors.tohero.domain.domain.user.model.UserOpinion; + +public interface UserOpinionRepository { + void createSignOutOpinion(UserOpinion userOpinion); +} diff --git a/src/main/java/com/neighbors/tohero/infrastructure/entity/UserOpinionEntity.java b/src/main/java/com/neighbors/tohero/infrastructure/entity/UserOpinionEntity.java new file mode 100644 index 0000000..1fa0e0c --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/entity/UserOpinionEntity.java @@ -0,0 +1,33 @@ +package com.neighbors.tohero.infrastructure.entity; + +import jakarta.persistence.*; +import lombok.Builder; + +@Entity +@Table(name = "`UserOpinion`") +public class UserOpinionEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_opinion_id") + long userOpinionId; + + @Column(name = "signout_category") + String signOutCategory; + + @Column(name = "advice_for_service") + String adviceForService; + + @Column(name = "user_email") + String userEmail; + + private UserOpinionEntity(String signOutCategory, String adviceForService, String email){ + this.signOutCategory = signOutCategory; + this.adviceForService = adviceForService; + this.userEmail = email; + } + + public static UserOpinionEntity of(String signOutCategory, String adviceForService, String email) { + return new UserOpinionEntity(signOutCategory, adviceForService, email); + } +} diff --git a/src/main/java/com/neighbors/tohero/infrastructure/mapper/UserOpinionMapper.java b/src/main/java/com/neighbors/tohero/infrastructure/mapper/UserOpinionMapper.java new file mode 100644 index 0000000..c254c45 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/mapper/UserOpinionMapper.java @@ -0,0 +1,13 @@ +package com.neighbors.tohero.infrastructure.mapper; + +import com.neighbors.tohero.domain.domain.user.model.UserOpinion; +import com.neighbors.tohero.infrastructure.entity.UserOpinionEntity; +import org.springframework.stereotype.Component; + +@Component +public class UserOpinionMapper { + + public UserOpinionEntity toEntity(UserOpinion userOpinion) { + return UserOpinionEntity.of(userOpinion.getSignOutCategory(), userOpinion.getAdviceForService(), userOpinion.getUserEmail()); + } +} diff --git a/src/main/java/com/neighbors/tohero/infrastructure/query/impl/UserOpinionRepositoryImpl.java b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/UserOpinionRepositoryImpl.java new file mode 100644 index 0000000..e0e38b7 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/UserOpinionRepositoryImpl.java @@ -0,0 +1,23 @@ +package com.neighbors.tohero.infrastructure.query.impl; + +import com.neighbors.tohero.domain.domain.user.model.UserOpinion; +import com.neighbors.tohero.domain.query.UserOpinionRepository; +import com.neighbors.tohero.infrastructure.entity.UserOpinionEntity; +import com.neighbors.tohero.infrastructure.mapper.UserOpinionMapper; +import com.neighbors.tohero.infrastructure.repository.UserOpinionEntityRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class UserOpinionRepositoryImpl implements UserOpinionRepository { + + private final UserOpinionMapper userOpinionMapper; + private final UserOpinionEntityRepository userOpinionEntityRepository; + + @Override + public void createSignOutOpinion(UserOpinion userOpinion) { + UserOpinionEntity userOpinionEntity = userOpinionMapper.toEntity(userOpinion); + userOpinionEntityRepository.save(userOpinionEntity); + } +} diff --git a/src/main/java/com/neighbors/tohero/infrastructure/repository/UserOpinionEntityRepository.java b/src/main/java/com/neighbors/tohero/infrastructure/repository/UserOpinionEntityRepository.java new file mode 100644 index 0000000..0cc1b42 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/repository/UserOpinionEntityRepository.java @@ -0,0 +1,9 @@ +package com.neighbors.tohero.infrastructure.repository; + +import com.neighbors.tohero.infrastructure.entity.UserOpinionEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserOpinionEntityRepository extends JpaRepository { +} diff --git a/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java b/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java index a129096..dffe015 100644 --- a/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java +++ b/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java @@ -2,6 +2,7 @@ import com.neighbors.tohero.application.baseResponse.BaseResponse; import com.neighbors.tohero.application.user.dto.AuthenticateUserRequest; +import com.neighbors.tohero.application.user.dto.SignOutRequest; import com.neighbors.tohero.application.user.dto.UpdateUserName; import com.neighbors.tohero.application.user.service.UserService; import com.neighbors.tohero.common.jwt.JwtUserDetails; @@ -50,9 +51,10 @@ public ResponseEntity logout(@Parameter(hidden=true) HttpSession h @PostMapping("/signout") public ResponseEntity signout( @Parameter(hidden=true) @AuthenticationPrincipal JwtUserDetails jwtUserDetail, - @Parameter(hidden=true) HttpSession httpSession + @Parameter(hidden=true) HttpSession httpSession, + @RequestBody @Validated SignOutRequest signOutRequest ){ return ResponseEntity.ok() - .body(userService.signout(jwtUserDetail, httpSession)); + .body(userService.signout(jwtUserDetail, httpSession, signOutRequest)); } }