diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml
deleted file mode 100644
index 02a1f2d..0000000
--- a/.github/workflows/auto-assign.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: Auto Assignees and PR Reviewers
-
-on:
- issues:
- types: [ opened ]
- pull_request:
- types: [ opened, ready_for_review ]
-
-jobs:
- auto_assign:
- runs-on: ubuntu-latest
- steps:
- - name: Assign Issue assignees
- if: ${{ github.event_name == 'issues' }}
- uses: actions-ecosystem/action-add-assignees@v1
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- assignees: ${{ github.actor }}
-
- - name: Assign PR reviewers
- if: ${{ github.event_name == 'pull_request' }}
- uses: hkusu/review-assign-action@v1
- with:
- assignees: ${{ github.actor }}
- reviewers: 2heunxun, JangYeongHu, semi-yu
\ No newline at end of file
diff --git a/.github/workflows/code-style-test.yml b/.github/workflows/code-style-test.yml
new file mode 100644
index 0000000..b389c45
--- /dev/null
+++ b/.github/workflows/code-style-test.yml
@@ -0,0 +1,43 @@
+name: Java Code Style Check
+
+on:
+ pull_request:
+ branches: ['**']
+ push:
+ branches: ['**']
+ workflow_dispatch:
+
+jobs:
+ style-check:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v3
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+
+ - name: Run Spotless and Checkstyle
+ run: |
+ set -e
+ ./gradlew spotlessCheck --no-daemon
+ ./gradlew checkstyleMain checkstyleTest --no-daemon
+ shell: bash
+
+ - name: Show summary
+ run: |
+ if [ $? -eq 0 ]; then
+ echo "๐ Code style checks passed!"
+ else
+ echo "โ Code style violations detected!"
+ echo "Please run './gradlew spotlessApply' locally and fix Checkstyle issues."
+ exit 1
+ fi
+ shell: bash
diff --git a/build.gradle b/build.gradle
index 10b912a..ed442ea 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,6 +2,7 @@ plugins {
id 'java'
id 'org.springframework.boot' version '3.5.7'
id 'io.spring.dependency-management' version '1.1.7'
+ id 'com.diffplug.spotless' version '6.25.0'
}
group = 'opensource'
@@ -64,3 +65,27 @@ dependencies {
tasks.named('test') {
useJUnitPlatform()
}
+
+apply plugin: 'checkstyle'
+
+checkstyle {
+ toolVersion = '10.12.0'
+ configFile = file('config/checkstyle/google_checks.xml')
+}
+
+tasks.withType(Checkstyle) {
+ reports {
+ xml.required.set(true)
+ html.required.set(true)
+ }
+}
+
+// Spotless ์ ์ฉ
+apply plugin: 'com.diffplug.spotless'
+
+spotless {
+ java {
+ googleJavaFormat()
+ target 'src/**/*.java'
+ }
+}
\ No newline at end of file
diff --git a/config/checkstyle/google_checks.xml b/config/checkstyle/google_checks.xml
new file mode 100644
index 0000000..6eff7fe
--- /dev/null
+++ b/config/checkstyle/google_checks.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/opensource/bravest/BravestApplication.java b/src/main/java/opensource/bravest/BravestApplication.java
index 58c22c0..144da2e 100644
--- a/src/main/java/opensource/bravest/BravestApplication.java
+++ b/src/main/java/opensource/bravest/BravestApplication.java
@@ -6,8 +6,7 @@
@SpringBootApplication
public class BravestApplication {
- public static void main(String[] args) {
- SpringApplication.run(BravestApplication.class, args);
- }
-
+ public static void main(String[] args) {
+ SpringApplication.run(BravestApplication.class, args);
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/chatList/controller/ChatListController.java b/src/main/java/opensource/bravest/domain/chatList/controller/ChatListController.java
index 3f6bdc7..38810d3 100644
--- a/src/main/java/opensource/bravest/domain/chatList/controller/ChatListController.java
+++ b/src/main/java/opensource/bravest/domain/chatList/controller/ChatListController.java
@@ -1,9 +1,12 @@
package opensource.bravest.domain.chatList.controller;
+import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListCreateRequest;
import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListResponse;
import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListUpdateRequest;
-import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListCreateRequest;
+import jakarta.validation.Valid;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
import opensource.bravest.domain.chatList.service.ChatListService;
import opensource.bravest.global.apiPayload.ApiResponse;
import org.springframework.web.bind.annotation.DeleteMapping;
@@ -15,47 +18,42 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import jakarta.validation.Valid;
-import java.util.List;
-
@RestController
@RequestMapping("/chatlists")
@RequiredArgsConstructor
public class ChatListController {
- private final ChatListService chatListService;
-
- @PostMapping
- public ApiResponse createChatList(@Valid @RequestBody ChatListCreateRequest request) {
- ChatListResponse response = chatListService.createChatList(request);
- return ApiResponse.onSuccess(response);
- }
-
- @GetMapping("/room/{roomId}")
- public ApiResponse> getChatListsByRoomId(@PathVariable Long roomId) {
- List response = chatListService.getChatListsByRoomId(roomId);
- return ApiResponse.onSuccess(response);
- }
-
- @GetMapping("/{id}")
- public ApiResponse getChatListById(@PathVariable Long id) {
- ChatListResponse response = chatListService.getChatListById(id);
- return ApiResponse.onSuccess(response);
- }
-
- @PutMapping("/{id}")
- public ApiResponse updateChatList(@PathVariable Long id,
- @Valid @RequestBody ChatListUpdateRequest request) {
- ChatListResponse response = chatListService.updateChatList(id, request);
- return ApiResponse.onSuccess(response);
- }
-
- @DeleteMapping("/{id}")
- public ApiResponse deleteChatList(@PathVariable Long id) {
- chatListService.deleteChatList(id);
- return ApiResponse.onSuccess(null);
- }
-}
\ No newline at end of file
+ private final ChatListService chatListService;
+
+ @PostMapping
+ public ApiResponse createChatList(
+ @Valid @RequestBody ChatListCreateRequest request) {
+ ChatListResponse response = chatListService.createChatList(request);
+ return ApiResponse.onSuccess(response);
+ }
+
+ @GetMapping("/room/{roomId}")
+ public ApiResponse> getChatListsByRoomId(@PathVariable Long roomId) {
+ List response = chatListService.getChatListsByRoomId(roomId);
+ return ApiResponse.onSuccess(response);
+ }
+
+ @GetMapping("/{id}")
+ public ApiResponse getChatListById(@PathVariable Long id) {
+ ChatListResponse response = chatListService.getChatListById(id);
+ return ApiResponse.onSuccess(response);
+ }
+
+ @PutMapping("/{id}")
+ public ApiResponse updateChatList(
+ @PathVariable Long id, @Valid @RequestBody ChatListUpdateRequest request) {
+ ChatListResponse response = chatListService.updateChatList(id, request);
+ return ApiResponse.onSuccess(response);
+ }
+
+ @DeleteMapping("/{id}")
+ public ApiResponse deleteChatList(@PathVariable Long id) {
+ chatListService.deleteChatList(id);
+ return ApiResponse.onSuccess(null);
+ }
+}
diff --git a/src/main/java/opensource/bravest/domain/chatList/dto/ChatListDto.java b/src/main/java/opensource/bravest/domain/chatList/dto/ChatListDto.java
index 282cfb4..77baf7d 100644
--- a/src/main/java/opensource/bravest/domain/chatList/dto/ChatListDto.java
+++ b/src/main/java/opensource/bravest/domain/chatList/dto/ChatListDto.java
@@ -1,53 +1,51 @@
package opensource.bravest.domain.chatList.dto;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
+import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import opensource.bravest.domain.chatList.entity.ChatList;
-import java.time.LocalDateTime;
public class ChatListDto {
- // 1. ์์ด๋์ด ์์ฑ ์์ฒญ DTO (Create Request)
- @Getter
- @Setter
- public static class ChatListCreateRequest {
-
- private Long roomId;
-
- private String content;
-
- private Long registeredBy;
- }
-
- // 2. ์์ด๋์ด ์์ ์์ฒญ DTO (Update Request)
- @Getter
- @Setter
- public static class ChatListUpdateRequest {
-
- // ์์ด๋์ด ๋ด์ฉ ์์ ๋ง ๊ฐ์
- private String content;
- }
-
- @Getter
- @Builder
- public static class ChatListResponse {
- private Long id;
- private Long roomId;
- private String content;
- private Long registeredBy;
- private LocalDateTime createdAt;
-
- public static ChatListResponse fromEntity(ChatList chatList) {
- return ChatListResponse.builder()
- .id(chatList.getId())
- .roomId(chatList.getRoomId())
- .content(chatList.getContent())
- .registeredBy(chatList.getRegisteredBy().getId())
- .createdAt(chatList.getCreatedAt())
- .build();
- }
+ // 1. ์์ด๋์ด ์์ฑ ์์ฒญ DTO (Create Request)
+ @Getter
+ @Setter
+ public static class ChatListCreateRequest {
+
+ private Long roomId;
+
+ private String content;
+
+ private Long registeredBy;
+ }
+
+ // 2. ์์ด๋์ด ์์ ์์ฒญ DTO (Update Request)
+ @Getter
+ @Setter
+ public static class ChatListUpdateRequest {
+
+ // ์์ด๋์ด ๋ด์ฉ ์์ ๋ง ๊ฐ์
+ private String content;
+ }
+
+ @Getter
+ @Builder
+ public static class ChatListResponse {
+ private Long id;
+ private Long roomId;
+ private String content;
+ private Long registeredBy;
+ private LocalDateTime createdAt;
+
+ public static ChatListResponse fromEntity(ChatList chatList) {
+ return ChatListResponse.builder()
+ .id(chatList.getId())
+ .roomId(chatList.getRoomId())
+ .content(chatList.getContent())
+ .registeredBy(chatList.getRegisteredBy().getId())
+ .createdAt(chatList.getCreatedAt())
+ .build();
}
-}
\ No newline at end of file
+ }
+}
diff --git a/src/main/java/opensource/bravest/domain/chatList/entity/ChatList.java b/src/main/java/opensource/bravest/domain/chatList/entity/ChatList.java
index a9014d1..63cb45a 100644
--- a/src/main/java/opensource/bravest/domain/chatList/entity/ChatList.java
+++ b/src/main/java/opensource/bravest/domain/chatList/entity/ChatList.java
@@ -8,12 +8,10 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
+import java.time.LocalDateTime;
import lombok.AccessLevel;
-import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -21,49 +19,46 @@
import opensource.bravest.domain.room.entity.AnonymousRoom;
import org.hibernate.annotations.CreationTimestamp;
-import java.time.LocalDateTime;
-
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "chat_list")
public class ChatList {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "room_id", nullable = false)
- private AnonymousRoom room;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "room_id", nullable = false)
+ private AnonymousRoom room;
- @NotNull
- @Column(length = 255)
- private String content;
+ @NotNull
+ @Column(length = 255)
+ private String content;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "profile_id", nullable = false)
- private AnonymousProfile registeredBy;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "profile_id", nullable = false)
+ private AnonymousProfile registeredBy;
- @CreationTimestamp
- private LocalDateTime createdAt;
+ @CreationTimestamp private LocalDateTime createdAt;
- @Builder
- public ChatList(AnonymousRoom room, String content, AnonymousProfile registeredBy) {
- this.room = room;
- this.content = content;
- this.registeredBy = registeredBy;
- }
+ @Builder
+ public ChatList(AnonymousRoom room, String content, AnonymousProfile registeredBy) {
+ this.room = room;
+ this.content = content;
+ this.registeredBy = registeredBy;
+ }
- public void updateContent(String content) {
- this.content = content;
- }
+ public void updateContent(String content) {
+ this.content = content;
+ }
- public Long getRoomId() {
- return this.room.getId();
- }
+ public Long getRoomId() {
+ return this.room.getId();
+ }
- public Long getProfileId() {
- return this.registeredBy.getId();
- }
-}
\ No newline at end of file
+ public Long getProfileId() {
+ return this.registeredBy.getId();
+ }
+}
diff --git a/src/main/java/opensource/bravest/domain/chatList/repository/ChatListRepository.java b/src/main/java/opensource/bravest/domain/chatList/repository/ChatListRepository.java
index 45db599..b90efd1 100644
--- a/src/main/java/opensource/bravest/domain/chatList/repository/ChatListRepository.java
+++ b/src/main/java/opensource/bravest/domain/chatList/repository/ChatListRepository.java
@@ -1,13 +1,12 @@
package opensource.bravest.domain.chatList.repository;
+import java.util.List;
import opensource.bravest.domain.chatList.entity.ChatList;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
-import java.util.List;
-
public interface ChatListRepository extends JpaRepository {
- @Query("SELECT c FROM ChatList c WHERE c.room.id = :roomId ORDER BY c.createdAt DESC")
- List findAllByRoomId(Long roomId);
-}
\ No newline at end of file
+ @Query("SELECT c FROM ChatList c WHERE c.room.id = :roomId ORDER BY c.createdAt DESC")
+ List findAllByRoomId(Long roomId);
+}
diff --git a/src/main/java/opensource/bravest/domain/chatList/service/ChatListService.java b/src/main/java/opensource/bravest/domain/chatList/service/ChatListService.java
index 6050c7e..e375a13 100644
--- a/src/main/java/opensource/bravest/domain/chatList/service/ChatListService.java
+++ b/src/main/java/opensource/bravest/domain/chatList/service/ChatListService.java
@@ -1,12 +1,14 @@
package opensource.bravest.domain.chatList.service;
+import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListCreateRequest;
import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListResponse;
import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListUpdateRequest;
-import static opensource.bravest.domain.chatList.dto.ChatListDto.ChatListCreateRequest;
import static opensource.bravest.global.apiPayload.code.status.ErrorStatus._CHATLIST_NOT_FOUND;
import static opensource.bravest.global.apiPayload.code.status.ErrorStatus._CHATROOM_NOT_FOUND;
import static opensource.bravest.global.apiPayload.code.status.ErrorStatus._USER_NOT_FOUND;
+import java.util.List;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import opensource.bravest.domain.chatList.entity.ChatList;
import opensource.bravest.domain.chatList.repository.ChatListRepository;
@@ -18,64 +20,60 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.List;
-import java.util.stream.Collectors;
-
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ChatListService {
- private final ChatListRepository chatListRepository;
- private final AnonymousRoomRepository anonymousRoomRepository;
- private final AnonymousProfileRepository anonymousProfileRepository;
+ private final ChatListRepository chatListRepository;
+ private final AnonymousRoomRepository anonymousRoomRepository;
+ private final AnonymousProfileRepository anonymousProfileRepository;
- @Transactional
- public ChatListResponse createChatList(ChatListCreateRequest request) {
- AnonymousRoom room = anonymousRoomRepository.findById(request.getRoomId())
+ @Transactional
+ public ChatListResponse createChatList(ChatListCreateRequest request) {
+ AnonymousRoom room =
+ anonymousRoomRepository
+ .findById(request.getRoomId())
.orElseThrow(() -> new CustomException(_CHATROOM_NOT_FOUND));
- AnonymousProfile profile = anonymousProfileRepository.findById(request.getRegisteredBy())
+ AnonymousProfile profile =
+ anonymousProfileRepository
+ .findById(request.getRegisteredBy())
.orElseThrow(() -> new CustomException(_USER_NOT_FOUND));
- ChatList chatList = ChatList.builder()
- .room(room)
- .registeredBy(profile)
- .content(request.getContent())
- .build();
+ ChatList chatList =
+ ChatList.builder().room(room).registeredBy(profile).content(request.getContent()).build();
- ChatList savedList = chatListRepository.save(chatList);
- return ChatListResponse.fromEntity(savedList);
- }
+ ChatList savedList = chatListRepository.save(chatList);
+ return ChatListResponse.fromEntity(savedList);
+ }
- public List getChatListsByRoomId(Long roomId) {
- List chatLists = chatListRepository.findAllByRoomId(roomId);
- return chatLists.stream()
- .map(ChatListResponse::fromEntity)
- .collect(Collectors.toList());
- }
+ public List getChatListsByRoomId(Long roomId) {
+ List chatLists = chatListRepository.findAllByRoomId(roomId);
+ return chatLists.stream().map(ChatListResponse::fromEntity).collect(Collectors.toList());
+ }
- public ChatListResponse getChatListById(Long id) {
- ChatList chatList = chatListRepository.findById(id)
- .orElseThrow(() -> new CustomException(_CHATLIST_NOT_FOUND));
- return ChatListResponse.fromEntity(chatList);
- }
+ public ChatListResponse getChatListById(Long id) {
+ ChatList chatList =
+ chatListRepository.findById(id).orElseThrow(() -> new CustomException(_CHATLIST_NOT_FOUND));
+ return ChatListResponse.fromEntity(chatList);
+ }
- @Transactional
- public ChatListResponse updateChatList(Long id, ChatListUpdateRequest request) {
- ChatList chatList = chatListRepository.findById(id)
- .orElseThrow(() -> new CustomException(_CHATLIST_NOT_FOUND));
+ @Transactional
+ public ChatListResponse updateChatList(Long id, ChatListUpdateRequest request) {
+ ChatList chatList =
+ chatListRepository.findById(id).orElseThrow(() -> new CustomException(_CHATLIST_NOT_FOUND));
- chatList.updateContent(request.getContent());
+ chatList.updateContent(request.getContent());
- return ChatListResponse.fromEntity(chatList);
- }
+ return ChatListResponse.fromEntity(chatList);
+ }
- @Transactional
- public void deleteChatList(Long id) {
- if (!chatListRepository.existsById(id)) {
- throw new CustomException(_CHATLIST_NOT_FOUND);
- }
- chatListRepository.deleteById(id);
+ @Transactional
+ public void deleteChatList(Long id) {
+ if (!chatListRepository.existsById(id)) {
+ throw new CustomException(_CHATLIST_NOT_FOUND);
}
-}
\ No newline at end of file
+ chatListRepository.deleteById(id);
+ }
+}
diff --git a/src/main/java/opensource/bravest/domain/message/controller/ChatMessageController.java b/src/main/java/opensource/bravest/domain/message/controller/ChatMessageController.java
index 7c7bee1..609e347 100644
--- a/src/main/java/opensource/bravest/domain/message/controller/ChatMessageController.java
+++ b/src/main/java/opensource/bravest/domain/message/controller/ChatMessageController.java
@@ -1,36 +1,33 @@
package opensource.bravest.domain.message.controller;
+import static opensource.bravest.domain.message.dto.MessageDto.MessageRequest;
+import static opensource.bravest.domain.message.dto.MessageDto.MessageResponse;
+
+import java.security.Principal;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import opensource.bravest.domain.message.service.ChatMessageService;
import opensource.bravest.global.apiPayload.ApiResponse;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
-import org.springframework.stereotype.Controller;
import org.springframework.messaging.simp.SimpMessagingTemplate;
-
-import java.security.Principal;
-
-import static opensource.bravest.domain.message.dto.MessageDto.MessageRequest;
-import static opensource.bravest.domain.message.dto.MessageDto.MessageResponse;
+import org.springframework.stereotype.Controller;
@Slf4j
@Controller
@RequiredArgsConstructor
public class ChatMessageController {
- private final ChatMessageService chatMessageService;
- private final SimpMessagingTemplate messagingTemplate;
+ private final ChatMessageService chatMessageService;
+ private final SimpMessagingTemplate messagingTemplate;
- @MessageMapping("/send")
- @SendTo("/subs/chat-rooms")
- public void receiveMessage(MessageRequest request, Principal principal) {
- Long id = Long.parseLong(principal.getName());
- MessageResponse response = chatMessageService.send(request, id);
+ @MessageMapping("/send")
+ @SendTo("/subs/chat-rooms")
+ public void receiveMessage(MessageRequest request, Principal principal) {
+ Long id = Long.parseLong(principal.getName());
+ MessageResponse response = chatMessageService.send(request, id);
- // ํน์ ์ฑํ
๋ฐฉ ๊ตฌ๋
์๋ค์๊ฒ ๋ฉ์์ง ์ ์ก
- messagingTemplate.convertAndSend(
- "/subs/chat-rooms/" + request.getChatRoomId(),
- ApiResponse.onSuccess(response)
- );
- }
+ // ํน์ ์ฑํ
๋ฐฉ ๊ตฌ๋
์๋ค์๊ฒ ๋ฉ์์ง ์ ์ก
+ messagingTemplate.convertAndSend(
+ "/subs/chat-rooms/" + request.getChatRoomId(), ApiResponse.onSuccess(response));
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/message/dto/MessageDto.java b/src/main/java/opensource/bravest/domain/message/dto/MessageDto.java
index 1660bed..72b32c5 100644
--- a/src/main/java/opensource/bravest/domain/message/dto/MessageDto.java
+++ b/src/main/java/opensource/bravest/domain/message/dto/MessageDto.java
@@ -1,44 +1,42 @@
package opensource.bravest.domain.message.dto;
+import java.time.LocalDateTime;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import opensource.bravest.domain.message.entity.ChatMessage;
-import java.time.LocalDateTime;
-
public class MessageDto {
- @Getter
- public static class SendMessageRequest {
- private String content;
- }
-
- @Getter
- @RequiredArgsConstructor
- public static class MessageResponse {
- private final String senderName; // ์ต๋ช
๋๋ค์
- private final String content;
- private final LocalDateTime createdAt;
-
- public static MessageResponse from(ChatMessage chatMessage) {
- return new MessageResponse(
- chatMessage.getSender().getAnonymousName(),
- chatMessage.getContent(),
- chatMessage.getCreatedAt()
- );
- }
- }
-
- @Getter
- @RequiredArgsConstructor
- public static class MessageRequest {
- private final Long chatRoomId;
- private final String content;
- }
-
- @Getter
- @RequiredArgsConstructor
- public static class ChatReadRequest {
- private final Long chatRoomId;
+ @Getter
+ public static class SendMessageRequest {
+ private String content;
+ }
+
+ @Getter
+ @RequiredArgsConstructor
+ public static class MessageResponse {
+ private final String senderName; // ์ต๋ช
๋๋ค์
+ private final String content;
+ private final LocalDateTime createdAt;
+
+ public static MessageResponse from(ChatMessage chatMessage) {
+ return new MessageResponse(
+ chatMessage.getSender().getAnonymousName(),
+ chatMessage.getContent(),
+ chatMessage.getCreatedAt());
}
+ }
+
+ @Getter
+ @RequiredArgsConstructor
+ public static class MessageRequest {
+ private final Long chatRoomId;
+ private final String content;
+ }
+
+ @Getter
+ @RequiredArgsConstructor
+ public static class ChatReadRequest {
+ private final Long chatRoomId;
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/message/entity/ChatMessage.java b/src/main/java/opensource/bravest/domain/message/entity/ChatMessage.java
index e70ba58..2ab7d59 100644
--- a/src/main/java/opensource/bravest/domain/message/entity/ChatMessage.java
+++ b/src/main/java/opensource/bravest/domain/message/entity/ChatMessage.java
@@ -1,12 +1,11 @@
package opensource.bravest.domain.message.entity;
import jakarta.persistence.*;
+import java.time.LocalDateTime;
import lombok.*;
import opensource.bravest.domain.profile.entity.AnonymousProfile;
import opensource.bravest.domain.room.entity.AnonymousRoom;
-import java.time.LocalDateTime;
-
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@@ -14,22 +13,22 @@
@Builder
public class ChatMessage {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- // ์ด๋ ๋ฐฉ์ ๋ฉ์์ง์ธ์ง
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "room_id", nullable = false)
- private AnonymousRoom room;
+ // ์ด๋ ๋ฐฉ์ ๋ฉ์์ง์ธ์ง
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "room_id", nullable = false)
+ private AnonymousRoom room;
- // ๋๊ฐ ๋ณด๋๋์ง (์ต๋ช
ํ๋กํ ๊ธฐ์ค)
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "anonymous_profile_id", nullable = false)
- private AnonymousProfile sender;
+ // ๋๊ฐ ๋ณด๋๋์ง (์ต๋ช
ํ๋กํ ๊ธฐ์ค)
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "anonymous_profile_id", nullable = false)
+ private AnonymousProfile sender;
- @Column(nullable = false, length = 1000)
- private String content;
+ @Column(nullable = false, length = 1000)
+ private String content;
- private LocalDateTime createdAt;
+ private LocalDateTime createdAt;
}
diff --git a/src/main/java/opensource/bravest/domain/message/repository/ChatMessageRepository.java b/src/main/java/opensource/bravest/domain/message/repository/ChatMessageRepository.java
index 2866c8b..eaae205 100644
--- a/src/main/java/opensource/bravest/domain/message/repository/ChatMessageRepository.java
+++ b/src/main/java/opensource/bravest/domain/message/repository/ChatMessageRepository.java
@@ -1,14 +1,12 @@
package opensource.bravest.domain.message.repository;
-
+import java.util.List;
import opensource.bravest.domain.message.entity.ChatMessage;
import opensource.bravest.domain.room.entity.AnonymousRoom;
import org.springframework.data.jpa.repository.JpaRepository;
-import java.util.List;
-
public interface ChatMessageRepository extends JpaRepository {
- // ๋ฐฉ ๊ธฐ์ค์ผ๋ก ์ต๊ทผ ๋ฉ์์ง ๋ชฉ๋ก
- List findByRoomOrderByCreatedAtAsc(AnonymousRoom room);
+ // ๋ฐฉ ๊ธฐ์ค์ผ๋ก ์ต๊ทผ ๋ฉ์์ง ๋ชฉ๋ก
+ List findByRoomOrderByCreatedAtAsc(AnonymousRoom room);
}
diff --git a/src/main/java/opensource/bravest/domain/message/service/ChatMessageService.java b/src/main/java/opensource/bravest/domain/message/service/ChatMessageService.java
index b0db7ef..57808a6 100644
--- a/src/main/java/opensource/bravest/domain/message/service/ChatMessageService.java
+++ b/src/main/java/opensource/bravest/domain/message/service/ChatMessageService.java
@@ -1,13 +1,12 @@
package opensource.bravest.domain.message.service;
-import jakarta.transaction.Transactional;
-import lombok.RequiredArgsConstructor;
-import static opensource.bravest.domain.message.dto.MessageDto.MessageResponse;
-
import static opensource.bravest.domain.message.dto.MessageDto.MessageRequest;
+import static opensource.bravest.domain.message.dto.MessageDto.MessageResponse;
import static opensource.bravest.global.apiPayload.code.status.ErrorStatus._CHATROOM_NOT_FOUND;
import static opensource.bravest.global.apiPayload.code.status.ErrorStatus._USER_NOT_FOUND;
+import jakarta.transaction.Transactional;
+import lombok.RequiredArgsConstructor;
import opensource.bravest.domain.message.entity.ChatMessage;
import opensource.bravest.domain.message.repository.ChatMessageRepository;
import opensource.bravest.domain.profile.entity.AnonymousProfile;
@@ -17,45 +16,45 @@
import opensource.bravest.global.exception.CustomException;
import org.springframework.stereotype.Service;
-import java.util.Objects;
-
@Service
@Transactional
@RequiredArgsConstructor
public class ChatMessageService {
- private final AnonymousProfileRepository memberRepository;
- private final AnonymousRoomRepository chatRoomRepository;
- private final ChatMessageRepository chatMessageRepository;
+ private final AnonymousProfileRepository memberRepository;
+ private final AnonymousRoomRepository chatRoomRepository;
+ private final ChatMessageRepository chatMessageRepository;
- // ๋ฉ์์ง ์ ์ก
- public MessageResponse send(MessageRequest request, Long id) {
- AnonymousProfile sender = memberRepository.findById(id)
- .orElseThrow(() -> new CustomException(_USER_NOT_FOUND));
+ // ๋ฉ์์ง ์ ์ก
+ public MessageResponse send(MessageRequest request, Long id) {
+ AnonymousProfile sender =
+ memberRepository.findById(id).orElseThrow(() -> new CustomException(_USER_NOT_FOUND));
- AnonymousRoom chatRoom = chatRoomRepository.findById(request.getChatRoomId())
+ AnonymousRoom chatRoom =
+ chatRoomRepository
+ .findById(request.getChatRoomId())
.orElseThrow(() -> new CustomException(_CHATROOM_NOT_FOUND));
- ChatMessage chatMessage = ChatMessage.builder()
- .room(chatRoom)
- .sender(sender)
- .content(request.getContent())
- .build();
+ ChatMessage chatMessage =
+ ChatMessage.builder().room(chatRoom).sender(sender).content(request.getContent()).build();
- chatMessageRepository.save(chatMessage);
+ chatMessageRepository.save(chatMessage);
- return MessageResponse.from(chatMessage);
- }
+ return MessageResponse.from(chatMessage);
+ }
- @Transactional
- public void readMessages(Long chatRoomId, Long memberId) {
- AnonymousRoom chatRoom = chatRoomRepository.findById(chatRoomId)
+ @Transactional
+ public void readMessages(Long chatRoomId, Long memberId) {
+ AnonymousRoom chatRoom =
+ chatRoomRepository
+ .findById(chatRoomId)
.orElseThrow(() -> new CustomException(_CHATROOM_NOT_FOUND));
-// if (!Objects.equals(chatRoom.getMember1().getId(), memberId) && !Objects.equals(chatRoom.getMember2().getId(),
-// memberId)) {
-// throw new BaseException(ChatExceptionType.CHAT_ROOM_ACCESS_DENIED);
-// }
-// messageReceiptRepository.bulkUpdateStatusToRead(chatRoomId, memberId);
- }
-}
\ No newline at end of file
+ // if (!Objects.equals(chatRoom.getMember1().getId(), memberId) &&
+ // !Objects.equals(chatRoom.getMember2().getId(),
+ // memberId)) {
+ // throw new BaseException(ChatExceptionType.CHAT_ROOM_ACCESS_DENIED);
+ // }
+ // messageReceiptRepository.bulkUpdateStatusToRead(chatRoomId, memberId);
+ }
+}
diff --git a/src/main/java/opensource/bravest/domain/profile/controller/AnonymousProfileController.java b/src/main/java/opensource/bravest/domain/profile/controller/AnonymousProfileController.java
index 26a5d5d..6b2923f 100644
--- a/src/main/java/opensource/bravest/domain/profile/controller/AnonymousProfileController.java
+++ b/src/main/java/opensource/bravest/domain/profile/controller/AnonymousProfileController.java
@@ -10,30 +10,26 @@
import opensource.bravest.global.apiPayload.code.status.SuccessStatus;
import org.springframework.web.bind.annotation.*;
-
@RestController
@RequiredArgsConstructor
@RequestMapping("/anonymous-profiles")
public class AnonymousProfileController {
- private final AnonymousProfileService anonymousProfileService;
-
+ private final AnonymousProfileService anonymousProfileService;
- @Operation(summary = "์ต๋ช
ํ๋กํ ์์ฑ", description = "ํน์ ์ฑํ
๋ฐฉ์ ๋ํ ์๋ก์ด ์ต๋ช
ํ๋กํ์ ์์ฑํฉ๋๋ค.")
- @PostMapping("/rooms/{roomId}")
- public ApiResponse createAnonymousProfile(
- @PathVariable Long roomId,
- @RequestBody CreateAnonymousProfileRequest request
- ) {
- AnonymousProfile profile = anonymousProfileService.createAnonymousProfile(roomId, request);
- AnonymousProfileResponse response = AnonymousProfileResponse.from(profile);
- return ApiResponse.of(SuccessStatus._CREATED, SuccessStatus._CREATED.getMessage(), response);
- }
+ @Operation(summary = "์ต๋ช
ํ๋กํ ์์ฑ", description = "ํน์ ์ฑํ
๋ฐฉ์ ๋ํ ์๋ก์ด ์ต๋ช
ํ๋กํ์ ์์ฑํฉ๋๋ค.")
+ @PostMapping("/rooms/{roomId}")
+ public ApiResponse createAnonymousProfile(
+ @PathVariable Long roomId, @RequestBody CreateAnonymousProfileRequest request) {
+ AnonymousProfile profile = anonymousProfileService.createAnonymousProfile(roomId, request);
+ AnonymousProfileResponse response = AnonymousProfileResponse.from(profile);
+ return ApiResponse.of(SuccessStatus._CREATED, SuccessStatus._CREATED.getMessage(), response);
+ }
- @DeleteMapping("/{profileId}")
- @Operation(summary = "์ต๋ช
ํ๋กํ ์ญ์ ", description = "ID๋ก ํน์ ์ต๋ช
ํ๋กํ์ ์ญ์ ํฉ๋๋ค.")
- public ApiResponse> deleteAnonymousProfile(@PathVariable Long profileId) {
- anonymousProfileService.deleteAnonymousProfile(profileId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
- }
+ @DeleteMapping("/{profileId}")
+ @Operation(summary = "์ต๋ช
ํ๋กํ ์ญ์ ", description = "ID๋ก ํน์ ์ต๋ช
ํ๋กํ์ ์ญ์ ํฉ๋๋ค.")
+ public ApiResponse> deleteAnonymousProfile(@PathVariable Long profileId) {
+ anonymousProfileService.deleteAnonymousProfile(profileId);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/profile/dto/AnonymousProfileResponse.java b/src/main/java/opensource/bravest/domain/profile/dto/AnonymousProfileResponse.java
index e7d8c8c..95165ea 100644
--- a/src/main/java/opensource/bravest/domain/profile/dto/AnonymousProfileResponse.java
+++ b/src/main/java/opensource/bravest/domain/profile/dto/AnonymousProfileResponse.java
@@ -7,16 +7,17 @@
@Getter
@Builder
public class AnonymousProfileResponse {
- private Long id;
- private Long roomId;
- private String nickname;
- // ํ์ํ ํ๋๋ง
+ private Long id;
+ private Long roomId;
+ private String nickname;
- public static AnonymousProfileResponse from(AnonymousProfile profile) {
- return AnonymousProfileResponse.builder()
- .id(profile.getId())
- .roomId(profile.getRoom().getId())
- .nickname(profile.getAnonymousName())
- .build();
- }
+ // ํ์ํ ํ๋๋ง
+
+ public static AnonymousProfileResponse from(AnonymousProfile profile) {
+ return AnonymousProfileResponse.builder()
+ .id(profile.getId())
+ .roomId(profile.getRoom().getId())
+ .nickname(profile.getAnonymousName())
+ .build();
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/profile/dto/CreateAnonymousProfileRequest.java b/src/main/java/opensource/bravest/domain/profile/dto/CreateAnonymousProfileRequest.java
index 4b06c9e..9c43be9 100644
--- a/src/main/java/opensource/bravest/domain/profile/dto/CreateAnonymousProfileRequest.java
+++ b/src/main/java/opensource/bravest/domain/profile/dto/CreateAnonymousProfileRequest.java
@@ -6,6 +6,6 @@
@Getter
@NoArgsConstructor
public class CreateAnonymousProfileRequest {
- private Long realUserId;
- private String anonymousName;
+ private Long realUserId;
+ private String anonymousName;
}
diff --git a/src/main/java/opensource/bravest/domain/profile/entity/AnonymousProfile.java b/src/main/java/opensource/bravest/domain/profile/entity/AnonymousProfile.java
index 954be53..fe773e5 100644
--- a/src/main/java/opensource/bravest/domain/profile/entity/AnonymousProfile.java
+++ b/src/main/java/opensource/bravest/domain/profile/entity/AnonymousProfile.java
@@ -11,20 +11,20 @@
@Builder
public class AnonymousProfile {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- // ์ด๋ค ๋ฐฉ์ ์ํ ์ต๋ช
ํ๋กํ์ธ์ง
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "room_id", nullable = false)
- private AnonymousRoom room;
+ // ์ด๋ค ๋ฐฉ์ ์ํ ์ต๋ช
ํ๋กํ์ธ์ง
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "room_id", nullable = false)
+ private AnonymousRoom room;
- // ์ค์ ์ ์ PK (User ํ
์ด๋ธ ์๋ค๋ฉด JWT์ userId ๊ธฐ์ค์ผ๋ก)
- @Column(nullable = false)
- private Long realUserId;
+ // ์ค์ ์ ์ PK (User ํ
์ด๋ธ ์๋ค๋ฉด JWT์ userId ๊ธฐ์ค์ผ๋ก)
+ @Column(nullable = false)
+ private Long realUserId;
- // ๋ฐฉ ์์์ ๋ณด์ฌ์ค ์ต๋ช
๋๋ค์ (์: BlueTiger12)
- @Column(nullable = false, length = 50)
- private String anonymousName;
-}
\ No newline at end of file
+ // ๋ฐฉ ์์์ ๋ณด์ฌ์ค ์ต๋ช
๋๋ค์ (์: BlueTiger12)
+ @Column(nullable = false, length = 50)
+ private String anonymousName;
+}
diff --git a/src/main/java/opensource/bravest/domain/profile/repository/AnonymousProfileRepository.java b/src/main/java/opensource/bravest/domain/profile/repository/AnonymousProfileRepository.java
index bdef7a7..88bbdbe 100644
--- a/src/main/java/opensource/bravest/domain/profile/repository/AnonymousProfileRepository.java
+++ b/src/main/java/opensource/bravest/domain/profile/repository/AnonymousProfileRepository.java
@@ -1,13 +1,12 @@
package opensource.bravest.domain.profile.repository;
+import java.util.Optional;
import opensource.bravest.domain.profile.entity.AnonymousProfile;
import opensource.bravest.domain.room.entity.AnonymousRoom;
import org.springframework.data.jpa.repository.JpaRepository;
-import java.util.Optional;
-
public interface AnonymousProfileRepository extends JpaRepository {
- // ๊ฐ์ ๋ฐฉ + ๊ฐ์ ์ค์ ์ ์ ๋ผ๋ฉด ์ต๋ช
ํ๋กํ ํ๋๋ง ์ฌ์ฉ
- Optional findByRoomAndRealUserId(AnonymousRoom room, Long realUserId);
-}
\ No newline at end of file
+ // ๊ฐ์ ๋ฐฉ + ๊ฐ์ ์ค์ ์ ์ ๋ผ๋ฉด ์ต๋ช
ํ๋กํ ํ๋๋ง ์ฌ์ฉ
+ Optional findByRoomAndRealUserId(AnonymousRoom room, Long realUserId);
+}
diff --git a/src/main/java/opensource/bravest/domain/profile/service/AnonymousProfileService.java b/src/main/java/opensource/bravest/domain/profile/service/AnonymousProfileService.java
index 74326d5..0217c7d 100644
--- a/src/main/java/opensource/bravest/domain/profile/service/AnonymousProfileService.java
+++ b/src/main/java/opensource/bravest/domain/profile/service/AnonymousProfileService.java
@@ -1,5 +1,6 @@
package opensource.bravest.domain.profile.service;
+import java.util.Optional;
import lombok.RequiredArgsConstructor;
import opensource.bravest.domain.profile.dto.CreateAnonymousProfileRequest;
import opensource.bravest.domain.profile.entity.AnonymousProfile;
@@ -9,41 +10,44 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.Optional;
-
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AnonymousProfileService {
- private final AnonymousProfileRepository anonymousProfileRepository;
- private final AnonymousRoomRepository anonymousRoomRepository;
-
- @Transactional
- public AnonymousProfile createAnonymousProfile(Long roomId, CreateAnonymousProfileRequest request) {
- AnonymousRoom room = anonymousRoomRepository.findById(roomId)
- .orElseThrow(() -> new RuntimeException("๋ฐฉ์ ์ฐพ์ ์ ์์.๋ฟก"));
-
- // ์ค๋ณต ํ๋กํ ์ฒดํฌ
- Optional existingProfile = anonymousProfileRepository.findByRoomAndRealUserId(room, request.getRealUserId());
- if (existingProfile.isPresent()) {
- throw new RuntimeException("์ด๋ฏธ ๋ฐฉ์ ์กด์ฌํ๋ ์ ์ ์. ๋ค๋ฅธ๊ฑธ๋ก ์ ์ํ์
.");
- }
+ private final AnonymousProfileRepository anonymousProfileRepository;
+ private final AnonymousRoomRepository anonymousRoomRepository;
+
+ @Transactional
+ public AnonymousProfile createAnonymousProfile(
+ Long roomId, CreateAnonymousProfileRequest request) {
+ AnonymousRoom room =
+ anonymousRoomRepository
+ .findById(roomId)
+ .orElseThrow(() -> new RuntimeException("๋ฐฉ์ ์ฐพ์ ์ ์์.๋ฟก"));
+
+ // ์ค๋ณต ํ๋กํ ์ฒดํฌ
+ Optional existingProfile =
+ anonymousProfileRepository.findByRoomAndRealUserId(room, request.getRealUserId());
+ if (existingProfile.isPresent()) {
+ throw new RuntimeException("์ด๋ฏธ ๋ฐฉ์ ์กด์ฌํ๋ ์ ์ ์. ๋ค๋ฅธ๊ฑธ๋ก ์ ์ํ์
.");
+ }
- AnonymousProfile newProfile = AnonymousProfile.builder()
- .room(room)
- .realUserId(request.getRealUserId())
- .anonymousName(request.getAnonymousName())
- .build();
+ AnonymousProfile newProfile =
+ AnonymousProfile.builder()
+ .room(room)
+ .realUserId(request.getRealUserId())
+ .anonymousName(request.getAnonymousName())
+ .build();
- return anonymousProfileRepository.save(newProfile);
- }
+ return anonymousProfileRepository.save(newProfile);
+ }
- @Transactional
- public void deleteAnonymousProfile(Long profileId) {
- if (!anonymousProfileRepository.existsById(profileId)) {
- throw new RuntimeException("์๋ ์ฌ์ฉ์์. ๋~ ๋๊ตฌ์ผ!");
- }
- anonymousProfileRepository.deleteById(profileId);
+ @Transactional
+ public void deleteAnonymousProfile(Long profileId) {
+ if (!anonymousProfileRepository.existsById(profileId)) {
+ throw new RuntimeException("์๋ ์ฌ์ฉ์์. ๋~ ๋๊ตฌ์ผ!");
}
+ anonymousProfileRepository.deleteById(profileId);
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/room/controller/RoomController.java b/src/main/java/opensource/bravest/domain/room/controller/RoomController.java
index b331461..3a12474 100644
--- a/src/main/java/opensource/bravest/domain/room/controller/RoomController.java
+++ b/src/main/java/opensource/bravest/domain/room/controller/RoomController.java
@@ -14,67 +14,81 @@
@RequestMapping("/rooms")
public class RoomController {
- private final RoomService roomService;
+ private final RoomService roomService;
- @PostMapping
- @Operation(summary = "์ฑํ
๋ฐฉ ์์ฑ", description = "์๋ก์ด ์ฑํ
๋ฐฉ์ ์์ฑํฉ๋๋ค.")
- public ApiResponse createRoom(@RequestBody RoomDto.CreateRoomRequest request) {
- AnonymousRoom room = roomService.createRoom(request);
- return ApiResponse.of(SuccessStatus._CREATED, SuccessStatus._CREATED.getMessage(), RoomDto.RoomResponse.builder()
- .id(room.getId())
- .roomCode(room.getRoomCode())
- .title(room.getTitle())
- .createdAt(room.getCreatedAt())
- .build());
- }
+ @PostMapping
+ @Operation(summary = "์ฑํ
๋ฐฉ ์์ฑ", description = "์๋ก์ด ์ฑํ
๋ฐฉ์ ์์ฑํฉ๋๋ค.")
+ public ApiResponse createRoom(
+ @RequestBody RoomDto.CreateRoomRequest request) {
+ AnonymousRoom room = roomService.createRoom(request);
+ return ApiResponse.of(
+ SuccessStatus._CREATED,
+ SuccessStatus._CREATED.getMessage(),
+ RoomDto.RoomResponse.builder()
+ .id(room.getId())
+ .roomCode(room.getRoomCode())
+ .title(room.getTitle())
+ .createdAt(room.getCreatedAt())
+ .build());
+ }
- @GetMapping("/{roomId}")
- @Operation(summary = "์ฑํ
๋ฐฉ ์กฐํ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค.")
- public ApiResponse getRoom(@PathVariable Long roomId) {
- AnonymousRoom room = roomService.getRoom(roomId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), RoomDto.RoomResponse.builder()
- .id(room.getId())
- .roomCode(room.getRoomCode())
- .title(room.getTitle())
- .createdAt(room.getCreatedAt())
- .build());
- }
+ @GetMapping("/{roomId}")
+ @Operation(summary = "์ฑํ
๋ฐฉ ์กฐํ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค.")
+ public ApiResponse getRoom(@PathVariable Long roomId) {
+ AnonymousRoom room = roomService.getRoom(roomId);
+ return ApiResponse.of(
+ SuccessStatus._OK,
+ SuccessStatus._OK.getMessage(),
+ RoomDto.RoomResponse.builder()
+ .id(room.getId())
+ .roomCode(room.getRoomCode())
+ .title(room.getTitle())
+ .createdAt(room.getCreatedAt())
+ .build());
+ }
- @PutMapping("/{roomId}")
- @Operation(summary = "์ฑํ
๋ฐฉ ์ ๋ณด ์์ ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ ๋ณด๋ฅผ ์์ ํฉ๋๋ค.")
- public ApiResponse updateRoom(@PathVariable Long roomId, @RequestBody RoomDto.UpdateRoomRequest request) {
- AnonymousRoom room = roomService.updateRoom(roomId, request);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), RoomDto.RoomResponse.builder()
- .id(room.getId())
- .roomCode(room.getRoomCode())
- .title(room.getTitle())
- .createdAt(room.getCreatedAt())
- .build());
- }
+ @PutMapping("/{roomId}")
+ @Operation(summary = "์ฑํ
๋ฐฉ ์ ๋ณด ์์ ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ ๋ณด๋ฅผ ์์ ํฉ๋๋ค.")
+ public ApiResponse updateRoom(
+ @PathVariable Long roomId, @RequestBody RoomDto.UpdateRoomRequest request) {
+ AnonymousRoom room = roomService.updateRoom(roomId, request);
+ return ApiResponse.of(
+ SuccessStatus._OK,
+ SuccessStatus._OK.getMessage(),
+ RoomDto.RoomResponse.builder()
+ .id(room.getId())
+ .roomCode(room.getRoomCode())
+ .title(room.getTitle())
+ .createdAt(room.getCreatedAt())
+ .build());
+ }
- @DeleteMapping("/{roomId}")
- @Operation(summary = "์ฑํ
๋ฐฉ ์ญ์ ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ญ์ ํฉ๋๋ค.")
- public ApiResponse> deleteRoom(@PathVariable Long roomId) {
- roomService.deleteRoom(roomId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
- }
+ @DeleteMapping("/{roomId}")
+ @Operation(summary = "์ฑํ
๋ฐฉ ์ญ์ ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ญ์ ํฉ๋๋ค.")
+ public ApiResponse> deleteRoom(@PathVariable Long roomId) {
+ roomService.deleteRoom(roomId);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
+ }
- @GetMapping("/{roomId}/invite-code")
- @Operation(summary = "์ด๋ ์ฝ๋ ์กฐํ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ด๋ ์ฝ๋๋ฅผ ์กฐํํฉ๋๋ค.")
- public ApiResponse getInviteCode(@PathVariable Long roomId) {
- String inviteCode = roomService.getInviteCode(roomId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), inviteCode);
- }
+ @GetMapping("/{roomId}/invite-code")
+ @Operation(summary = "์ด๋ ์ฝ๋ ์กฐํ", description = "ID๋ก ํน์ ์ฑํ
๋ฐฉ์ ์ด๋ ์ฝ๋๋ฅผ ์กฐํํฉ๋๋ค.")
+ public ApiResponse getInviteCode(@PathVariable Long roomId) {
+ String inviteCode = roomService.getInviteCode(roomId);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), inviteCode);
+ }
- @PostMapping("/join")
- @Operation(summary = "์ด๋ ์ฝ๋๋ก ์ฑํ
๋ฐฉ ์ฐธ์ฌ", description = "์ด๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ฑํ
๋ฐฉ์ ์ฐธ์ฌํฉ๋๋ค.")
- public ApiResponse joinRoom(@RequestBody RoomDto.JoinRoomRequest request) {
- AnonymousRoom room = roomService.joinRoom(request.getRoomCode());
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), RoomDto.RoomResponse.builder()
- .id(room.getId())
- .roomCode(room.getRoomCode())
- .title(room.getTitle())
- .createdAt(room.getCreatedAt())
- .build());
- }
+ @PostMapping("/join")
+ @Operation(summary = "์ด๋ ์ฝ๋๋ก ์ฑํ
๋ฐฉ ์ฐธ์ฌ", description = "์ด๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ฑํ
๋ฐฉ์ ์ฐธ์ฌํฉ๋๋ค.")
+ public ApiResponse joinRoom(@RequestBody RoomDto.JoinRoomRequest request) {
+ AnonymousRoom room = roomService.joinRoom(request.getRoomCode());
+ return ApiResponse.of(
+ SuccessStatus._OK,
+ SuccessStatus._OK.getMessage(),
+ RoomDto.RoomResponse.builder()
+ .id(room.getId())
+ .roomCode(room.getRoomCode())
+ .title(room.getTitle())
+ .createdAt(room.getCreatedAt())
+ .build());
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/room/dto/RoomDto.java b/src/main/java/opensource/bravest/domain/room/dto/RoomDto.java
index e1175e2..8655c0c 100644
--- a/src/main/java/opensource/bravest/domain/room/dto/RoomDto.java
+++ b/src/main/java/opensource/bravest/domain/room/dto/RoomDto.java
@@ -1,40 +1,39 @@
package opensource.bravest.domain.room.dto;
+import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
-import java.time.LocalDateTime;
-
public class RoomDto {
- @Getter
- @NoArgsConstructor
- public static class CreateRoomRequest {
- private String title;
- }
+ @Getter
+ @NoArgsConstructor
+ public static class CreateRoomRequest {
+ private String title;
+ }
- @Getter
- @NoArgsConstructor
- public static class UpdateRoomRequest {
- private String title;
- }
+ @Getter
+ @NoArgsConstructor
+ public static class UpdateRoomRequest {
+ private String title;
+ }
- @Getter
- @Builder
- @NoArgsConstructor
- @AllArgsConstructor
- public static class RoomResponse {
- private Long id;
- private String roomCode;
- private String title;
- private LocalDateTime createdAt;
- }
+ @Getter
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class RoomResponse {
+ private Long id;
+ private String roomCode;
+ private String title;
+ private LocalDateTime createdAt;
+ }
- @Getter
- @NoArgsConstructor
- public static class JoinRoomRequest {
- private String roomCode;
- }
+ @Getter
+ @NoArgsConstructor
+ public static class JoinRoomRequest {
+ private String roomCode;
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/room/entity/AnonymousRoom.java b/src/main/java/opensource/bravest/domain/room/entity/AnonymousRoom.java
index aae4aa7..3be35e9 100644
--- a/src/main/java/opensource/bravest/domain/room/entity/AnonymousRoom.java
+++ b/src/main/java/opensource/bravest/domain/room/entity/AnonymousRoom.java
@@ -1,11 +1,11 @@
package opensource.bravest.domain.room.entity;
-import jakarta.persistence.*;
-import lombok.*;
-import opensource.bravest.domain.profile.entity.AnonymousProfile;
+import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
+import lombok.*;
+import opensource.bravest.domain.profile.entity.AnonymousProfile;
@Entity
@Getter
@@ -14,26 +14,25 @@
@Builder
public class AnonymousRoom {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
-
- // ์น๊ตฌ๋ค์๊ฒ ๊ณต์ ํ๋ ์ฝ๋ (์: ABC123)
- @Column(nullable = false, unique = true, length = 20)
- private String roomCode;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- // ๋ฐฉ ์ ๋ชฉ (์ ํ)
- @Column(nullable = false, length = 100)
- private String title;
+ // ์น๊ตฌ๋ค์๊ฒ ๊ณต์ ํ๋ ์ฝ๋ (์: ABC123)
+ @Column(nullable = false, unique = true, length = 20)
+ private String roomCode;
- @OneToMany(mappedBy = "room", cascade = CascadeType.ALL, orphanRemoval = true)
- @Builder.Default
- private List profiles = new ArrayList<>();
+ // ๋ฐฉ ์ ๋ชฉ (์ ํ)
+ @Column(nullable = false, length = 100)
+ private String title;
+ @OneToMany(mappedBy = "room", cascade = CascadeType.ALL, orphanRemoval = true)
+ @Builder.Default
+ private List profiles = new ArrayList<>();
- private LocalDateTime createdAt;
+ private LocalDateTime createdAt;
- public void updateTitle(String title) {
- this.title = title;
- }
-}
\ No newline at end of file
+ public void updateTitle(String title) {
+ this.title = title;
+ }
+}
diff --git a/src/main/java/opensource/bravest/domain/room/repository/AnonymousRoomRepository.java b/src/main/java/opensource/bravest/domain/room/repository/AnonymousRoomRepository.java
index 51b518e..a900571 100644
--- a/src/main/java/opensource/bravest/domain/room/repository/AnonymousRoomRepository.java
+++ b/src/main/java/opensource/bravest/domain/room/repository/AnonymousRoomRepository.java
@@ -1,13 +1,12 @@
package opensource.bravest.domain.room.repository;
+import java.util.Optional;
import opensource.bravest.domain.room.entity.AnonymousRoom;
import org.springframework.data.jpa.repository.JpaRepository;
-import java.util.Optional;
-
public interface AnonymousRoomRepository extends JpaRepository {
- Optional findByRoomCode(String roomCode);
+ Optional findByRoomCode(String roomCode);
- boolean existsByRoomCode(String roomCode);
-}
\ No newline at end of file
+ boolean existsByRoomCode(String roomCode);
+}
diff --git a/src/main/java/opensource/bravest/domain/room/service/RoomService.java b/src/main/java/opensource/bravest/domain/room/service/RoomService.java
index 2ffb4a5..21d1c2c 100644
--- a/src/main/java/opensource/bravest/domain/room/service/RoomService.java
+++ b/src/main/java/opensource/bravest/domain/room/service/RoomService.java
@@ -1,5 +1,7 @@
package opensource.bravest.domain.room.service;
+import java.time.LocalDateTime;
+import java.util.UUID;
import lombok.RequiredArgsConstructor;
import opensource.bravest.domain.room.dto.RoomDto;
import opensource.bravest.domain.room.entity.AnonymousRoom;
@@ -7,62 +9,62 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.time.LocalDateTime;
-import java.util.UUID;
-
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class RoomService {
- private final AnonymousRoomRepository anonymousRoomRepository;
+ private final AnonymousRoomRepository anonymousRoomRepository;
- @Transactional
- public AnonymousRoom createRoom(RoomDto.CreateRoomRequest request) {
- String roomCode = generateUniqueRoomCode();
- AnonymousRoom room = AnonymousRoom.builder()
- .title(request.getTitle())
- .roomCode(roomCode)
- .createdAt(LocalDateTime.now())
- .build();
- return anonymousRoomRepository.save(room);
- }
+ @Transactional
+ public AnonymousRoom createRoom(RoomDto.CreateRoomRequest request) {
+ String roomCode = generateUniqueRoomCode();
+ AnonymousRoom room =
+ AnonymousRoom.builder()
+ .title(request.getTitle())
+ .roomCode(roomCode)
+ .createdAt(LocalDateTime.now())
+ .build();
+ return anonymousRoomRepository.save(room);
+ }
- public AnonymousRoom getRoom(Long roomId) {
- return anonymousRoomRepository.findById(roomId)
- .orElseThrow(() -> new RuntimeException("Room not found"));
- }
+ public AnonymousRoom getRoom(Long roomId) {
+ return anonymousRoomRepository
+ .findById(roomId)
+ .orElseThrow(() -> new RuntimeException("Room not found"));
+ }
- @Transactional
- public AnonymousRoom updateRoom(Long roomId, RoomDto.UpdateRoomRequest request) {
- AnonymousRoom room = getRoom(roomId);
- room.updateTitle(request.getTitle());
- return room;
- }
+ @Transactional
+ public AnonymousRoom updateRoom(Long roomId, RoomDto.UpdateRoomRequest request) {
+ AnonymousRoom room = getRoom(roomId);
+ room.updateTitle(request.getTitle());
+ return room;
+ }
- @Transactional
- public void deleteRoom(Long roomId) {
- if (!anonymousRoomRepository.existsById(roomId)) {
- throw new RuntimeException("Room not found");
- }
- anonymousRoomRepository.deleteById(roomId);
+ @Transactional
+ public void deleteRoom(Long roomId) {
+ if (!anonymousRoomRepository.existsById(roomId)) {
+ throw new RuntimeException("Room not found");
}
+ anonymousRoomRepository.deleteById(roomId);
+ }
- public String getInviteCode(Long roomId) {
- AnonymousRoom room = getRoom(roomId);
- return room.getRoomCode();
- }
+ public String getInviteCode(Long roomId) {
+ AnonymousRoom room = getRoom(roomId);
+ return room.getRoomCode();
+ }
- public AnonymousRoom joinRoom(String roomCode) {
- return anonymousRoomRepository.findByRoomCode(roomCode)
- .orElseThrow(() -> new RuntimeException("Room not found with code: " + roomCode));
- }
+ public AnonymousRoom joinRoom(String roomCode) {
+ return anonymousRoomRepository
+ .findByRoomCode(roomCode)
+ .orElseThrow(() -> new RuntimeException("Room not found with code: " + roomCode));
+ }
- private String generateUniqueRoomCode() {
- String roomCode;
- do {
- roomCode = UUID.randomUUID().toString().substring(0, 6).toUpperCase();
- } while (anonymousRoomRepository.existsByRoomCode(roomCode));
- return roomCode;
- }
+ private String generateUniqueRoomCode() {
+ String roomCode;
+ do {
+ roomCode = UUID.randomUUID().toString().substring(0, 6).toUpperCase();
+ } while (anonymousRoomRepository.existsByRoomCode(roomCode));
+ return roomCode;
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/vote/controller/VoteController.java b/src/main/java/opensource/bravest/domain/vote/controller/VoteController.java
index bf40633..e46aca8 100644
--- a/src/main/java/opensource/bravest/domain/vote/controller/VoteController.java
+++ b/src/main/java/opensource/bravest/domain/vote/controller/VoteController.java
@@ -14,49 +14,51 @@
@RequestMapping("/votes")
public class VoteController {
- private final VoteService voteService;
-
- @PostMapping
- @Operation(summary = "ํฌํ ์์ฑ", description = "์๋ก์ด ํฌํ๋ฅผ ์์ฑํฉ๋๋ค.")
- public ApiResponse createVote(@RequestBody VoteDto.CreateVoteRequest request) {
- Vote vote = voteService.createVote(request);
- // The response DTO needs to be built manually
- VoteDto.VoteResponse responseDto = voteService.getVoteResult(vote.getId());
- return ApiResponse.of(SuccessStatus._CREATED, SuccessStatus._CREATED.getMessage(), responseDto);
- }
-
- @GetMapping("/{voteId}")
- @Operation(summary = "ํฌํ ์กฐํ", description = "ID๋ก ํน์ ํฌํ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค.")
- public ApiResponse getVote(@PathVariable Long voteId) {
- VoteDto.VoteResponse responseDto = voteService.getVoteResult(voteId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), responseDto);
- }
-
- @PostMapping("/{voteId}/cast")
- @Operation(summary = "ํฌํ ์ฐธ์ฌ", description = "ํน์ ํฌํ ํญ๋ชฉ์ ํฌํํฉ๋๋ค.")
- public ApiResponse> castVote(@PathVariable Long voteId, @RequestBody VoteDto.CastVoteRequest request) {
- voteService.castVote(voteId, request);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
- }
-
- @PostMapping("/{voteId}/end")
- @Operation(summary = "ํฌํ ์ข
๋ฃ", description = "ํน์ ํฌํ๋ฅผ ์ข
๋ฃํฉ๋๋ค.")
- public ApiResponse> endVote(@PathVariable Long voteId) {
- voteService.endVote(voteId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
- }
-
- @GetMapping("/{voteId}/result")
- @Operation(summary = "ํฌํ ๊ฒฐ๊ณผ ์กฐํ", description = "์ข
๋ฃ๋ ํฌํ์ ๊ฒฐ๊ณผ๋ฅผ ์กฐํํฉ๋๋ค.")
- public ApiResponse getVoteResult(@PathVariable Long voteId) {
- VoteDto.VoteResponse responseDto = voteService.getVoteResult(voteId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), responseDto);
- }
-
- @DeleteMapping("/{voteId}")
- @Operation(summary = "ํฌํ ์ญ์ ", description = "ID๋ก ํน์ ํฌํ๋ฅผ ์ญ์ ํฉ๋๋ค.")
- public ApiResponse> deleteVote(@PathVariable Long voteId) {
- voteService.deleteVote(voteId);
- return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
- }
+ private final VoteService voteService;
+
+ @PostMapping
+ @Operation(summary = "ํฌํ ์์ฑ", description = "์๋ก์ด ํฌํ๋ฅผ ์์ฑํฉ๋๋ค.")
+ public ApiResponse createVote(
+ @RequestBody VoteDto.CreateVoteRequest request) {
+ Vote vote = voteService.createVote(request);
+ // The response DTO needs to be built manually
+ VoteDto.VoteResponse responseDto = voteService.getVoteResult(vote.getId());
+ return ApiResponse.of(SuccessStatus._CREATED, SuccessStatus._CREATED.getMessage(), responseDto);
+ }
+
+ @GetMapping("/{voteId}")
+ @Operation(summary = "ํฌํ ์กฐํ", description = "ID๋ก ํน์ ํฌํ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค.")
+ public ApiResponse getVote(@PathVariable Long voteId) {
+ VoteDto.VoteResponse responseDto = voteService.getVoteResult(voteId);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), responseDto);
+ }
+
+ @PostMapping("/{voteId}/cast")
+ @Operation(summary = "ํฌํ ์ฐธ์ฌ", description = "ํน์ ํฌํ ํญ๋ชฉ์ ํฌํํฉ๋๋ค.")
+ public ApiResponse> castVote(
+ @PathVariable Long voteId, @RequestBody VoteDto.CastVoteRequest request) {
+ voteService.castVote(voteId, request);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
+ }
+
+ @PostMapping("/{voteId}/end")
+ @Operation(summary = "ํฌํ ์ข
๋ฃ", description = "ํน์ ํฌํ๋ฅผ ์ข
๋ฃํฉ๋๋ค.")
+ public ApiResponse> endVote(@PathVariable Long voteId) {
+ voteService.endVote(voteId);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
+ }
+
+ @GetMapping("/{voteId}/result")
+ @Operation(summary = "ํฌํ ๊ฒฐ๊ณผ ์กฐํ", description = "์ข
๋ฃ๋ ํฌํ์ ๊ฒฐ๊ณผ๋ฅผ ์กฐํํฉ๋๋ค.")
+ public ApiResponse getVoteResult(@PathVariable Long voteId) {
+ VoteDto.VoteResponse responseDto = voteService.getVoteResult(voteId);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), responseDto);
+ }
+
+ @DeleteMapping("/{voteId}")
+ @Operation(summary = "ํฌํ ์ญ์ ", description = "ID๋ก ํน์ ํฌํ๋ฅผ ์ญ์ ํฉ๋๋ค.")
+ public ApiResponse> deleteVote(@PathVariable Long voteId) {
+ voteService.deleteVote(voteId);
+ return ApiResponse.of(SuccessStatus._OK, SuccessStatus._OK.getMessage(), null);
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/vote/dto/VoteDto.java b/src/main/java/opensource/bravest/domain/vote/dto/VoteDto.java
index 77ac32d..83cd3dd 100644
--- a/src/main/java/opensource/bravest/domain/vote/dto/VoteDto.java
+++ b/src/main/java/opensource/bravest/domain/vote/dto/VoteDto.java
@@ -1,43 +1,42 @@
package opensource.bravest.domain.vote.dto;
+import java.time.LocalDateTime;
+import java.util.List;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
-import java.time.LocalDateTime;
-import java.util.List;
-
public class VoteDto {
- @Getter
- @NoArgsConstructor
- public static class CreateVoteRequest {
- private Long roomId;
- private List messages;
- }
+ @Getter
+ @NoArgsConstructor
+ public static class CreateVoteRequest {
+ private Long roomId;
+ private List messages;
+ }
- @Getter
- @NoArgsConstructor
- public static class CastVoteRequest {
- private Long voteOptionId;
- private Long anonymousProfileId;
- }
+ @Getter
+ @NoArgsConstructor
+ public static class CastVoteRequest {
+ private Long voteOptionId;
+ private Long anonymousProfileId;
+ }
- @Getter
- @Builder
- public static class VoteResponse {
- private Long id;
- private String title;
- private boolean isActive;
- private LocalDateTime createdAt;
- private List options;
- }
+ @Getter
+ @Builder
+ public static class VoteResponse {
+ private Long id;
+ private String title;
+ private boolean isActive;
+ private LocalDateTime createdAt;
+ private List options;
+ }
- @Getter
- @Builder
- public static class VoteOptionResponse {
- private Long id;
- private String messageContent;
- private int voteCount;
- }
+ @Getter
+ @Builder
+ public static class VoteOptionResponse {
+ private Long id;
+ private String messageContent;
+ private int voteCount;
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/vote/entity/UserVote.java b/src/main/java/opensource/bravest/domain/vote/entity/UserVote.java
index 2b71b82..f88a73b 100644
--- a/src/main/java/opensource/bravest/domain/vote/entity/UserVote.java
+++ b/src/main/java/opensource/bravest/domain/vote/entity/UserVote.java
@@ -11,19 +11,19 @@
@Builder
public class UserVote {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "vote_id", nullable = false)
- private Vote vote;
-
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "vote_option_id", nullable = false)
- private VoteOption voteOption;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "vote_id", nullable = false)
+ private Vote vote;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "anonymous_profile_id", nullable = false)
- private AnonymousProfile voter;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "vote_option_id", nullable = false)
+ private VoteOption voteOption;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "anonymous_profile_id", nullable = false)
+ private AnonymousProfile voter;
}
diff --git a/src/main/java/opensource/bravest/domain/vote/entity/Vote.java b/src/main/java/opensource/bravest/domain/vote/entity/Vote.java
index 03ca1d5..3f2df78 100644
--- a/src/main/java/opensource/bravest/domain/vote/entity/Vote.java
+++ b/src/main/java/opensource/bravest/domain/vote/entity/Vote.java
@@ -1,12 +1,11 @@
package opensource.bravest.domain.vote.entity;
import jakarta.persistence.*;
-import lombok.*;
-import opensource.bravest.domain.room.entity.AnonymousRoom;
-
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
+import lombok.*;
+import opensource.bravest.domain.room.entity.AnonymousRoom;
@Entity
@Getter
@@ -15,26 +14,26 @@
@Builder
public class Vote {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "room_id", nullable = false)
- private AnonymousRoom room;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "room_id", nullable = false)
+ private AnonymousRoom room;
- @Column(nullable = false, length = 100)
- private String title;
+ @Column(nullable = false, length = 100)
+ private String title;
- @Builder.Default
- @OneToMany(mappedBy = "vote", cascade = CascadeType.ALL, orphanRemoval = true)
- private List options = new ArrayList<>();
+ @Builder.Default
+ @OneToMany(mappedBy = "vote", cascade = CascadeType.ALL, orphanRemoval = true)
+ private List options = new ArrayList<>();
- private boolean isActive;
+ private boolean isActive;
- private LocalDateTime createdAt;
+ private LocalDateTime createdAt;
- public void endVote() {
- this.isActive = false;
- }
+ public void endVote() {
+ this.isActive = false;
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/vote/entity/VoteOption.java b/src/main/java/opensource/bravest/domain/vote/entity/VoteOption.java
index 2ed3825..70f03c7 100644
--- a/src/main/java/opensource/bravest/domain/vote/entity/VoteOption.java
+++ b/src/main/java/opensource/bravest/domain/vote/entity/VoteOption.java
@@ -2,7 +2,6 @@
import jakarta.persistence.*;
import lombok.*;
-import opensource.bravest.domain.message.entity.ChatMessage;
@Entity
@Getter
@@ -11,21 +10,21 @@
@Builder
public class VoteOption {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "vote_id", nullable = false)
- private Vote vote;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "vote_id", nullable = false)
+ private Vote vote;
- @Column(name = "message_content", nullable = false)
- private String messageContent;
+ @Column(name = "message_content", nullable = false)
+ private String messageContent;
- @Column(nullable = false)
- private int voteCount;
+ @Column(nullable = false)
+ private int voteCount;
- public void incrementVoteCount() {
- this.voteCount++;
- }
+ public void incrementVoteCount() {
+ this.voteCount++;
+ }
}
diff --git a/src/main/java/opensource/bravest/domain/vote/repository/UserVoteRepository.java b/src/main/java/opensource/bravest/domain/vote/repository/UserVoteRepository.java
index d9e3579..7fe9954 100644
--- a/src/main/java/opensource/bravest/domain/vote/repository/UserVoteRepository.java
+++ b/src/main/java/opensource/bravest/domain/vote/repository/UserVoteRepository.java
@@ -1,12 +1,11 @@
package opensource.bravest.domain.vote.repository;
+import java.util.Optional;
import opensource.bravest.domain.profile.entity.AnonymousProfile;
import opensource.bravest.domain.vote.entity.UserVote;
import opensource.bravest.domain.vote.entity.Vote;
import org.springframework.data.jpa.repository.JpaRepository;
-import java.util.Optional;
-
public interface UserVoteRepository extends JpaRepository {
- Optional findByVoteAndVoter(Vote vote, AnonymousProfile voter);
+ Optional findByVoteAndVoter(Vote vote, AnonymousProfile voter);
}
diff --git a/src/main/java/opensource/bravest/domain/vote/repository/VoteOptionRepository.java b/src/main/java/opensource/bravest/domain/vote/repository/VoteOptionRepository.java
index 5b97137..ccc2c49 100644
--- a/src/main/java/opensource/bravest/domain/vote/repository/VoteOptionRepository.java
+++ b/src/main/java/opensource/bravest/domain/vote/repository/VoteOptionRepository.java
@@ -3,5 +3,4 @@
import opensource.bravest.domain.vote.entity.VoteOption;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface VoteOptionRepository extends JpaRepository {
-}
+public interface VoteOptionRepository extends JpaRepository {}
diff --git a/src/main/java/opensource/bravest/domain/vote/repository/VoteRepository.java b/src/main/java/opensource/bravest/domain/vote/repository/VoteRepository.java
index e7b9d91..8dcfded 100644
--- a/src/main/java/opensource/bravest/domain/vote/repository/VoteRepository.java
+++ b/src/main/java/opensource/bravest/domain/vote/repository/VoteRepository.java
@@ -3,5 +3,4 @@
import opensource.bravest.domain.vote.entity.Vote;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface VoteRepository extends JpaRepository {
-}
+public interface VoteRepository extends JpaRepository {}
diff --git a/src/main/java/opensource/bravest/domain/vote/service/VoteService.java b/src/main/java/opensource/bravest/domain/vote/service/VoteService.java
index 8d39887..39224b9 100644
--- a/src/main/java/opensource/bravest/domain/vote/service/VoteService.java
+++ b/src/main/java/opensource/bravest/domain/vote/service/VoteService.java
@@ -1,8 +1,9 @@
package opensource.bravest.domain.vote.service;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import opensource.bravest.domain.message.entity.ChatMessage;
-import opensource.bravest.domain.message.repository.ChatMessageRepository;
import opensource.bravest.domain.profile.entity.AnonymousProfile;
import opensource.bravest.domain.profile.repository.AnonymousProfileRepository;
import opensource.bravest.domain.room.entity.AnonymousRoom;
@@ -16,112 +17,112 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.stream.Collectors;
-
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class VoteService {
- private final VoteRepository voteRepository;
- private final UserVoteRepository userVoteRepository;
- private final AnonymousRoomRepository anonymousRoomRepository;
- private final AnonymousProfileRepository anonymousProfileRepository;
-
- @Transactional
- public Vote createVote(VoteDto.CreateVoteRequest request) {
- AnonymousRoom room = anonymousRoomRepository.findById(request.getRoomId())
- .orElseThrow(() -> new RuntimeException("Room not found"));
-
- Vote vote = Vote.builder()
- .room(room)
- .title(room.getTitle())
- .isActive(true)
- .createdAt(LocalDateTime.now())
- .build();
-
- List options = request.getMessages().stream()
- .map(message -> VoteOption.builder()
- .vote(vote)
- .messageContent(message)
- .voteCount(0)
- .build())
- .collect(Collectors.toList());
+ private final VoteRepository voteRepository;
+ private final UserVoteRepository userVoteRepository;
+ private final AnonymousRoomRepository anonymousRoomRepository;
+ private final AnonymousProfileRepository anonymousProfileRepository;
+
+ @Transactional
+ public Vote createVote(VoteDto.CreateVoteRequest request) {
+ AnonymousRoom room =
+ anonymousRoomRepository
+ .findById(request.getRoomId())
+ .orElseThrow(() -> new RuntimeException("Room not found"));
+
+ Vote vote =
+ Vote.builder()
+ .room(room)
+ .title(room.getTitle())
+ .isActive(true)
+ .createdAt(LocalDateTime.now())
+ .build();
+
+ List options =
+ request.getMessages().stream()
+ .map(
+ message ->
+ VoteOption.builder().vote(vote).messageContent(message).voteCount(0).build())
+ .collect(Collectors.toList());
+
+ vote.getOptions().addAll(options);
+
+ return voteRepository.save(vote);
+ }
+
+ @Transactional
+ public void castVote(Long voteId, VoteDto.CastVoteRequest request) {
+ Vote vote =
+ voteRepository.findById(voteId).orElseThrow(() -> new RuntimeException("Vote not found"));
+ if (!vote.isActive()) {
+ throw new RuntimeException("Vote is not active");
+ }
- vote.getOptions().addAll(options);
+ AnonymousProfile voter =
+ anonymousProfileRepository
+ .findById(request.getAnonymousProfileId())
+ .orElseThrow(() -> new RuntimeException("AnonymousProfile not found"));
- return voteRepository.save(vote);
+ if (userVoteRepository.findByVoteAndVoter(vote, voter).isPresent()) {
+ throw new RuntimeException("User has already voted");
}
- @Transactional
- public void castVote(Long voteId, VoteDto.CastVoteRequest request) {
- Vote vote = voteRepository.findById(voteId)
- .orElseThrow(() -> new RuntimeException("Vote not found"));
- if (!vote.isActive()) {
- throw new RuntimeException("Vote is not active");
- }
-
- AnonymousProfile voter = anonymousProfileRepository.findById(request.getAnonymousProfileId())
- .orElseThrow(() -> new RuntimeException("AnonymousProfile not found"));
-
- if (userVoteRepository.findByVoteAndVoter(vote, voter).isPresent()) {
- throw new RuntimeException("User has already voted");
- }
-
- VoteOption voteOption = vote.getOptions().stream()
- .filter(option -> option.getId().equals(request.getVoteOptionId()))
- .findFirst()
- .orElseThrow(() -> new RuntimeException("VoteOption not found"));
-
- voteOption.incrementVoteCount();
-
- UserVote userVote = UserVote.builder()
- .vote(vote)
- .voteOption(voteOption)
- .voter(voter)
- .build();
- userVoteRepository.save(userVote);
- }
+ VoteOption voteOption =
+ vote.getOptions().stream()
+ .filter(option -> option.getId().equals(request.getVoteOptionId()))
+ .findFirst()
+ .orElseThrow(() -> new RuntimeException("VoteOption not found"));
- @Transactional
- public void endVote(Long voteId) {
- Vote vote = voteRepository.findById(voteId)
- .orElseThrow(() -> new RuntimeException("Vote not found"));
- vote.endVote();
- }
+ voteOption.incrementVoteCount();
- public VoteDto.VoteResponse getVoteResult(Long voteId) {
- Vote vote = voteRepository.findById(voteId)
- .orElseThrow(() -> new RuntimeException("Vote not found"));
+ UserVote userVote = UserVote.builder().vote(vote).voteOption(voteOption).voter(voter).build();
+ userVoteRepository.save(userVote);
+ }
- return buildVoteResponse(vote);
- }
+ @Transactional
+ public void endVote(Long voteId) {
+ Vote vote =
+ voteRepository.findById(voteId).orElseThrow(() -> new RuntimeException("Vote not found"));
+ vote.endVote();
+ }
- @Transactional
- public void deleteVote(Long voteId) {
- if (!voteRepository.existsById(voteId)) {
- throw new RuntimeException("Vote not found");
- }
- voteRepository.deleteById(voteId);
- }
+ public VoteDto.VoteResponse getVoteResult(Long voteId) {
+ Vote vote =
+ voteRepository.findById(voteId).orElseThrow(() -> new RuntimeException("Vote not found"));
+
+ return buildVoteResponse(vote);
+ }
- private VoteDto.VoteResponse buildVoteResponse(Vote vote) {
- List optionResponses = vote.getOptions().stream()
- .map(option -> VoteDto.VoteOptionResponse.builder()
+ @Transactional
+ public void deleteVote(Long voteId) {
+ if (!voteRepository.existsById(voteId)) {
+ throw new RuntimeException("Vote not found");
+ }
+ voteRepository.deleteById(voteId);
+ }
+
+ private VoteDto.VoteResponse buildVoteResponse(Vote vote) {
+ List optionResponses =
+ vote.getOptions().stream()
+ .map(
+ option ->
+ VoteDto.VoteOptionResponse.builder()
.id(option.getId())
.messageContent(option.getMessageContent())
.voteCount(option.getVoteCount())
.build())
- .collect(Collectors.toList());
-
- return VoteDto.VoteResponse.builder()
- .id(vote.getId())
- .title(vote.getTitle())
- .isActive(vote.isActive())
- .createdAt(vote.getCreatedAt())
- .options(optionResponses)
- .build();
- }
+ .collect(Collectors.toList());
+
+ return VoteDto.VoteResponse.builder()
+ .id(vote.getId())
+ .title(vote.getTitle())
+ .isActive(vote.isActive())
+ .createdAt(vote.getCreatedAt())
+ .options(optionResponses)
+ .build();
+ }
}
diff --git a/src/main/java/opensource/bravest/global/apiPayload/ApiResponse.java b/src/main/java/opensource/bravest/global/apiPayload/ApiResponse.java
index 098aeec..b577884 100644
--- a/src/main/java/opensource/bravest/global/apiPayload/ApiResponse.java
+++ b/src/main/java/opensource/bravest/global/apiPayload/ApiResponse.java
@@ -1,6 +1,5 @@
package opensource.bravest.global.apiPayload;
-
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@@ -13,10 +12,11 @@
@Getter
@AllArgsConstructor
-@JsonPropertyOrder({ "isSuccess", "code", "message", "data" })
+@JsonPropertyOrder({"isSuccess", "code", "message", "data"})
public class ApiResponse {
@JsonProperty("isSuccess")
private final boolean isSuccess;
+
private final String code;
private final String message;
@@ -25,27 +25,17 @@ public class ApiResponse {
public static ApiResponse onSuccess(T data) {
return new ApiResponse<>(
- true,
- SuccessStatus._OK.getCode(),
- SuccessStatus._OK.getMessage(),
- data);
+ true, SuccessStatus._OK.getCode(), SuccessStatus._OK.getMessage(), data);
}
public static ApiResponse of(BaseCode code, String message, T data) {
return new ApiResponse<>(
- true,
- code.getReasonHttpStatus().getCode(),
- code.getReasonHttpStatus().getMessage(),
- data);
+ true, code.getReasonHttpStatus().getCode(), code.getReasonHttpStatus().getMessage(), data);
}
public static ApiResponse onFailure(BaseErrorCode errorCode, T data) {
ErrorReasonDto reason = errorCode.getReasonHttpStatus();
- return new ApiResponse<>(
- reason.getIsSuccess(),
- reason.getCode(),
- reason.getMessage(),
- data);
+ return new ApiResponse<>(reason.getIsSuccess(), reason.getCode(), reason.getMessage(), data);
}
public static ApiResponse onFailure(String code, String message, T data) {
diff --git a/src/main/java/opensource/bravest/global/apiPayload/code/BaseCode.java b/src/main/java/opensource/bravest/global/apiPayload/code/BaseCode.java
index df8f866..00f3dd4 100644
--- a/src/main/java/opensource/bravest/global/apiPayload/code/BaseCode.java
+++ b/src/main/java/opensource/bravest/global/apiPayload/code/BaseCode.java
@@ -2,5 +2,6 @@
public interface BaseCode {
ReasonDto getReason();
+
ReasonDto getReasonHttpStatus();
-}
\ No newline at end of file
+}
diff --git a/src/main/java/opensource/bravest/global/apiPayload/code/BaseErrorCode.java b/src/main/java/opensource/bravest/global/apiPayload/code/BaseErrorCode.java
index e52b4d4..6f514a7 100644
--- a/src/main/java/opensource/bravest/global/apiPayload/code/BaseErrorCode.java
+++ b/src/main/java/opensource/bravest/global/apiPayload/code/BaseErrorCode.java
@@ -2,5 +2,6 @@
public interface BaseErrorCode {
ErrorReasonDto getReason();
+
ErrorReasonDto getReasonHttpStatus();
}
diff --git a/src/main/java/opensource/bravest/global/apiPayload/code/status/ErrorStatus.java b/src/main/java/opensource/bravest/global/apiPayload/code/status/ErrorStatus.java
index 8afd9f2..b0ae3d4 100644
--- a/src/main/java/opensource/bravest/global/apiPayload/code/status/ErrorStatus.java
+++ b/src/main/java/opensource/bravest/global/apiPayload/code/status/ErrorStatus.java
@@ -1,6 +1,5 @@
package opensource.bravest.global.apiPayload.code.status;
-
import lombok.AllArgsConstructor;
import lombok.Getter;
import opensource.bravest.global.apiPayload.code.BaseErrorCode;
@@ -19,7 +18,6 @@ public enum ErrorStatus implements BaseErrorCode {
_USER_NOT_FOUND(HttpStatus.NOT_FOUND, "USER404", "์ฌ์ฉ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค."),
_CHATROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "USER404", "์ฑํ
๋ฐฉ์ ์ฐพ์ ์ ์์ต๋๋ค."),
_CHATLIST_NOT_FOUND(HttpStatus.NOT_FOUND, "USER404", "๋ฆฌ์คํธ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค."),
-
;
private final HttpStatus httpStatus;
@@ -28,11 +26,7 @@ public enum ErrorStatus implements BaseErrorCode {
@Override
public ErrorReasonDto getReason() {
- return ErrorReasonDto.builder()
- .isSuccess(false)
- .message(message)
- .code(code)
- .build();
+ return ErrorReasonDto.builder().isSuccess(false).message(message).code(code).build();
}
@Override
diff --git a/src/main/java/opensource/bravest/global/apiPayload/code/status/SuccessStatus.java b/src/main/java/opensource/bravest/global/apiPayload/code/status/SuccessStatus.java
index 2400189..7845515 100644
--- a/src/main/java/opensource/bravest/global/apiPayload/code/status/SuccessStatus.java
+++ b/src/main/java/opensource/bravest/global/apiPayload/code/status/SuccessStatus.java
@@ -18,11 +18,7 @@ public enum SuccessStatus implements BaseCode {
@Override
public ReasonDto getReason() {
- return ReasonDto.builder()
- .isSuccess(true)
- .message(message)
- .code(code)
- .build();
+ return ReasonDto.builder().isSuccess(true).message(message).code(code).build();
}
@Override
@@ -34,5 +30,4 @@ public ReasonDto getReasonHttpStatus() {
.message(message)
.build();
}
-
}
diff --git a/src/main/java/opensource/bravest/global/config/OpenApiConfig.java b/src/main/java/opensource/bravest/global/config/OpenApiConfig.java
index 48e4c39..25c4cff 100644
--- a/src/main/java/opensource/bravest/global/config/OpenApiConfig.java
+++ b/src/main/java/opensource/bravest/global/config/OpenApiConfig.java
@@ -13,28 +13,29 @@
@Configuration
public class OpenApiConfig {
- private static final String SECURITY_SCHEME_NAME = "bearerAuth";
+ private static final String SECURITY_SCHEME_NAME = "bearerAuth";
- @Bean
- public OpenAPI baseOpenAPI() {
- return new OpenAPI()
- // 1) ์ ์ญ์ผ๋ก "์ด API๋ ์ด ์ธ์ฆ ๋ฐฉ์์ ์ด๋ค" ์ ์ธ
- .addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME))
- // 2) JWT Bearer ์คํค๋ง ์ ์
- .components(new Components()
- .addSecuritySchemes(SECURITY_SCHEME_NAME,
- new SecurityScheme()
- .name(SECURITY_SCHEME_NAME)
- .type(SecurityScheme.Type.HTTP)
- .scheme("bearer")
- .bearerFormat("JWT")
- )
- )
- .info(new Info()
- .title("openSource Bravest API")
- .description("openSource Bravest ๋ฐฑ์๋ API ๋ฌธ์")
- .version("v1.0.0")
- .license(new License().name("MIT")))
- .externalDocs(new ExternalDocumentation().description("README"));
- }
+ @Bean
+ public OpenAPI baseOpenAPI() {
+ return new OpenAPI()
+ // 1) ์ ์ญ์ผ๋ก "์ด API๋ ์ด ์ธ์ฆ ๋ฐฉ์์ ์ด๋ค" ์ ์ธ
+ .addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME))
+ // 2) JWT Bearer ์คํค๋ง ์ ์
+ .components(
+ new Components()
+ .addSecuritySchemes(
+ SECURITY_SCHEME_NAME,
+ new SecurityScheme()
+ .name(SECURITY_SCHEME_NAME)
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")))
+ .info(
+ new Info()
+ .title("openSource Bravest API")
+ .description("openSource Bravest ๋ฐฑ์๋ API ๋ฌธ์")
+ .version("v1.0.0")
+ .license(new License().name("MIT")))
+ .externalDocs(new ExternalDocumentation().description("README"));
+ }
}
diff --git a/src/main/java/opensource/bravest/global/config/SecurityConfig.java b/src/main/java/opensource/bravest/global/config/SecurityConfig.java
index eb5b4be..35abcef 100644
--- a/src/main/java/opensource/bravest/global/config/SecurityConfig.java
+++ b/src/main/java/opensource/bravest/global/config/SecurityConfig.java
@@ -1,5 +1,8 @@
package opensource.bravest.global.config;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import opensource.bravest.global.apiPayload.code.status.ErrorStatus;
import opensource.bravest.global.security.jwt.JwtAuthenticationFilter;
@@ -17,10 +20,6 @@
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.*;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@@ -29,27 +28,30 @@ public class SecurityConfig {
private final JwtTokenProvider jwtTokenProvider;
// Swagger
- private static final String[] SWAGGER = {
- "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html"
- };
+ private static final String[] SWAGGER = {"/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html"};
// ๋ก๊ทธ์ธ/ํ ํฐ ๊ตํ/๋ฆฌ๋ค์ด๋ ํธ/ํฌ์ค์ฒดํฌ ๋ฑ ๊ณต๊ฐ ๊ฒฝ๋ก
private static final String[] PUBLIC = {
- "/", "/actuator/health",
- "/api/auth/**", // ์นด์นด์ค ์ฝ๋ ๊ตํ API ๋ฑ
- "/oauth2/**",
- "/login/**", "/login/oauth2/**",
- "/api/test/auth/**",
- "/rooms/**",
- "/chatlists/**",
- "/anonymous-profiles/**",
- "/votes/**",
- "/ws-connect/**", "/chat-test", "/pub/**", "/sub/**"
+ "/",
+ "/actuator/health",
+ "/api/auth/**", // ์นด์นด์ค ์ฝ๋ ๊ตํ API ๋ฑ
+ "/oauth2/**",
+ "/login/**",
+ "/login/oauth2/**",
+ "/api/test/auth/**",
+ "/rooms/**",
+ "/chatlists/**",
+ "/anonymous-profiles/**",
+ "/votes/**",
+ "/ws-connect/**",
+ "/chat-test",
+ "/pub/**",
+ "/sub/**"
};
// ์ ์ ๋ฆฌ์์ค
private static final String[] STATIC = {
- "/favicon.ico", "/assets/**", "/css/**", "/js/**", "/images/**"
+ "/favicon.ico", "/assets/**", "/css/**", "/js/**", "/images/**"
};
@Bean
@@ -73,37 +75,46 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestCache(cache -> cache.disable())
// ๊ถํ ๊ท์น
- .authorizeHttpRequests(auth -> auth
- .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // CORS preflight ํ์ฉ
- .requestMatchers(SWAGGER).permitAll()
- .requestMatchers(PUBLIC).permitAll()
- .requestMatchers(STATIC).permitAll()
- .anyRequest().authenticated())
+ .authorizeHttpRequests(
+ auth ->
+ auth.requestMatchers(HttpMethod.OPTIONS, "/**")
+ .permitAll() // CORS preflight ํ์ฉ
+ .requestMatchers(SWAGGER)
+ .permitAll()
+ .requestMatchers(PUBLIC)
+ .permitAll()
+ .requestMatchers(STATIC)
+ .permitAll()
+ .anyRequest()
+ .authenticated())
// ์ธ์ฆ/์ธ๊ฐ ์คํจ ๊ณตํต ์๋ต(JSON) - ApiResponse ํ์
- .exceptionHandling(ex -> ex
- .authenticationEntryPoint((req, res, ex1) -> {
- ErrorStatus errorStatus = ErrorStatus._UNAUTHORIZED;
- res.setStatus(errorStatus.getReasonHttpStatus().getHttpStatus().value());
- res.setContentType("application/json;charset=UTF-8");
- try (PrintWriter w = res.getWriter()) {
- w.write(String.format(
- "{\"isSuccess\":false,\"code\":\"%s\",\"message\":\"%s\",\"data\":null}",
- errorStatus.getCode(),
- errorStatus.getMessage()));
- }
- })
- .accessDeniedHandler((req, res, ex2) -> {
- ErrorStatus errorStatus = ErrorStatus._FORBIDDEN;
- res.setStatus(errorStatus.getReasonHttpStatus().getHttpStatus().value());
- res.setContentType("application/json;charset=UTF-8");
- try (PrintWriter w = res.getWriter()) {
- w.write(String.format(
- "{\"isSuccess\":false,\"code\":\"%s\",\"message\":\"%s\",\"data\":null}",
- errorStatus.getCode(),
- errorStatus.getMessage()));
- }
- }))
+ .exceptionHandling(
+ ex ->
+ ex.authenticationEntryPoint(
+ (req, res, ex1) -> {
+ ErrorStatus errorStatus = ErrorStatus._UNAUTHORIZED;
+ res.setStatus(errorStatus.getReasonHttpStatus().getHttpStatus().value());
+ res.setContentType("application/json;charset=UTF-8");
+ try (PrintWriter w = res.getWriter()) {
+ w.write(
+ String.format(
+ "{\"isSuccess\":false,\"code\":\"%s\",\"message\":\"%s\",\"data\":null}",
+ errorStatus.getCode(), errorStatus.getMessage()));
+ }
+ })
+ .accessDeniedHandler(
+ (req, res, ex2) -> {
+ ErrorStatus errorStatus = ErrorStatus._FORBIDDEN;
+ res.setStatus(errorStatus.getReasonHttpStatus().getHttpStatus().value());
+ res.setContentType("application/json;charset=UTF-8");
+ try (PrintWriter w = res.getWriter()) {
+ w.write(
+ String.format(
+ "{\"isSuccess\":false,\"code\":\"%s\",\"message\":\"%s\",\"data\":null}",
+ errorStatus.getCode(), errorStatus.getMessage()));
+ }
+ }))
// JWT ํํฐ ๋ฑ๋ก(UsernamePasswordAuthenticationFilter ์)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
@@ -112,15 +123,15 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
}
private static void addAll(List target, String[] arr) {
- for (String s : arr)
- target.add(s);
+ for (String s : arr) target.add(s);
}
// CORS (๊ฐ๋ฐ์ฉ: ํ์ ์ ๋๋ฉ์ธ ๊ณ ์ /์ถ์)
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration c = new CorsConfiguration();
- c.setAllowedOrigins(List.of("http://localhost:3000", "http://127.0.0.1:3000", "http://localhost:5173"));
+ c.setAllowedOrigins(
+ List.of("http://localhost:3000", "http://127.0.0.1:3000", "http://localhost:5173"));
c.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
c.setAllowedHeaders(List.of("*"));
c.setExposedHeaders(List.of("Authorization", "Location"));
diff --git a/src/main/java/opensource/bravest/global/config/ValkeyConfig.java b/src/main/java/opensource/bravest/global/config/ValkeyConfig.java
index f13aea9..be6c578 100644
--- a/src/main/java/opensource/bravest/global/config/ValkeyConfig.java
+++ b/src/main/java/opensource/bravest/global/config/ValkeyConfig.java
@@ -2,15 +2,14 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class ValkeyConfig {
- @Bean
- public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
- return new StringRedisTemplate(connectionFactory);
- }
+ @Bean
+ public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
+ return new StringRedisTemplate(connectionFactory);
+ }
}
diff --git a/src/main/java/opensource/bravest/global/config/WebSocketConfig.java b/src/main/java/opensource/bravest/global/config/WebSocketConfig.java
index 87931a0..177db70 100644
--- a/src/main/java/opensource/bravest/global/config/WebSocketConfig.java
+++ b/src/main/java/opensource/bravest/global/config/WebSocketConfig.java
@@ -14,23 +14,21 @@
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
- private final StompHandler stompHandler;
+ private final StompHandler stompHandler;
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry.addEndpoint("/ws-connect")
- .setAllowedOriginPatterns("*")
- .withSockJS();
- }
+ @Override
+ public void registerStompEndpoints(StompEndpointRegistry registry) {
+ registry.addEndpoint("/ws-connect").setAllowedOriginPatterns("*").withSockJS();
+ }
- @Override
- public void configureMessageBroker(MessageBrokerRegistry registry) {
- registry.enableSimpleBroker("/subs");
- registry.setApplicationDestinationPrefixes("/pubs");
- }
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry registry) {
+ registry.enableSimpleBroker("/subs");
+ registry.setApplicationDestinationPrefixes("/pubs");
+ }
- @Override
- public void configureClientInboundChannel(ChannelRegistration registration) {
- registration.interceptors(stompHandler);
- }
+ @Override
+ public void configureClientInboundChannel(ChannelRegistration registration) {
+ registration.interceptors(stompHandler);
+ }
}
diff --git a/src/main/java/opensource/bravest/global/exception/CustomException.java b/src/main/java/opensource/bravest/global/exception/CustomException.java
index 1ae5428..3fb913e 100644
--- a/src/main/java/opensource/bravest/global/exception/CustomException.java
+++ b/src/main/java/opensource/bravest/global/exception/CustomException.java
@@ -1,19 +1,16 @@
package opensource.bravest.global.exception;
-
import lombok.Getter;
import opensource.bravest.global.apiPayload.code.BaseErrorCode;
-/**
- * ์๋น์ค/๋๋ฉ์ธ ๋ ์ด์ด์์ ํ์คํ๋ ์๋ฌ์ฝ๋๋ฅผ ๋์ง๊ธฐ ์ํ ์์ธ
- */
+/** ์๋น์ค/๋๋ฉ์ธ ๋ ์ด์ด์์ ํ์คํ๋ ์๋ฌ์ฝ๋๋ฅผ ๋์ง๊ธฐ ์ํ ์์ธ */
@Getter
public class CustomException extends RuntimeException {
- private final BaseErrorCode errorCode;
+ private final BaseErrorCode errorCode;
- public CustomException(BaseErrorCode errorCode) {
- super(errorCode.getReason().getMessage());
- this.errorCode = errorCode;
- }
-}
\ No newline at end of file
+ public CustomException(BaseErrorCode errorCode) {
+ super(errorCode.getReason().getMessage());
+ this.errorCode = errorCode;
+ }
+}
diff --git a/src/main/java/opensource/bravest/global/exception/GlobalExceptionHandler.java b/src/main/java/opensource/bravest/global/exception/GlobalExceptionHandler.java
index aeddd45..6faa479 100644
--- a/src/main/java/opensource/bravest/global/exception/GlobalExceptionHandler.java
+++ b/src/main/java/opensource/bravest/global/exception/GlobalExceptionHandler.java
@@ -14,8 +14,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(CustomException.class)
public ResponseEntity> handleCustomException(CustomException e) {
log.warn("CustomException: {}", e.getMessage());
- return ResponseEntity
- .status(e.getErrorCode().getReasonHttpStatus().getHttpStatus())
+ return ResponseEntity.status(e.getErrorCode().getReasonHttpStatus().getHttpStatus())
.body(ApiResponse.onFailure(e.getErrorCode(), null));
}
@@ -27,31 +26,31 @@ public ResponseEntity> handleRuntimeException(RuntimeExcepti
if (message != null) {
if (message.contains("์ ํจํ์ง ์์ ์ด๋ ์ฝ๋") || message.contains("๊ฐ์กฑ์ ์ฐพ์ ์ ์์ต๋๋ค")) {
log.warn("Family not found: {}", message);
- return ResponseEntity
- .status(ErrorStatus._FAMILY_NOT_FOUND.getReasonHttpStatus().getHttpStatus())
+ return ResponseEntity.status(
+ ErrorStatus._FAMILY_NOT_FOUND.getReasonHttpStatus().getHttpStatus())
.body(ApiResponse.onFailure(ErrorStatus._FAMILY_NOT_FOUND, null));
}
if (message.contains("์ฌ์ฉ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค")) {
log.warn("User not found: {}", message);
- return ResponseEntity
- .status(ErrorStatus._USER_NOT_FOUND.getReasonHttpStatus().getHttpStatus())
+ return ResponseEntity.status(
+ ErrorStatus._USER_NOT_FOUND.getReasonHttpStatus().getHttpStatus())
.body(ApiResponse.onFailure(ErrorStatus._USER_NOT_FOUND, null));
}
}
// ๊ธฐ๋ณธ๊ฐ: 500 Internal Server Error
log.error("RuntimeException: ", e);
- return ResponseEntity
- .status(ErrorStatus._INTERNAL_SERVER_ERROR.getReasonHttpStatus().getHttpStatus())
+ return ResponseEntity.status(
+ ErrorStatus._INTERNAL_SERVER_ERROR.getReasonHttpStatus().getHttpStatus())
.body(ApiResponse.onFailure(ErrorStatus._INTERNAL_SERVER_ERROR, null));
}
@ExceptionHandler(Exception.class)
public ResponseEntity> handleException(Exception e) {
log.error("Unexpected exception: ", e);
- return ResponseEntity
- .status(ErrorStatus._INTERNAL_SERVER_ERROR.getReasonHttpStatus().getHttpStatus())
+ return ResponseEntity.status(
+ ErrorStatus._INTERNAL_SERVER_ERROR.getReasonHttpStatus().getHttpStatus())
.body(ApiResponse.onFailure(ErrorStatus._INTERNAL_SERVER_ERROR, null));
}
}
diff --git a/src/main/java/opensource/bravest/global/handler/StompHandler.java b/src/main/java/opensource/bravest/global/handler/StompHandler.java
index c3ab889..d7ec8d8 100644
--- a/src/main/java/opensource/bravest/global/handler/StompHandler.java
+++ b/src/main/java/opensource/bravest/global/handler/StompHandler.java
@@ -1,5 +1,7 @@
package opensource.bravest.global.handler;
+import java.security.Principal;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import opensource.bravest.domain.profile.repository.AnonymousProfileRepository;
@@ -16,136 +18,141 @@
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
-import java.security.Principal;
-import java.util.List;
-
@Slf4j
@Component
@RequiredArgsConstructor
public class StompHandler implements ChannelInterceptor {
- private final AnonymousProfileRepository anonymousProfileRepository;
- private final StringRedisTemplate redisTemplate;
+ private final AnonymousProfileRepository anonymousProfileRepository;
+ private final StringRedisTemplate redisTemplate;
- private static final String USER_SUB_KEY_PREFIX = "ws:subs:user:"; // + anonymousId
- private static final String METRIC_TOTAL_SUB = "ws:metrics:sub:total";
- private static final String METRIC_DUP_SUB = "ws:metrics:sub:duplicate";
+ private static final String USER_SUB_KEY_PREFIX = "ws:subs:user:"; // + anonymousId
+ private static final String METRIC_TOTAL_SUB = "ws:metrics:sub:total";
+ private static final String METRIC_DUP_SUB = "ws:metrics:sub:duplicate";
- @Override
- public Message> preSend(Message> message, MessageChannel channel) {
- StompHeaderAccessor accessor =
- MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
+ @Override
+ public Message> preSend(Message> message, MessageChannel channel) {
+ StompHeaderAccessor accessor =
+ MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
- if (accessor == null) {
- return message;
- }
+ if (accessor == null) {
+ return message;
+ }
- StompCommand command = accessor.getCommand();
-
- // 1) CONNECT: anonymousId๋ฅผ Principal๋ก ์ค์
- if (StompCommand.CONNECT.equals(command)) {
- String anonymousId = accessor.getFirstNativeHeader("anonymousId");
- if (anonymousId == null || anonymousId.isBlank()) {
- log.warn("STOMP CONNECT: anonymousId missing");
- throw new IllegalArgumentException("anonymousId header is required");
- }
-
- anonymousProfileRepository.findById(Long.valueOf(anonymousId))
- .ifPresentOrElse(member -> {
- Authentication auth = new UsernamePasswordAuthenticationToken(
- anonymousId,
- null,
- List.of(new SimpleGrantedAuthority("ROLE_ANONYMOUS"))
- );
- SecurityContextHolder.getContext().setAuthentication(auth);
- accessor.setUser(auth);
- log.info("STOMP CONNECT: anonymousId={} principal set", anonymousId);
- }, () -> {
- log.warn("STOMP CONNECT: invalid anonymousId={}", anonymousId);
- throw new IllegalArgumentException("Invalid anonymousId");
- });
- }
+ StompCommand command = accessor.getCommand();
+
+ // 1) CONNECT: anonymousId๋ฅผ Principal๋ก ์ค์
+ if (StompCommand.CONNECT.equals(command)) {
+ String anonymousId = accessor.getFirstNativeHeader("anonymousId");
+ if (anonymousId == null || anonymousId.isBlank()) {
+ log.warn("STOMP CONNECT: anonymousId missing");
+ throw new IllegalArgumentException("anonymousId header is required");
+ }
+
+ anonymousProfileRepository
+ .findById(Long.valueOf(anonymousId))
+ .ifPresentOrElse(
+ member -> {
+ Authentication auth =
+ new UsernamePasswordAuthenticationToken(
+ anonymousId, null, List.of(new SimpleGrantedAuthority("ROLE_ANONYMOUS")));
+ SecurityContextHolder.getContext().setAuthentication(auth);
+ accessor.setUser(auth);
+ log.info("STOMP CONNECT: anonymousId={} principal set", anonymousId);
+ },
+ () -> {
+ log.warn("STOMP CONNECT: invalid anonymousId={}", anonymousId);
+ throw new IllegalArgumentException("Invalid anonymousId");
+ });
+ }
- // 2) SUBSCRIBE: Redis๋ฅผ ์ฌ์ฉํด anonymousId ๊ธฐ์ค ์ค๋ณต ๊ตฌ๋
๋ฐฉ์ง + ๋ฉํธ๋ฆญ ๊ธฐ๋ก
- if (StompCommand.SUBSCRIBE.equals(command)) {
- Principal user = accessor.getUser();
- if (user == null) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null) {
- accessor.setUser(auth);
- user = auth;
- }
- }
-
- String destination = accessor.getDestination();
-
- if (user != null && destination != null) {
- String anonymousId = user.getName();
- String key = USER_SUB_KEY_PREFIX + anonymousId;
-
- log.info("[SUBSCRIBE] handling: anonymousId={}, destination={}, key={}",
- anonymousId, destination, key);
-
- try {
- Long total = redisTemplate.opsForValue().increment(METRIC_TOTAL_SUB);
- Long added = redisTemplate.opsForSet().add(key, destination);
- redisTemplate.expire(key, java.time.Duration.ofHours(1));
-
- log.info("[SUBSCRIBE] redis result: total={}, added={}", total, added);
-
- if (added != null && added == 0L) {
- Long dup = redisTemplate.opsForValue().increment(METRIC_DUP_SUB);
- log.warn("[SUBSCRIBE] duplicate detected: anonymousId={}, dest={}, dupCount={}",
- anonymousId, destination, dup);
- return null;
- }
-
- log.info("[SUBSCRIBE] stored in Redis: key={}, member={}", key, destination);
-
- } catch (Exception e) {
- log.error("Redis error while handling SUBSCRIBE", e);
- }
- } else {
- log.warn("[SUBSCRIBE] skipped: user or destination is null (user={}, dest={})",
- user, destination);
- }
+ // 2) SUBSCRIBE: Redis๋ฅผ ์ฌ์ฉํด anonymousId ๊ธฐ์ค ์ค๋ณต ๊ตฌ๋
๋ฐฉ์ง + ๋ฉํธ๋ฆญ ๊ธฐ๋ก
+ if (StompCommand.SUBSCRIBE.equals(command)) {
+ Principal user = accessor.getUser();
+ if (user == null) {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ if (auth != null) {
+ accessor.setUser(auth);
+ user = auth;
}
+ }
+
+ String destination = accessor.getDestination();
+ if (user != null && destination != null) {
+ String anonymousId = user.getName();
+ String key = USER_SUB_KEY_PREFIX + anonymousId;
- // 3) SEND: Principal ๋น์ด ์์ผ๋ฉด SecurityContext์์ ๋ณต๊ตฌ
- if (StompCommand.SEND.equals(command)) {
- Principal user = accessor.getUser();
- if (user == null) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null) {
- accessor.setUser(auth);
- }
- }
+ log.info(
+ "[SUBSCRIBE] handling: anonymousId={}, destination={}, key={}",
+ anonymousId,
+ destination,
+ key);
+
+ try {
+ Long total = redisTemplate.opsForValue().increment(METRIC_TOTAL_SUB);
+ Long added = redisTemplate.opsForSet().add(key, destination);
+ redisTemplate.expire(key, java.time.Duration.ofHours(1));
+
+ log.info("[SUBSCRIBE] redis result: total={}, added={}", total, added);
+
+ if (added != null && added == 0L) {
+ Long dup = redisTemplate.opsForValue().increment(METRIC_DUP_SUB);
+ log.warn(
+ "[SUBSCRIBE] duplicate detected: anonymousId={}, dest={}, dupCount={}",
+ anonymousId,
+ destination,
+ dup);
+ return null;
+ }
+
+ log.info("[SUBSCRIBE] stored in Redis: key={}, member={}", key, destination);
+
+ } catch (Exception e) {
+ log.error("Redis error while handling SUBSCRIBE", e);
}
+ } else {
+ log.warn(
+ "[SUBSCRIBE] skipped: user or destination is null (user={}, dest={})",
+ user,
+ destination);
+ }
+ }
- // 4) DISCONNECT: ์ ์ ๋ณ ๊ตฌ๋
ํค๋ฅผ ์ ๋ฆฌํ ์ง ์ฌ๋ถ (์ต์
)
- // - ์ ์ฒด ๋ฐฉ ์ ์ฒด ์ ์ ์๊ฐ ํฌ์ง ์๋ค๋ฉด TTL๋ง์ผ๋ก๋ ์ถฉ๋ถ.
- if (StompCommand.DISCONNECT.equals(command)) {
- Principal user = accessor.getUser();
- if (user == null) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null) {
- user = auth;
- }
- }
- if (user != null) {
- String anonymousId = user.getName();
- String key = USER_SUB_KEY_PREFIX + anonymousId;
- try {
- // ์์ ํ ์ ๋ฆฌํ๊ณ ์ถ์ผ๋ฉด delete
- redisTemplate.delete(key);
- log.info("DISCONNECT: cleared subscriptions for anonymousId={}", anonymousId);
- } catch (Exception e) {
- log.error("Redis error while handling DISCONNECT", e);
- }
- }
+ // 3) SEND: Principal ๋น์ด ์์ผ๋ฉด SecurityContext์์ ๋ณต๊ตฌ
+ if (StompCommand.SEND.equals(command)) {
+ Principal user = accessor.getUser();
+ if (user == null) {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ if (auth != null) {
+ accessor.setUser(auth);
}
+ }
+ }
- return message;
+ // 4) DISCONNECT: ์ ์ ๋ณ ๊ตฌ๋
ํค๋ฅผ ์ ๋ฆฌํ ์ง ์ฌ๋ถ (์ต์
)
+ // - ์ ์ฒด ๋ฐฉ ์ ์ฒด ์ ์ ์๊ฐ ํฌ์ง ์๋ค๋ฉด TTL๋ง์ผ๋ก๋ ์ถฉ๋ถ.
+ if (StompCommand.DISCONNECT.equals(command)) {
+ Principal user = accessor.getUser();
+ if (user == null) {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ if (auth != null) {
+ user = auth;
+ }
+ }
+ if (user != null) {
+ String anonymousId = user.getName();
+ String key = USER_SUB_KEY_PREFIX + anonymousId;
+ try {
+ // ์์ ํ ์ ๋ฆฌํ๊ณ ์ถ์ผ๋ฉด delete
+ redisTemplate.delete(key);
+ log.info("DISCONNECT: cleared subscriptions for anonymousId={}", anonymousId);
+ } catch (Exception e) {
+ log.error("Redis error while handling DISCONNECT", e);
+ }
+ }
}
+
+ return message;
+ }
}
diff --git a/src/main/java/opensource/bravest/global/security/jwt/JwtAuthenticationFilter.java b/src/main/java/opensource/bravest/global/security/jwt/JwtAuthenticationFilter.java
index 5f7c282..34ccece 100644
--- a/src/main/java/opensource/bravest/global/security/jwt/JwtAuthenticationFilter.java
+++ b/src/main/java/opensource/bravest/global/security/jwt/JwtAuthenticationFilter.java
@@ -5,68 +5,67 @@
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
/**
- * JWT๊ฐ ํ์ํ ๋ณดํธ ๊ฒฝ๋ก์๋ง ๋์ํ๋๋ก ๋ง๋ ํํฐ.
- * - ํ์ดํธ๋ฆฌ์คํธ(permitAll) ๊ฒฝ๋ก์ OPTIONS ํ๋ฆฌํ๋ผ์ดํธ๋ ํํฐ๋ฅผ ๊ฑด๋๋.
- * - ํ ํฐ์ด ์ ํจํ๋ฉด SecurityContext ์ค์ , ์๋๋ฉด ์ฒด์ธ ์งํ (401์ EntryPoint๊ฐ ์ฒ๋ฆฌ)
+ * JWT๊ฐ ํ์ํ ๋ณดํธ ๊ฒฝ๋ก์๋ง ๋์ํ๋๋ก ๋ง๋ ํํฐ. - ํ์ดํธ๋ฆฌ์คํธ(permitAll) ๊ฒฝ๋ก์ OPTIONS ํ๋ฆฌํ๋ผ์ดํธ๋ ํํฐ๋ฅผ ๊ฑด๋๋. - ํ ํฐ์ด ์ ํจํ๋ฉด
+ * SecurityContext ์ค์ , ์๋๋ฉด ์ฒด์ธ ์งํ (401์ EntryPoint๊ฐ ์ฒ๋ฆฌ)
*/
public class JwtAuthenticationFilter extends OncePerRequestFilter {
- private final JwtTokenProvider jwtTokenProvider;
- private final List skipPatterns; // ํํฐ๋ฅผ ์คํตํ ๊ฒฝ๋ก ํจํด๋ค(ant style)
- private final AntPathMatcher matcher = new AntPathMatcher();
+ private final JwtTokenProvider jwtTokenProvider;
+ private final List skipPatterns; // ํํฐ๋ฅผ ์คํตํ ๊ฒฝ๋ก ํจํด๋ค(ant style)
+ private final AntPathMatcher matcher = new AntPathMatcher();
- public JwtAuthenticationFilter(JwtTokenProvider provider, Collection skipPatterns) {
- this.jwtTokenProvider = provider;
- this.skipPatterns = skipPatterns == null ? List.of() : List.copyOf(skipPatterns);
- }
+ public JwtAuthenticationFilter(JwtTokenProvider provider, Collection skipPatterns) {
+ this.jwtTokenProvider = provider;
+ this.skipPatterns = skipPatterns == null ? List.of() : List.copyOf(skipPatterns);
+ }
- @Override
- protected boolean shouldNotFilter(HttpServletRequest request) {
- // 1) CORS preflight๋ ํญ์ ์คํต
- if ("OPTIONS".equalsIgnoreCase(request.getMethod())) return true;
+ @Override
+ protected boolean shouldNotFilter(HttpServletRequest request) {
+ // 1) CORS preflight๋ ํญ์ ์คํต
+ if ("OPTIONS".equalsIgnoreCase(request.getMethod())) return true;
- // 2) ํ์ดํธ๋ฆฌ์คํธ ํจํด์ ์คํต
- String path = request.getServletPath();
- for (String p : skipPatterns) {
- if (matcher.match(p, path)) return true;
- }
- return false;
+ // 2) ํ์ดํธ๋ฆฌ์คํธ ํจํด์ ์คํต
+ String path = request.getServletPath();
+ for (String p : skipPatterns) {
+ if (matcher.match(p, path)) return true;
}
+ return false;
+ }
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
- throws ServletException, IOException {
+ @Override
+ protected void doFilterInternal(
+ HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+ throws ServletException, IOException {
- String header = request.getHeader(HttpHeaders.AUTHORIZATION);
+ String header = request.getHeader(HttpHeaders.AUTHORIZATION);
- if (header != null && header.startsWith("Bearer ")) {
- String token = header.substring(7);
- try {
- Claims claims = jwtTokenProvider.parseClaims(token);
- String subject = claims.getSubject();
- if (subject != null && SecurityContextHolder.getContext().getAuthentication() == null) {
- // ํ์ ์ roles/authorities๋ฅผ claims์์ ๊บผ๋ด์ ๋ฃ์ด๋ ๋จ
- var auth = new UsernamePasswordAuthenticationToken(subject, null, Collections.emptyList());
- SecurityContextHolder.getContext().setAuthentication(auth);
- }
- } catch (Exception ignored) {
- // ์ ํจํ์ง ์์ผ๋ฉด ๊ทธ๋ฅ ํต๊ณผ -> ์ต์ข
์ ์ผ๋ก EntryPoint๊ฐ 401 ์๋ต ์ฒ๋ฆฌ
- }
+ if (header != null && header.startsWith("Bearer ")) {
+ String token = header.substring(7);
+ try {
+ Claims claims = jwtTokenProvider.parseClaims(token);
+ String subject = claims.getSubject();
+ if (subject != null && SecurityContextHolder.getContext().getAuthentication() == null) {
+ // ํ์ ์ roles/authorities๋ฅผ claims์์ ๊บผ๋ด์ ๋ฃ์ด๋ ๋จ
+ var auth =
+ new UsernamePasswordAuthenticationToken(subject, null, Collections.emptyList());
+ SecurityContextHolder.getContext().setAuthentication(auth);
}
-
- chain.doFilter(request, response);
+ } catch (Exception ignored) {
+ // ์ ํจํ์ง ์์ผ๋ฉด ๊ทธ๋ฅ ํต๊ณผ -> ์ต์ข
์ ์ผ๋ก EntryPoint๊ฐ 401 ์๋ต ์ฒ๋ฆฌ
+ }
}
-}
+ chain.doFilter(request, response);
+ }
+}
diff --git a/src/main/java/opensource/bravest/global/security/jwt/JwtTokenProvider.java b/src/main/java/opensource/bravest/global/security/jwt/JwtTokenProvider.java
index e2e3b36..f5a8f66 100644
--- a/src/main/java/opensource/bravest/global/security/jwt/JwtTokenProvider.java
+++ b/src/main/java/opensource/bravest/global/security/jwt/JwtTokenProvider.java
@@ -1,99 +1,93 @@
package opensource.bravest.global.security.jwt;
+import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.io.Decoders;
-import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.security.Keys;
import jakarta.annotation.PostConstruct;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Date;
import java.util.Map;
+import javax.crypto.SecretKey;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
@Component
public class JwtTokenProvider {
- @Value("${jwt.secret}")
- private String secret;
-
- @Value("${jwt.access-token-validity-seconds}")
- private long accessValidity;
-
- @Value("${jwt.refresh-token-validity-seconds}")
- private long refreshValidity;
+ @Value("${jwt.secret}")
+ private String secret;
- private SecretKey key;
+ @Value("${jwt.access-token-validity-seconds}")
+ private long accessValidity;
- @PostConstruct
- void init() {
- if (secret == null || secret.isBlank()) {
- throw new IllegalStateException("jwt.secret is not configured. Check your application.yml / env.");
- }
+ @Value("${jwt.refresh-token-validity-seconds}")
+ private long refreshValidity;
- byte[] keyBytes;
- try {
- // secret์ด Base64๋ฉด ์ฌ๊ธฐ์ ์ ์ ๋์ฝ๋ฉ
- keyBytes = Decoders.BASE64.decode(secret);
- } catch (IllegalArgumentException e) {
- // Base64 ์๋๋ฉด ๊ทธ๋ฅ ๋ฌธ์์ด ๋ฐ์ดํธ๋ก ์ฌ์ฉ
- keyBytes = secret.getBytes(StandardCharsets.UTF_8);
- }
+ private SecretKey key;
- this.key = Keys.hmacShaKeyFor(keyBytes);
+ @PostConstruct
+ void init() {
+ if (secret == null || secret.isBlank()) {
+ throw new IllegalStateException(
+ "jwt.secret is not configured. Check your application.yml / env.");
}
- public String createAccessToken(String subject, Map claims) {
- Instant now = Instant.now();
- return Jwts.builder()
- .subject(subject)
- .claims(claims)
- .issuedAt(Date.from(now))
- .expiration(Date.from(now.plusSeconds(accessValidity)))
- .signWith(key)
- .compact();
+ byte[] keyBytes;
+ try {
+ // secret์ด Base64๋ฉด ์ฌ๊ธฐ์ ์ ์ ๋์ฝ๋ฉ
+ keyBytes = Decoders.BASE64.decode(secret);
+ } catch (IllegalArgumentException e) {
+ // Base64 ์๋๋ฉด ๊ทธ๋ฅ ๋ฌธ์์ด ๋ฐ์ดํธ๋ก ์ฌ์ฉ
+ keyBytes = secret.getBytes(StandardCharsets.UTF_8);
}
- public String createRefreshToken(String subject) {
- Instant now = Instant.now();
- return Jwts.builder()
- .subject(subject)
- .issuedAt(Date.from(now))
- .expiration(Date.from(now.plusSeconds(refreshValidity)))
- .signWith(key)
- .compact();
+ this.key = Keys.hmacShaKeyFor(keyBytes);
+ }
+
+ public String createAccessToken(String subject, Map claims) {
+ Instant now = Instant.now();
+ return Jwts.builder()
+ .subject(subject)
+ .claims(claims)
+ .issuedAt(Date.from(now))
+ .expiration(Date.from(now.plusSeconds(accessValidity)))
+ .signWith(key)
+ .compact();
+ }
+
+ public String createRefreshToken(String subject) {
+ Instant now = Instant.now();
+ return Jwts.builder()
+ .subject(subject)
+ .issuedAt(Date.from(now))
+ .expiration(Date.from(now.plusSeconds(refreshValidity)))
+ .signWith(key)
+ .compact();
+ }
+
+ public Long getIdFromToken(String token) {
+ Claims claims =
+ Jwts.parser()
+ .verifyWith(key) // init()์์ ๋ง๋ key ์ฌ์ฌ์ฉ
+ .build()
+ .parseSignedClaims(token)
+ .getPayload();
+
+ return claims.get("id", Long.class);
+ }
+
+ public boolean validateToken(String token) {
+ try {
+ Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
+ return true;
+ } catch (Exception e) {
+ return false;
}
+ }
- public Long getIdFromToken(String token) {
- Claims claims = Jwts.parser()
- .verifyWith(key) // init()์์ ๋ง๋ key ์ฌ์ฌ์ฉ
- .build()
- .parseSignedClaims(token)
- .getPayload();
-
- return claims.get("id", Long.class);
- }
-
- public boolean validateToken(String token) {
- try {
- Jwts.parser()
- .verifyWith(key)
- .build()
- .parseSignedClaims(token);
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- public Claims parseClaims(String token) {
- return Jwts.parser()
- .verifyWith(key)
- .build()
- .parseSignedClaims(token)
- .getPayload();
- }
+ public Claims parseClaims(String token) {
+ return Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload();
+ }
}
diff --git a/src/test/java/opensource/bravest/BravestApplicationTests.java b/src/test/java/opensource/bravest/BravestApplicationTests.java
index 6494944..bde485a 100644
--- a/src/test/java/opensource/bravest/BravestApplicationTests.java
+++ b/src/test/java/opensource/bravest/BravestApplicationTests.java
@@ -6,8 +6,6 @@
@SpringBootTest
class BravestApplicationTests {
- @Test
- void contextLoads() {
- }
-
+ @Test
+ void contextLoads() {}
}