diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000000..7a427fbc28 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,19 @@ + + + + + h2.unified + true + true + $PROJECT_DIR$/src/main/resources/application.yml + org.h2.Driver + jdbc:h2:mem:testdb + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/controller/ChannelController.java b/src/main/java/com/sprint/mission/discodeit/controller/ChannelController.java new file mode 100644 index 0000000000..5ec10ac071 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/controller/ChannelController.java @@ -0,0 +1,50 @@ +package com.sprint.mission.discodeit.controller; + + +import com.sprint.mission.discodeit.dto.channelService.ChannelCreateRequest; +import com.sprint.mission.discodeit.dto.channelService.ChannelDTO; +import com.sprint.mission.discodeit.dto.channelService.ChannelUpdateRequest; +import com.sprint.mission.discodeit.dto.channelService.PrivateChannelCreateRequest; +import com.sprint.mission.discodeit.entity.Channel; +import com.sprint.mission.discodeit.service.basic.ChannelService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.UUID; + +@RestController +@RequestMapping("/channels") +@RequiredArgsConstructor + +public class ChannelController { + private final ChannelService channelService; + + @RequestMapping(value = "/public", method = RequestMethod.POST) + public Channel createPublicChannel(@RequestBody ChannelCreateRequest request) { + return channelService.createPublicChannel(request); + } + + @RequestMapping(value = "/private", method = RequestMethod.POST) + public Channel createPrivateChannel(@RequestBody PrivateChannelCreateRequest request) { + return channelService.createPrivateChannel(request); + } + + @RequestMapping(value = "/update", method = RequestMethod.PUT) + public ChannelDTO updateChannel(@RequestBody ChannelUpdateRequest request) { + return channelService.update(request); + } + + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + public void deleteChannel(@PathVariable UUID id) { + channelService.delete(id); + } + + @RequestMapping(value = "", method = RequestMethod.GET) + public List getUserChannels(@RequestParam UUID userId) { + return channelService.findAllByUserId(userId); + } + + + +} diff --git a/src/main/java/com/sprint/mission/discodeit/controller/MessageController.java b/src/main/java/com/sprint/mission/discodeit/controller/MessageController.java new file mode 100644 index 0000000000..903df3a5ba --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/controller/MessageController.java @@ -0,0 +1,52 @@ +package com.sprint.mission.discodeit.controller; + +import com.sprint.mission.discodeit.dto.MessageService.MessageCreateRequestDTO; +import com.sprint.mission.discodeit.dto.MessageService.MessageResponseDTO; +import com.sprint.mission.discodeit.dto.MessageService.MessageUpdateRequestDTO; +import com.sprint.mission.discodeit.entity.Message; +import com.sprint.mission.discodeit.service.basic.BasicMessageService; +import com.sprint.mission.discodeit.service.basic.MessageService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.UUID; + +@RestController +@RequestMapping("/messages") +@RequiredArgsConstructor +public class MessageController { + + private final MessageService messageService; + // 메시지 생성 API + @RequestMapping(value = "/create", method = RequestMethod.POST) + public Message createMessage(@RequestBody MessageCreateRequestDTO request) { + return messageService.create(request, List.of()); // 현재는 첨부파일 없이 메시지만 생성 + } + + // 특정 메시지 조회 API + @RequestMapping(value = "/{messageId}", method = RequestMethod.GET) + public Message getMessage(@PathVariable UUID messageId) { + return messageService.find(messageId); + } + + // 특정 채널의 모든 메시지 조회 API + @RequestMapping(method = RequestMethod.GET) + public List getMessagesByChannel(@RequestParam UUID channelId) { + return messageService.findAllByChannelId(channelId); + } + + // 메시지 수정 API + @RequestMapping(value = "/{messageId}", method = RequestMethod.PUT) + public Message updateMessage(@PathVariable UUID messageId, @RequestBody MessageUpdateRequestDTO request) { + return messageService.update(messageId, request); + } + + // 메시지 삭제 + @RequestMapping(value = "/{messageId}", method = RequestMethod.DELETE) + public void deleteMessage(@PathVariable UUID messageId) { + messageService.delete(messageId); + } + + +} diff --git a/src/main/java/com/sprint/mission/discodeit/controller/ReadStatusController.java b/src/main/java/com/sprint/mission/discodeit/controller/ReadStatusController.java new file mode 100644 index 0000000000..8cf78812e0 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/controller/ReadStatusController.java @@ -0,0 +1,49 @@ +package com.sprint.mission.discodeit.controller; + +import com.sprint.mission.discodeit.dto.ReadStatusService.ReadStatusCreateRequestDTO; +import com.sprint.mission.discodeit.dto.ReadStatusService.ReadStatusUpdateRequestDTO; +import com.sprint.mission.discodeit.entity.ReadStatus; +import com.sprint.mission.discodeit.service.readStatus.ReadStatusService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.UUID; + +@RestController +@RequestMapping("/read-status") +@RequiredArgsConstructor +public class ReadStatusController { + + private final ReadStatusService readStatusService; + + // ✅ 특정 채널의 메시지 수신 정보 생성 (POST /read-status/create) + @RequestMapping(value = "/create", method = RequestMethod.POST) + public ReadStatus createReadStatus(@RequestBody ReadStatusCreateRequestDTO request) { + return readStatusService.create(request); + } + + // ✅ 특정 메시지 수신 정보 조회 (GET /read-status/{id}) + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + public ReadStatus getReadStatus(@PathVariable UUID id) { + return readStatusService.find(id); + } + + // ✅ 특정 사용자의 모든 메시지 수신 정보 조회 (GET /read-status/user/{userId}) + @RequestMapping(value = "/user/{userId}", method = RequestMethod.GET) + public List getReadStatusByUser(@PathVariable UUID userId) { + return readStatusService.findAllByUserId(userId); + } + + // ✅ 특정 채널의 메시지 수신 정보 수정 (PUT /read-status/update) + @RequestMapping(value = "/update", method = RequestMethod.PUT) + public ReadStatus updateReadStatus(@RequestBody ReadStatusUpdateRequestDTO request) { + return readStatusService.update(request); + } + + // ✅ 특정 메시지 수신 정보 삭제 (DELETE /read-status/{id}) + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + public void deleteReadStatus(@PathVariable UUID id) { + readStatusService.delete(id); + } +} diff --git a/src/main/java/com/sprint/mission/discodeit/controller/UserController.java b/src/main/java/com/sprint/mission/discodeit/controller/UserController.java index 32aacf9fe3..0027e40c97 100644 --- a/src/main/java/com/sprint/mission/discodeit/controller/UserController.java +++ b/src/main/java/com/sprint/mission/discodeit/controller/UserController.java @@ -2,6 +2,7 @@ import com.sprint.mission.discodeit.dto.authService.LoginRequest; import com.sprint.mission.discodeit.dto.authService.LoginResponse; +import com.sprint.mission.discodeit.dto.binaryContentService.BinaryContentCreateRequestDTO; import com.sprint.mission.discodeit.dto.userService.UserCreateRequest; import com.sprint.mission.discodeit.dto.userService.UserDTO; import com.sprint.mission.discodeit.dto.userService.UserProfileImageRequest; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Optional; import java.util.UUID; @RestController @@ -26,16 +28,20 @@ public class UserController { // 사용자 생성 API (POST /users/create) @RequestMapping(value = "/create", method = RequestMethod.POST) - public User createUser(@RequestBody UserCreateRequest userRequest) { - return userService.create(userRequest, null); + public User createUser(@RequestBody UserCreateRequest userRequest, + @RequestBody(required = false) BinaryContentCreateRequestDTO profileImage) { + return userService.create(userRequest, Optional.ofNullable(profileImage)); } + // 사용자 정보 수정 API (PUT /users/update) @RequestMapping(value = "/update", method = RequestMethod.PUT) - public UserDTO updateUser(@RequestBody UserUpdateRequest userRequest) { - return userService.update(userRequest, null); + public User updateUser(@RequestBody UserUpdateRequest userRequest) { + return userService.update(userRequest, Optional.empty()); } + + // 특정 사용자 조회 API (GET /users/{id}) @RequestMapping(value = "/{id}", method = RequestMethod.GET) public UserDTO getUser(@PathVariable UUID id) { @@ -56,11 +62,7 @@ public List getAllUsers() { // 로그인 API (POST /users/login) @RequestMapping(value = "/login", method = RequestMethod.POST) - public LoginResponse login(@RequestBody LoginRequest request) { + public User login(@RequestBody LoginRequest request) { return authService.login(request); } - - - - } diff --git a/src/main/java/com/sprint/mission/discodeit/dto/MessageService/MessageUpdateRequestDTO.java b/src/main/java/com/sprint/mission/discodeit/dto/MessageService/MessageUpdateRequestDTO.java index 5849da4dda..f5605c343d 100644 --- a/src/main/java/com/sprint/mission/discodeit/dto/MessageService/MessageUpdateRequestDTO.java +++ b/src/main/java/com/sprint/mission/discodeit/dto/MessageService/MessageUpdateRequestDTO.java @@ -7,9 +7,6 @@ import java.util.UUID; public record MessageUpdateRequestDTO( - UUID messageId, // 수정할 메시지 ID - String newContent, // 수정할 메시지 내용 - List fileIds // 새롭게 등록할 첨부파일 ID 리스트 (선택적) + String newContent ) { - } diff --git a/src/main/java/com/sprint/mission/discodeit/dto/authService/LoginRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/authService/LoginRequest.java index 386c5c01fe..1dbc48fc7e 100644 --- a/src/main/java/com/sprint/mission/discodeit/dto/authService/LoginRequest.java +++ b/src/main/java/com/sprint/mission/discodeit/dto/authService/LoginRequest.java @@ -1,6 +1,6 @@ package com.sprint.mission.discodeit.dto.authService; public record LoginRequest( - String email, + String username, String password ) {} diff --git a/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentCreateRequestDTO.java b/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentCreateRequestDTO.java index 8047fb04aa..c5bb1551d4 100644 --- a/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentCreateRequestDTO.java +++ b/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentCreateRequestDTO.java @@ -5,19 +5,8 @@ import java.util.UUID; public record BinaryContentCreateRequestDTO( - UUID userId, - UUID messageId, - String mimeType, String fileName, - byte[] data + String contentType, + byte[] bytes ) { - public BinaryContent from() { - return new BinaryContent( - userId, - messageId, - mimeType, - fileName, - data - ); - } } diff --git a/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentDTO.java b/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentDTO.java index dd33ecea35..0e48977a74 100644 --- a/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentDTO.java +++ b/src/main/java/com/sprint/mission/discodeit/dto/binaryContentService/BinaryContentDTO.java @@ -1,5 +1,7 @@ package com.sprint.mission.discodeit.dto.binaryContentService; +import com.sprint.mission.discodeit.entity.BinaryContent; + import java.util.UUID; public record BinaryContentDTO( @@ -7,4 +9,11 @@ public record BinaryContentDTO( String fileName, // 파일 이름 String mimeType // 파일 타입 (예: image/png) ) { + public static BinaryContentDTO from(BinaryContent binaryContent) { + return new BinaryContentDTO( + binaryContent.getId(), + binaryContent.getFileName(), + binaryContent.getContentType() + ); + } } diff --git a/src/main/java/com/sprint/mission/discodeit/dto/channelService/PrivateChannelCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/channelService/PrivateChannelCreateRequest.java index 0721289560..12b83aef45 100644 --- a/src/main/java/com/sprint/mission/discodeit/dto/channelService/PrivateChannelCreateRequest.java +++ b/src/main/java/com/sprint/mission/discodeit/dto/channelService/PrivateChannelCreateRequest.java @@ -4,7 +4,9 @@ import java.util.UUID; public record PrivateChannelCreateRequest( - String password, // PRIVATE 채널은 비밀번호가 필요함 - List userIds // 채널에 참여할 유저 ID 목록 -) { -} + String name, // 채널 이름 추가 + String description, // 채널 설명 추가 + String password, // PRIVATE 채널은 비밀번호가 필요함 + List userIds // 채널에 참여할 유저 ID 목록 +) {} + diff --git a/src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java b/src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java index 1e89ceb8b7..3af46c7d17 100644 --- a/src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java +++ b/src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java @@ -1,38 +1,29 @@ package com.sprint.mission.discodeit.entity; import lombok.Getter; -import lombok.Setter; import java.io.Serializable; import java.time.Instant; import java.util.UUID; @Getter -@Setter public class BinaryContent implements Serializable { private static final long serialVersionUID = 1L; - - private final UUID id; - private final Instant createdAt; - - private UUID userId; - @Setter - private UUID messageId; + private UUID id; + private Instant createdAt; + // private String fileName; - private String mimeType; - private byte[] data; + private Long size; + private String contentType; + private byte[] bytes; - public BinaryContent(UUID userId, UUID messageId, String mimeType, String fileName, byte[] content) { + public BinaryContent(String fileName, Long size, String contentType, byte[] bytes) { this.id = UUID.randomUUID(); this.createdAt = Instant.now(); - - this.userId = userId; - this.messageId = messageId; - + // this.fileName = fileName; - this.mimeType = mimeType; - this.data = content.clone(); + this.size = size; + this.contentType = contentType; + this.bytes = bytes; } - - } diff --git a/src/main/java/com/sprint/mission/discodeit/entity/Message.java b/src/main/java/com/sprint/mission/discodeit/entity/Message.java index a39e984630..870f90b5f9 100644 --- a/src/main/java/com/sprint/mission/discodeit/entity/Message.java +++ b/src/main/java/com/sprint/mission/discodeit/entity/Message.java @@ -4,6 +4,7 @@ import java.io.Serializable; import java.time.Instant; +import java.util.List; import java.util.UUID; @Getter @@ -18,14 +19,16 @@ public class Message implements Serializable { // private UUID channelId; private UUID authorId; + private List attachmentIds; - public Message(String content, UUID channelId, UUID authorId) { + public Message(String content, UUID channelId, UUID authorId, List attachmentIds) { this.id = UUID.randomUUID(); this.createdAt = Instant.now(); // this.content = content; this.channelId = channelId; this.authorId = authorId; + this.attachmentIds = attachmentIds; } public void update(String newContent) { diff --git a/src/main/java/com/sprint/mission/discodeit/entity/User.java b/src/main/java/com/sprint/mission/discodeit/entity/User.java index 319f5ce788..089ac73025 100644 --- a/src/main/java/com/sprint/mission/discodeit/entity/User.java +++ b/src/main/java/com/sprint/mission/discodeit/entity/User.java @@ -17,17 +17,19 @@ public class User implements Serializable { private String username; private String email; private String password; + private UUID profileId; // BinaryContent - public User(String username, String email, String password) { + public User(String username, String email, String password, UUID profileId) { this.id = UUID.randomUUID(); this.createdAt = Instant.now(); // this.username = username; this.email = email; this.password = password; + this.profileId = profileId; } - public void update(String newUsername, String newEmail, String newPassword) { + public void update(String newUsername, String newEmail, String newPassword, UUID newProfileId) { boolean anyValueUpdated = false; if (newUsername != null && !newUsername.equals(this.username)) { this.username = newUsername; @@ -41,6 +43,10 @@ public void update(String newUsername, String newEmail, String newPassword) { this.password = newPassword; anyValueUpdated = true; } + if (newProfileId != null && !newProfileId.equals(this.profileId)) { + this.profileId = newProfileId; + anyValueUpdated = true; + } if (anyValueUpdated) { this.updatedAt = Instant.now(); diff --git a/src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java index 09bcf9f2ee..01d485c248 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java @@ -11,15 +11,9 @@ public interface BinaryContentRepository { Optional findById(UUID id); - List findAllByUserId(UUID userId); - - List findAllByMessageId(UUID messageId); - List findAllByIdIn(List id); void deleteById(UUID id); // 개별 파일 삭제 - void deleteByMessageId(UUID messageId); // 특정 메시지에 속한 모든 파일 삭제 - boolean existsById(UUID id); } diff --git a/src/main/java/com/sprint/mission/discodeit/repository/file/FileBinaryContentRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/file/FileBinaryContentRepository.java index 00c8bdaf73..2eb4fde8be 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/file/FileBinaryContentRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/file/FileBinaryContentRepository.java @@ -9,6 +9,7 @@ import java.nio.file.*; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; @Repository public class FileBinaryContentRepository implements BinaryContentRepository { @@ -31,48 +32,56 @@ private Path resolvePath(UUID id) { } @Override - public BinaryContent save(BinaryContent content) { - Path path = resolvePath(content.getId()); - try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(path))) { - oos.writeObject(content); + public BinaryContent save(BinaryContent binaryContent) { + Path path = resolvePath(binaryContent.getId()); + try ( + FileOutputStream fos = new FileOutputStream(path.toFile()); + ObjectOutputStream oos = new ObjectOutputStream(fos) + ) { + oos.writeObject(binaryContent); } catch (IOException e) { throw new RuntimeException(e); } - return content; + return binaryContent; } @Override public Optional findById(UUID id) { + BinaryContent binaryContentNullable = null; Path path = resolvePath(id); if (Files.exists(path)) { - try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(path))) { - return Optional.of((BinaryContent) ois.readObject()); + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + binaryContentNullable = (BinaryContent) ois.readObject(); } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); } } - return Optional.empty(); - } - - @Override - public List findAllByUserId(UUID userId) { - return findAll().stream() - .filter(content -> content.getUserId() != null && content.getUserId().equals(userId)) - .collect(Collectors.toList()); - } - - @Override - public List findAllByMessageId(UUID messageId) { - return findAll().stream() - .filter(content -> content.getMessageId() != null && content.getMessageId().equals(messageId)) - .collect(Collectors.toList()); + return Optional.ofNullable(binaryContentNullable); } @Override public List findAllByIdIn(List ids) { - return findAll().stream() - .filter(content -> ids.contains(content.getId())) - .collect(Collectors.toList()); + try (Stream paths = Files.list(DIRECTORY)) { + return paths + .filter(path -> path.toString().endsWith(EXTENSION)) + .map(path -> { + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return (BinaryContent) ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + }) + .filter(content -> ids.contains(content.getId())) + .toList(); + } catch (IOException e) { + throw new RuntimeException(e); + } } @Override @@ -85,33 +94,10 @@ public void deleteById(UUID id) { } } - @Override - public void deleteByMessageId(UUID messageId) { - findAllByMessageId(messageId).forEach(content -> deleteById(content.getId())); - } @Override public boolean existsById(UUID id) { - return Files.exists(resolvePath(id)); - } - - private List findAll() { - try { - if (Files.notExists(DIRECTORY)) { - return Collections.emptyList(); - } - return Files.list(DIRECTORY) - .filter(path -> path.toString().endsWith(EXTENSION)) - .map(path -> { - try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(path))) { - return (BinaryContent) ois.readObject(); - } catch (IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - }) - .collect(Collectors.toList()); - } catch (IOException e) { - throw new RuntimeException(e); - } + Path path = resolvePath(id); + return Files.exists(path); } } diff --git a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFBinaryContentRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFBinaryContentRepository.java index 1b5bb661ad..be127a609c 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFBinaryContentRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFBinaryContentRepository.java @@ -16,50 +16,30 @@ public JCFBinaryContentRepository() { } @Override - public BinaryContent save(BinaryContent content) { - data.put(content.getId(), content); - return content; + public BinaryContent save(BinaryContent binaryContent) { + this.data.put(binaryContent.getId(), binaryContent); + return binaryContent; } @Override public Optional findById(UUID id) { - return Optional.ofNullable(data.get(id)); - } - - @Override - public List findAllByUserId(UUID userId) { - return data.values().stream() - .filter(content -> content.getUserId() != null && content.getUserId().equals(userId)) - .toList(); - } - - @Override - public List findAllByMessageId(UUID messageId) { - return data.values().stream() - .filter(content -> content.getMessageId() != null && content.getMessageId().equals(messageId)) - .toList(); + return Optional.ofNullable(this.data.get(id)); } @Override public List findAllByIdIn(List ids) { - return data.values().stream() + return this.data.values().stream() .filter(content -> ids.contains(content.getId())) .toList(); } @Override - public void deleteById(UUID id) { - data.remove(id); - } - - @Override - public void deleteByMessageId(UUID messageId) { - data.entrySet().removeIf(entry -> - entry.getValue().getMessageId() != null && entry.getValue().getMessageId().equals(messageId)); + public boolean existsById(UUID id) { + return this.data.containsKey(id); } @Override - public boolean existsById(UUID id) { - return data.containsKey(id); + public void deleteById(UUID id) { + this.data.remove(id); } } diff --git a/src/main/java/com/sprint/mission/discodeit/service/auth/AuthService.java b/src/main/java/com/sprint/mission/discodeit/service/auth/AuthService.java index 22a5df3eea..18a907b472 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/auth/AuthService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/auth/AuthService.java @@ -3,7 +3,7 @@ import com.sprint.mission.discodeit.dto.authService.LoginRequest; import com.sprint.mission.discodeit.dto.authService.LoginResponse; import com.sprint.mission.discodeit.dto.userService.UserDTO; +import com.sprint.mission.discodeit.entity.User; public interface AuthService { - LoginResponse login(LoginRequest loginRequest); -} + User login(LoginRequest loginRequest);} diff --git a/src/main/java/com/sprint/mission/discodeit/service/auth/AuthServiceImpl.java b/src/main/java/com/sprint/mission/discodeit/service/auth/AuthServiceImpl.java index 35f99d76a4..8024ea0c44 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/auth/AuthServiceImpl.java +++ b/src/main/java/com/sprint/mission/discodeit/service/auth/AuthServiceImpl.java @@ -18,21 +18,18 @@ public class AuthServiceImpl implements AuthService { private final UserRepository userRepository; @Override - public LoginResponse login(LoginRequest loginRequest) { - // 이메일로 사용자 조회 - User user = userRepository.findByEmail(loginRequest.email()) - .orElseThrow(() -> new NoSuchElementException("Invalid email or password")); - - // 비밀번호 검증 - if (!user.getPassword().equals(loginRequest.password())) { - throw new IllegalArgumentException("Invalid email or password"); - } + public User login(LoginRequest loginRequest) { + String username = loginRequest.username(); + String password = loginRequest.password(); + + User user = userRepository.findByUsername(username) + .orElseThrow(() -> new NoSuchElementException("User with username " + username + " not found")); - // 임시 토큰 생성 - String token = UUID.randomUUID().toString(); + if (!user.getPassword().equals(password)) { + throw new IllegalArgumentException("Wrong password"); + } - // 로그인 응답 반환 - return new LoginResponse(user.getId(), user.getUsername(), user.getEmail(), token); + return user; } } diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicChannelService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicChannelService.java index a7501d6681..642cec79fa 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicChannelService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicChannelService.java @@ -38,21 +38,30 @@ public Channel createPublicChannel(ChannelCreateRequest request) { @Override public Channel createPrivateChannel(PrivateChannelCreateRequest request) { if (request.password() == null || request.password().isBlank()) { - throw new IllegalArgumentException("Password is required"); + throw new IllegalArgumentException("Password is required for private channels."); } - Channel channel = new Channel(ChannelType.PRIVATE, "Private Channel", "Private description", request.password()); + // 비공개 채널 생성 + Channel channel = new Channel(ChannelType.PRIVATE, request.name(), request.description(), request.password()); - for (UUID userId : request.userIds()) { + // 채널을 먼저 저장 + channelRepository.save(channel); + + // 비공개 채널 참여자 등록 + List participantIds = (request.userIds() != null) ? request.userIds() : List.of(); + + for (UUID userId : participantIds) { if (!userRepository.existsById(userId)) { throw new IllegalArgumentException("User with id " + userId + " not found"); } - ReadStatus readStatus = new ReadStatus(userId, channel.getId(), null, null); // ✅ 수정됨 + ReadStatus readStatus = new ReadStatus(userId, channel.getId(), null, null); readStatusRepository.save(readStatus); } + return channel; } + @Override public ChannelDTO find(UUID channelId) { //채널찾기 @@ -89,11 +98,6 @@ public List findAllByUserId(UUID userId) { .collect(Collectors.toList()); } - @Override - public Instant findLastMessageAtByChannelId(UUID channelId) { - return messageRepository.findLastMessageAtByChannelId(channelId).orElse(null); - } - @Override public ChannelDTO update(ChannelUpdateRequest request) { Channel channel = channelRepository.findById(request.channelId()) @@ -133,5 +137,11 @@ public void delete(UUID channelId) { readStatusRepository.deleteByChannelId(channelId); channelRepository.deleteById(channelId); + + } + + @Override + public Instant findLastMessageAtByChannelId(UUID channelId) { + return messageRepository.findLastMessageAtByChannelId(channelId).orElse(null); } } diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicMessageService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicMessageService.java index 17eec2d26e..ccd40fc912 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicMessageService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicMessageService.java @@ -3,6 +3,7 @@ import com.sprint.mission.discodeit.dto.MessageService.MessageCreateRequestDTO; import com.sprint.mission.discodeit.dto.MessageService.MessageResponseDTO; import com.sprint.mission.discodeit.dto.MessageService.MessageUpdateRequestDTO; +import com.sprint.mission.discodeit.dto.binaryContentService.BinaryContentCreateRequestDTO; import com.sprint.mission.discodeit.dto.binaryContentService.BinaryContentDTO; import com.sprint.mission.discodeit.entity.BinaryContent; import com.sprint.mission.discodeit.entity.Message; @@ -26,28 +27,37 @@ public class BasicMessageService implements MessageService { private final ReadStatusRepository readStatusRepository; @Override - public Message create(MessageCreateRequestDTO request) { - if(!channelRepository.existsById(request.channelId())) { - throw new NoSuchElementException("Channel with id " + request.channelId() + " not found"); - } - if(!userRepository.existsById(request.authorId())) { - throw new NoSuchElementException("User with id " + request.authorId() + " not found"); - } + public Message create(MessageCreateRequestDTO messageCreateRequest, List binaryContentCreateRequests) { + UUID channelId = messageCreateRequest.channelId(); + UUID authorId = messageCreateRequest.authorId(); - Message message = new Message(request.content(), request.channelId(), request.authorId()); - messageRepository.save(message); - //첨부파일 저장 - if (request.fileIds() != null && !request.fileIds().isEmpty()) { - for (UUID fileId : request.fileIds()) { - BinaryContent binaryContent = binaryContentRepository.findById(fileId) - .orElseThrow(() -> new NoSuchElementException("file with id" + fileId + "not found")); + if (!channelRepository.existsById(channelId)) { + throw new NoSuchElementException("Channel with id " + channelId + " does not exist"); + } + if (!userRepository.existsById(authorId)) { + throw new NoSuchElementException("Author with id " + authorId + " does not exist"); + } - binaryContent.setMessageId(message.getId()); - binaryContentRepository.save(binaryContent); - } + List attachmentIds = binaryContentCreateRequests.stream() + .map(attachmentRequest -> { + String fileName = attachmentRequest.fileName(); + String contentType = attachmentRequest.contentType(); + byte[] bytes = attachmentRequest.bytes(); - } - return message; + BinaryContent binaryContent = new BinaryContent(fileName, (long) bytes.length, contentType, bytes); + BinaryContent createdBinaryContent = binaryContentRepository.save(binaryContent); + return createdBinaryContent.getId(); + }) + .toList(); + + String content = messageCreateRequest.content(); + Message message = new Message( + content, + channelId, + authorId, + attachmentIds + ); + return messageRepository.save(message); } @Override @@ -57,67 +67,29 @@ public Message find(UUID messageId) { } @Override - public List findAllByChannelId(UUID channelId) { - if (!channelRepository.existsById(channelId)) { - throw new NoSuchElementException("Channel with id " + channelId + " not found"); - } - - List messages = messageRepository.findAllByChannelId(channelId); - - return messages.stream() - .map(message -> { - // ✅ 직접 첨부파일 리스트 생성 - List attachments = binaryContentRepository.findAllByMessageId(message.getId()).stream() - .map(file -> new BinaryContentDTO(file.getId(), file.getFileName(), file.getMimeType())) - .toList(); - - return MessageResponseDTO.from(message, attachments); - }) + public List findAllByChannelId(UUID channelId) { + return messageRepository.findAllByChannelId(channelId).stream() .toList(); } - @Override - public MessageResponseDTO update(MessageUpdateRequestDTO request) { - Message message = messageRepository.findById(request.messageId()) - .orElseThrow(() -> new NoSuchElementException("Message with id " + request.messageId() + " not found")); - - if (request.newContent() != null && !request.newContent().isBlank()) { - message.update(request.newContent()); - } - - if (request.fileIds() != null) { - // 기존 첨부파일 삭제 - binaryContentRepository.deleteByMessageId(request.messageId()); - - // 새로운 첨부파일 등록 - for (UUID fileId : request.fileIds()) { - BinaryContent file = binaryContentRepository.findById(fileId) - .orElseThrow(() -> new NoSuchElementException("File with id " + fileId + " not found")); - file.setMessageId(message.getId()); - binaryContentRepository.save(file); - } - } - - messageRepository.save(message); - - // 여기서 직접 첨부파일 리스트 생성 - List attachments = binaryContentRepository.findAllByMessageId(message.getId()).stream() - .map(file -> new BinaryContentDTO(file.getId(), file.getFileName(), file.getMimeType())) - .toList(); - - return MessageResponseDTO.from(message, attachments); + public Message update(UUID messageId, MessageUpdateRequestDTO request) { + String newContent = request.newContent(); + Message message = messageRepository.findById(messageId) + .orElseThrow(() -> new NoSuchElementException("Message with id " + messageId + " not found")); + message.update(newContent); + return messageRepository.save(message); } @Override public void delete(UUID messageId) { - if (!messageRepository.existsById(messageId)) { - throw new NoSuchElementException("Message with id " + messageId + " not found"); - } + Message message = messageRepository.findById(messageId) + .orElseThrow(() -> new NoSuchElementException("Message with id " + messageId + " not found")); + + message.getAttachmentIds() + .forEach(binaryContentRepository::deleteById); - binaryContentRepository.deleteByMessageId(messageId); // 첨부파일 삭제 - readStatusRepository.deleteByMessageId(messageId); // ReadStatus 삭제 messageRepository.deleteById(messageId); } } diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserService.java index 8083677723..f668714dee 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserService.java @@ -1,5 +1,6 @@ package com.sprint.mission.discodeit.service.basic; +import com.sprint.mission.discodeit.dto.binaryContentService.BinaryContentCreateRequestDTO; import com.sprint.mission.discodeit.dto.userService.UserCreateRequest; import com.sprint.mission.discodeit.dto.userService.UserDTO; import com.sprint.mission.discodeit.dto.userService.UserProfileImageRequest; @@ -18,6 +19,7 @@ import java.time.Instant; import java.util.List; import java.util.NoSuchElementException; +import java.util.Optional; import java.util.UUID; @Service @@ -30,25 +32,36 @@ public class BasicUserService implements UserService { @Override - public User create(UserCreateRequest userRequest, UserProfileImageRequest profileImage) { - if (userRepository.existsByUsername(userRequest.username())) { - throw new IllegalArgumentException("Username already exists: " + userRequest.username()); + public User create(UserCreateRequest userCreateRequest, Optional optionalProfileCreateRequest) { + String username = userCreateRequest.username(); + String email = userCreateRequest.email(); + + if (userRepository.existsByEmail(email)) { + throw new IllegalArgumentException("User with email " + email + " already exists"); } - if (userRepository.existsByEmail(userRequest.email())) { - throw new IllegalArgumentException("Email already exists: " + userRequest.email()); + if (userRepository.existsByUsername(username)) { + throw new IllegalArgumentException("User with username " + username + " already exists"); } - User user = new User(userRequest.username(), userRequest.email(), userRequest.password()); - userRepository.save(user); - UserStatus userStatus = new UserStatus(user.getId(), Instant.now()); - userStatusRepository.save(userStatus); + UUID nullableProfileId = optionalProfileCreateRequest + .map(profileRequest -> { + String fileName = profileRequest.fileName(); + String contentType = profileRequest.contentType(); + byte[] bytes = profileRequest.bytes(); + BinaryContent binaryContent = new BinaryContent(fileName, (long)bytes.length, contentType, bytes); + return binaryContentRepository.save(binaryContent).getId(); + }) + .orElse(null); + String password = userCreateRequest.password(); - if(profileImage != null && profileImage.data() != null) { - BinaryContent profile = new BinaryContent(user.getId(),null, profileImage.contentType(), profileImage.fileName(), profileImage.data()); - binaryContentRepository.save(profile); - } - return user; + User user = new User(username, email, password, nullableProfileId); + User createdUser = userRepository.save(user); + + Instant now = Instant.now(); + UserStatus userStatus = new UserStatus(createdUser.getId(), now); + userStatusRepository.save(userStatus); + return createdUser; } @Override @@ -77,29 +90,37 @@ public List findAll() { } @Override - public UserDTO update(UserUpdateRequest userRequest, UserProfileImageRequest profileImage) { - User user = userRepository.findById(userRequest.userId()) + public User update(UserUpdateRequest userRequest, Optional profileImage) { + User user = userRepository.findById(userRequest.userId()) // ✅ userId 제거 .orElseThrow(() -> new NoSuchElementException("User with id " + userRequest.userId() + " not found")); - // 사용자 정보 업데이트 - user.update(userRequest.newUsername(), userRequest.newEmail(), userRequest.newPassword()); + String newUsername = userRequest.newUsername(); + String newEmail = userRequest.newEmail(); - if (profileImage != null && profileImage.data() != null) { - BinaryContent profile = new BinaryContent( - user.getId(), - null, - profileImage.contentType(), - profileImage.fileName(), - profileImage.data() - ); - binaryContentRepository.save(profile); + if (userRepository.existsByEmail(newEmail)) { + throw new IllegalArgumentException("User with email " + newEmail + " already exists"); + } + if (userRepository.existsByUsername(newUsername)) { + throw new IllegalArgumentException("User with username " + newUsername + " already exists"); } - // 반환값 추가 (UserDTO로 변환하여 반환) - return UserDTO.from(user, userStatusRepository.findByUserId(user.getId()).orElse(null)); + // 프로필 이미지 처리 (Optional 사용) + UUID profileId = profileImage.map(image -> { + BinaryContent binaryContent = new BinaryContent( + image.fileName(), + (long) image.bytes().length, + image.contentType(), + image.bytes() + ); + return binaryContentRepository.save(binaryContent).getId(); + }).orElse(null); + + user.update(newUsername, newEmail, userRequest.newPassword(), profileId); + return userRepository.save(user); } + @Override public void delete(UUID userId) { if (!userRepository.existsById(userId)) { diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/MessageService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/MessageService.java index 64a872d508..ca9ab16f7f 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/basic/MessageService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/MessageService.java @@ -3,15 +3,16 @@ import com.sprint.mission.discodeit.dto.MessageService.MessageCreateRequestDTO; import com.sprint.mission.discodeit.dto.MessageService.MessageResponseDTO; import com.sprint.mission.discodeit.dto.MessageService.MessageUpdateRequestDTO; +import com.sprint.mission.discodeit.dto.binaryContentService.BinaryContentCreateRequestDTO; import com.sprint.mission.discodeit.entity.Message; import java.util.List; import java.util.UUID; public interface MessageService { - Message create(MessageCreateRequestDTO requestDTO); + Message create(MessageCreateRequestDTO requestDTO, List binaryContentCreateRequests); Message find(UUID messageId); - List findAllByChannelId(UUID channelId); - MessageResponseDTO update(MessageUpdateRequestDTO request); + List findAllByChannelId(UUID channelId); + Message update(UUID messageId, MessageUpdateRequestDTO request); void delete(UUID messageId); } diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/UserService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/UserService.java index 63bb3c77b4..1452dfd0cd 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/basic/UserService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/UserService.java @@ -1,5 +1,6 @@ package com.sprint.mission.discodeit.service.basic; +import com.sprint.mission.discodeit.dto.binaryContentService.BinaryContentCreateRequestDTO; import com.sprint.mission.discodeit.dto.userService.UserCreateRequest; import com.sprint.mission.discodeit.dto.userService.UserDTO; import com.sprint.mission.discodeit.dto.userService.UserProfileImageRequest; @@ -7,12 +8,12 @@ import com.sprint.mission.discodeit.entity.User; import java.util.List; +import java.util.Optional; import java.util.UUID; public interface UserService { - User create(UserCreateRequest userCreateRequest, UserProfileImageRequest profileImage); - UserDTO find(UUID userId); + User create(UserCreateRequest userCreateRequest, Optional profileCreateRequest); UserDTO find(UUID userId); List findAll(); - UserDTO update(UserUpdateRequest userUpdateRequest, UserProfileImageRequest profileImage); + User update(UserUpdateRequest userUpdateRequest, Optional optionalProfileCreateRequest); void delete(UUID userId); } diff --git a/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentService.java b/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentService.java index deed058e48..3431277183 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentService.java @@ -8,7 +8,7 @@ public interface BinaryContentService { BinaryContent create(BinaryContentCreateRequestDTO request); - BinaryContent find(UUID id); - List findAllByIdIn(List id); - void delete(UUID id); + BinaryContent find(UUID binaryContentId); + List findAllByIdIn(List binaryContentIds); + void delete(UUID binaryContentId); } diff --git a/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentServiceImpl.java b/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentServiceImpl.java index 9453841d3a..8c44d7e712 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentServiceImpl.java +++ b/src/main/java/com/sprint/mission/discodeit/service/binaryContent/BinaryContentServiceImpl.java @@ -19,29 +19,36 @@ public class BinaryContentServiceImpl implements BinaryContentService { @Override public BinaryContent create(BinaryContentCreateRequestDTO request) { - BinaryContent binaryContent = request.from(); - + String fileName = request.fileName(); + byte[] bytes = request.bytes(); + String contentType = request.contentType(); + BinaryContent binaryContent = new BinaryContent( + fileName, + (long) bytes.length, + contentType, + bytes + ); return binaryContentRepository.save(binaryContent); } @Override - public BinaryContent find(UUID id) { - return binaryContentRepository.findById(id). - orElseThrow(() -> new NoSuchElementException("BinaryContent not found")); + public BinaryContent find(UUID binaryContentId) { + return binaryContentRepository.findById(binaryContentId) + .orElseThrow(() -> new NoSuchElementException("BinaryContent with id " + binaryContentId + " not found")); } @Override - public List findAllByIdIn(List id) { - return binaryContentRepository.findAllByIdIn(id); + public List findAllByIdIn(List binaryContentIds) { + return binaryContentRepository.findAllByIdIn(binaryContentIds).stream() + .toList(); } @Override - public void delete(UUID id) { - if(!binaryContentRepository.existsById(id)) { - throw new NoSuchElementException("BinaryContent not found"); + public void delete(UUID binaryContentId) { + if (!binaryContentRepository.existsById(binaryContentId)) { + throw new NoSuchElementException("BinaryContent with id " + binaryContentId + " not found"); } - - binaryContentRepository.deleteById(id); + binaryContentRepository.deleteById(binaryContentId); }