Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
81366db
feat: image ์—”ํ‹ฐํ‹ฐ์™€ encyclopediacard ์—”ํ‹ฐํ‹ฐ ์—ฐ๊ด€ ๊ด€๊ณ„ ์ œ๊ฑฐ ๋ฐ ์ด๋ฏธ์ง€ ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ ๋ฐฉ์‹ ์ ์šฉ ์™„๋ฃŒ
qkrcodus Jul 22, 2025
3fadbdd
refactor: DTO์—์„œ service ์˜์กด์„ฑ ์ œ๊ฑฐ
qkrcodus Jul 23, 2025
771fe87
refactor: thumnail url, imageurls ์—์„œ /cards ๊ฒฝ๋กœ ์ œ๊ฑฐ
qkrcodus Jul 23, 2025
172db36
refactor: getCards ์—์„œ ๋ฐ˜๋ณต ํ˜ธ์ถœ์ค‘์ด๋˜ imageService ์ œ๊ฑฐ -> SYSTEM_DOGAM_PROFILโ€ฆ
qkrcodus Jul 24, 2025
53520d2
fix: ๋™์ผ cardId์— ๋„๊ฐ ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ ์ฒซ ๋ฒˆ์งธ ์ด๋ฏธ์ง€๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ์ค‘๋ณต ์ œ๊ฑฐ ์ฒ˜๋ฆฌ
qkrcodus Jul 24, 2025
4256770
Merge pull request #69 from DivaryOfficial/fix/#66-encyclopedia-image
qkrcodus Jul 24, 2025
5b40e93
feat/#55: ์ปค์Šคํ…€ ์ธ์ฆ ๊ตฌํ˜„์ฒด ์ถ”๊ฐ€ ๋ฐ JWT ์ธ์ฆ ๋กœ์ง ๊ฐœ์„ 
Baguette-bbang Jul 22, 2025
e02f843
chore/#55: ํ•„์š”์—†๋Š” ์ฃผ์„ ์ œ๊ฑฐ
Baguette-bbang Jul 22, 2025
453b4a2
feat/#55: Swagger JWT ์ „์—ญ ์„ค์ • ์ถ”๊ฐ€ ๋ฐ SecurityConfig์— chatRoom ๊ฒฝ๋กœ ์ถ”๊ฐ€'
Baguette-bbang Jul 22, 2025
0abec3f
feat/#55: ํ…Œ์ŠคํŠธ ์œ ์ € ๋ฐ JWT ํ† ํฐ ๋ฐœ๊ธ‰ API ์ถ”๊ฐ€
Baguette-bbang Jul 22, 2025
4a54ee0
feat/#55: ํ•„์š”์—†๋Š” global exception ์ œ๊ฑฐ, jwt ํ•„ํ„ฐ์— ์—๋Ÿฌ์ฝ”๋“œ ์ถ”๊ฐ€
Baguette-bbang Jul 22, 2025
a65c893
feat/#55: ์ฑ„ํŒ… ๋„๋ฉ”์ธ์— @AuthenticationPrincipal๋ฅผ ํ†ตํ•œ ์œ ์ € ์ธ์ฆ ์ถ”๊ฐ€
Baguette-bbang Jul 22, 2025
5876d10
feat/#55: ํ† ํฐ์ด ์—†๋Š”๊ฒฝ์šฐ 401์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์„ค์ •
Baguette-bbang Jul 22, 2025
8f4c181
feat/#55: ์—๋Ÿฌ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ๋  ์—๋Ÿฌ์ฝ”๋“œ ๋ฏธ๋ฆฌ ์ถ”๊ฐ€
Baguette-bbang Jul 22, 2025
a6985b4
feat/#63: ์ฑ„ํŒ… ๋„๋ฉ”์ธ ์—๋Ÿฌ์ฝ”๋“œ ์ ์šฉ ๋ฐ ์ปจํŠธ๋กค๋Ÿฌ์— ์—๋Ÿฌ ์Šค์›จ๊ฑฐ ๋ฌธ์„œ ์ž‘์„ฑ
Baguette-bbang Jul 23, 2025
615e839
feat/#63: ์—๋Ÿฌ ์‘๋‹ต ๋ฐ˜ํ™˜ ์‹œ path๋„ ํฌํ•จํ•ด์„œ ๋ฐ˜ํ™˜ ํ•˜๋„๋ก ์ˆ˜์ •
Baguette-bbang Jul 23, 2025
c015167
feat/#55: ์ •ํ˜•ํ™”๋œ ์—๋Ÿฌ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋„๋กฅ handleJwtException ์„ค์ •
Baguette-bbang Jul 23, 2025
a94896b
Merge pull request #70 from DivaryOfficial/feat/#55-chat-domain-autheโ€ฆ
Baguette-bbang Jul 24, 2025
5edd1ed
feat: ์ž„์‹œ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์„œ๋น„์Šค ๊ตฌํ˜„
Baguette-bbang Jul 24, 2025
2f39b23
feat: ์ด๋ฏธ์ง€ ์„œ๋น„์Šค ํ†ตํ•ฉ ๋ฐ ์ž„์‹œ ์—…๋กœ๋“œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Baguette-bbang Jul 24, 2025
d529708
refactor: Image ์—”ํ‹ฐํ‹ฐ ๋ฐ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ๊ฐœ์„ 
Baguette-bbang Jul 24, 2025
9910b84
refactor: ImageController ์˜์กด์„ฑ ๋‹จ์ˆœํ™”
Baguette-bbang Jul 24, 2025
e719369
feat: ImageStorageService ํŒŒ์ผ ์กฐ์ž‘ ๊ธฐ๋Šฅ ํ™•์žฅ
Baguette-bbang Jul 24, 2025
edebfea
feat/#64:log delete,put,patch api ๊ตฌํ˜„
sereene Jul 26, 2025
c62d888
FEAT/#64:delete,put,patch ๋ณด์™„
sereene Jul 26, 2025
3c25306
feat: ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์ถ•
Baguette-bbang Jul 28, 2025
7865e97
fix/#64:repository ๋ฉ”์„œ๋“œ ์ˆ˜์ • ๋ฐ ์–ด๋…ธํ…Œ์ด์…˜ ์ˆ˜์ •
sereene Jul 29, 2025
cdc1761
Merge pull request #74 from DivaryOfficial/feat/#64-logbook
sereene Jul 29, 2025
7c4e5b6
Merge pull request #79 from DivaryOfficial/feat/#72-image-temp-upload
Baguette-bbang Jul 30, 2025
d5918d5
feat: ์ด๋ฏธ์ง€-๊ฒŒ์‹œ๊ธ€ ์ฐธ์กฐ ์ถ”์  ์‹œ์Šคํ…œ ๊ตฌํ˜„
Baguette-bbang Jul 29, 2025
6a6f393
fix: SystemController ์‘๋‹ต ์ฒ˜๋ฆฌ ๋ฐ ์ด๋ฏธ์ง€ URL ์ •๊ทœ์‹ ํŒจํ„ด ์ˆ˜์ •
Baguette-bbang Jul 29, 2025
0abcf6d
refactor: ์ด๋ฏธ์ง€ ์„œ๋น„์Šค ๋‹จ์ผ ์ฑ…์ž„ ์›์น™์— ๋”ฐ๋ฅธ ๋ฆฌํŒฉํ† ๋ง
Baguette-bbang Jul 30, 2025
e3d3a70
refactor: ์ด๋ฏธ์ง€ ๊ฒ€์ฆ ๋กœ์ง์„ ImageValidationService๋กœ ํ†ตํ•ฉ
Baguette-bbang Jul 30, 2025
ee1313e
refactor: ImageType์„ entity์—์„œ enums ํŒจํ‚ค์ง€๋กœ ์ด๋™
Baguette-bbang Jul 30, 2025
a9fc7cc
refactor: ์ด๋ฏธ์ง€ ์„œ๋น„์Šค ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์„ String์—์„œ Long์œผ๋กœ ๋ณ€๊ฒฝ
Baguette-bbang Jul 30, 2025
31282e9
fix: LogBaseInfo ์—”ํ‹ฐํ‹ฐ์— @Builder.Default ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€
Baguette-bbang Jul 30, 2025
7d2f770
feat(image): ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ฑ ๋ฐ ์ˆ˜์ • ์‹œ ์‚ฌ์šฉํ•  ํ†ตํ•ฉ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
Baguette-bbang Jul 31, 2025
b35cd68
feat(image): ์ด๋ฏธ์ง€ cleanup ์Šค์ผ€์ค„๋Ÿฌ
Baguette-bbang Jul 31, 2025
6ef10e8
Merge pull request #86 from DivaryOfficial/feat/#80-image-cleanup-update
Baguette-bbang Jul 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ target/
.gradle/
build/

### Eclipse ###
bin/
.metadata

### STS ###
.apt_generated
.classpath
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/divary/DivaryApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class DivaryApplication {

public static void main(String[] args) {
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/com/divary/common/response/ApiResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public class ApiResponse<T> {
@Schema(description = "์‘๋‹ต ๋ฉ”์‹œ์ง€", example = "์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
private String message;

@Schema(description = "์š”์ฒญ ๊ฒฝ๋กœ", example = "/api/v1/example")
private String path;

@Schema(description = "์‘๋‹ต ๋ฐ์ดํ„ฐ")
private T data;

Expand Down Expand Up @@ -62,6 +65,16 @@ public static <T> ApiResponse<T> error(int status, String code, String message)
.build();
}

public static <T> ApiResponse<T> error(int status, String code, String message, String path) {
return ApiResponse.<T>builder()
.timestamp(LocalDateTime.now())
.status(status)
.code(code)
.message(message)
.path(path)
.build();
}

public static <T> ApiResponse<T> error(ErrorCode errorCode) {
return ApiResponse.<T>builder()
.timestamp(LocalDateTime.now())
Expand All @@ -70,4 +83,14 @@ public static <T> ApiResponse<T> error(ErrorCode errorCode) {
.message(errorCode.getMessage())
.build();
}

public static <T> ApiResponse<T> error(ErrorCode errorCode, String path) {
return ApiResponse.<T>builder()
.timestamp(LocalDateTime.now())
.status(errorCode.getStatus().value())
.code(errorCode.getCode())
.message(errorCode.getMessage())
.path(path)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@
import com.divary.domain.chatroom.dto.response.ChatRoomMessageResponse;
import com.divary.domain.chatroom.dto.response.ChatRoomResponse;
import com.divary.domain.chatroom.service.ChatRoomService;
import com.divary.global.config.SwaggerConfig.ApiErrorExamples;
import com.divary.global.config.SwaggerConfig.ApiSuccessResponse;
import com.divary.global.config.security.CustomUserPrincipal;
import com.divary.global.exception.ErrorCode;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("chatrooms")
@RequiredArgsConstructor
Expand All @@ -27,16 +33,19 @@ public class ChatRoomController {
@PostMapping(consumes = "multipart/form-data")
@Operation(summary = "์ฑ„ํŒ…๋ฐฉ ๋ฉ”์‹œ์ง€ ์ „์†ก", description = "์ƒˆ ์ฑ„ํŒ…๋ฐฉ ์ƒ์„ฑ ๋˜๋Š” ๊ธฐ์กด ์ฑ„ํŒ…๋ฐฉ์— ๋ฉ”์‹œ์ง€ ์ „์†ก\n chatRoomId ์—†์œผ๋ฉด ์ƒˆ ์ฑ„ํŒ…๋ฐฉ ์ƒ์„ฑ\n ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€์™€ AI ์‘๋‹ต๋งŒ ๋ฐ˜ํ™˜")
@ApiSuccessResponse(dataType = ChatRoomMessageResponse.class)
@ApiErrorExamples(value = {ErrorCode.CHAT_ROOM_ACCESS_DENIED, ErrorCode.AUTHENTICATION_REQUIRED})
public ApiResponse<ChatRoomMessageResponse> sendChatRoomMessage(
@Valid @ModelAttribute ChatRoomMessageRequest request) {
@Valid @ModelAttribute ChatRoomMessageRequest request,
@AuthenticationPrincipal CustomUserPrincipal userPrincipal) {

ChatRoomMessageResponse response = chatRoomService.sendChatRoomMessage(request);
ChatRoomMessageResponse response = chatRoomService.sendChatRoomMessage(request, userPrincipal.getId());
return ApiResponse.success(response);
}

@GetMapping("/{chatRoomId}")
@Operation(summary = "์ฑ„ํŒ…๋ฐฉ ์ƒ์„ธ ์กฐํšŒ", description = "์ฑ„ํŒ…๋ฐฉ์˜ ์ƒ์„ธ ์ •๋ณด๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.")
@ApiSuccessResponse(dataType = ChatRoomDetailResponse.class)
@ApiErrorExamples(value = {ErrorCode.CHAT_ROOM_NOT_FOUND, ErrorCode.CHAT_ROOM_ACCESS_DENIED, ErrorCode.AUTHENTICATION_REQUIRED})
public ApiResponse<ChatRoomDetailResponse> getChatRoomDetail(@PathVariable Long chatRoomId) {
ChatRoomDetailResponse response = chatRoomService.getChatRoomDetail(chatRoomId);
return ApiResponse.success(response);
Expand All @@ -45,10 +54,12 @@ public ApiResponse<ChatRoomDetailResponse> getChatRoomDetail(@PathVariable Long

@GetMapping
@Operation(summary = "์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก ์กฐํšŒ", description = "์‚ฌ์šฉ์ž์˜ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.")
public ApiResponse<List<ChatRoomResponse>> getChatRooms() {
// ์ž„์‹œ๋กœ ์‚ฌ์šฉ์ž ID ํ•˜๋“œ์ฝ”๋”ฉ
// TODO: ์‚ฌ์šฉ์ž ID๋ฅผ Authorization ํ—ค๋”์—์„œ ๊ฐ€์ ธ์˜ค๋„๋ก ์ˆ˜์ •
Long userId = 1L;
@ApiSuccessResponse(dataType = ChatRoomResponse.class, isArray = true)
@ApiErrorExamples(value = {ErrorCode.AUTHENTICATION_REQUIRED})
public ApiResponse<List<ChatRoomResponse>> getChatRooms(
@AuthenticationPrincipal CustomUserPrincipal userPrincipal) {

Long userId = userPrincipal.getId();

List<ChatRoomResponse> responses = chatRoomService.getChatRoomsByUserId(userId);
return ApiResponse.success(responses);
Expand All @@ -57,10 +68,10 @@ public ApiResponse<List<ChatRoomResponse>> getChatRooms() {
@DeleteMapping("/{chatRoomId}")
@Operation(summary = "์ฑ„ํŒ…๋ฐฉ ์‚ญ์ œ", description = "์ฑ„ํŒ…๋ฐฉ์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.")
@ApiSuccessResponse(dataType = Void.class)
public ApiResponse<Void> deleteChatRoom(@PathVariable Long chatRoomId) {
// ์ž„์‹œ๋กœ ์‚ฌ์šฉ์ž ID ํ•˜๋“œ์ฝ”๋”ฉ
// TODO: ์‚ฌ์šฉ์ž ID๋ฅผ Authorization ํ—ค๋”์—์„œ ๊ฐ€์ ธ์˜ค๋„๋ก ์ˆ˜์ •
Long userId = 1L;
@ApiErrorExamples(value = {ErrorCode.CHAT_ROOM_NOT_FOUND, ErrorCode.CHAT_ROOM_ACCESS_DENIED, ErrorCode.AUTHENTICATION_REQUIRED})
public ApiResponse<Void> deleteChatRoom(@PathVariable Long chatRoomId,
@AuthenticationPrincipal CustomUserPrincipal userPrincipal) {
Long userId = userPrincipal.getId();

chatRoomService.deleteChatRoom(chatRoomId, userId);
return ApiResponse.success(null);
Expand All @@ -69,11 +80,11 @@ public ApiResponse<Void> deleteChatRoom(@PathVariable Long chatRoomId) {
@PatchMapping("/{chatRoomId}/title")
@Operation(summary = "์ฑ„ํŒ…๋ฐฉ ์ œ๋ชฉ ๋ณ€๊ฒฝ", description = "์ฑ„ํŒ…๋ฐฉ์˜ ์ œ๋ชฉ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.")
@ApiSuccessResponse(dataType = Void.class)
@ApiErrorExamples(value = {ErrorCode.CHAT_ROOM_NOT_FOUND, ErrorCode.CHAT_ROOM_ACCESS_DENIED, ErrorCode.AUTHENTICATION_REQUIRED})
public ApiResponse<Void> updateChatRoomTitle(@PathVariable Long chatRoomId,
@Valid @RequestBody ChatRoomTitleUpdateRequest request) {
// ์ž„์‹œ๋กœ ์‚ฌ์šฉ์ž ID ํ•˜๋“œ์ฝ”๋”ฉ
// TODO: ์‚ฌ์šฉ์ž ID๋ฅผ Authorization ํ—ค๋”์—์„œ ๊ฐ€์ ธ์˜ค๋„๋ก ์ˆ˜์ •
Long userId = 1L;
@Valid @RequestBody ChatRoomTitleUpdateRequest request,
@AuthenticationPrincipal CustomUserPrincipal userPrincipal) {
Long userId = userPrincipal.getId();

chatRoomService.updateChatRoomTitle(chatRoomId, userId, request.getTitle());
return ApiResponse.success(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
import com.divary.domain.chatroom.entity.ChatRoom;
import com.divary.domain.chatroom.repository.ChatRoomRepository;
import com.divary.domain.image.dto.response.ImageResponse;
import com.divary.domain.image.entity.ImageType;
import com.divary.domain.image.enums.ImageType;
import com.divary.domain.image.service.ImageService;
import com.divary.global.exception.BusinessException;
import com.divary.global.exception.ErrorCode;
import com.divary.common.converter.TypeConverter;

import lombok.RequiredArgsConstructor;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -38,8 +40,7 @@ public class ChatRoomService {

// ์ฑ„ํŒ…๋ฐฉ ๋ฉ”์‹œ์ง€ ์ „์†ก (์ƒˆ ์ฑ„ํŒ…๋ฐฉ ์ƒ์„ฑ ๋˜๋Š” ๊ธฐ์กด ์ฑ„ํŒ…๋ฐฉ์— ๋ฉ”์‹œ์ง€ ์ถ”๊ฐ€)
@Transactional
public ChatRoomMessageResponse sendChatRoomMessage(ChatRoomMessageRequest request) {
Long userId = getCurrentUserId();
public ChatRoomMessageResponse sendChatRoomMessage(ChatRoomMessageRequest request, Long userId) {
ChatRoom chatRoom;
List<String> newMessageIds = new java.util.ArrayList<>();

Expand Down Expand Up @@ -89,7 +90,7 @@ private ChatRoom createNewChatRoom(Long userId, ChatRoomMessageRequest request)
String firstMessageId = (String) metadata.get("lastMessageId");
HashMap<String, Object> userMessage = TypeConverter.castToHashMap(messages.get(firstMessageId));

processImageUpload(userMessage, request.getImage(), userId, savedChatRoom.getId().toString());
processImageUpload(userMessage, request.getImage(), userId, savedChatRoom.getId());

messages.put(firstMessageId, userMessage);
savedChatRoom.updateMessages(messages);
Expand All @@ -106,21 +107,21 @@ private ChatRoom addMessageToExistingChatRoom(Long chatRoomId, Long userId, Chat
validateChatRoomOwnership(chatRoom, userId);

// ์ƒˆ ๋ฉ”์‹œ์ง€ ์ถ”๊ฐ€
addUserMessageToChatRoom(chatRoom, request);
addUserMessageToChatRoom(chatRoom, request, userId);

return chatRoom;
}

// ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€๋ฅผ ์ฑ„ํŒ…๋ฐฉ์— ์ถ”๊ฐ€
private void addUserMessageToChatRoom(ChatRoom chatRoom, ChatRoomMessageRequest request) {
private void addUserMessageToChatRoom(ChatRoom chatRoom, ChatRoomMessageRequest request, Long userId) {
HashMap<String, Object> messages = chatRoom.getMessages();
String newMessageId = messageFactory.generateNextMessageId(messages);

// ๋ฉ”์‹œ์ง€ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
HashMap<String, Object> messageData = messageFactory.createUserMessageData(request.getMessage(), null);

// ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ
processImageUpload(messageData, request.getImage(), getCurrentUserId(), chatRoom.getId().toString());
processImageUpload(messageData, request.getImage(), userId, chatRoom.getId());

messages.put(newMessageId, messageData);

Expand Down Expand Up @@ -157,24 +158,17 @@ private String addAiResponseToMessages(ChatRoom chatRoom, OpenAIResponse aiRespo

return nextMessageId;
}

// ํ˜„์žฌ ์‚ฌ์šฉ์ž ID ๊ฐ€์ ธ์˜ค๊ธฐ
private Long getCurrentUserId() {
// TODO: ์‚ฌ์šฉ์ž ID๋ฅผ Authorization ํ—ค๋”์—์„œ ๊ฐ€์ ธ์˜ค๋„๋ก ์ˆ˜์ •
return 1L;
}

// ์ฑ„ํŒ…๋ฐฉ ์†Œ์œ ์ž ๊ถŒํ•œ ํ™•์ธ
private void validateChatRoomOwnership(ChatRoom chatRoom, Long userId) {
// TODO: ์ฑ„ํŒ…๋ฐฉ ์†Œ์œ ์ž ํ™•์ธ ๋กœ์ง - ํ˜„์žฌ๋Š” ํ•˜๋“œ์ฝ”๋”ฉ์œผ๋กœ ์ฒ˜๋ฆฌ
if (!chatRoom.getUserId().equals(userId)) {
throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR);
throw new BusinessException(ErrorCode.CHAT_ROOM_ACCESS_DENIED);
}
}


// ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌ
private void processImageUpload(HashMap<String, Object> messageData, org.springframework.web.multipart.MultipartFile image, Long userId, String chatRoomId) {
private void processImageUpload(HashMap<String, Object> messageData, MultipartFile image, Long userId, Long chatRoomId) {
if (image != null && !image.isEmpty()) {
ImageResponse imageResponse = imageService.uploadImageByType(
ImageType.USER_CHAT,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package com.divary.domain.encyclopedia.controller;

import com.divary.common.response.ApiResponse;
import com.divary.domain.encyclopedia.dto.AppearanceResponse;
import com.divary.domain.encyclopedia.dto.EncyclopediaCardResponse;
import com.divary.domain.encyclopedia.dto.EncyclopediaCardSummaryResponse;
import com.divary.domain.encyclopedia.dto.PersonalityResponse;
import com.divary.domain.encyclopedia.dto.SignificantResponse;
import com.divary.domain.encyclopedia.service.EncyclopediaCardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/cards")
@RequestMapping("/cards")
@RequiredArgsConstructor
public class EncyclopediaCardController {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
import com.divary.domain.encyclopedia.embedded.Appearance;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Arrays;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

import java.util.List;

@Getter
@Builder
@Schema(description = "๋„๊ฐ ์ƒ๋ฌผ ์™ธ๋ชจ ์‘๋‹ต DTO")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package com.divary.domain.encyclopedia.dto;

import com.divary.domain.encyclopedia.entity.EncyclopediaCard;
import com.divary.domain.image.entity.Image;
import com.divary.domain.image.entity.ImageType;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Optional;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

import java.util.List;

@Getter
@Builder
@Schema(description = "๋„๊ฐ ์นด๋“œ ์ƒ์„ธ ์‘๋‹ต")
Expand Down Expand Up @@ -48,31 +43,4 @@ public class EncyclopediaCardResponse {
@Schema(description = "ํŠน์ด์‚ฌํ•ญ ์ •๋ณด")
private SignificantResponse significant;

public static EncyclopediaCardResponse from(EncyclopediaCard card) {
return EncyclopediaCardResponse.builder()
.id(card.getId())
.name(card.getName())
.type(card.getType().getDescription())
.size(card.getSize())
.appearPeriod(card.getAppearPeriod())
.place(card.getPlace())
.imageUrls(
card.getImages().stream()
.filter(img -> img.getType() == ImageType.SYSTEM_DOGAM)
.map(Image::getS3Key)
.toList()
)
.appearance(Optional.ofNullable(card.getAppearance())
.map(AppearanceResponse::from)
.orElse(null))
.personality(Optional.ofNullable(card.getPersonality())
.map(PersonalityResponse::from)
.orElse(null))
.significant(Optional.ofNullable(card.getSignificant())
.map(SignificantResponse::from)
.orElse(null))
.build();
}


}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.divary.domain.encyclopedia.dto;

import com.divary.domain.encyclopedia.entity.EncyclopediaCard;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Collections;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

Expand All @@ -21,19 +18,7 @@ public class EncyclopediaCardSummaryResponse {
@Schema(description = "์ƒ๋ฌผ ์ข…๋ฅ˜", example = "์–ด๋ฅ˜")
private String type;

@Schema(description = "์ธ๋„ค์ผ ์ด๋ฏธ์ง€ URL ๋ชฉ๋ก", example = "[\"https://s3.example.com/card1-thumbnail.jpg\"]")
private List<String> imageUrls;
@Schema(description = "๋„๊ฐ ์ด๋ชจ์ง€ ํ”„๋กœํ•„ URL", example = "\"https://s3.example.com/card1-thumbnail.jpg\"")
private String dogamProfileUrl;

public static EncyclopediaCardSummaryResponse from(EncyclopediaCard card) {
return EncyclopediaCardSummaryResponse.builder()
.id(card.getId())
.name(card.getName())
.type(card.getType().getDescription())
.imageUrls(
card.getThumbnail() != null
? Collections.singletonList(card.getThumbnail().getS3Key())
: Collections.emptyList()
)
.build();
}
}
Loading