diff --git a/backend/src/main/java/middle_point_search/backend/common/exception/errorCode/UserErrorCode.java b/backend/src/main/java/middle_point_search/backend/common/exception/errorCode/UserErrorCode.java index 9e71bb46..dcdc2994 100644 --- a/backend/src/main/java/middle_point_search/backend/common/exception/errorCode/UserErrorCode.java +++ b/backend/src/main/java/middle_point_search/backend/common/exception/errorCode/UserErrorCode.java @@ -19,6 +19,7 @@ public enum UserErrorCode implements ErrorCode { ROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 방입니다."), PLACE_NOT_FOUND(HttpStatus.NOT_FOUND, "방에 입력된 장소가 없습니다."), PLACE_CONFLICT(HttpStatus.CONFLICT, "이미 장소를 저장하였습니다."), + ROOM_TYPE_UNPROCESSABLE(HttpStatus.UNPROCESSABLE_ENTITY, "방의 타입이 일치하지 않습니다."), VOTE_NOT_FOUND(HttpStatus.NOT_FOUND, "투표를 한 적이 없습니다."), VOTE_ROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "생성된 투표방이 없습니다."), @@ -27,9 +28,7 @@ public enum UserErrorCode implements ErrorCode { DUPLICATE_VOTE_ROOM(HttpStatus.CONFLICT, "이미 투표방이 존재합니다."), //5xx - API_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "API 서버에 문제가 발생하였습니다.") - - ; + API_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "API 서버에 문제가 발생하였습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/backend/src/main/java/middle_point_search/backend/common/properties/JwtProperties.java b/backend/src/main/java/middle_point_search/backend/common/properties/JwtProperties.java index 750c9b6b..4dbcd8dc 100644 --- a/backend/src/main/java/middle_point_search/backend/common/properties/JwtProperties.java +++ b/backend/src/main/java/middle_point_search/backend/common/properties/JwtProperties.java @@ -15,6 +15,7 @@ public class JwtProperties { private Access access; private Refresh refresh; private RoomId roomId; + private RoomType roomType; private String ACCESS_TOKEN_SUBJECT = "AccessToken"; private String REFRESH_TOKEN_SUBJECT = "RefreshToken"; @@ -41,4 +42,10 @@ public static class Refresh { public static class RoomId { private String header; } + + @Getter + @Setter + public static class RoomType { + private String header; + } } diff --git a/backend/src/main/java/middle_point_search/backend/common/security/conf/SecurityConfig.java b/backend/src/main/java/middle_point_search/backend/common/security/conf/SecurityConfig.java index f91a23d1..2fd5c4ff 100644 --- a/backend/src/main/java/middle_point_search/backend/common/security/conf/SecurityConfig.java +++ b/backend/src/main/java/middle_point_search/backend/common/security/conf/SecurityConfig.java @@ -28,6 +28,7 @@ import middle_point_search.backend.common.security.login.handler.LoginSuccessHandler; import middle_point_search.backend.common.security.login.provider.CustomAuthenticationProvider; import middle_point_search.backend.domains.member.repository.MemberRepository; +import middle_point_search.backend.domains.room.repository.RoomRepository; @Configuration @EnableWebSecurity @@ -38,6 +39,7 @@ public class SecurityConfig { private final CustomAuthenticationProvider authenticationProvider; private final JwtTokenProvider jwtTokenProvider; private final MemberRepository memberRepository; + private final RoomRepository roomRepository; private final SecurityProperties securityProperties; private final UrlBasedCorsConfigurationSource ConfigurationSource; @@ -107,7 +109,7 @@ public JsonNamePwAuthenticationFilter jsonUsernamePasswordLoginFilter() throws E //JWT 필터 등록 @Bean public JwtAuthenticationFilter jwtAuthenticationFilter() { - return new JwtAuthenticationFilter(jwtTokenProvider, memberRepository, securityProperties, pathMatcher); + return new JwtAuthenticationFilter(jwtTokenProvider, memberRepository, securityProperties, pathMatcher, roomRepository); } //예외 핸들링 필터 등록 diff --git a/backend/src/main/java/middle_point_search/backend/common/security/jwt/filter/JwtAuthenticationFilter.java b/backend/src/main/java/middle_point_search/backend/common/security/jwt/filter/JwtAuthenticationFilter.java index 3030baf3..8ae03b18 100644 --- a/backend/src/main/java/middle_point_search/backend/common/security/jwt/filter/JwtAuthenticationFilter.java +++ b/backend/src/main/java/middle_point_search/backend/common/security/jwt/filter/JwtAuthenticationFilter.java @@ -23,6 +23,9 @@ import middle_point_search.backend.common.properties.SecurityProperties; import middle_point_search.backend.common.security.jwt.provider.JwtTokenProvider; import middle_point_search.backend.domains.member.repository.MemberRepository; +import middle_point_search.backend.domains.room.domain.Room; +import middle_point_search.backend.domains.room.domain.RoomType; +import middle_point_search.backend.domains.room.repository.RoomRepository; @Slf4j @RequiredArgsConstructor @@ -32,6 +35,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final MemberRepository memberRepository; private final SecurityProperties securityProperties; private final AntPathMatcher pathMatcher; + private final RoomRepository roomRepository; @Override protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { @@ -51,8 +55,12 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse final String refreshToken = jwtTokenProvider.extractRefreshToken(request).orElse(null); final String accessToken = jwtTokenProvider.extractAccessToken(request).orElse(null); + final String tokenRoomId = jwtTokenProvider.extractRoomId(accessToken).orElse(null); + final String nowRoomId = jwtTokenProvider.extractRoomId(request).orElse(null); - final String tokenRoomId = jwtTokenProvider.extractRoomId(accessToken).orElse(null); + final RoomType nowRoomType = jwtTokenProvider.extractRoomType(request).orElse(null); + final Room room = roomRepository.findByIdentityNumber(nowRoomId) + .orElseThrow(() -> new CustomException(ROOM_NOT_FOUND)); //1. access토큰이 존재하며, accessToken이 유효하면 인증 //2. access토큰이 존재하며, accesToken이 유효하지 않으면 에러 리턴 @@ -72,6 +80,11 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse throw new CustomException(UNAUTHORIZED); } + //토큰의 있는 방의 Type과 헤더릐 RoomType이 같은지 검사 + if (nowRoomType != room.getRoomType()) { + throw new CustomException(ROOM_TYPE_UNPROCESSABLE); + } + log.info("access토큰 인증 성공"); Authentication authentication = jwtTokenProvider.getAuthentication(accessToken); saveAuthentication(authentication); diff --git a/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProvider.java b/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProvider.java index b6665529..aad68dca 100644 --- a/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProvider.java +++ b/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProvider.java @@ -7,6 +7,7 @@ import io.jsonwebtoken.Claims; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import middle_point_search.backend.domains.room.domain.RoomType; public interface JwtTokenProvider { @@ -30,6 +31,8 @@ public interface JwtTokenProvider { Optional extractRoomId(HttpServletRequest request); + Optional extractRoomType(HttpServletRequest request); + Claims parseClaims(String accessToken); Optional extractName(String accessToken); diff --git a/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProviderImpl.java b/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProviderImpl.java index 5cb55212..c5bb24c2 100644 --- a/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProviderImpl.java +++ b/backend/src/main/java/middle_point_search/backend/common/security/jwt/provider/JwtTokenProviderImpl.java @@ -36,6 +36,7 @@ import middle_point_search.backend.common.util.ResponseWriter; import middle_point_search.backend.domains.member.domain.Member; import middle_point_search.backend.domains.member.repository.MemberRepository; +import middle_point_search.backend.domains.room.domain.RoomType; @Transactional(readOnly = true) @Service @@ -161,6 +162,12 @@ public Optional extractRoomId(HttpServletRequest request) { return Optional.ofNullable(request.getHeader(jwtProperties.getRoomId().getHeader())); } + @Override + public Optional extractRoomType(HttpServletRequest request) { + String roomType = request.getHeader(jwtProperties.getRoomType().getHeader()); + return Optional.ofNullable(RoomType.getRoomTypeByName(roomType)); + } + @Override public Claims parseClaims(String accessToken) { try { diff --git a/backend/src/main/java/middle_point_search/backend/common/security/login/service/CustomUserDetailsServiceImpl.java b/backend/src/main/java/middle_point_search/backend/common/security/login/service/CustomUserDetailsServiceImpl.java index 2781560c..345be58d 100644 --- a/backend/src/main/java/middle_point_search/backend/common/security/login/service/CustomUserDetailsServiceImpl.java +++ b/backend/src/main/java/middle_point_search/backend/common/security/login/service/CustomUserDetailsServiceImpl.java @@ -31,7 +31,7 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService { @Transactional public UserDetails loadUserByUsernameAndRoomId(String roomId, String name, String pw) throws UsernameNotFoundException, RoomNotFoundException { - roomRepository.findRoomByIdentityNumber(roomId); + roomRepository.findByIdentityNumber(roomId); if (!roomRepository.existsByIdentityNumber(roomId)) { throw new RoomNotFoundException("해당하는 방이 존재하지 않습니다"); } diff --git a/backend/src/main/java/middle_point_search/backend/common/util/MemberLoader.java b/backend/src/main/java/middle_point_search/backend/common/util/MemberLoader.java index f310a176..cd5387d1 100644 --- a/backend/src/main/java/middle_point_search/backend/common/util/MemberLoader.java +++ b/backend/src/main/java/middle_point_search/backend/common/util/MemberLoader.java @@ -35,7 +35,7 @@ public Member getMember() { public Room getRoom() { String roomId = getRoomId(); - return roomRepository.findRoomByIdentityNumber(roomId) + return roomRepository.findByIdentityNumber(roomId) .orElseThrow(() -> new CustomException(ROOM_NOT_FOUND)); } diff --git a/backend/src/main/java/middle_point_search/backend/domains/member/service/MemberService.java b/backend/src/main/java/middle_point_search/backend/domains/member/service/MemberService.java index 6982e28b..c60ba06f 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/member/service/MemberService.java +++ b/backend/src/main/java/middle_point_search/backend/domains/member/service/MemberService.java @@ -40,7 +40,7 @@ public class MemberService { public Member createMember(String roomId, String name, String pw) throws RoomNotFoundException { pw = encodePassword(pw); - Room room = roomRepository.findRoomByIdentityNumber(roomId) + Room room = roomRepository.findByIdentityNumber(roomId) .orElseThrow(() -> new RoomNotFoundException("해당하는 방이 존재하지 않습니다")); //회원 권한 정하기 diff --git a/backend/src/main/java/middle_point_search/backend/domains/midPoint/controller/MidPointController.java b/backend/src/main/java/middle_point_search/backend/domains/midPoint/controller/MidPointController.java index f159ba99..cdbda3c4 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/midPoint/controller/MidPointController.java +++ b/backend/src/main/java/middle_point_search/backend/domains/midPoint/controller/MidPointController.java @@ -38,7 +38,8 @@ public class MidPointController { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -64,6 +65,10 @@ public class MidPointController { responseCode = "404", description = "방에 입력된 장소가 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) diff --git a/backend/src/main/java/middle_point_search/backend/domains/place/controller/PlaceController.java b/backend/src/main/java/middle_point_search/backend/domains/place/controller/PlaceController.java index 6e342b37..d485ae6e 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/place/controller/PlaceController.java +++ b/backend/src/main/java/middle_point_search/backend/domains/place/controller/PlaceController.java @@ -48,20 +48,21 @@ public class PlaceController { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( responseCode = "200", description = "성공" ), - @ApiResponse( - responseCode = "400", - description = "방 타입이 일치하지 않습니다." - ), @ApiResponse( responseCode = "401", description = "인증에 실패하였습니다." + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -87,24 +88,25 @@ public ResponseEntity placeSaveOrUpdate(@RequestBody @Valid PlaceS AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( responseCode = "200", description = "성공" ), - @ApiResponse( - responseCode = "400", - description = "방 타입이 일치하지 않습니다." - ), @ApiResponse( responseCode = "401", description = "인증에 실패하였습니다." + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) - public ResponseEntity placesSaveOrUpdateBySelf(@RequestBody PlacesSaveOrUpdateBySelfRequest request) { + public ResponseEntity placesSaveOrUpdateBySelf(@RequestBody @Valid PlacesSaveOrUpdateBySelfRequest request) { Room room = memberLoader.getRoom(); @@ -123,7 +125,8 @@ public ResponseEntity placesSaveOrUpdateBySelf(@RequestBody Places AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -137,6 +140,10 @@ public ResponseEntity placesSaveOrUpdateBySelf(@RequestBody Places @ApiResponse( responseCode = "401", description = "인증에 실패하였습니다." + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -157,7 +164,8 @@ public ResponseEntity> placeFind() { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -171,6 +179,10 @@ public ResponseEntity> placeFind() { @ApiResponse( responseCode = "401", description = "인증에 실패하였습니다." + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) diff --git a/backend/src/main/java/middle_point_search/backend/domains/place/service/PlaceService.java b/backend/src/main/java/middle_point_search/backend/domains/place/service/PlaceService.java index 2a010e0d..1a639334 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/place/service/PlaceService.java +++ b/backend/src/main/java/middle_point_search/backend/domains/place/service/PlaceService.java @@ -23,8 +23,6 @@ import middle_point_search.backend.domains.place.dto.PlaceDTO.PlacesSaveOrUpdateBySelfRequest; import middle_point_search.backend.domains.place.repository.PlaceRepository; import middle_point_search.backend.domains.room.domain.Room; -import middle_point_search.backend.domains.room.domain.RoomType; -import middle_point_search.backend.domains.room.service.RoomService; @Slf4j @Service @@ -33,14 +31,12 @@ public class PlaceService { private final PlaceRepository placeRepository; - private final RoomService roomService; private final MemberService memberService; //장소 저장 및 업데이트 하고, Member 및 Room 역할 변경 @Transactional(rollbackFor = {CustomException.class}) public void saveOrUpdatePlaceAndRoleUpdate(Room room, Member member, PlaceSaveOrUpdateRequest request) { - roomService.updateRoomType(room, RoomType.TOGETHER); saveOrUpdatePlace(room, member, request); memberService.updateMemberRole(member, Role.USER); } @@ -69,7 +65,6 @@ private void saveOrUpdatePlace(Room room, Member member, PlaceSaveOrUpdateReques public void saveOrUpdatePlacesBySelfAndRoleUpdate(Room room, PlacesSaveOrUpdateBySelfRequest request) { String roomId = room.getIdentityNumber(); - roomService.updateRoomType(room, RoomType.SELF); saveOrUpdatePlacesBySelf(room, request); memberService.updateRomeMembersRole(roomId, Role.USER); } @@ -100,7 +95,7 @@ public PlaceFindResponse findPlace(String roomId, String memberName) { //내 장소 조회 PlaceVO myPlace = placeRepository.findByRoom_IdentityNumberAndMember_Name(roomId, memberName) - .map(Place:: toVO) + .map(Place::toVO) .orElse(null); //내 장소 존재 유무 diff --git a/backend/src/main/java/middle_point_search/backend/domains/placeVoteRoom/controller/PlaceVoteRoomController.java b/backend/src/main/java/middle_point_search/backend/domains/placeVoteRoom/controller/PlaceVoteRoomController.java index b939b430..738634d3 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/placeVoteRoom/controller/PlaceVoteRoomController.java +++ b/backend/src/main/java/middle_point_search/backend/domains/placeVoteRoom/controller/PlaceVoteRoomController.java @@ -48,7 +48,8 @@ public class PlaceVoteRoomController { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -74,6 +75,10 @@ public class PlaceVoteRoomController { responseCode = "409", description = "이미 투표방이 존재합니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -96,7 +101,8 @@ public ResponseEntity> placeVoteRoomCr AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -122,6 +128,10 @@ public ResponseEntity> placeVoteRoomCr responseCode = "404", description = "생성된 투표방이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -143,7 +153,8 @@ public ResponseEntity> placeVoteRoomRe AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -164,6 +175,10 @@ public ResponseEntity> placeVoteRoomRe responseCode = "404", description = "생성된 투표방이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -184,7 +199,8 @@ public ResponseEntity> placeVoteRoomGet() { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -215,6 +231,10 @@ public ResponseEntity> placeVoteRoomGet() { responseCode = "409", description = "이미 투표를 하였습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -236,7 +256,8 @@ public ResponseEntity vote(@RequestBody @Valid PlaceVoteRequest request) { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -267,6 +288,10 @@ public ResponseEntity vote(@RequestBody @Valid PlaceVoteRequest request) { responseCode = "404", description = "투표를 한 적이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -288,7 +313,8 @@ public ResponseEntity voteUpdate(@RequestBody @Valid PlaceVoteRequest request AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -304,6 +330,10 @@ public ResponseEntity voteUpdate(@RequestBody @Valid PlaceVoteRequest request responseCode = "403", description = "접근이 거부되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -324,7 +354,8 @@ public ResponseEntity> placeVoteRoomHas() { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -345,6 +376,10 @@ public ResponseEntity> placeVoteRoomHas() { responseCode = "404", description = "생성된 투표방이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) diff --git a/backend/src/main/java/middle_point_search/backend/domains/recommendPlace/controller/RecommendPlaceController.java b/backend/src/main/java/middle_point_search/backend/domains/recommendPlace/controller/RecommendPlaceController.java index 0ca6e28b..20b0075d 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/recommendPlace/controller/RecommendPlaceController.java +++ b/backend/src/main/java/middle_point_search/backend/domains/recommendPlace/controller/RecommendPlaceController.java @@ -44,7 +44,8 @@ public class RecommendPlaceController { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -65,6 +66,10 @@ public class RecommendPlaceController { responseCode = "403", description = "접근이 거부되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) diff --git a/backend/src/main/java/middle_point_search/backend/domains/room/controller/RoomController.java b/backend/src/main/java/middle_point_search/backend/domains/room/controller/RoomController.java index 8898c6d5..1f0c0b6f 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/room/controller/RoomController.java +++ b/backend/src/main/java/middle_point_search/backend/domains/room/controller/RoomController.java @@ -4,6 +4,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; 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; @@ -20,6 +21,7 @@ import middle_point_search.backend.common.util.MemberLoader; import middle_point_search.backend.domains.room.domain.Room; import middle_point_search.backend.domains.room.dto.RoomDTO; +import middle_point_search.backend.domains.room.dto.RoomDTO.RoomCreateRequest; import middle_point_search.backend.domains.room.dto.RoomDTO.RoomCreateResponse; import middle_point_search.backend.domains.room.dto.RoomDTO.RoomExistenceCheckResponse; import middle_point_search.backend.domains.room.service.RoomService; @@ -49,8 +51,8 @@ public class RoomController { ) } ) - public ResponseEntity> roomCreate() { - RoomCreateResponse response = roomService.createRoom(); + public ResponseEntity> roomCreate(@RequestBody RoomCreateRequest request) { + RoomCreateResponse response = roomService.createRoom(request); return ResponseEntity.ok(DataResponse.from(response)); } @@ -81,7 +83,8 @@ public ResponseEntity> roomExistenceChe accessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -92,6 +95,15 @@ public ResponseEntity> roomExistenceChe responseCode = "401", description = "인증에 실패하였습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "403", + description = "접근이 거부되었습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) diff --git a/backend/src/main/java/middle_point_search/backend/domains/room/domain/Room.java b/backend/src/main/java/middle_point_search/backend/domains/room/domain/Room.java index 145d502b..4a735068 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/room/domain/Room.java +++ b/backend/src/main/java/middle_point_search/backend/domains/room/domain/Room.java @@ -46,8 +46,7 @@ public class Room { private List members = new ArrayList<>(); @OneToMany(mappedBy = "room", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List places - = new ArrayList<>(); + private List places = new ArrayList<>(); @Enumerated(EnumType.STRING) private RoomType roomType; @@ -55,17 +54,14 @@ public class Room { @Enumerated(EnumType.STRING) private Animal roomName; - public Room(String identityNumber) { + public Room(String identityNumber, RoomType roomType) { this.identityNumber = identityNumber; - this.roomType = RoomType.DISABLED; + this.roomType = roomType; this.roomName = Animal.getRandomAnimal(); } - public static Room from(String identityNumber) { - return new Room(identityNumber); + public static Room from(String identityNumber, RoomType roomType) { + return new Room(identityNumber, roomType); } - public void updateRoomType(RoomType roomType) { - this.roomType = roomType; - } } diff --git a/backend/src/main/java/middle_point_search/backend/domains/room/domain/RoomType.java b/backend/src/main/java/middle_point_search/backend/domains/room/domain/RoomType.java index fab95fa8..0958af92 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/room/domain/RoomType.java +++ b/backend/src/main/java/middle_point_search/backend/domains/room/domain/RoomType.java @@ -1,10 +1,27 @@ package middle_point_search.backend.domains.room.domain; +import static middle_point_search.backend.common.exception.errorCode.CommonErrorCode.*; + +import java.util.Arrays; +import java.util.Objects; + +import middle_point_search.backend.common.exception.CustomException; + public enum RoomType { - TOGETHER, - SELF, - DISABLED; + TOGETHER("TOGETHER"), + SELF("SELF"), + DISABLED("DISABLED"); + + private String roomName; + + RoomType(String roomName) { + this.roomName = roomName; + } - RoomType() { + public static RoomType getRoomTypeByName(String name) { + return Arrays.stream(RoomType.values()) + .filter(roomType -> Objects.equals(roomType.roomName, name)) + .findFirst() + .orElseThrow(() -> new CustomException(BAD_REQUEST)); } } diff --git a/backend/src/main/java/middle_point_search/backend/domains/room/dto/RoomDTO.java b/backend/src/main/java/middle_point_search/backend/domains/room/dto/RoomDTO.java index 65eff1a7..34fc30c6 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/room/dto/RoomDTO.java +++ b/backend/src/main/java/middle_point_search/backend/domains/room/dto/RoomDTO.java @@ -1,8 +1,11 @@ package middle_point_search.backend.domains.room.dto; +import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; +import middle_point_search.backend.domains.room.domain.RoomType; public class RoomDTO { @@ -35,4 +38,12 @@ public static RoomNameResponse from(String name) { return new RoomNameResponse(name); } } + + @Getter + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class RoomCreateRequest { + + @NotNull + private RoomType roomType; + } } diff --git a/backend/src/main/java/middle_point_search/backend/domains/room/repository/RoomRepository.java b/backend/src/main/java/middle_point_search/backend/domains/room/repository/RoomRepository.java index 267252ee..c4c214a8 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/room/repository/RoomRepository.java +++ b/backend/src/main/java/middle_point_search/backend/domains/room/repository/RoomRepository.java @@ -11,7 +11,7 @@ public interface RoomRepository extends JpaRepository { boolean existsByIdentityNumber(String identityNumber); - Optional findRoomByIdentityNumber(String identityNumber); + Optional findByIdentityNumber(String identityNumber); void deleteByCreatedAtBefore(LocalDateTime localDateTime); diff --git a/backend/src/main/java/middle_point_search/backend/domains/room/service/RoomService.java b/backend/src/main/java/middle_point_search/backend/domains/room/service/RoomService.java index a5d78275..33afee99 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/room/service/RoomService.java +++ b/backend/src/main/java/middle_point_search/backend/domains/room/service/RoomService.java @@ -11,6 +11,7 @@ import middle_point_search.backend.domains.room.domain.Room; import middle_point_search.backend.domains.room.domain.RoomType; import middle_point_search.backend.domains.room.dto.RoomDTO; +import middle_point_search.backend.domains.room.dto.RoomDTO.RoomCreateRequest; import middle_point_search.backend.domains.room.dto.RoomDTO.RoomCreateResponse; import middle_point_search.backend.domains.room.dto.RoomDTO.RoomExistenceCheckResponse; import middle_point_search.backend.domains.room.dto.RoomDTO.RoomNameResponse; @@ -25,10 +26,11 @@ public class RoomService { //Room 저장하기 @Transactional - public RoomCreateResponse createRoom() { + public RoomCreateResponse createRoom(RoomCreateRequest request) { String identityNumber = UUID.randomUUID().toString(); + RoomType roomType = request.getRoomType(); - Room room = Room.from(identityNumber); + Room room = Room.from(identityNumber, roomType); roomRepository.save(room); @@ -41,19 +43,6 @@ public RoomExistenceCheckResponse checkRoomExistence(String identityNumber) { return RoomExistenceCheckResponse.from(existence); } - //RoomType 변경하기 - @Transactional - public void updateRoomType(Room room, RoomType roomType) { - //1.방 type이 disable로 지정이 안되어 있을 경우에만 변경 - //2.방 type과 다른 방타입으로 요청이 왔으면 에러 리턴 - //3.그 외는 패스 - if (room.getRoomType() == RoomType.DISABLED) { - room.updateRoomType(roomType); - } else if (roomType != room.getRoomType()) { - throw new CustomException(CommonErrorCode.BAD_REQUEST); - } - } - //Room 이름 조회 public RoomNameResponse findRoomName(Room room) { String name = room.getRoomName().getKoreanName(); diff --git a/backend/src/main/java/middle_point_search/backend/domains/timeVoteRoom/controller/TimeVoteRoomController.java b/backend/src/main/java/middle_point_search/backend/domains/timeVoteRoom/controller/TimeVoteRoomController.java index 3b279359..7a8620ee 100644 --- a/backend/src/main/java/middle_point_search/backend/domains/timeVoteRoom/controller/TimeVoteRoomController.java +++ b/backend/src/main/java/middle_point_search/backend/domains/timeVoteRoom/controller/TimeVoteRoomController.java @@ -37,8 +37,6 @@ public class TimeVoteRoomController { private final MemberLoader memberLoader; //투표방 생성 - //투표방 재생성 - @PostMapping @Operation( summary = "시간투표방 생성하기", @@ -49,7 +47,8 @@ public class TimeVoteRoomController { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -87,6 +86,8 @@ public ResponseEntity> timeVoteRoomCrea return ResponseEntity.ok(DataResponse.from(response)); } + + //투표방 재생성 @PutMapping @Operation( summary = "시간투표방 재생성하기", @@ -97,7 +98,8 @@ public ResponseEntity> timeVoteRoomCrea AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -123,6 +125,10 @@ public ResponseEntity> timeVoteRoomCrea responseCode = "404", description = "생성된 투표방이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -145,7 +151,8 @@ public ResponseEntity> timeVoteRoomRecr AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -172,6 +179,10 @@ public ResponseEntity> timeVoteRoomRecr responseCode = "409", description = "이미 투표를 하였습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -194,7 +205,8 @@ public ResponseEntity vote(@RequestBody @Valid TimeVoteRoomVoteRequest reques AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -220,6 +232,10 @@ public ResponseEntity vote(@RequestBody @Valid TimeVoteRoomVoteRequest reques responseCode = "404", description = "투표를 한 적이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -242,7 +258,8 @@ public ResponseEntity voteUpdate(@RequestBody @Valid TimeVoteRoomVoteRequest AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -258,6 +275,10 @@ public ResponseEntity voteUpdate(@RequestBody @Valid TimeVoteRoomVoteRequest responseCode = "403", description = "접근이 거부되었습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -279,7 +300,8 @@ public ResponseEntity> timeVoteRoomHas() { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -300,6 +322,10 @@ public ResponseEntity> timeVoteRoomHas() { responseCode = "404", description = "생성된 투표방이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) } ) @@ -322,7 +348,8 @@ public ResponseEntity> votedHas() { AccessToken 필요.""", parameters = { - @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER) + @Parameter(name = "RoomId", description = "roomId 필요", in = ParameterIn.HEADER), + @Parameter(name = "RoomType", description = "roomType 필요. [TOGETHER, SELF] 중 하나", in = ParameterIn.HEADER) }, responses = { @ApiResponse( @@ -343,6 +370,10 @@ public ResponseEntity> votedHas() { responseCode = "404", description = "생성된 투표방이 없습니다.", content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "422", + description = "방의 타입이 일치하지 않습니다" ) }