diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..8af972cd --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/.gitignore b/.gitignore index 8ec73278..c2065bc2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,11 @@ +HELP.md .gradle build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ -### IntelliJ IDEA ### -.idea -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### Eclipse ### +### STS ### .apt_generated .classpath .factorypath @@ -29,6 +17,15 @@ bin/ !**/src/main/**/bin/ !**/src/test/**/bin/ +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + ### NetBeans ### /nbproject/private/ /nbbuild/ @@ -38,6 +35,3 @@ bin/ ### VS Code ### .vscode/ - -### Mac OS ### -.DS_Store \ No newline at end of file diff --git a/build.gradle b/build.gradle index 668101a2..1c8b5c58 100644 --- a/build.gradle +++ b/build.gradle @@ -1,19 +1,36 @@ plugins { - id 'java' + id 'java' + id 'org.springframework.boot' version '3.4.4' + id 'io.spring.dependency-management' version '1.1.7' } group = 'com.sprint.mission' -version = '1.0-SNAPSHOT' +version = '0.0.1-SNAPSHOT' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} repositories { - mavenCentral() + mavenCentral() } dependencies { - testImplementation platform('org.junit:junit-bom:5.10.0') - testImplementation 'org.junit.jupiter:junit-jupiter' + implementation 'org.springframework.boot:spring-boot-starter-web' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } -test { - useJUnitPlatform() -} \ No newline at end of file +tasks.named('test') { + useJUnitPlatform() +} diff --git a/data/channels/3126edda-9b93-496b-8ed5-9cb219c303d5.ser b/data/channels/3126edda-9b93-496b-8ed5-9cb219c303d5.ser new file mode 100644 index 00000000..1a031f23 Binary files /dev/null and b/data/channels/3126edda-9b93-496b-8ed5-9cb219c303d5.ser differ diff --git a/data/channels/4f797470-eea3-499b-9fff-a18b33554ce8.ser b/data/channels/4f797470-eea3-499b-9fff-a18b33554ce8.ser new file mode 100644 index 00000000..4747cc81 Binary files /dev/null and b/data/channels/4f797470-eea3-499b-9fff-a18b33554ce8.ser differ diff --git a/data/channels/73d6de13-4bfe-4c8f-9e08-8e58420ca18c.ser b/data/channels/73d6de13-4bfe-4c8f-9e08-8e58420ca18c.ser new file mode 100644 index 00000000..d73cd3f1 Binary files /dev/null and b/data/channels/73d6de13-4bfe-4c8f-9e08-8e58420ca18c.ser differ diff --git a/data/messages/0d5aed07-e2da-40c2-a3c9-52f35e34fbfc.ser b/data/messages/0d5aed07-e2da-40c2-a3c9-52f35e34fbfc.ser new file mode 100644 index 00000000..64648e7b Binary files /dev/null and b/data/messages/0d5aed07-e2da-40c2-a3c9-52f35e34fbfc.ser differ diff --git a/data/messages/60dbe397-bcff-4dfc-9733-0f2bb18afb19.ser b/data/messages/60dbe397-bcff-4dfc-9733-0f2bb18afb19.ser new file mode 100644 index 00000000..697df220 Binary files /dev/null and b/data/messages/60dbe397-bcff-4dfc-9733-0f2bb18afb19.ser differ diff --git a/data/messages/99a84d84-8299-4dd1-aec2-c76bcf009118.ser b/data/messages/99a84d84-8299-4dd1-aec2-c76bcf009118.ser new file mode 100644 index 00000000..a9efaa4d Binary files /dev/null and b/data/messages/99a84d84-8299-4dd1-aec2-c76bcf009118.ser differ diff --git a/data/users/3f11a10f-78f5-4a20-87f4-370c96434f6a.ser b/data/users/3f11a10f-78f5-4a20-87f4-370c96434f6a.ser new file mode 100644 index 00000000..d8f00a82 Binary files /dev/null and b/data/users/3f11a10f-78f5-4a20-87f4-370c96434f6a.ser differ diff --git a/data/users/437981ca-9bbd-4982-bb5b-644023a9e270.ser b/data/users/437981ca-9bbd-4982-bb5b-644023a9e270.ser new file mode 100644 index 00000000..54c7eff6 Binary files /dev/null and b/data/users/437981ca-9bbd-4982-bb5b-644023a9e270.ser differ diff --git a/data/users/eb5ccca0-234a-482b-b15b-ea9bceaea16d.ser b/data/users/eb5ccca0-234a-482b-b15b-ea9bceaea16d.ser new file mode 100644 index 00000000..d94b5ebd Binary files /dev/null and b/data/users/eb5ccca0-234a-482b-b15b-ea9bceaea16d.ser differ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832..9bbc975c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 10dc931b..37f853b1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Tue Apr 08 18:10:09 KST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c7873..faf93008 100644 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +82,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +133,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +200,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +216,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd32..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,10 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +27,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle index 79373e36..2437dfb2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ -rootProject.name = '3-sprint-mission' - +rootProject.name = 'discodeit' diff --git a/src/main/java/com/sprint/mission/discodeit/DiscodeitApplication.java b/src/main/java/com/sprint/mission/discodeit/DiscodeitApplication.java new file mode 100644 index 00000000..12c3c047 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/DiscodeitApplication.java @@ -0,0 +1,57 @@ +package com.sprint.mission.discodeit; + +import com.sprint.mission.discodeit.dto.data.ChannelDto; +import com.sprint.mission.discodeit.dto.data.UserDto; +import com.sprint.mission.discodeit.dto.request.MessageCreateRequest; +import com.sprint.mission.discodeit.dto.request.PublicChannelCreateRequest; +import com.sprint.mission.discodeit.dto.request.UserCreateRequest; +import com.sprint.mission.discodeit.entity.Channel; +import com.sprint.mission.discodeit.entity.Message; +import com.sprint.mission.discodeit.entity.User; +import com.sprint.mission.discodeit.repository.ChannelRepository; +import com.sprint.mission.discodeit.repository.UserRepository; +import com.sprint.mission.discodeit.service.ChannelService; +import com.sprint.mission.discodeit.service.MessageService; +import com.sprint.mission.discodeit.service.UserService; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Optional; + +@SpringBootApplication +public class DiscodeitApplication { + + static User setupUser(UserService userService) { + UserCreateRequest request = new UserCreateRequest("woody", "woody@codeit.com", "woody1234"); + User user = userService.create(request, Optional.empty()); + return user; + } + + static Channel setupChannel(ChannelService channelService) { + PublicChannelCreateRequest request = new PublicChannelCreateRequest("공지", "공지 채널입니다."); + Channel channel = channelService.create(request); + return channel; + } + + static void messageCreateTest(MessageService messageService, Channel channel, User author) { + MessageCreateRequest request = new MessageCreateRequest(channel.getId(), author.getId(), "안녕하세요."); + Message message = messageService.create(request, new ArrayList<>()); + System.out.println("메시지 생성: " + message.getId()); + } + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(DiscodeitApplication.class, args); + + UserService userService = context.getBean(UserService.class); + ChannelService channelService = context.getBean(ChannelService.class); + MessageService messageService = context.getBean(MessageService.class); + + User user = setupUser(userService); + Channel channel = setupChannel(channelService); + + messageCreateTest(messageService, channel, user); + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/JavaApplication.java b/src/main/java/com/sprint/mission/discodeit/JavaApplication.java deleted file mode 100644 index cf589c5f..00000000 --- a/src/main/java/com/sprint/mission/discodeit/JavaApplication.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.sprint.mission.discodeit; - -import com.sprint.mission.discodeit.menu.ChannelMenu; -import com.sprint.mission.discodeit.menu.MessageMenu; -import com.sprint.mission.discodeit.menu.UserMenu; -import com.sprint.mission.discodeit.repository.ChannelRepository; -import com.sprint.mission.discodeit.repository.MessageRepository; -import com.sprint.mission.discodeit.repository.UserRepository; -import com.sprint.mission.discodeit.repository.file.FileChannelRepository; -import com.sprint.mission.discodeit.repository.file.FileMessageRepository; -import com.sprint.mission.discodeit.repository.file.FileUserRepository; -import com.sprint.mission.discodeit.service.ChannelService; -import com.sprint.mission.discodeit.service.MessageService; -import com.sprint.mission.discodeit.service.UserService; -import com.sprint.mission.discodeit.service.basic.BasicChannelService; -import com.sprint.mission.discodeit.service.basic.BasicMessageService; -import com.sprint.mission.discodeit.service.basic.BasicUserService; -import com.sprint.mission.discodeit.service.file.FileChannelService; -import com.sprint.mission.discodeit.service.file.FileMessageService; -import com.sprint.mission.discodeit.service.file.FileUserService; -import com.sprint.mission.discodeit.service.jcf.integration.ChannelIntegration; -import com.sprint.mission.discodeit.service.jcf.JCFChannelService; -import com.sprint.mission.discodeit.service.jcf.JCFMessageService; -import com.sprint.mission.discodeit.service.jcf.JCFUserService; -import com.sprint.mission.discodeit.service.jcf.integration.MessageIntegration; -import com.sprint.mission.discodeit.service.jcf.integration.UserIntegration; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Scanner; - -// 기존 코드 -//public class JavaApplication { -// public static void main(String[] args) { -// Scanner scanner = new Scanner(System.in); -// -//// JCF*Service 구현 -//// UserService userService = new JCFUserService(); -//// MessageService messageService = new JCFMessageService(); -//// ChannelService channelService = new JCFChannelService(); -// -//// File*Service 구현 -// Path userDir = Paths.get(System.getProperty("user.dir"), "data", "users"); -// Path channelDir = Paths.get(System.getProperty("user.dir"), "data", "channels"); -// Path messageDir = Paths.get(System.getProperty("user.dir"), "data", "messages"); -// -// UserService userService = new FileUserService(userDir); -// ChannelService channelService = new FileChannelService(channelDir); -// MessageService messageService = new FileMessageService(messageDir); -// -// UserIntegration userIntegration = new UserIntegration(userService, channelService); -// MessageIntegration messageIntegration = new MessageIntegration(messageService, userService, channelService); -// ChannelIntegration channelIntegration = new ChannelIntegration(channelService, userService, messageService); -// -// while (true) { -// System.out.println("\n===== MAIN MENU ====="); -// System.out.println("1. 사용자 메뉴"); -// System.out.println("2. 채널 메뉴"); -// System.out.println("3. 메시지 메뉴"); -// System.out.println("0. 종료"); -// System.out.print("번호를 입력하세요: "); -// -// String mainChoice = scanner.nextLine(); -// -// try { -// switch (mainChoice) { -// case "1": -// UserMenu.manageUsers(scanner, userService, userIntegration); -// break; -// case "2": -// ChannelMenu.manageChannels(scanner, channelService, channelIntegration); -// break; -// case "3": -// MessageMenu.manageMessages(scanner, messageService, messageIntegration); -// break; -// case "0": -// System.out.println("종료합니다."); -// return; -// default: -// System.out.println("올바른 번호를 선택하세요."); -// } -// } catch (Exception e) { -// System.out.println("[오류] 메뉴 처리 중 문제가 발생했습니다: " + e.getMessage()); -// } -// } -// } -//} - -public class JavaApplication { - public static void main(String[] args) { - UserRepository userRepository = new FileUserRepository(Paths.get("data/users")); - ChannelRepository channelRepository = new FileChannelRepository(Paths.get("data/channels")); - MessageRepository messageRepository = new FileMessageRepository(Paths.get("data/messages")); - - UserService userService = new BasicUserService(userRepository); - ChannelService channelService = new BasicChannelService(channelRepository); - MessageService messageService = new BasicMessageService(messageRepository); - - UserIntegration userIntegration = new UserIntegration(userService, channelService); - ChannelIntegration channelIntegration = new ChannelIntegration(channelService, userService, messageService); - MessageIntegration messageIntegration = new MessageIntegration(messageService, userService, channelService); - - Scanner scanner = new Scanner(System.in); - while (true) { - System.out.println("\n===== MAIN MENU ====="); - System.out.println("1. 사용자 메뉴"); - System.out.println("2. 채널 메뉴"); - System.out.println("3. 메시지 메뉴"); - System.out.println("0. 종료"); - System.out.print("번호를 입력하세요: "); - String input = scanner.nextLine(); - - switch (input) { - case "1" -> UserMenu.manageUsers(scanner, userService, userIntegration); - case "2" -> ChannelMenu.manageChannels(scanner, channelService, channelIntegration); - case "3" -> MessageMenu.manageMessages(scanner, messageService, messageIntegration); - case "0" -> { - System.out.println("종료합니다."); - return; - } - default -> System.out.println("올바른 번호를 입력하세요."); - } - } - } -} - -/* -JCF*Service, File*Service와 Basic*Service의 차이 -Basic은 저장 로직을 분리해서 서비스에 비즈니스 로직만 위치함 -구현체를 생성자로 교체 가능해서 확장성이 좋음 -저장소를 변경하더라도 로직에 영향을 안줌 - */ \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/data/ChannelDto.java b/src/main/java/com/sprint/mission/discodeit/dto/data/ChannelDto.java new file mode 100644 index 00000000..7a874e3c --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/data/ChannelDto.java @@ -0,0 +1,16 @@ +package com.sprint.mission.discodeit.dto.data; + +import com.sprint.mission.discodeit.entity.ChannelType; + +import java.time.Instant; +import java.util.List; +import java.util.UUID; + +public record ChannelDto( + UUID id, + String name, + String description, + ChannelType type, + Instant latestMessageTimestamp, + List memberIds +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/data/UserDto.java b/src/main/java/com/sprint/mission/discodeit/dto/data/UserDto.java new file mode 100644 index 00000000..1f2a918e --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/data/UserDto.java @@ -0,0 +1,14 @@ +package com.sprint.mission.discodeit.dto.data; + +import java.time.Instant; +import java.util.UUID; + +public record UserDto ( + UUID id, + Instant createdAt, + Instant updatedAt, + String username, + String email, + UUID profileId, + Boolean online +) {} diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/BinaryContentCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/BinaryContentCreateRequest.java new file mode 100644 index 00000000..6f2c3464 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/BinaryContentCreateRequest.java @@ -0,0 +1,7 @@ +package com.sprint.mission.discodeit.dto.request; + +public record BinaryContentCreateRequest( + String fileName, + byte[] data, + String contentType +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/LoginRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/LoginRequest.java new file mode 100644 index 00000000..63f2d84c --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/LoginRequest.java @@ -0,0 +1,6 @@ +package com.sprint.mission.discodeit.dto.request; + +public record LoginRequest( + String username, + String password +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/MessageCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/MessageCreateRequest.java new file mode 100644 index 00000000..3bdb606d --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/MessageCreateRequest.java @@ -0,0 +1,9 @@ +package com.sprint.mission.discodeit.dto.request; + +import java.util.UUID; + +public record MessageCreateRequest( + UUID channelId, + UUID authorId, + String content +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/MessageUpdateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/MessageUpdateRequest.java new file mode 100644 index 00000000..d9ad692e --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/MessageUpdateRequest.java @@ -0,0 +1,5 @@ +package com.sprint.mission.discodeit.dto.request; + +public record MessageUpdateRequest( + String content +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/PrivateChannelCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/PrivateChannelCreateRequest.java new file mode 100644 index 00000000..75c83df5 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/PrivateChannelCreateRequest.java @@ -0,0 +1,8 @@ +package com.sprint.mission.discodeit.dto.request; + +import java.util.List; +import java.util.UUID; + +public record PrivateChannelCreateRequest( + List memberIds +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/PublicChannelCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/PublicChannelCreateRequest.java new file mode 100644 index 00000000..0e9a8075 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/PublicChannelCreateRequest.java @@ -0,0 +1,6 @@ +package com.sprint.mission.discodeit.dto.request; + +public record PublicChannelCreateRequest( + String name, + String description +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/PublicChannelUpdateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/PublicChannelUpdateRequest.java new file mode 100644 index 00000000..be000d58 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/PublicChannelUpdateRequest.java @@ -0,0 +1,6 @@ +package com.sprint.mission.discodeit.dto.request; + +public record PublicChannelUpdateRequest( + String name, + String description +) {} diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/ReadStatusCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/ReadStatusCreateRequest.java new file mode 100644 index 00000000..06e35b44 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/ReadStatusCreateRequest.java @@ -0,0 +1,10 @@ +package com.sprint.mission.discodeit.dto.request; + +import java.time.Instant; +import java.util.UUID; + +public record ReadStatusCreateRequest( + UUID channelId, + UUID userId, + Instant lastReadAt +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/ReadStatusUpdateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/ReadStatusUpdateRequest.java new file mode 100644 index 00000000..d9da70f3 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/ReadStatusUpdateRequest.java @@ -0,0 +1,7 @@ +package com.sprint.mission.discodeit.dto.request; + +import java.time.Instant; + +public record ReadStatusUpdateRequest( + Instant newLastReadAt +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/UserCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/UserCreateRequest.java new file mode 100644 index 00000000..b2c65abc --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/UserCreateRequest.java @@ -0,0 +1,7 @@ +package com.sprint.mission.discodeit.dto.request; + +public record UserCreateRequest ( + String username, + String email, + String password +) {} diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/UserStatusCreateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/UserStatusCreateRequest.java new file mode 100644 index 00000000..81a260df --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/UserStatusCreateRequest.java @@ -0,0 +1,9 @@ +package com.sprint.mission.discodeit.dto.request; + +import java.time.Instant; +import java.util.UUID; + +public record UserStatusCreateRequest( + UUID userId, + Instant lastOnlineAt +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/UserStatusUpdateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/UserStatusUpdateRequest.java new file mode 100644 index 00000000..13d1f630 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/UserStatusUpdateRequest.java @@ -0,0 +1,7 @@ +package com.sprint.mission.discodeit.dto.request; + +import java.time.Instant; + +public record UserStatusUpdateRequest( + Instant lastOnlineAt +) {} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/dto/request/UserUpdateRequest.java b/src/main/java/com/sprint/mission/discodeit/dto/request/UserUpdateRequest.java new file mode 100644 index 00000000..4b258e59 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/dto/request/UserUpdateRequest.java @@ -0,0 +1,7 @@ +package com.sprint.mission.discodeit.dto.request; + +public record UserUpdateRequest ( + String username, + String email, + String password +) {} diff --git a/src/main/java/com/sprint/mission/discodeit/entity/BaseEntity.java b/src/main/java/com/sprint/mission/discodeit/entity/BaseEntity.java deleted file mode 100644 index 1eaca384..00000000 --- a/src/main/java/com/sprint/mission/discodeit/entity/BaseEntity.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sprint.mission.discodeit.entity; - -import java.io.Serializable; -import java.util.UUID; - -public abstract class BaseEntity implements Serializable { - private static final long serialVersionUID = 1L; - - private final UUID id; - private final long createdAt; - private long updatedAt; - - public BaseEntity() { - this.id = UUID.randomUUID(); - this.createdAt = System.currentTimeMillis(); - this.updatedAt = createdAt; - } - - public UUID getId() { - return id; - } - - public long getCreatedAt() { - return createdAt; - } - - public long getUpdatedAt() { - return updatedAt; - } - - public void updateTime() { - this.updatedAt = System.currentTimeMillis(); - } - -} diff --git a/src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java b/src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java new file mode 100644 index 00000000..81107aef --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java @@ -0,0 +1,32 @@ +package com.sprint.mission.discodeit.entity; + +import lombok.Getter; + +import java.io.Serial; +import java.io.Serializable; +import java.time.Instant; +import java.util.Arrays; +import java.util.UUID; + +@Getter +public class BinaryContent implements Serializable { + + @Serial + private static final long serialVersionUID = 1887370024504996215L; + + private UUID id; + private Instant createdAt; + private String fileName; + private Long size; + private String contentType; + private byte[] bytes; + + public BinaryContent(String fileName, Long size, String contentType, byte[] bytes) { + this.id = UUID.randomUUID(); + this.createdAt = Instant.now(); + this.fileName = fileName; + this.size = size; + this.contentType = contentType; + this.bytes = bytes; + } +} diff --git a/src/main/java/com/sprint/mission/discodeit/entity/Channel.java b/src/main/java/com/sprint/mission/discodeit/entity/Channel.java index 79c3664e..5d86ad9d 100644 --- a/src/main/java/com/sprint/mission/discodeit/entity/Channel.java +++ b/src/main/java/com/sprint/mission/discodeit/entity/Channel.java @@ -1,51 +1,46 @@ package com.sprint.mission.discodeit.entity; +import lombok.Getter; + +import java.io.Serial; import java.io.Serializable; +import java.time.Instant; import java.util.*; -public class Channel extends BaseEntity implements Serializable { - private static final long serialVersionUID = 1L; - private String channelName; - private final Set userIds = new HashSet<>(); - private final List messageIds = new ArrayList<>(); - - public Channel(String channelName) { - this.channelName = channelName; - } - - public String getChannelName() { - return channelName; - } - - public void updateChannelName(String channelName) { - this.channelName = channelName; - updateTime(); - } - - public Set getUserIds() { - return userIds; - } - - public List getMessageIds() { return messageIds; } - - public void addUser(UUID userId) { - userIds.add(userId); - updateTime(); - } - - public void addMessage(UUID messageId) { - messageIds.add(messageId); - updateTime(); +@Getter +public class Channel implements Serializable { + + @Serial + private static final long serialVersionUID = 3253334103732539416L; + + private UUID id; + private Instant createdAt; + private Instant updatedAt; + private ChannelType type; + private String name; + private String description; + + public Channel(ChannelType type, String name, String description) { + this.id = UUID.randomUUID(); + this.createdAt = Instant.now(); + this.updatedAt = createdAt; + this.type = type; + this.name = name; + this.description = description; } - @Override - public String toString() { - return "Channel{" + - "channelName='" + channelName + '\'' + - ", userIds=" + userIds + - ", messageIds=" + messageIds + - ", createdAt=" + new Date(getCreatedAt()) + - ", updatedAt=" + new Date(getUpdatedAt()) + - '}'; + public void update(String newName, String newDescription) { + boolean updated = false; + if (newName != null && !newName.equals(this.name)) { + this.name = newName; + updated = true; + } + if (newDescription != null && !newDescription.equals(this.description)) { + this.description = newDescription; + updated = true; + } + if (updated) { + this.updatedAt = Instant.now(); + } } } diff --git a/src/main/java/com/sprint/mission/discodeit/entity/ChannelType.java b/src/main/java/com/sprint/mission/discodeit/entity/ChannelType.java new file mode 100644 index 00000000..9a2ff3f0 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/entity/ChannelType.java @@ -0,0 +1,6 @@ +package com.sprint.mission.discodeit.entity; + +public enum ChannelType { + PUBLIC, + PRIVATE, +} 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 8b44fc0c..f94428d4 100644 --- a/src/main/java/com/sprint/mission/discodeit/entity/Message.java +++ b/src/main/java/com/sprint/mission/discodeit/entity/Message.java @@ -1,46 +1,40 @@ package com.sprint.mission.discodeit.entity; -import java.io.Serializable; -import java.util.Date; -import java.util.UUID; - -public class Message extends BaseEntity implements Serializable { - private static final long serialVersionUID = 1L; - private String msgContent; - private final UUID senderId; - private final UUID channelId; +import lombok.Getter; - public Message(String msgContent, UUID senderId, UUID channelId) { - this.msgContent = msgContent; - this.senderId = senderId; +import java.io.Serial; +import java.io.Serializable; +import java.time.Instant; +import java.util.*; + +@Getter +public class Message implements Serializable { + + @Serial + private static final long serialVersionUID = 5140283631663474458L; + + private UUID id; + private Instant createdAt; + private Instant updatedAt; + private String content; + private UUID channelId; + private UUID authorId; + private List attachmentIds; + + public Message(String content, UUID channelId, UUID authorId, List attachmentIds) { + this.id = UUID.randomUUID(); + this.createdAt = Instant.now(); + this.updatedAt = createdAt; + this.content = content; this.channelId = channelId; + this.authorId = authorId; + this.attachmentIds = attachmentIds; } - public void updateMsgContent(String msgContent) { - this.msgContent = msgContent; - updateTime(); - } - - public UUID getSenderId() { return senderId; } - - public UUID getChannelId() { - return channelId; - } - - public boolean isUpdated() { - return getUpdatedAt() != getCreatedAt(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - long displayTime = isUpdated() ? getUpdatedAt() : getCreatedAt(); - sb.append("[").append(new Date(displayTime)).append("] "); - sb.append(msgContent); - if (isUpdated()) { - sb.append(" (수정됨)"); + public void update(String newContent) { + if (newContent != null && !newContent.equals(this.content)) { + this.content = newContent; + this.updatedAt = Instant.now(); } - sb.append(" [").append(senderId).append("] "); - return sb.toString(); } } diff --git a/src/main/java/com/sprint/mission/discodeit/entity/ReadStatus.java b/src/main/java/com/sprint/mission/discodeit/entity/ReadStatus.java new file mode 100644 index 00000000..5d906997 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/entity/ReadStatus.java @@ -0,0 +1,38 @@ +package com.sprint.mission.discodeit.entity; + +import lombok.Getter; + +import java.io.Serial; +import java.io.Serializable; +import java.time.Instant; +import java.util.UUID; + +@Getter +public class ReadStatus implements Serializable { + + @Serial + private static final long serialVersionUID = 4852408247773241680L; + + private UUID id; + private Instant createdAt; + private Instant updatedAt; + private UUID userId; + private UUID channelId; + private Instant lastReadAt; + + public ReadStatus(UUID userId, UUID channelId, Instant lastReadAt) { + this.id = UUID.randomUUID(); + this.createdAt = Instant.now(); + this.updatedAt = createdAt; + this.userId = userId; + this.channelId = channelId; + this.lastReadAt = lastReadAt; + } + + public void update(Instant newLastReadAt) { + if (newLastReadAt != null && !newLastReadAt.equals(this.lastReadAt)) { + this.lastReadAt = newLastReadAt; + this.updatedAt = Instant.now(); + } + } +} 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 f3f96ceb..afb2c1e9 100644 --- a/src/main/java/com/sprint/mission/discodeit/entity/User.java +++ b/src/main/java/com/sprint/mission/discodeit/entity/User.java @@ -1,39 +1,59 @@ package com.sprint.mission.discodeit.entity; +import lombok.Getter; + +import java.io.Serial; import java.io.Serializable; +import java.time.Instant; import java.util.Date; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; -public class User extends BaseEntity implements Serializable { - private static final long serialVersionUID = 1L; - private String userName; - private final Set channelIds = new HashSet<>(); +@Getter +public class User implements Serializable { - public User(String userName) { - this.userName = userName; - } + @Serial + private static final long serialVersionUID = -1421022282607757997L; - public Set getChannelIds() { - return channelIds; - } + private UUID id; + private Instant createdAt; + private Instant updatedAt; + private String username; + private String email; + private String password; + private UUID profileId; - public void updateUserName(String userName) { - this.userName = userName; - updateTime(); + public User(String username, String email, String password, UUID profileId) { + this.id = UUID.randomUUID(); + this.createdAt = Instant.now(); + this.updatedAt = createdAt; + this.username = username; + this.email = email; + this.password = password; + this.profileId = profileId; } - public void addChannel(UUID channelId) { - channelIds.add(channelId); - } + public void update(String newUsername, String newEmail, String newPassword, UUID newProfileId) { + boolean anyValueUpdated = false; + + if (newUsername != null && !newUsername.equals(this.username)) { + this.username = newUsername; + anyValueUpdated = true; + } + if (newEmail != null && !newEmail.equals(this.email)) { + this.email = newEmail; + anyValueUpdated = true; + } + if (newPassword != null && !newPassword.equals(this.password)) { + this.password = newPassword; + anyValueUpdated = true; + } + if (newProfileId != null && !newProfileId.equals(this.profileId)) { + this.profileId = newProfileId; + anyValueUpdated = true; + } - @Override - public String toString() { - return "User{name='" + userName + '\'' + - ", channelIds=" + channelIds + - ", createdAt=" + new Date(getCreatedAt()) + - ", updatedAt=" + new Date(getUpdatedAt()) + - '}'; + if (anyValueUpdated) { + this.updatedAt = Instant.now(); + } } -} +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/entity/UserStatus.java b/src/main/java/com/sprint/mission/discodeit/entity/UserStatus.java new file mode 100644 index 00000000..333dbcce --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/entity/UserStatus.java @@ -0,0 +1,41 @@ +package com.sprint.mission.discodeit.entity; + +import lombok.Getter; + +import java.io.Serial; +import java.io.Serializable; +import java.time.Duration; +import java.time.Instant; +import java.util.UUID; + +@Getter +public class UserStatus implements Serializable { + + @Serial + private static final long serialVersionUID = -8852497287437352577L; + + private UUID id; + private Instant createdAt; + private Instant updatedAt; + private UUID userId; + private Instant lastActiveAt; + + public UserStatus(UUID userId, Instant lastActiveAt) { + this.id = UUID.randomUUID(); + this.createdAt = Instant.now(); + this.updatedAt = createdAt; + this.userId = userId; + this.lastActiveAt = lastActiveAt; + } + + public void update(Instant lastActiveAt) { + if (lastActiveAt != null && !lastActiveAt.equals(this.lastActiveAt)) { + this.lastActiveAt = lastActiveAt; + this.updatedAt = Instant.now(); + } + } + + public Boolean isOnline() { + return lastActiveAt.isAfter(Instant.now().minus(Duration.ofMinutes(5))); + } +} diff --git a/src/main/java/com/sprint/mission/discodeit/menu/ChannelMenu.java b/src/main/java/com/sprint/mission/discodeit/menu/ChannelMenu.java index e05a0d62..91f69cd4 100644 --- a/src/main/java/com/sprint/mission/discodeit/menu/ChannelMenu.java +++ b/src/main/java/com/sprint/mission/discodeit/menu/ChannelMenu.java @@ -1,77 +1,70 @@ package com.sprint.mission.discodeit.menu; -import com.sprint.mission.discodeit.service.jcf.integration.ChannelIntegration; -import com.sprint.mission.discodeit.entity.Channel; -import com.sprint.mission.discodeit.service.ChannelService; - -import java.util.Scanner; -import java.util.UUID; - public class ChannelMenu { - public static void manageChannels(Scanner scanner, ChannelService channelService, ChannelIntegration channelIntegration) { - while (true) { - System.out.println("\n===== CHANNEL MENU ====="); - System.out.println("1. 채널 생성"); - System.out.println("2. 채널 단건 조회"); - System.out.println("3. 채널 다건 조회"); - System.out.println("4. 채널 수정"); - System.out.println("5. 채널 삭제"); - System.out.println("6. 채널에 사용자 추가"); - System.out.println("0. 초기 화면으로"); - System.out.print("번호를 입력하세요: "); - String select = scanner.nextLine(); - - try { - switch (select) { - case "1": - System.out.print("채널 이름 입력: "); - String name = scanner.nextLine(); - Channel ch = new Channel(name); - channelService.createChannel(ch); - System.out.println("생성된 채널 ID: " + ch.getId()); - break; - case "2": - System.out.print("채널 ID 입력: "); - UUID id = UUID.fromString(scanner.nextLine()); - channelService.getChannel(id) - .ifPresentOrElse( - System.out::println, - () -> System.out.println("채널을 찾을 수 없습니다.") - ); - break; - case "3": - channelService.getAllChannels().forEach(System.out::println); - break; - case "4": - System.out.print("수정할 채널 ID 입력: "); - UUID upId = UUID.fromString(scanner.nextLine()); - System.out.print("새 이름 입력: "); - String newName = scanner.nextLine(); - channelService.getChannel(upId).ifPresent(c -> { - c.updateChannelName(newName); - channelService.updateChannel(c); - }); - break; - case "5": - System.out.print("삭제할 채널 ID 입력: "); - UUID delId = UUID.fromString(scanner.nextLine()); - channelIntegration.deleteChannel(delId); - break; - case "6": - System.out.print("채널 ID 입력: "); - UUID chId = UUID.fromString(scanner.nextLine()); - System.out.print("사용자 ID 입력: "); - UUID userId = UUID.fromString(scanner.nextLine()); - channelIntegration.addUserToChannel(chId, userId); - break; - case "0": - return; - default: - System.out.println("올바른 번호를 선택하세요."); - } - } catch (Exception e) { - System.out.println("[오류] 채널 메뉴 처리 중 문제가 발생했습니다: " + e.getMessage()); - } - } - } +// public static void manageChannels(Scanner scanner, ChannelService channelService, ChannelIntegration channelIntegration) { +// while (true) { +// System.out.println("\n===== CHANNEL MENU ====="); +// System.out.println("1. 채널 생성"); +// System.out.println("2. 채널 단건 조회"); +// System.out.println("3. 채널 다건 조회"); +// System.out.println("4. 채널 수정"); +// System.out.println("5. 채널 삭제"); +// System.out.println("6. 채널에 사용자 추가"); +// System.out.println("0. 초기 화면으로"); +// System.out.print("번호를 입력하세요: "); +// String select = scanner.nextLine(); +// +// try { +// switch (select) { +// case "1": +// System.out.print("채널 이름 입력: "); +// String name = scanner.nextLine(); +// Channel ch = new Channel(name); +// channelService.createChannel(ch); +// System.out.println("생성된 채널 ID: " + ch.getId()); +// break; +// case "2": +// System.out.print("채널 ID 입력: "); +// UUID id = UUID.fromString(scanner.nextLine()); +// channelService.getChannel(id) +// .ifPresentOrElse( +// System.out::println, +// () -> System.out.println("채널을 찾을 수 없습니다.") +// ); +// break; +// case "3": +// channelService.getAllChannels().forEach(System.out::println); +// break; +// case "4": +// System.out.print("수정할 채널 ID 입력: "); +// UUID upId = UUID.fromString(scanner.nextLine()); +// System.out.print("새 이름 입력: "); +// String newName = scanner.nextLine(); +// channelService.getChannel(upId).ifPresent(c -> { +// c.updateChannelName(newName); +// channelService.updateChannel(c); +// }); +// break; +// case "5": +// System.out.print("삭제할 채널 ID 입력: "); +// UUID delId = UUID.fromString(scanner.nextLine()); +// channelIntegration.deleteChannel(delId); +// break; +// case "6": +// System.out.print("채널 ID 입력: "); +// UUID chId = UUID.fromString(scanner.nextLine()); +// System.out.print("사용자 ID 입력: "); +// UUID userId = UUID.fromString(scanner.nextLine()); +// channelIntegration.addUserToChannel(chId, userId); +// break; +// case "0": +// return; +// default: +// System.out.println("올바른 번호를 선택하세요."); +// } +// } catch (Exception e) { +// System.out.println("[오류] 채널 메뉴 처리 중 문제가 발생했습니다: " + e.getMessage()); +// } +// } +// } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/menu/MessageMenu.java b/src/main/java/com/sprint/mission/discodeit/menu/MessageMenu.java index 589f2dcc..13e79ec2 100644 --- a/src/main/java/com/sprint/mission/discodeit/menu/MessageMenu.java +++ b/src/main/java/com/sprint/mission/discodeit/menu/MessageMenu.java @@ -1,69 +1,62 @@ package com.sprint.mission.discodeit.menu; -import com.sprint.mission.discodeit.entity.Message; -import com.sprint.mission.discodeit.service.MessageService; -import com.sprint.mission.discodeit.service.jcf.integration.MessageIntegration; - -import java.util.Scanner; -import java.util.UUID; - public class MessageMenu { - public static void manageMessages(Scanner scanner, MessageService messageService, MessageIntegration messageIntegration) { - while (true) { - System.out.println("\n===== MESSAGE MENU ====="); - System.out.println("1. 메시지 생성"); - System.out.println("2. 메시지 단건 조회"); - System.out.println("3. 메시지 다건 조회"); - System.out.println("4. 메시지 수정"); - System.out.println("5. 메시지 삭제"); - System.out.println("0. 초기 화면으로"); - System.out.print("번호를 입력하세요: "); - String select = scanner.nextLine(); - - try { - switch (select) { - case "1": - System.out.print("메시지 내용 입력: "); - String content = scanner.nextLine(); - System.out.print("보낸 사용자 ID: "); - UUID sender = UUID.fromString(scanner.nextLine()); - System.out.print("채널 ID: "); - UUID ch = UUID.fromString(scanner.nextLine()); - Message m = messageIntegration.createMessage(content, sender, ch); - System.out.println("생성된 메시지 ID: " + m.getId()); - break; - case "2": - System.out.print("메시지 ID 입력: "); - UUID id = UUID.fromString(scanner.nextLine()); - messageService.getMessage(id) - .ifPresentOrElse( - System.out::println, - () -> System.out.println("메시지를 찾을 수 없습니다.") - ); - break; - case "3": - messageService.getAllMessages().forEach(System.out::println); - break; - case "4": - System.out.print("수정할 메시지 ID 입력: "); - UUID upId = UUID.fromString(scanner.nextLine()); - System.out.print("새 내용 입력: "); - String newContent = scanner.nextLine(); - messageService.updateMessage(upId, newContent); - break; - case "5": - System.out.print("삭제할 메시지 ID 입력: "); - UUID delId = UUID.fromString(scanner.nextLine()); - messageIntegration.deleteMessage(delId); - break; - case "0": - return; - default: - System.out.println("올바른 번호를 선택하세요."); - } - } catch (Exception e) { - System.out.println("[오류] 메시지 메뉴 처리 중 문제가 발생했습니다: " + e.getMessage()); - } - } - } +// public static void manageMessages(Scanner scanner, MessageService messageService, MessageIntegration messageIntegration) { +// while (true) { +// System.out.println("\n===== MESSAGE MENU ====="); +// System.out.println("1. 메시지 생성"); +// System.out.println("2. 메시지 단건 조회"); +// System.out.println("3. 메시지 다건 조회"); +// System.out.println("4. 메시지 수정"); +// System.out.println("5. 메시지 삭제"); +// System.out.println("0. 초기 화면으로"); +// System.out.print("번호를 입력하세요: "); +// String select = scanner.nextLine(); +// +// try { +// switch (select) { +// case "1": +// System.out.print("메시지 내용 입력: "); +// String content = scanner.nextLine(); +// System.out.print("보낸 사용자 ID: "); +// UUID sender = UUID.fromString(scanner.nextLine()); +// System.out.print("채널 ID: "); +// UUID ch = UUID.fromString(scanner.nextLine()); +// Message m = messageIntegration.createMessage(content, sender, ch); +// System.out.println("생성된 메시지 ID: " + m.getId()); +// break; +// case "2": +// System.out.print("메시지 ID 입력: "); +// UUID id = UUID.fromString(scanner.nextLine()); +// messageService.getMessage(id) +// .ifPresentOrElse( +// System.out::println, +// () -> System.out.println("메시지를 찾을 수 없습니다.") +// ); +// break; +// case "3": +// messageService.getAllMessages().forEach(System.out::println); +// break; +// case "4": +// System.out.print("수정할 메시지 ID 입력: "); +// UUID upId = UUID.fromString(scanner.nextLine()); +// System.out.print("새 내용 입력: "); +// String newContent = scanner.nextLine(); +// messageService.updateMessage(upId, newContent); +// break; +// case "5": +// System.out.print("삭제할 메시지 ID 입력: "); +// UUID delId = UUID.fromString(scanner.nextLine()); +// messageIntegration.deleteMessage(delId); +// break; +// case "0": +// return; +// default: +// System.out.println("올바른 번호를 선택하세요."); +// } +// } catch (Exception e) { +// System.out.println("[오류] 메시지 메뉴 처리 중 문제가 발생했습니다: " + e.getMessage()); +// } +// } +// } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/menu/UserMenu.java b/src/main/java/com/sprint/mission/discodeit/menu/UserMenu.java index 58aa9351..1c4ef99e 100644 --- a/src/main/java/com/sprint/mission/discodeit/menu/UserMenu.java +++ b/src/main/java/com/sprint/mission/discodeit/menu/UserMenu.java @@ -1,69 +1,62 @@ package com.sprint.mission.discodeit.menu; -import com.sprint.mission.discodeit.entity.User; -import com.sprint.mission.discodeit.service.UserService; -import com.sprint.mission.discodeit.service.jcf.integration.UserIntegration; - -import java.util.Scanner; -import java.util.UUID; - public class UserMenu { - public static void manageUsers(Scanner scanner, UserService userService, UserIntegration userIntegration) { - while (true) { - System.out.println("\n===== USER MENU ====="); - System.out.println("1. 사용자 등록"); - System.out.println("2. 사용자 단건 조회"); - System.out.println("3. 사용자 다건 조회"); - System.out.println("4. 사용자 수정"); - System.out.println("5. 사용자 삭제"); - System.out.println("0. 초기 화면으로"); - System.out.print("번호를 입력하세요: "); - String select = scanner.nextLine(); - - try { - switch (select) { - case "1": - System.out.print("사용자 이름 입력: "); - String name = scanner.nextLine(); - User user = new User(name); - userService.createUser(user); - System.out.println("생성된 사용자 ID: " + user.getId()); - break; - case "2": - System.out.print("조회할 사용자 ID 입력: "); - UUID id = UUID.fromString(scanner.nextLine()); - userService.getUser(id) - .ifPresentOrElse( - System.out::println, - () -> System.out.println("사용자를 찾을 수 없습니다.") - ); - break; - case "3": - userService.getAllUsers().forEach(System.out::println); - break; - case "4": - System.out.print("수정할 사용자 ID 입력: "); - UUID updateId = UUID.fromString(scanner.nextLine()); - System.out.print("새 이름 입력: "); - String newName = scanner.nextLine(); - userService.getUser(updateId).ifPresent(u -> { - u.updateUserName(newName); - userService.updateUser(u); - }); - break; - case "5": - System.out.print("삭제할 사용자 ID 입력: "); - UUID delId = UUID.fromString(scanner.nextLine()); - userIntegration.deleteUser(delId); - break; - case "0": - return; - default: - System.out.println("올바른 번호를 선택하세요."); - } - } catch (Exception e) { - System.out.println("[오류] 사용자 메뉴 처리 중 문제가 발생했습니다: " + e.getMessage()); - } - } - } +// public static void manageUsers(Scanner scanner, UserService userService, UserIntegration userIntegration) { +// while (true) { +// System.out.println("\n===== USER MENU ====="); +// System.out.println("1. 사용자 등록"); +// System.out.println("2. 사용자 단건 조회"); +// System.out.println("3. 사용자 다건 조회"); +// System.out.println("4. 사용자 수정"); +// System.out.println("5. 사용자 삭제"); +// System.out.println("0. 초기 화면으로"); +// System.out.print("번호를 입력하세요: "); +// String select = scanner.nextLine(); +// +// try { +// switch (select) { +// case "1": +// System.out.print("사용자 이름 입력: "); +// String name = scanner.nextLine(); +// User user = new User(name); +// userService.createUser(user); +// System.out.println("생성된 사용자 ID: " + user.getId()); +// break; +// case "2": +// System.out.print("조회할 사용자 ID 입력: "); +// UUID id = UUID.fromString(scanner.nextLine()); +// userService.getUser(id) +// .ifPresentOrElse( +// System.out::println, +// () -> System.out.println("사용자를 찾을 수 없습니다.") +// ); +// break; +// case "3": +// userService.getAllUsers().forEach(System.out::println); +// break; +// case "4": +// System.out.print("수정할 사용자 ID 입력: "); +// UUID updateId = UUID.fromString(scanner.nextLine()); +// System.out.print("새 이름 입력: "); +// String newName = scanner.nextLine(); +// userService.getUser(updateId).ifPresent(u -> { +// u.updateUserName(newName); +// userService.updateUser(u); +// }); +// break; +// case "5": +// System.out.print("삭제할 사용자 ID 입력: "); +// UUID delId = UUID.fromString(scanner.nextLine()); +// userIntegration.deleteUser(delId); +// break; +// case "0": +// return; +// default: +// System.out.println("올바른 번호를 선택하세요."); +// } +// } catch (Exception e) { +// System.out.println("[오류] 사용자 메뉴 처리 중 문제가 발생했습니다: " + e.getMessage()); +// } +// } +// } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java new file mode 100644 index 00000000..a6e66b2e --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java @@ -0,0 +1,15 @@ +package com.sprint.mission.discodeit.repository; + +import com.sprint.mission.discodeit.entity.BinaryContent; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface BinaryContentRepository { + BinaryContent save(BinaryContent binaryContent); + Optional findById(UUID id); + List findAllByIdIn(List ids); + boolean existsById(UUID id); + void deleteById(UUID id); +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/ChannelRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/ChannelRepository.java index 37822d08..36adbaed 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/ChannelRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/ChannelRepository.java @@ -7,8 +7,9 @@ import java.util.UUID; public interface ChannelRepository { - Channel save(Channel channel); // 저장 로직 - Optional findById(UUID channelId); // 저장 로직 - List findAll(); // 저장 로직 - void deleteById(UUID channelId); // 저장 로직 -} + Channel save(Channel channel); + Optional findById(UUID id); + List findAll(); + boolean existsById(UUID id); + void deleteById(UUID id); +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/MessageRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/MessageRepository.java index 2cdb0516..69547b22 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/MessageRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/MessageRepository.java @@ -7,8 +7,10 @@ import java.util.UUID; public interface MessageRepository { - Message save(Message message); // 저장 로직 - Optional findById(UUID messageId); // 저장 로직 - List findAll(); // 저장 로직 - void deleteById(UUID messageId); // 저장 로직 + Message save(Message message); + Optional findById(UUID id); + List findAllByChannelId(UUID channelId); + boolean existsById(UUID id); + void deleteById(UUID id); + void deleteAllByChannelId(UUID channelId); } diff --git a/src/main/java/com/sprint/mission/discodeit/repository/ReadStatusRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/ReadStatusRepository.java new file mode 100644 index 00000000..e0ef9c69 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/ReadStatusRepository.java @@ -0,0 +1,17 @@ +package com.sprint.mission.discodeit.repository; + +import com.sprint.mission.discodeit.entity.ReadStatus; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface ReadStatusRepository { + ReadStatus save(ReadStatus readStatus); + Optional findById(UUID id); + List findAllByUserId(UUID userId); + List findAllByChannelId(UUID channelId); + boolean existsById(UUID id); + void deleteById(UUID id); + void deleteAllByChannelId(UUID channelId); +} diff --git a/src/main/java/com/sprint/mission/discodeit/repository/UserRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/UserRepository.java index 85c186f5..b5b19c23 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/UserRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/UserRepository.java @@ -4,9 +4,14 @@ import java.util.*; + public interface UserRepository { - User save(User user); // 저장 로직 - Optional findById(UUID userId); // 저장 로직 - List findAll(); // 저장 로직 - void deleteById(UUID userId); // 저장 로직 + User save(User user); + Optional findById(UUID id); + Optional findByUsername(String username); + List findAll(); + boolean existsById(UUID id); + boolean existsByUsername(String username); + boolean existsByEmail(String email); + void deleteById(UUID id); } diff --git a/src/main/java/com/sprint/mission/discodeit/repository/UserStatusRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/UserStatusRepository.java new file mode 100644 index 00000000..6651bd20 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/UserStatusRepository.java @@ -0,0 +1,17 @@ +package com.sprint.mission.discodeit.repository; + +import com.sprint.mission.discodeit.entity.UserStatus; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface UserStatusRepository { + UserStatus save(UserStatus userStatus); + Optional findById(UUID id); + Optional findByUserId(UUID userId); + List findAll(); + boolean existsById(UUID id); + void deleteById(UUID id); + void deleteByUserId(UUID userId); +} 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 new file mode 100644 index 00000000..5daf3c90 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/file/FileBinaryContentRepository.java @@ -0,0 +1,88 @@ +package com.sprint.mission.discodeit.repository.file; + +import com.sprint.mission.discodeit.entity.BinaryContent; +import com.sprint.mission.discodeit.repository.BinaryContentRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "file") +@Repository +public class FileBinaryContentRepository implements BinaryContentRepository { + private final Path DIRECTORY; + private final String EXTENSION = ".ser"; + + public FileBinaryContentRepository() { + this.DIRECTORY = Paths.get(System.getProperty("user.dir"), "file-data-map", BinaryContent.class.getSimpleName()); + if (Files.notExists(DIRECTORY)) { + try { + Files.createDirectories(DIRECTORY); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + private Path resolvePath(UUID id) { + return DIRECTORY.resolve(id + EXTENSION); + } + + @Override + 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 binaryContent; + } + + @Override + public Optional findById(UUID id) { + Path path = resolvePath(id); + if (!Files.exists(path)) return Optional.empty(); + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return Optional.of((BinaryContent) ois.readObject()); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + @Override + public List findAllByIdIn(List ids) { + return ids.stream() + .map(this::findById) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + + @Override + public boolean existsById(UUID id) { + return Files.exists(resolvePath(id)); + } + + @Override + public void deleteById(UUID id) { + try { + Files.deleteIfExists(resolvePath(id)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/file/FileChannelRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/file/FileChannelRepository.java index 3c7e93cd..a59194d0 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/file/FileChannelRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/file/FileChannelRepository.java @@ -2,94 +2,91 @@ import com.sprint.mission.discodeit.entity.Channel; import com.sprint.mission.discodeit.repository.ChannelRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "file") +@Repository public class FileChannelRepository implements ChannelRepository { - private final Path directory; + private final Path DIRECTORY; + private final String EXTENSION = ".ser"; - public FileChannelRepository(Path directory) { - this.directory = directory; - initDirectory(); - } - - private void initDirectory() { - if (!Files.exists(directory)) { + public FileChannelRepository() { + this.DIRECTORY = Paths.get(System.getProperty("user.dir"), "file-data-map", Channel.class.getSimpleName()); + if (Files.notExists(DIRECTORY)) { try { - Files.createDirectories(directory); + Files.createDirectories(DIRECTORY); } catch (IOException e) { - throw new RuntimeException("디렉토리 생성 실패: " + e); + throw new RuntimeException(e); } } } private Path resolvePath(UUID id) { - return directory.resolve(id.toString().concat(".ser")); + return DIRECTORY.resolve(id + EXTENSION); } - private Channel saveFile(Channel channel) { + @Override + public Channel save(Channel channel) { + Path path = resolvePath(channel.getId()); try ( - FileOutputStream fos = new FileOutputStream(resolvePath(channel.getId()).toFile()); + FileOutputStream fos = new FileOutputStream(path.toFile()); ObjectOutputStream oos = new ObjectOutputStream(fos) ) { oos.writeObject(channel); - return channel; } catch (IOException e) { - throw new RuntimeException("채널 저장 실패: " + e); + throw new RuntimeException(e); } + return channel; } - private Optional loadFile(UUID id) { + @Override + public Optional findById(UUID id) { Path path = resolvePath(id); - if (Files.exists(path)) { - try ( - FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - Channel loaded = (Channel) ois.readObject(); - return Optional.of(loaded); - } catch (IOException | ClassNotFoundException e) { - return Optional.empty(); - } - } else { - return Optional.empty(); + if (!Files.exists(path)) return Optional.empty(); + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return Optional.of((Channel) ois.readObject()); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); } } @Override - public Channel save(Channel channel) { - return saveFile(channel); - } - - @Override - public Optional findById(UUID id) { - return loadFile(id); + public List findAll() { + try { + return Files.list(DIRECTORY) + .filter(path -> path.toString().endsWith(EXTENSION)) + .map(path -> { + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return (Channel) ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } catch (IOException e) { + throw new RuntimeException(e); + } } @Override - public List findAll() { - List channels = new ArrayList<>(); - if (Files.exists(directory)) { - try { - Files.list(directory) - .filter(path -> path.toString().endsWith(".ser")) - .forEach(path -> { - try ( - FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - Channel channel = (Channel) ois.readObject(); - if (channel != null) channels.add(channel); - } catch (IOException | ClassNotFoundException ignored) {} - }); - } catch (IOException e) { - throw new RuntimeException("채널 전체 조회 실패", e); - } - } - return channels; + public boolean existsById(UUID id) { + return Files.exists(resolvePath(id)); } @Override @@ -97,7 +94,7 @@ public void deleteById(UUID id) { try { Files.deleteIfExists(resolvePath(id)); } catch (IOException e) { - throw new RuntimeException("채널 삭제 실패: " + id, e); + throw new RuntimeException(e); } } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/file/FileMessageRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/file/FileMessageRepository.java index 44572e2d..6199dc42 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/file/FileMessageRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/file/FileMessageRepository.java @@ -2,102 +2,110 @@ import com.sprint.mission.discodeit.entity.Message; import com.sprint.mission.discodeit.repository.MessageRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; import java.io.*; -import java.nio.file.*; -import java.util.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "file") +@Repository public class FileMessageRepository implements MessageRepository { - private final Path directory; + private final Path DIRECTORY; + private final String EXTENSION = ".ser"; - public FileMessageRepository(Path directory) { - this.directory = directory; - initDirectory(); - } - - private void initDirectory() { - try { - if (!Files.exists(directory)) { - Files.createDirectories(directory); + public FileMessageRepository() { + this.DIRECTORY = Paths.get(System.getProperty("user.dir"), "file-data-map", Message.class.getSimpleName()); + if (Files.notExists(DIRECTORY)) { + try { + Files.createDirectories(DIRECTORY); + } catch (IOException e) { + throw new RuntimeException(e); } - } catch (IOException e) { - throw new RuntimeException("디렉토리 생성 실패: ", e); } } private Path resolvePath(UUID id) { - return directory.resolve(id.toString().concat(".ser")); + return DIRECTORY.resolve(id + EXTENSION); } - private Message saveFile(Message message) { + @Override + public Message save(Message message) { + Path path = resolvePath(message.getId()); try ( - FileOutputStream fos = new FileOutputStream(resolvePath(message.getId()).toFile()); + FileOutputStream fos = new FileOutputStream(path.toFile()); ObjectOutputStream oos = new ObjectOutputStream(fos) ) { oos.writeObject(message); - return message; } catch (IOException e) { - throw new RuntimeException("메시지 저장 실패: " + e); + throw new RuntimeException(e); } + return message; } - private Optional loadFile(UUID id) { - if (Files.exists(resolvePath(id))) { - try ( - FileInputStream fis = new FileInputStream(resolvePath(id).toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - return Optional.of((Message) ois.readObject()); - } catch (IOException | ClassNotFoundException e) { - return Optional.empty(); - } - } else { - return Optional.empty(); + @Override + public Optional findById(UUID id) { + Path path = resolvePath(id); + if (!Files.exists(path)) return Optional.empty(); + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return Optional.of((Message) ois.readObject()); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); } } @Override - public Message save(Message message) { - return saveFile(message); + public List findAllByChannelId(UUID channelId) { + return findAll().stream() + .filter(m -> m.getChannelId().equals(channelId)) + .collect(Collectors.toList()); } @Override - public Optional findById(UUID id) { - return loadFile(id); + public boolean existsById(UUID id) { + return Files.exists(resolvePath(id)); } @Override - public List findAll() { - if (Files.exists(directory)) { - try { - return Files.list(directory) - .filter(path -> path.toString().endsWith(".ser")) - .map(path -> { - try ( - FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - return (Message) ois.readObject(); - } catch (IOException | ClassNotFoundException e) { - return null; - } - }) - .filter(Objects::nonNull) - .toList(); - } catch (IOException e) { - throw new RuntimeException("메시지 전체 조회 실패", e); - } - } else { - return new ArrayList<>(); + public void deleteById(UUID id) { + try { + Files.deleteIfExists(resolvePath(id)); + } catch (IOException e) { + throw new RuntimeException(e); } } @Override - public void deleteById(UUID id) { + public void deleteAllByChannelId(UUID channelId) { + findAllByChannelId(channelId).forEach(msg -> deleteById(msg.getId())); + } + + private List findAll() { try { - Files.deleteIfExists(resolvePath(id)); + return Files.list(DIRECTORY) + .filter(path -> path.toString().endsWith(EXTENSION)) + .map(path -> { + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return (Message) ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); } catch (IOException e) { - throw new RuntimeException("메시지 삭제 실패: " + id, e); + throw new RuntimeException(e); } } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/file/FileReadStatusRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/file/FileReadStatusRepository.java new file mode 100644 index 00000000..e1099792 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/file/FileReadStatusRepository.java @@ -0,0 +1,118 @@ +package com.sprint.mission.discodeit.repository.file; + +import com.sprint.mission.discodeit.entity.ReadStatus; +import com.sprint.mission.discodeit.repository.ReadStatusRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "file") +@Repository +public class FileReadStatusRepository implements ReadStatusRepository { + private final Path DIRECTORY; + private final String EXTENSION = ".ser"; + + public FileReadStatusRepository() { + this.DIRECTORY = Paths.get(System.getProperty("user.dir"), "file-data-map", ReadStatus.class.getSimpleName()); + if (Files.notExists(DIRECTORY)) { + try { + Files.createDirectories(DIRECTORY); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + private Path resolvePath(UUID id) { + return DIRECTORY.resolve(id + EXTENSION); + } + + @Override + public ReadStatus save(ReadStatus readStatus) { + Path path = resolvePath(readStatus.getId()); + try ( + FileOutputStream fos = new FileOutputStream(path.toFile()); + ObjectOutputStream oos = new ObjectOutputStream(fos) + ) { + oos.writeObject(readStatus); + } catch (IOException e) { + throw new RuntimeException(e); + } + return readStatus; + } + + @Override + public Optional findById(UUID id) { + Path path = resolvePath(id); + if (!Files.exists(path)) return Optional.empty(); + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return Optional.of((ReadStatus) ois.readObject()); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + @Override + public List findAllByUserId(UUID userId) { + return findAll().stream() + .filter(rs -> rs.getUserId().equals(userId)) + .collect(Collectors.toList()); + } + + @Override + public List findAllByChannelId(UUID channelId) { + return findAll().stream() + .filter(rs -> rs.getChannelId().equals(channelId)) + .collect(Collectors.toList()); + } + + @Override + public boolean existsById(UUID id) { + return Files.exists(resolvePath(id)); + } + + @Override + public void deleteById(UUID id) { + try { + Files.deleteIfExists(resolvePath(id)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void deleteAllByChannelId(UUID channelId) { + findAllByChannelId(channelId).forEach(rs -> deleteById(rs.getId())); + } + + private List findAll() { + try { + return Files.list(DIRECTORY) + .filter(path -> path.toString().endsWith(EXTENSION)) + .map(path -> { + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return (ReadStatus) ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/file/FileUserRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/file/FileUserRepository.java index fc1eedd8..8a0d0789 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/file/FileUserRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/file/FileUserRepository.java @@ -2,98 +2,122 @@ import com.sprint.mission.discodeit.entity.User; import com.sprint.mission.discodeit.repository.UserRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "file") +@Repository public class FileUserRepository implements UserRepository { - private final Path directory; + private final Path DIRECTORY; + private final String EXTENSION = ".ser"; - public FileUserRepository(Path directory) { - this.directory = directory; - initDirectory(); - } - - private void initDirectory() { - if (!Files.exists(directory)) { + public FileUserRepository() { + this.DIRECTORY = Paths.get(System.getProperty("user.dir"), "file-data-map", User.class.getSimpleName()); + if (Files.notExists(DIRECTORY)) { try { - Files.createDirectories(directory); + Files.createDirectories(DIRECTORY); } catch (IOException e) { - throw new RuntimeException("디렉토리 생성 실패: " + e); + throw new RuntimeException(e); } } } private Path resolvePath(UUID id) { - return directory.resolve(id.toString().concat(".ser")); + return DIRECTORY.resolve(id + EXTENSION); } - private void saveFile(User user) { - try (FileOutputStream fos = new FileOutputStream(resolvePath(user.getId()).toFile()); - ObjectOutputStream oos = new ObjectOutputStream(fos)) { + @Override + public User save(User user) { + Path path = resolvePath(user.getId()); + try ( + FileOutputStream fos = new FileOutputStream(path.toFile()); + ObjectOutputStream oos = new ObjectOutputStream(fos) + ) { oos.writeObject(user); } catch (IOException e) { - throw new RuntimeException("유저 저장 실패: " + e); + throw new RuntimeException(e); } + return user; } - private Optional loadFile(UUID id) { + @Override + public Optional findById(UUID id) { + User userNullable = null; Path path = resolvePath(id); if (Files.exists(path)) { - try (FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis)) { - return Optional.of((User) ois.readObject()); + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + userNullable = (User) ois.readObject(); } catch (IOException | ClassNotFoundException e) { - return Optional.empty(); + throw new RuntimeException(e); } - } else { - return Optional.empty(); } + return Optional.ofNullable(userNullable); } @Override - public User save(User user) { - saveFile(user); - return user; + public Optional findByUsername(String username) { + return this.findAll().stream() + .filter(user -> user.getUsername().equals(username)) + .findFirst(); } @Override - public Optional findById(UUID id) { - return loadFile(id); + public List findAll() { + try { + return Files.list(DIRECTORY) + .filter(path -> path.toString().endsWith(EXTENSION)) + .map(path -> { + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return (User) ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + }) + .toList(); + } catch (IOException e) { + throw new RuntimeException(e); + } } @Override - public List findAll() { - if (Files.exists(directory)) { - try { - return Files.list(directory) - .filter(path -> path.toString().endsWith(".ser")) - .map(path -> { - try (FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis)) { - return (User) ois.readObject(); - } catch (IOException | ClassNotFoundException e) { - return null; - } - }) - .filter(Objects::nonNull) - .toList(); - } catch (IOException e) { - throw new RuntimeException("유저 전체 조회 실패", e); - } - } else { - return new ArrayList<>(); - } + public boolean existsById(UUID id) { + Path path = resolvePath(id); + return Files.exists(path); } @Override public void deleteById(UUID id) { + Path path = resolvePath(id); try { - Files.deleteIfExists(resolvePath(id)); + Files.delete(path); } catch (IOException e) { - throw new RuntimeException("유저 삭제 실패: " + id, e); + throw new RuntimeException(e); } } -} + + @Override + public boolean existsByEmail(String email) { + return this.findAll().stream() + .anyMatch(user -> user.getEmail().equals(email)); + } + + @Override + public boolean existsByUsername(String username) { + return this.findAll().stream() + .anyMatch(user -> user.getUsername().equals(username)); + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/file/FileUserStatusRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/file/FileUserStatusRepository.java new file mode 100644 index 00000000..21d8700f --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/file/FileUserStatusRepository.java @@ -0,0 +1,112 @@ +package com.sprint.mission.discodeit.repository.file; + +import com.sprint.mission.discodeit.entity.UserStatus; +import com.sprint.mission.discodeit.repository.UserStatusRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "file") +@Repository +public class FileUserStatusRepository implements UserStatusRepository { + private final Path DIRECTORY; + private final String EXTENSION = ".ser"; + + public FileUserStatusRepository() { + this.DIRECTORY = Paths.get(System.getProperty("user.dir"), "file-data-map", UserStatus.class.getSimpleName()); + if (Files.notExists(DIRECTORY)) { + try { + Files.createDirectories(DIRECTORY); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + private Path resolvePath(UUID id) { + return DIRECTORY.resolve(id + EXTENSION); + } + + @Override + public UserStatus save(UserStatus userStatus) { + Path path = resolvePath(userStatus.getId()); + try ( + FileOutputStream fos = new FileOutputStream(path.toFile()); + ObjectOutputStream oos = new ObjectOutputStream(fos) + ) { + oos.writeObject(userStatus); + } catch (IOException e) { + throw new RuntimeException(e); + } + return userStatus; + } + + @Override + public Optional findById(UUID id) { + Path path = resolvePath(id); + if (!Files.exists(path)) return Optional.empty(); + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return Optional.of((UserStatus) ois.readObject()); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + @Override + public Optional findByUserId(UUID userId) { + return findAll().stream() + .filter(us -> us.getUserId().equals(userId)) + .findFirst(); + } + + @Override + public List findAll() { + try { + return Files.list(DIRECTORY) + .filter(path -> path.toString().endsWith(EXTENSION)) + .map(path -> { + try ( + FileInputStream fis = new FileInputStream(path.toFile()); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + return (UserStatus) ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean existsById(UUID id) { + return Files.exists(resolvePath(id)); + } + + @Override + public void deleteById(UUID id) { + try { + Files.deleteIfExists(resolvePath(id)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void deleteByUserId(UUID userId) { + findByUserId(userId).ifPresent(status -> deleteById(status.getId())); + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..90a5c51d --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFBinaryContentRepository.java @@ -0,0 +1,48 @@ +package com.sprint.mission.discodeit.repository.jcf; + +import com.sprint.mission.discodeit.entity.BinaryContent; +import com.sprint.mission.discodeit.repository.BinaryContentRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; + +import java.util.*; + +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "jcf", matchIfMissing = true) +@Repository +public class JCFBinaryContentRepository implements BinaryContentRepository { + private final Map data = new HashMap<>(); + + @Override + public BinaryContent save(BinaryContent binaryContent) { + data.put(binaryContent.getId(), binaryContent); + return binaryContent; + } + + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(data.get(id)); + } + + @Override + public boolean existsById(UUID id) { + return data.containsKey(id); + } + + @Override + public void deleteById(UUID id) { + data.remove(id); + } + + @Override + public List findAllByIdIn(List ids) { + List results = new ArrayList<>(); + for (UUID id : ids) { + BinaryContent content = data.get(id); + if (content != null) { + results.add(content); + } + } + return results; + } +} + diff --git a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFChannelRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFChannelRepository.java index eca4eb3f..c54759d1 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFChannelRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFChannelRepository.java @@ -2,14 +2,39 @@ import com.sprint.mission.discodeit.entity.Channel; import com.sprint.mission.discodeit.repository.ChannelRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; import java.util.*; +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "jcf", matchIfMissing = true) +@Repository public class JCFChannelRepository implements ChannelRepository { private final Map data = new HashMap<>(); - public Channel save(Channel channel) { return data.put(channel.getId(), channel); } - public Optional findById(UUID channelId) { return Optional.ofNullable(data.get(channelId)); } - public List findAll() { return new ArrayList<>(data.values()); } - public void deleteById(UUID channelId) { data.remove(channelId); } + @Override + public Channel save(Channel channel) { + data.put(channel.getId(), channel); + return channel; + } + + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(data.get(id)); + } + + @Override + public List findAll() { + return new ArrayList<>(data.values()); + } + + @Override + public boolean existsById(UUID id) { + return data.containsKey(id); + } + + @Override + public void deleteById(UUID id) { + data.remove(id); + } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFMessageRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFMessageRepository.java index 2fbe0a4f..767d6801 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFMessageRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFMessageRepository.java @@ -2,14 +2,58 @@ import com.sprint.mission.discodeit.entity.Message; import com.sprint.mission.discodeit.repository.MessageRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; import java.util.*; +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "jcf", matchIfMissing = true) +@Repository public class JCFMessageRepository implements MessageRepository { - private final Map data = new HashMap<>(); + private final Map storage = new HashMap<>(); - public Message save(Message message) { return data.put(message.getId(), message); } - public Optional findById(UUID messageId) { return Optional.ofNullable(data.get(messageId)); } - public List findAll() { return new ArrayList<>(data.values()); } - public void deleteById(UUID messageId) { data.remove(messageId); } + @Override + public Message save(Message message) { + storage.put(message.getId(), message); + return message; + } + + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(storage.get(id)); + } + + @Override + public List findAllByChannelId(UUID channelId) { + List result = new ArrayList<>(); + for (Message message : storage.values()) { + if (message.getChannelId().equals(channelId)) { + result.add(message); + } + } + return result; + } + + @Override + public boolean existsById(UUID id) { + return storage.containsKey(id); + } + + @Override + public void deleteById(UUID id) { + storage.remove(id); + } + + @Override + public void deleteAllByChannelId(UUID channelId) { + List toRemove = new ArrayList<>(); + for (Message message : storage.values()) { + if (message.getChannelId().equals(channelId)) { + toRemove.add(message.getId()); + } + } + for (UUID id : toRemove) { + storage.remove(id); + } + } } diff --git a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFReadStatusRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFReadStatusRepository.java new file mode 100644 index 00000000..5b5924c5 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFReadStatusRepository.java @@ -0,0 +1,70 @@ +package com.sprint.mission.discodeit.repository.jcf; + +import com.sprint.mission.discodeit.entity.ReadStatus; +import com.sprint.mission.discodeit.repository.ReadStatusRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; + +import java.util.*; + +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "jcf", matchIfMissing = true) +@Repository +public class JCFReadStatusRepository implements ReadStatusRepository { + private final Map storage = new HashMap<>(); + + @Override + public ReadStatus save(ReadStatus readStatus) { + storage.put(readStatus.getId(), readStatus); + return readStatus; + } + + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(storage.get(id)); + } + + @Override + public List findAllByUserId(UUID userId) { + List result = new ArrayList<>(); + for (ReadStatus status : storage.values()) { + if (status.getUserId().equals(userId)) { + result.add(status); + } + } + return result; + } + + @Override + public List findAllByChannelId(UUID channelId) { + List result = new ArrayList<>(); + for (ReadStatus status : storage.values()) { + if (status.getChannelId().equals(channelId)) { + result.add(status); + } + } + return result; + } + + @Override + public boolean existsById(UUID id) { + return storage.containsKey(id); + } + + @Override + public void deleteById(UUID id) { + storage.remove(id); + } + + @Override + public void deleteAllByChannelId(UUID channelId) { + List toRemove = new ArrayList<>(); + for (ReadStatus status : storage.values()) { + if (status.getChannelId().equals(channelId)) { + toRemove.add(status.getId()); + } + } + for (UUID id : toRemove) { + storage.remove(id); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFUserRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFUserRepository.java index 91704ab1..b6e7d0d8 100644 --- a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFUserRepository.java +++ b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFUserRepository.java @@ -2,14 +2,59 @@ import com.sprint.mission.discodeit.entity.User; import com.sprint.mission.discodeit.repository.UserRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "jcf", matchIfMissing = true) +@Repository public class JCFUserRepository implements UserRepository { - private final Map data = new HashMap<>(); + private final Map storage = new HashMap<>(); - public User save(User user) { return data.put(user.getId(), user); } - public Optional findById(UUID userId) { return Optional.ofNullable(data.get(userId)); } - public List findAll() { return new ArrayList<>(data.values()); } - public void deleteById(UUID userId) { data.remove(userId); } -} \ No newline at end of file + @Override + public User save(User user) { + storage.put(user.getId(), user); + return user; + } + + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(storage.get(id)); + } + + @Override + public Optional findByUsername(String username) { + return storage.values().stream() + .filter(u -> u.getUsername().equals(username)) + .findFirst(); + } + + @Override + public List findAll() { + return new ArrayList<>(storage.values()); + } + + @Override + public boolean existsById(UUID id) { + return storage.containsKey(id); + } + + @Override + public boolean existsByUsername(String username) { + return storage.values().stream() + .anyMatch(u -> u.getUsername().equals(username)); + } + + @Override + public boolean existsByEmail(String email) { + return storage.values().stream() + .anyMatch(u -> u.getEmail().equals(email)); + } + + @Override + public void deleteById(UUID id) { + storage.remove(id); + } +} diff --git a/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFUserStatusRepository.java b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFUserStatusRepository.java new file mode 100644 index 00000000..2c897d9b --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/repository/jcf/JCFUserStatusRepository.java @@ -0,0 +1,60 @@ +package com.sprint.mission.discodeit.repository.jcf; + +import com.sprint.mission.discodeit.entity.UserStatus; +import com.sprint.mission.discodeit.repository.UserStatusRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Repository; + +import java.util.*; + +@ConditionalOnProperty(name = "discodeit.repository.type", havingValue = "jcf", matchIfMissing = true) +@Repository +public class JCFUserStatusRepository implements UserStatusRepository { + private final Map storage = new HashMap<>(); + + @Override + public UserStatus save(UserStatus userStatus) { + storage.put(userStatus.getId(), userStatus); + return userStatus; + } + + @Override + public Optional findById(UUID id) { + return Optional.ofNullable(storage.get(id)); + } + + @Override + public Optional findByUserId(UUID userId) { + return storage.values().stream() + .filter(status -> status.getUserId().equals(userId)) + .findFirst(); + } + + @Override + public List findAll() { + return new ArrayList<>(storage.values()); + } + + @Override + public boolean existsById(UUID id) { + return storage.containsKey(id); + } + + @Override + public void deleteById(UUID id) { + storage.remove(id); + } + + @Override + public void deleteByUserId(UUID userId) { + List toRemove = new ArrayList<>(); + for (UserStatus status : storage.values()) { + if (status.getUserId().equals(userId)) { + toRemove.add(status.getId()); + } + } + for (UUID id : toRemove) { + storage.remove(id); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/AuthService.java b/src/main/java/com/sprint/mission/discodeit/service/AuthService.java new file mode 100644 index 00000000..5745d03a --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/AuthService.java @@ -0,0 +1,9 @@ +package com.sprint.mission.discodeit.service; + +import com.sprint.mission.discodeit.dto.data.UserDto; +import com.sprint.mission.discodeit.dto.request.LoginRequest; +import com.sprint.mission.discodeit.entity.User; + +public interface AuthService { + User login(LoginRequest loginRequest); +} diff --git a/src/main/java/com/sprint/mission/discodeit/service/BinaryContentService.java b/src/main/java/com/sprint/mission/discodeit/service/BinaryContentService.java new file mode 100644 index 00000000..77d8358b --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/BinaryContentService.java @@ -0,0 +1,14 @@ +package com.sprint.mission.discodeit.service; + +import com.sprint.mission.discodeit.dto.request.BinaryContentCreateRequest; +import com.sprint.mission.discodeit.entity.BinaryContent; + +import java.util.List; +import java.util.UUID; + +public interface BinaryContentService { + BinaryContent create(BinaryContentCreateRequest request); + BinaryContent find(UUID binaryContentId); + List findAllByIdIn(List binaryContentIds); + void delete(UUID binaryContentId); +} diff --git a/src/main/java/com/sprint/mission/discodeit/service/ChannelService.java b/src/main/java/com/sprint/mission/discodeit/service/ChannelService.java index 2dc6b021..bf7ab807 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/ChannelService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/ChannelService.java @@ -1,15 +1,19 @@ package com.sprint.mission.discodeit.service; +import com.sprint.mission.discodeit.dto.data.ChannelDto; +import com.sprint.mission.discodeit.dto.request.PrivateChannelCreateRequest; +import com.sprint.mission.discodeit.dto.request.PublicChannelCreateRequest; +import com.sprint.mission.discodeit.dto.request.PublicChannelUpdateRequest; import com.sprint.mission.discodeit.entity.Channel; import java.util.List; -import java.util.Optional; import java.util.UUID; public interface ChannelService { - Channel createChannel(Channel channel); - Optional getChannel(UUID channelId); - List getAllChannels(); - void updateChannel(Channel channel); - void deleteChannel(UUID channelId); + Channel create(PublicChannelCreateRequest request); + Channel create(PrivateChannelCreateRequest request); + ChannelDto find(UUID channelId); + List findAllByUserId(UUID userId); + Channel update(UUID channelId, PublicChannelUpdateRequest request); + void delete(UUID channelId); } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/MessageService.java b/src/main/java/com/sprint/mission/discodeit/service/MessageService.java index 3bb2d45b..95d92d68 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/MessageService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/MessageService.java @@ -1,15 +1,19 @@ package com.sprint.mission.discodeit.service; +import com.sprint.mission.discodeit.dto.request.BinaryContentCreateRequest; +import com.sprint.mission.discodeit.dto.request.MessageCreateRequest; +import com.sprint.mission.discodeit.dto.request.MessageUpdateRequest; import com.sprint.mission.discodeit.entity.Message; +import java.time.Instant; import java.util.List; import java.util.Optional; import java.util.UUID; public interface MessageService { - Message createMessage(Message message); - Optional getMessage(UUID messageId); - List getAllMessages(); - void updateMessage(UUID messageId, String msgContent); - void deleteMessage(UUID messageId); + Message create(MessageCreateRequest messageCreateRequest, List binaryContentCreateRequests); + Message find(UUID messageId); + List findAllByChannelId(UUID channelId); + Message update(UUID messageId, MessageUpdateRequest request); + void delete(UUID messageId); } diff --git a/src/main/java/com/sprint/mission/discodeit/service/ReadStatusService.java b/src/main/java/com/sprint/mission/discodeit/service/ReadStatusService.java new file mode 100644 index 00000000..fcbc82f9 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/ReadStatusService.java @@ -0,0 +1,16 @@ +package com.sprint.mission.discodeit.service; + +import com.sprint.mission.discodeit.dto.request.ReadStatusCreateRequest; +import com.sprint.mission.discodeit.dto.request.ReadStatusUpdateRequest; +import com.sprint.mission.discodeit.entity.ReadStatus; + +import java.util.List; +import java.util.UUID; + +public interface ReadStatusService { + ReadStatus create(ReadStatusCreateRequest request); + ReadStatus find(UUID readStatusId); + List findAllByUserId(UUID userId); + ReadStatus update(UUID readStatusId, ReadStatusUpdateRequest request); + void delete(UUID readStatusId); +} diff --git a/src/main/java/com/sprint/mission/discodeit/service/UserService.java b/src/main/java/com/sprint/mission/discodeit/service/UserService.java index 6fa01135..34dc9df3 100644 --- a/src/main/java/com/sprint/mission/discodeit/service/UserService.java +++ b/src/main/java/com/sprint/mission/discodeit/service/UserService.java @@ -1,5 +1,9 @@ package com.sprint.mission.discodeit.service; +import com.sprint.mission.discodeit.dto.data.UserDto; +import com.sprint.mission.discodeit.dto.request.BinaryContentCreateRequest; +import com.sprint.mission.discodeit.dto.request.UserCreateRequest; +import com.sprint.mission.discodeit.dto.request.UserUpdateRequest; import com.sprint.mission.discodeit.entity.User; import java.util.List; @@ -7,9 +11,9 @@ import java.util.UUID; public interface UserService { - User createUser(User user); - Optional getUser(UUID userId); - List getAllUsers(); - void updateUser(User user); - void deleteUser(UUID userId); + User create(UserCreateRequest userCreateRequest, Optional profileCreateRequest); + UserDto find(UUID userId); + List findAll(); + User update(UUID userId, UserUpdateRequest userUpdateRequest, Optional profileCreateRequest); + void delete(UUID userId); } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/UserStatusService.java b/src/main/java/com/sprint/mission/discodeit/service/UserStatusService.java new file mode 100644 index 00000000..47058277 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/UserStatusService.java @@ -0,0 +1,17 @@ +package com.sprint.mission.discodeit.service; + +import com.sprint.mission.discodeit.dto.request.UserStatusCreateRequest; +import com.sprint.mission.discodeit.dto.request.UserStatusUpdateRequest; +import com.sprint.mission.discodeit.entity.UserStatus; + +import java.util.List; +import java.util.UUID; + +public interface UserStatusService { + UserStatus create(UserStatusCreateRequest request); + UserStatus find(UUID userStatusId); + List findAll(); + UserStatus update(UUID userStatusId, UserStatusUpdateRequest request); + UserStatus updateByUserId(UUID userId, UserStatusUpdateRequest request); + void delete(UUID userStatusId); +} diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicAuthService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicAuthService.java new file mode 100644 index 00000000..7ffc8a70 --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicAuthService.java @@ -0,0 +1,31 @@ +package com.sprint.mission.discodeit.service.basic; + +import com.sprint.mission.discodeit.dto.request.LoginRequest; +import com.sprint.mission.discodeit.entity.User; +import com.sprint.mission.discodeit.repository.UserRepository; +import com.sprint.mission.discodeit.service.AuthService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.NoSuchElementException; + +@RequiredArgsConstructor +@Service +public class BasicAuthService implements AuthService { + private final UserRepository userRepository; + + @Override + public User login(LoginRequest loginRequest) { + String username = loginRequest.username(); + String password = loginRequest.password(); + + User user = userRepository.findByUsername(username) + .orElseThrow(() -> new NoSuchElementException("해당 사용자명을 찾을 수 없습니다.")); + + if (!user.getPassword().equals(password)) { + throw new IllegalArgumentException("비밀번호가 일치하지 않습니다."); + } + + return user; + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicBinaryContentService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicBinaryContentService.java new file mode 100644 index 00000000..db637d4a --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicBinaryContentService.java @@ -0,0 +1,46 @@ +package com.sprint.mission.discodeit.service.basic; + +import com.sprint.mission.discodeit.dto.request.BinaryContentCreateRequest; +import com.sprint.mission.discodeit.entity.BinaryContent; +import com.sprint.mission.discodeit.repository.BinaryContentRepository; +import com.sprint.mission.discodeit.service.BinaryContentService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.*; + +@RequiredArgsConstructor +@Service +public class BasicBinaryContentService implements BinaryContentService { + private final BinaryContentRepository binaryContentRepository; + + @Override + public BinaryContent create(BinaryContentCreateRequest request) { + BinaryContent binaryContent = new BinaryContent( + request.fileName(), + (long) request.data().length, + request.contentType(), + request.data() + ); + return binaryContentRepository.save(binaryContent); + } + + @Override + public BinaryContent find(UUID binaryContentId) { + return binaryContentRepository.findById(binaryContentId) + .orElseThrow(() -> new NoSuchElementException("해당 바이너리 데이터를 찾을 수 없습니다.")); + } + + @Override + public List findAllByIdIn(List binaryContentIds) { + return binaryContentRepository.findAllByIdIn(binaryContentIds); + } + + @Override + public void delete(UUID binaryContentId) { + if (!binaryContentRepository.existsById(binaryContentId)) { + throw new NoSuchElementException("해당 바이너리 데이터를 찾을 수 없습니다."); + } + binaryContentRepository.deleteById(binaryContentId); + } +} \ No newline at end of file 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 8bf2dc07..a929284d 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 @@ -1,40 +1,110 @@ package com.sprint.mission.discodeit.service.basic; +import com.sprint.mission.discodeit.dto.data.ChannelDto; +import com.sprint.mission.discodeit.dto.request.PrivateChannelCreateRequest; +import com.sprint.mission.discodeit.dto.request.PublicChannelCreateRequest; +import com.sprint.mission.discodeit.dto.request.PublicChannelUpdateRequest; import com.sprint.mission.discodeit.entity.Channel; +import com.sprint.mission.discodeit.entity.ChannelType; +import com.sprint.mission.discodeit.entity.Message; +import com.sprint.mission.discodeit.entity.ReadStatus; import com.sprint.mission.discodeit.repository.ChannelRepository; +import com.sprint.mission.discodeit.repository.MessageRepository; +import com.sprint.mission.discodeit.repository.ReadStatusRepository; import com.sprint.mission.discodeit.service.ChannelService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import java.time.Instant; import java.util.*; +import java.util.stream.Collectors; +@RequiredArgsConstructor +@Service public class BasicChannelService implements ChannelService { private final ChannelRepository channelRepository; + private final ReadStatusRepository readStatusRepository; + private final MessageRepository messageRepository; - public BasicChannelService(ChannelRepository channelRepository) { - this.channelRepository = channelRepository; + @Override + public Channel create(PublicChannelCreateRequest request) { + Channel channel = new Channel(ChannelType.PUBLIC, request.name(), request.description()); + return channelRepository.save(channel); } @Override - public Channel createChannel(Channel channel) { - return channelRepository.save(channel); + public Channel create(PrivateChannelCreateRequest request) { + Channel channel = new Channel(ChannelType.PRIVATE, null, null); + Channel savedChannel = channelRepository.save(channel); + + request.memberIds().forEach(userId -> { + ReadStatus readStatus = new ReadStatus(userId, savedChannel.getId(), Instant.MIN); + readStatusRepository.save(readStatus); + }); + + return savedChannel; } @Override - public Optional getChannel(UUID channelId) { - return channelRepository.findById(channelId); + public ChannelDto find(UUID channelId) { + Channel channel = channelRepository.findById(channelId) + .orElseThrow(() -> new NoSuchElementException("해당 채널을 찾을 수 없습니다.")); + return toDto(channel); } @Override - public List getAllChannels() { - return channelRepository.findAll(); + public List findAllByUserId(UUID userId) { + List joinedChannelIds = readStatusRepository.findAllByUserId(userId) + .stream().map(ReadStatus::getChannelId).toList(); + + return channelRepository.findAll().stream() + .filter(ch -> ch.getType() == ChannelType.PUBLIC || joinedChannelIds.contains(ch.getId())) + .map(this::toDto) + .collect(Collectors.toList()); } @Override - public void updateChannel(Channel channel) { - channelRepository.save(channel); + public Channel update(UUID channelId, PublicChannelUpdateRequest request) { + Channel channel = channelRepository.findById(channelId) + .orElseThrow(() -> new NoSuchElementException("해당 채널을 찾을 수 없습니다.")); + + if (channel.getType() == ChannelType.PRIVATE) { + throw new IllegalArgumentException("비공개 채널은 수정할 수 없습니다."); + } + + channel.update(request.name(), request.description()); + return channelRepository.save(channel); } @Override - public void deleteChannel(UUID channelId) { + public void delete(UUID channelId) { + Channel channel = channelRepository.findById(channelId) + .orElseThrow(() -> new NoSuchElementException("해당 채널을 찾을 수 없습니다.")); + + messageRepository.deleteAllByChannelId(channelId); + readStatusRepository.deleteAllByChannelId(channelId); channelRepository.deleteById(channelId); } + + private ChannelDto toDto(Channel channel) { + Instant latestMessageTime = messageRepository.findAllByChannelId(channel.getId()).stream() + .map(Message::getCreatedAt) + .max(Instant::compareTo) + .orElse(Instant.MIN); + + List memberIds = channel.getType() == ChannelType.PRIVATE + ? readStatusRepository.findAllByChannelId(channel.getId()).stream() + .map(ReadStatus::getUserId) + .toList() + : Collections.emptyList(); + + return new ChannelDto( + channel.getId(), + channel.getName(), + channel.getDescription(), + channel.getType(), + latestMessageTime, + memberIds + ); + } } \ No newline at end of file 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 a0367532..85ee103a 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 @@ -1,43 +1,92 @@ package com.sprint.mission.discodeit.service.basic; +import com.sprint.mission.discodeit.dto.request.BinaryContentCreateRequest; +import com.sprint.mission.discodeit.dto.request.MessageCreateRequest; +import com.sprint.mission.discodeit.dto.request.MessageUpdateRequest; +import com.sprint.mission.discodeit.entity.BinaryContent; import com.sprint.mission.discodeit.entity.Message; +import com.sprint.mission.discodeit.repository.BinaryContentRepository; +import com.sprint.mission.discodeit.repository.ChannelRepository; import com.sprint.mission.discodeit.repository.MessageRepository; +import com.sprint.mission.discodeit.repository.UserRepository; import com.sprint.mission.discodeit.service.MessageService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; -import java.util.*; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.UUID; +import java.util.stream.Collectors; +@RequiredArgsConstructor +@Service public class BasicMessageService implements MessageService { private final MessageRepository messageRepository; - - public BasicMessageService(MessageRepository messageRepository) { - this.messageRepository = messageRepository; - } + private final ChannelRepository channelRepository; + private final UserRepository userRepository; + private final BinaryContentRepository binaryContentRepository; @Override - public Message createMessage(Message message) { + public Message create(MessageCreateRequest messageCreateRequest, List binaryContentCreateRequests) { + UUID channelId = messageCreateRequest.channelId(); + UUID authorId = messageCreateRequest.authorId(); + + if (!channelRepository.existsById(channelId)) { + throw new NoSuchElementException("해당 채널이 존재하지 않습니다."); + } + if (!userRepository.existsById(authorId)) { + throw new NoSuchElementException("해당 작성자가 존재하지 않습니다."); + } + + List attachmentIds = binaryContentCreateRequests.stream() + .map(req -> { + BinaryContent binaryContent = new BinaryContent( + req.fileName(), + (long) req.data().length, + req.contentType(), + req.data() + ); + return binaryContentRepository.save(binaryContent).getId(); + }) + .collect(Collectors.toList()); + + Message message = new Message( + messageCreateRequest.content(), + channelId, + authorId, + attachmentIds + ); + return messageRepository.save(message); } @Override - public Optional getMessage(UUID messageId) { - return messageRepository.findById(messageId); + public Message find(UUID messageId) { + return messageRepository.findById(messageId) + .orElseThrow(() -> new NoSuchElementException("해당 메시지를 찾을 수 없습니다.")); } @Override - public List getAllMessages() { - return messageRepository.findAll(); + public List findAllByChannelId(UUID channelId) { + return messageRepository.findAllByChannelId(channelId); } @Override - public void updateMessage(UUID messageId, String msgContent) { - getMessage(messageId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 메시지")) - .updateMsgContent(msgContent); - getMessage(messageId).ifPresent(messageRepository::save); + public Message update(UUID messageId, MessageUpdateRequest request) { + Message message = messageRepository.findById(messageId) + .orElseThrow(() -> new NoSuchElementException("해당 메시지를 찾을 수 없습니다.")); + message.update(request.content()); + return messageRepository.save(message); } @Override - public void deleteMessage(UUID messageId) { + public void delete(UUID messageId) { + Message message = messageRepository.findById(messageId) + .orElseThrow(() -> new NoSuchElementException("해당 메시지를 찾을 수 없습니다.")); + + message.getAttachmentIds() + .forEach(binaryContentRepository::deleteById); + messageRepository.deleteById(messageId); } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicReadStatusService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicReadStatusService.java new file mode 100644 index 00000000..d8a2c47c --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicReadStatusService.java @@ -0,0 +1,71 @@ +package com.sprint.mission.discodeit.service.basic; + +import com.sprint.mission.discodeit.dto.request.ReadStatusCreateRequest; +import com.sprint.mission.discodeit.dto.request.ReadStatusUpdateRequest; +import com.sprint.mission.discodeit.entity.ReadStatus; +import com.sprint.mission.discodeit.repository.ChannelRepository; +import com.sprint.mission.discodeit.repository.ReadStatusRepository; +import com.sprint.mission.discodeit.repository.UserRepository; +import com.sprint.mission.discodeit.service.ReadStatusService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.UUID; + +@RequiredArgsConstructor +@Service +public class BasicReadStatusService implements ReadStatusService { + private final ReadStatusRepository readStatusRepository; + private final UserRepository userRepository; + private final ChannelRepository channelRepository; + + @Override + public ReadStatus create(ReadStatusCreateRequest request) { + UUID userId = request.userId(); + UUID channelId = request.channelId(); + + if (!userRepository.existsById(userId)) { + throw new NoSuchElementException("해당 사용자가 존재하지 않습니다."); + } + if (!channelRepository.existsById(channelId)) { + throw new NoSuchElementException("해당 채널이 존재하지 않습니다."); + } + boolean exists = readStatusRepository.findAllByUserId(userId).stream() + .anyMatch(rs -> rs.getChannelId().equals(channelId)); + if (exists) { + throw new IllegalArgumentException("이미 해당 사용자와 채널의 읽기 상태가 존재합니다."); + } + + ReadStatus readStatus = new ReadStatus(userId, channelId, request.lastReadAt()); + return readStatusRepository.save(readStatus); + } + + @Override + public ReadStatus find(UUID readStatusId) { + return readStatusRepository.findById(readStatusId) + .orElseThrow(() -> new NoSuchElementException("해당 읽기 상태를 찾을 수 없습니다.")); + } + + @Override + public List findAllByUserId(UUID userId) { + return readStatusRepository.findAllByUserId(userId); + } + + @Override + public ReadStatus update(UUID readStatusId, ReadStatusUpdateRequest request) { + ReadStatus readStatus = readStatusRepository.findById(readStatusId) + .orElseThrow(() -> new NoSuchElementException("해당 읽기 상태를 찾을 수 없습니다.")); + readStatus.update(request.newLastReadAt()); + return readStatusRepository.save(readStatus); + } + + @Override + public void delete(UUID readStatusId) { + if (!readStatusRepository.existsById(readStatusId)) { + throw new NoSuchElementException("해당 읽기 상태를 찾을 수 없습니다."); + } + readStatusRepository.deleteById(readStatusId); + } +} \ No newline at end of file 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 1cf258cd..eb092324 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,40 +1,139 @@ package com.sprint.mission.discodeit.service.basic; +import com.sprint.mission.discodeit.dto.data.UserDto; +import com.sprint.mission.discodeit.dto.request.BinaryContentCreateRequest; +import com.sprint.mission.discodeit.dto.request.UserCreateRequest; +import com.sprint.mission.discodeit.dto.request.UserUpdateRequest; +import com.sprint.mission.discodeit.entity.BinaryContent; import com.sprint.mission.discodeit.entity.User; +import com.sprint.mission.discodeit.entity.UserStatus; +import com.sprint.mission.discodeit.repository.BinaryContentRepository; import com.sprint.mission.discodeit.repository.UserRepository; +import com.sprint.mission.discodeit.repository.UserStatusRepository; import com.sprint.mission.discodeit.service.UserService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; -import java.util.*; +import java.time.Instant; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.UUID; +@RequiredArgsConstructor +@Service public class BasicUserService implements UserService { private final UserRepository userRepository; - - public BasicUserService(UserRepository userRepository) { - this.userRepository = userRepository; - } + private final BinaryContentRepository binaryContentRepository; + private final UserStatusRepository userStatusRepository; @Override - public User createUser(User user) { - return userRepository.save(user); + public User create(UserCreateRequest userCreateRequest, Optional profileCreateRequest) { + if (userRepository.existsByEmail(userCreateRequest.email())) { + throw new IllegalArgumentException("이미 사용 중인 이메일입니다."); + } + if (userRepository.existsByUsername(userCreateRequest.username())) { + throw new IllegalArgumentException("이미 사용 중인 사용자명입니다."); + } + + UUID profileId = profileCreateRequest + .map(request -> { + BinaryContent profile = new BinaryContent( + request.fileName(), + (long) request.data().length, + request.contentType(), + request.data() + ); + return binaryContentRepository.save(profile).getId(); + }) + .orElse(null); + + User user = new User( + userCreateRequest.username(), + userCreateRequest.email(), + userCreateRequest.password(), + profileId + ); + + User createdUser = userRepository.save(user); + userStatusRepository.save(new UserStatus(createdUser.getId(), Instant.now())); + + return createdUser; } @Override - public Optional getUser(UUID userId) { - return userRepository.findById(userId); + public UserDto find(UUID userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new NoSuchElementException("해당 ID의 사용자를 찾을 수 없습니다.")); + + Boolean online = userStatusRepository.findByUserId(userId) + .map(UserStatus::isOnline) + .orElse(null); + + return new UserDto( + user.getId(), + user.getCreatedAt(), + user.getUpdatedAt(), + user.getUsername(), + user.getEmail(), + user.getProfileId(), + online + ); } @Override - public List getAllUsers() { - return userRepository.findAll(); + public List findAll() { + return userRepository.findAll().stream() + .map(user -> { + Boolean online = userStatusRepository.findByUserId(user.getId()) + .map(UserStatus::isOnline) + .orElse(null); + return new UserDto( + user.getId(), + user.getCreatedAt(), + user.getUpdatedAt(), + user.getUsername(), + user.getEmail(), + user.getProfileId(), + online + ); + }) + .toList(); } @Override - public void updateUser(User user) { - userRepository.save(user); + public User update(UUID userId, UserUpdateRequest request, Optional profileCreateRequest) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new NoSuchElementException("해당 ID의 사용자를 찾을 수 없습니다.")); + + UUID profileId = profileCreateRequest + .map(p -> { + Optional.ofNullable(user.getProfileId()) + .ifPresent(binaryContentRepository::deleteById); + + BinaryContent newProfile = new BinaryContent( + p.fileName(), + (long) p.data().length, + p.contentType(), + p.data() + ); + return binaryContentRepository.save(newProfile).getId(); + }) + .orElse(null); + + user.update(request.username(), request.email(), request.password(), profileId); + return userRepository.save(user); } @Override - public void deleteUser(UUID userId) { + public void delete(UUID userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new NoSuchElementException("해당 ID의 사용자를 찾을 수 없습니다.")); + + Optional.ofNullable(user.getProfileId()) + .ifPresent(binaryContentRepository::deleteById); + + userStatusRepository.deleteByUserId(userId); userRepository.deleteById(userId); } } \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserStatusService.java b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserStatusService.java new file mode 100644 index 00000000..539bebcd --- /dev/null +++ b/src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserStatusService.java @@ -0,0 +1,71 @@ +package com.sprint.mission.discodeit.service.basic; + +import com.sprint.mission.discodeit.dto.request.UserStatusCreateRequest; +import com.sprint.mission.discodeit.dto.request.UserStatusUpdateRequest; +import com.sprint.mission.discodeit.entity.UserStatus; +import com.sprint.mission.discodeit.repository.UserRepository; +import com.sprint.mission.discodeit.repository.UserStatusRepository; +import com.sprint.mission.discodeit.service.UserStatusService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.UUID; + +@RequiredArgsConstructor +@Service +public class BasicUserStatusService implements UserStatusService { + private final UserStatusRepository userStatusRepository; + private final UserRepository userRepository; + + @Override + public UserStatus create(UserStatusCreateRequest request) { + UUID userId = request.userId(); + + if (!userRepository.existsById(userId)) { + throw new NoSuchElementException("해당 사용자가 존재하지 않습니다."); + } + if (userStatusRepository.findByUserId(userId).isPresent()) { + throw new IllegalArgumentException("이미 사용자 상태가 존재합니다."); + } + + UserStatus userStatus = new UserStatus(userId, request.lastOnlineAt()); + return userStatusRepository.save(userStatus); + } + + @Override + public UserStatus find(UUID userStatusId) { + return userStatusRepository.findById(userStatusId) + .orElseThrow(() -> new NoSuchElementException("해당 사용자 상태를 찾을 수 없습니다.")); + } + + @Override + public List findAll() { + return userStatusRepository.findAll(); + } + + @Override + public UserStatus update(UUID userStatusId, UserStatusUpdateRequest request) { + UserStatus userStatus = userStatusRepository.findById(userStatusId) + .orElseThrow(() -> new NoSuchElementException("해당 사용자 상태를 찾을 수 없습니다.")); + userStatus.update(request.lastOnlineAt()); + return userStatusRepository.save(userStatus); + } + + @Override + public UserStatus updateByUserId(UUID userId, UserStatusUpdateRequest request) { + UserStatus userStatus = userStatusRepository.findByUserId(userId) + .orElseThrow(() -> new NoSuchElementException("해당 사용자 상태를 찾을 수 없습니다.")); + userStatus.update(request.lastOnlineAt()); + return userStatusRepository.save(userStatus); + } + + @Override + public void delete(UUID userStatusId) { + if (!userStatusRepository.existsById(userStatusId)) { + throw new NoSuchElementException("해당 사용자 상태를 찾을 수 없습니다."); + } + userStatusRepository.deleteById(userStatusId); + } +} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/file/FileChannelService.java b/src/main/java/com/sprint/mission/discodeit/service/file/FileChannelService.java deleted file mode 100644 index 226922ec..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/file/FileChannelService.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.sprint.mission.discodeit.service.file; - -import com.sprint.mission.discodeit.entity.Channel; -import com.sprint.mission.discodeit.service.ChannelService; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; - -public class FileChannelService implements ChannelService { - private Path directory; - - private void initDirectory() { - if (!Files.exists(directory)) { - try { - Files.createDirectories(directory); - } catch (IOException e) { - throw new RuntimeException("디렉토리 생성 실패:" + e); - } - } - } - - public FileChannelService(Path directory) { - this.directory = directory; - initDirectory(); - } - - private Path resolvePath(UUID channelId) { - return directory.resolve(channelId.toString().concat(".ser")); - } - - // 저장 로직 - private void saveFile(Channel channel) { - try ( - FileOutputStream fos = new FileOutputStream(resolvePath(channel.getId()).toFile()); - ObjectOutputStream oos = new ObjectOutputStream(fos) - ) { - oos.writeObject(channel); - } catch (IOException e) { - throw new RuntimeException("채널 저장 실패: " + e); - } - } - - // 저장 로직 - private Optional loadFile(UUID channelId) { - Path path = resolvePath(channelId); - if (Files.exists(path)) { - try ( - FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - Channel loaded = (Channel) ois.readObject(); - if (!loaded.getId().equals(channelId)) { - throw new RuntimeException("파일명과 객체 ID 불일치: " + channelId + " vs " + loaded.getId()); - } - return Optional.of(loaded); - } catch (IOException | ClassNotFoundException e) { - return Optional.empty(); - } - } else { - return Optional.empty(); - } - } - - // 비즈니스 로직 - @Override - public Channel createChannel(Channel channel) { - saveFile(channel); - return channel; - } - - // 비즈니스 로직 - @Override - public Optional getChannel(UUID channelId) { - return loadFile(channelId); - } - - // 비즈니스 로직 - @Override - public List getAllChannels() { - if (Files.exists(directory)) { - try { - return Files.list(directory) - .filter(path -> path.toString().endsWith(".ser")) - .map(path -> { - try ( - FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - return (Channel) ois.readObject(); - } catch (IOException | ClassNotFoundException e) { - throw new RuntimeException("채널 파일 로딩 실패: " + path, e); - } - }) - .filter(Objects::nonNull) - .toList(); - } catch (IOException e) { - throw new RuntimeException("채널 전체 조회 실패", e); - } - } else { - return new ArrayList<>(); - } - } - - // 비즈니스 로직 - @Override - public void updateChannel(Channel channel) { - saveFile(channel); - } - - // 비즈니스 로직 - @Override - public void deleteChannel(UUID channelId) { - try { - Files.deleteIfExists(resolvePath(channelId)); - } catch (IOException e) { - throw new RuntimeException("채널 삭제 실패: " + channelId, e); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/file/FileMessageService.java b/src/main/java/com/sprint/mission/discodeit/service/file/FileMessageService.java deleted file mode 100644 index 703d351b..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/file/FileMessageService.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.sprint.mission.discodeit.service.file; - -import com.sprint.mission.discodeit.entity.Message; -import com.sprint.mission.discodeit.entity.User; -import com.sprint.mission.discodeit.service.MessageService; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; - -public class FileMessageService implements MessageService { - private Path directory; - - private void initDirectory() { - try { - if (!Files.exists(directory)) { - Files.createDirectories(directory); - } - } catch (IOException e) { - throw new RuntimeException("디렉토리 생성 실패: ", e); - } - } - - public FileMessageService(Path directory) { - this.directory = directory; - initDirectory(); - } - - private Path resolvePath(UUID messageId) { - return directory.resolve(messageId.toString().concat(".ser")); - } - - // 저장 로직 - private void saveFile(Message message) { - try ( - FileOutputStream fos = new FileOutputStream(resolvePath(message.getId()).toFile()); - ObjectOutputStream oos = new ObjectOutputStream(fos) - ) { - oos.writeObject(message); - } catch (IOException e) { - throw new RuntimeException("메시지 저장 실패: " + e); - } - } - - // 저장 로직 - private Optional loadFile(UUID messageId) { - if (Files.exists(resolvePath(messageId))) { - try ( - FileInputStream fis = new FileInputStream(resolvePath(messageId).toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - return Optional.of((Message) ois.readObject()); - } catch (IOException | ClassNotFoundException e) { - return Optional.empty(); - } - } else { - return Optional.empty(); - } - } - - // 비즈니스 로직 - @Override - public Message createMessage(Message message) { - saveFile(message); - return message; - } - - // 비즈니스 로직 - @Override - public Optional getMessage(UUID messageId) { - return loadFile(messageId); - } - - // 비즈니스 로직 - @Override - public List getAllMessages() { - if (Files.exists(directory)) { - try { - return Files.list(directory) - .filter(path -> path.toString().endsWith(".ser")) - .map(path -> { - try ( - FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - return (Message) ois.readObject(); - } catch (IOException | ClassNotFoundException e) { - throw new RuntimeException("메시지 파일 로딩 실패: " + path, e); - } - }) - .filter(Objects::nonNull) - .toList(); - } catch (IOException e) { - throw new RuntimeException("메시지 전체 조회 실패", e); - } - } else { - return new ArrayList<>(); - } - } - - // 비즈니스 로직 - @Override - public void updateMessage(UUID messageId, String msgContent) { - getMessage(messageId).ifPresent(m -> { - m.updateMsgContent(msgContent); - saveFile(m); - }); - } - - // 비즈니스 로직 - @Override - public void deleteMessage(UUID messageId) { - try { - Files.deleteIfExists(resolvePath(messageId)); - } catch (IOException e) { - throw new RuntimeException("메시지 삭제 실패: " + messageId, e); - } - } -} diff --git a/src/main/java/com/sprint/mission/discodeit/service/file/FileUserService.java b/src/main/java/com/sprint/mission/discodeit/service/file/FileUserService.java deleted file mode 100644 index 8f4815f9..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/file/FileUserService.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.sprint.mission.discodeit.service.file; - -import com.sprint.mission.discodeit.entity.User; -import com.sprint.mission.discodeit.service.UserService; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; - -public class FileUserService implements UserService { - private Path directory; - - private void initDirectory() { - if (!Files.exists(directory)) { - try { - Files.createDirectories(directory); - } catch (IOException e) { - throw new RuntimeException("디렉토리 생성 실패: " + e); - } - } - } - - public FileUserService(Path directory) { - this.directory = directory; - initDirectory(); - } - - private Path resolvePath(UUID userId) { - return directory.resolve(userId.toString().concat(".ser")); - } - - // 저장 로직 - private void saveFile(User user) { - try ( - FileOutputStream fos = new FileOutputStream(resolvePath(user.getId()).toFile()); - ObjectOutputStream oos = new ObjectOutputStream(fos); - ) { - oos.writeObject(user); - } catch (IOException e) { - throw new RuntimeException("유저 저장 실패: " + e); - } - } - - // 저장 로직 - private Optional loadFile(UUID userId) { - if (Files.exists(resolvePath(userId))) { - try ( - FileInputStream fis = new FileInputStream(resolvePath(userId).toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - return Optional.of((User) ois.readObject()); - } catch (IOException | ClassNotFoundException e) { - return Optional.empty(); - } - } else { - return Optional.empty(); - } - } - - // 비즈니스 로직 - @Override - public User createUser(User user) { - saveFile(user); - return user; - } - - // 비즈니스 로직 - @Override - public Optional getUser(UUID userId) { - return loadFile(userId); - } - - // 비즈니스 로직 - @Override - public List getAllUsers() { - if (Files.exists(directory)) { - try { - return Files.list(directory) - .filter(path -> path.toString().endsWith(".ser")) - .map(path -> { - try ( - FileInputStream fis = new FileInputStream(path.toFile()); - ObjectInputStream ois = new ObjectInputStream(fis) - ) { - return (User) ois.readObject(); - } catch (IOException | ClassNotFoundException e) { - throw new RuntimeException("유저 파일 로딩 실패: " + path, e); - } - }) - .filter(Objects::nonNull) - .toList(); - } catch (IOException e) { - throw new RuntimeException("유저 전체 조회 실패", e); - } - } else { - return new ArrayList<>(); - } - } - - // 비즈니스 로직 - @Override - public void updateUser(User user) { - saveFile(user); - } - - // 비즈니스 로직 - @Override - public void deleteUser(UUID userId) { - try { - Files.deleteIfExists(resolvePath(userId)); - } catch (IOException e) { - throw new RuntimeException("유저 삭제 실패: " + userId, e); - } - } -} diff --git a/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFChannelService.java b/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFChannelService.java deleted file mode 100644 index d465c5ba..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFChannelService.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.sprint.mission.discodeit.service.jcf; - -import com.sprint.mission.discodeit.entity.Channel; -import com.sprint.mission.discodeit.service.ChannelService; - -import java.util.*; - -public class JCFChannelService implements ChannelService { - // 저장 로직 - private final Map data = new HashMap<>(); - - @Override - public Channel createChannel(Channel channel) { - // 저장 로직 - data.put(channel.getId(), channel); - return channel; - } - - @Override - public Optional getChannel(UUID channelId) { - // 저장 로직 - return Optional.ofNullable(data.get(channelId)); - } - - @Override - public List getAllChannels() { - // 저장 로직 - return new ArrayList<>(data.values()); - } - - @Override - public void updateChannel(Channel channel) { - // 저장 로직 - data.put(channel.getId(), channel); - } - - @Override - public void deleteChannel(UUID channelId) { - // 저장 로직 - data.remove(channelId); - } -} diff --git a/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFMessageService.java b/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFMessageService.java deleted file mode 100644 index fb242f2b..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFMessageService.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.sprint.mission.discodeit.service.jcf; - -import com.sprint.mission.discodeit.entity.Message; -import com.sprint.mission.discodeit.service.MessageService; - -import java.util.*; - -public class JCFMessageService implements MessageService { - // 저장 로직 - private final Map data = new HashMap<>(); - - @Override - public Message createMessage(Message message) { - // 저장 로직 - data.put(message.getId(), message); - return message; - } - - @Override - public Optional getMessage(UUID messageId) { - // 저장 로직 - return Optional.ofNullable(data.get(messageId)); - } - - @Override - public List getAllMessages() { - // 저장 로직 - return new ArrayList<>(data.values()); - } - - // update 실패 시 피드백 출력 - @Override - public void updateMessage(UUID messageId, String message) { - // 비즈니스 로직 + 저장 로직 - getMessage(messageId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 메시지")) - .updateMsgContent(message); - } - - @Override - public void deleteMessage(UUID messageId) { - // 저장 로직 - data.remove(messageId); - } -} diff --git a/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFUserService.java b/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFUserService.java deleted file mode 100644 index 047c4d8a..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/jcf/JCFUserService.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.sprint.mission.discodeit.service.jcf; - -import com.sprint.mission.discodeit.entity.User; -import com.sprint.mission.discodeit.service.UserService; - -import java.util.*; - -public class JCFUserService implements UserService { - // 저장 로직 - private final Map data = new HashMap<>(); - - @Override - public User createUser(User user) { - // 저장 로직 - data.put(user.getId(), user); - return user; - } - - @Override - public Optional getUser(UUID userId) { - // 저장 로직 - return Optional.ofNullable(data.get(userId)); - } - - @Override - public List getAllUsers() { - // 저장 로직 - return new ArrayList<>(data.values()); - } - - @Override - public void updateUser(User user) { - // 저장 로직 - data.put(user.getId(), user); - } - - @Override - public void deleteUser(UUID userId) { - // 저장 로직 - data.remove(userId); - } -} \ No newline at end of file diff --git a/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/ChannelIntegration.java b/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/ChannelIntegration.java deleted file mode 100644 index 9b45d8fa..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/ChannelIntegration.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.sprint.mission.discodeit.service.jcf.integration; - -import com.sprint.mission.discodeit.entity.Channel; -import com.sprint.mission.discodeit.entity.User; -import com.sprint.mission.discodeit.service.ChannelService; -import com.sprint.mission.discodeit.service.MessageService; -import com.sprint.mission.discodeit.service.UserService; - -import java.util.UUID; - -public class ChannelIntegration { - private final ChannelService channelService; - private final UserService userService; - private final MessageService messageService; - - public ChannelIntegration(ChannelService channelService, UserService userService, MessageService messageService) { - this.channelService = channelService; - this.userService = userService; - this.messageService = messageService; - } - - // 비즈니스 로직: 채널에 사용자 추가 - public void addUserToChannel(UUID channelId, UUID userId) { - Channel channel = channelService.getChannel(channelId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 채널")); - - User user = userService.getUser(userId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저")); - - user.addChannel(channelId); - channel.addUser(userId); - - userService.updateUser(user); - channelService.updateChannel(channel); - } - - // 비즈니스 로직 - public void deleteChannel(UUID channelId) { - Channel channel = channelService.getChannel(channelId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 채널")); - - for (UUID messageId : channel.getMessageIds()) { - messageService.deleteMessage(messageId); - } - - for (UUID userId : channel.getUserIds()) { - userService.getUser(userId).ifPresent(user -> { - user.getChannelIds().remove(channelId); - userService.updateUser(user); - }); - } - - channelService.deleteChannel(channelId); - } -} diff --git a/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/MessageIntegration.java b/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/MessageIntegration.java deleted file mode 100644 index 1e385184..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/MessageIntegration.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.sprint.mission.discodeit.service.jcf.integration; - -import com.sprint.mission.discodeit.entity.Channel; -import com.sprint.mission.discodeit.entity.Message; -import com.sprint.mission.discodeit.service.ChannelService; -import com.sprint.mission.discodeit.service.MessageService; -import com.sprint.mission.discodeit.service.UserService; - -import java.util.UUID; - -public class MessageIntegration { - private final MessageService messageService; - private final UserService userService; - private final ChannelService channelService; - - public MessageIntegration(MessageService messageService, UserService userService, ChannelService channelService) { - this.messageService = messageService; - this.userService = userService; - this.channelService = channelService; - } - - // 비즈니스 로직 - public Message createMessage(String msgContent, UUID senderId, UUID channelId) { - userService.getUser(senderId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저")); - - Channel channel = channelService.getChannel(channelId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 채널")); - - if (!channel.getUserIds().contains(senderId)) { - throw new SecurityException("채널에 속해있지 않은 유저"); - } - - Message message = new Message(msgContent, senderId, channelId); - Message created = messageService.createMessage(message); - - channel.addMessage(created.getId()); - channelService.updateChannel(channel); - - return created; - } - - // 비즈니스 로직 - public void deleteMessage(UUID messageId) { - Message message = messageService.getMessage(messageId) - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 메시지")); - - channelService.getChannel(message.getChannelId()).ifPresent(channel -> { - channel.getMessageIds().remove(messageId); - channelService.updateChannel(channel); - }); - - messageService.deleteMessage(messageId); - } -} diff --git a/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/UserIntegration.java b/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/UserIntegration.java deleted file mode 100644 index 55c7db45..00000000 --- a/src/main/java/com/sprint/mission/discodeit/service/jcf/integration/UserIntegration.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sprint.mission.discodeit.service.jcf.integration; - -import com.sprint.mission.discodeit.service.ChannelService; -import com.sprint.mission.discodeit.service.UserService; - -import java.util.UUID; - -public class UserIntegration { - private final UserService userService; - private final ChannelService channelService; - - public UserIntegration(UserService userService, ChannelService channelService) { - this.userService = userService; - this.channelService = channelService; - } - - // 비즈니스 로직 - public void deleteUser(UUID userId) { - userService.deleteUser(userId); - channelService.getAllChannels().forEach(channel -> { - if (channel.getUserIds().remove(userId)) { - channelService.updateChannel(channel); - } - }); - } -} \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 00000000..083530bc --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,8 @@ +spring: + application: + name: discodeit + +discodeit: + repository: + type: jcf # jcf | file + file-directory: .discodeit \ No newline at end of file diff --git a/src/test/java/com/sprint/mission/discodeit/DiscodeitApplicationTests.java b/src/test/java/com/sprint/mission/discodeit/DiscodeitApplicationTests.java new file mode 100644 index 00000000..3a987a21 --- /dev/null +++ b/src/test/java/com/sprint/mission/discodeit/DiscodeitApplicationTests.java @@ -0,0 +1,13 @@ +package com.sprint.mission.discodeit; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class DiscodeitApplicationTests { + + @Test + void contextLoads() { + } + +}