diff --git a/.gitignore b/.gitignore
index 1ad9c4d..610082a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -108,4 +108,6 @@ hs_err_pid*
# mac
.DS_Store
-src/main/resources/application.yml
+.idea/workspace.xml
+.idea/workspace.xml
+.idea/workspace.xml
diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml
new file mode 100644
index 0000000..f7cf746
--- /dev/null
+++ b/.idea/dataSources.local.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ #@
+ `
+ true
+
+
+ master_key
+ root
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index d8d6635..b86ed64 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,6 @@
plugins {
id 'java'
+ id 'war'
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.4'
}
@@ -34,6 +35,10 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
+ implementation 'org.springframework.boot:spring-boot-starter-websocket'
+ implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
+ implementation 'com.amazonaws:aws-java-sdk-s3:1.12.265'
+ implementation 'software.amazon.ion:ion-java:1.0.3'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
@@ -41,6 +46,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+ providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
}
tasks.named('test') {
diff --git a/src/main/java/meltingpot/server/ServerApplication.java b/src/main/java/meltingpot/server/ServerApplication.java
index 56b5843..48816d5 100644
--- a/src/main/java/meltingpot/server/ServerApplication.java
+++ b/src/main/java/meltingpot/server/ServerApplication.java
@@ -2,11 +2,18 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@SpringBootApplication
@EnableJpaAuditing
-public class ServerApplication {
+public class ServerApplication extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(ServerApplication.class);
+ }
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
diff --git a/src/main/java/meltingpot/server/chat/controller/ChatController.java b/src/main/java/meltingpot/server/chat/controller/ChatController.java
new file mode 100644
index 0000000..874670b
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/controller/ChatController.java
@@ -0,0 +1,26 @@
+package meltingpot.server.chat.controller;
+
+import lombok.RequiredArgsConstructor;
+import meltingpot.server.chat.dto.ChatMessageCreateResponse;
+import meltingpot.server.chat.dto.ChatMessageCreateRequest;
+import meltingpot.server.chat.service.ChatService;
+import org.springframework.messaging.handler.annotation.DestinationVariable;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.handler.annotation.Payload;
+import org.springframework.messaging.handler.annotation.SendTo;
+import org.springframework.stereotype.Controller;
+
+@Controller
+@RequiredArgsConstructor
+public class ChatController {
+ private final ChatService chatService;
+
+ @MessageMapping("/chat/rooms/{chatRoomId}/send") // <- 해당 경로로 들어오면 메서드 호출
+ @SendTo("/topic/public/rooms/{chatRoomId}") // 구독 중인 장소로 메세지 전달
+ public ChatMessageCreateResponse sendMessage(
+ @DestinationVariable Long chatRoomId,
+ @Payload ChatMessageCreateRequest request) {
+ ChatMessageCreateResponse response = chatService.createChatMessage(chatRoomId, request);
+ return response;
+ }
+}
diff --git a/src/main/java/meltingpot/server/chat/controller/ChatRoomController.java b/src/main/java/meltingpot/server/chat/controller/ChatRoomController.java
new file mode 100644
index 0000000..5d4a1b2
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/controller/ChatRoomController.java
@@ -0,0 +1,82 @@
+package meltingpot.server.chat.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import lombok.RequiredArgsConstructor;
+import meltingpot.server.chat.dto.*;
+import meltingpot.server.chat.service.ChatRoomQueryService;
+import meltingpot.server.chat.service.ChatRoomService;
+import meltingpot.server.util.PageResponse;
+import meltingpot.server.util.ResponseData;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+import static meltingpot.server.util.ResponseCode.SIGNIN_SUCCESS;
+
+@RestController
+@RequestMapping("/api/v1/chatRooms")
+@RequiredArgsConstructor
+public class ChatRoomController {
+ private final ChatRoomQueryService chatRoomQueryService;
+ private final ChatRoomService chatRoomService;
+
+ // [CHECK] /{userId}, PageResponse, param
+ @GetMapping("/{userId}")
+ @Operation(summary = "채팅방 전체 목록 조회")
+ @ApiResponse(responseCode = "100", description = "요청에 성공하였습니다.", content = @Content(mediaType = "application/json"))
+ @Parameter(name = "userId", description = "사용자 ID", required = true, example = "1")
+ public ResponseEntity>>> getChatRooms(
+ @PathVariable Long userId,
+ @RequestParam(defaultValue = "0") int page,
+ @RequestParam(defaultValue = "5") int size
+ ) {
+ return ResponseData.toResponseEntity(SIGNIN_SUCCESS, chatRoomQueryService.getChatRooms());
+ }
+
+ // [CHECK] /{userId}
+ @PatchMapping("/alarm/{chatRoomId}/{userId}")
+ @Operation(summary = "채팅방 알람 설정 변경")
+ @ApiResponse(responseCode = "1000", description = "요청에 성공하였습니다.", content = @Content(mediaType = "application/json"))
+ @Parameters({
+ @Parameter(name = "chatRoomId", description = "채팅룸 ID", required = true, example = "1"),
+ @Parameter(name = "userId", description = "사용자 ID", required = true, example = "1")
+ })
+ public ResponseEntity updateAlarmStatus(
+ @PathVariable Long userId,
+ @PathVariable Long chatRoomId
+ ) {
+ chatRoomService.updateAlarmStatus(userId, chatRoomId);
+ return ResponseData.toResponseEntity(SIGNIN_SUCCESS);
+ }
+
+ // [CHECK] PageResponse
+ @GetMapping("{chatRoomId}")
+ @Operation(summary = "채팅방 채팅 내역 조회")
+ @ApiResponse(responseCode = "1000", description = "요청에 성공하였습니다.", content = @Content(mediaType = "application/json"))
+ @Parameter(name = "chatRoomId", description = "채팅룸 ID", required = true, example = "1")
+ public ResponseEntity>>> getChatMessage(
+ @PathVariable Long chatRoomId,
+ @RequestParam(defaultValue = "0") int page,
+ @RequestParam(defaultValue = "5") int size
+ ) {
+ ChatMessageListQuery query = ChatMessageListQuery.builder()
+ .chatRoomId(chatRoomId)
+ .page(page)
+ .size(size)
+ .build();
+ return ResponseData.toResponseEntity(SIGNIN_SUCCESS, chatRoomQueryService.getChatMessage(query));
+ }
+
+ @GetMapping("{chatRoomId}/detail")
+ @Operation(summary = "채팅방 상단")
+ @ApiResponse(responseCode = "1000", description = "요청에 성공하였습니다.", content = @Content(mediaType = "application/json"))
+ @Parameter(description = "채팅룸 ID", required = true, example = "1")
+ public ResponseEntity> getChatRoomDetail(@PathVariable Long chatRoomId) {
+ return ResponseData.toResponseEntity(SIGNIN_SUCCESS, chatRoomQueryService.getRoomDetail(chatRoomId));
+ }
+}
diff --git a/src/main/java/meltingpot/server/chat/dto/ChatMessageCreateRequest.java b/src/main/java/meltingpot/server/chat/dto/ChatMessageCreateRequest.java
new file mode 100644
index 0000000..031955a
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/dto/ChatMessageCreateRequest.java
@@ -0,0 +1,8 @@
+package meltingpot.server.chat.dto;
+
+public record ChatMessageCreateRequest(
+ Long userId,
+ String content,
+ Long chatRoomId
+) {
+}
diff --git a/src/main/java/meltingpot/server/chat/dto/ChatMessageCreateResponse.java b/src/main/java/meltingpot/server/chat/dto/ChatMessageCreateResponse.java
new file mode 100644
index 0000000..9943957
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/dto/ChatMessageCreateResponse.java
@@ -0,0 +1,9 @@
+package meltingpot.server.chat.dto;
+
+import lombok.Builder;
+
+@Builder
+public record ChatMessageCreateResponse(
+ Long chatId
+) {
+}
diff --git a/src/main/java/meltingpot/server/chat/dto/ChatMessageGetResponse.java b/src/main/java/meltingpot/server/chat/dto/ChatMessageGetResponse.java
new file mode 100644
index 0000000..dd7d69a
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/dto/ChatMessageGetResponse.java
@@ -0,0 +1,19 @@
+package meltingpot.server.chat.dto;
+
+import meltingpot.server.domain.entity.chat.ChatMessage;
+import meltingpot.server.domain.entity.chat.enums.Role;
+import org.springframework.data.domain.Slice;
+
+public record ChatMessageGetResponse(
+ Long chatId,
+ String content,
+ Role role
+) {
+ public static ChatMessageGetResponse from(ChatMessage chatMessage) {
+ return new ChatMessageGetResponse(
+ chatMessage.getId(),
+ chatMessage.getContent(),
+ chatMessage.getRole()
+ );
+ }
+}
diff --git a/src/main/java/meltingpot/server/chat/dto/ChatMessageListQuery.java b/src/main/java/meltingpot/server/chat/dto/ChatMessageListQuery.java
new file mode 100644
index 0000000..2df5d93
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/dto/ChatMessageListQuery.java
@@ -0,0 +1,11 @@
+package meltingpot.server.chat.dto;
+
+import lombok.Builder;
+
+@Builder
+public record ChatMessageListQuery(
+ Long chatRoomId,
+ int page,
+ int size
+) {
+}
diff --git a/src/main/java/meltingpot/server/chat/dto/ChatRoomAlarmUpdateResponse.java b/src/main/java/meltingpot/server/chat/dto/ChatRoomAlarmUpdateResponse.java
new file mode 100644
index 0000000..2892e00
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/dto/ChatRoomAlarmUpdateResponse.java
@@ -0,0 +1,6 @@
+package meltingpot.server.chat.dto;
+
+public record ChatRoomAlarmUpdateResponse(
+ String status
+) {
+}
diff --git a/src/main/java/meltingpot/server/chat/dto/ChatRoomDetailGetResponse.java b/src/main/java/meltingpot/server/chat/dto/ChatRoomDetailGetResponse.java
new file mode 100644
index 0000000..fd9c88d
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/dto/ChatRoomDetailGetResponse.java
@@ -0,0 +1,19 @@
+package meltingpot.server.chat.dto;
+
+import meltingpot.server.domain.entity.party.Party;
+
+public record ChatRoomDetailGetResponse(
+ String imageKey,
+ String title,
+ Integer userCnt
+) {
+ public static ChatRoomDetailGetResponse of(Party party, int userCnt) {
+ return new ChatRoomDetailGetResponse(
+ // [CHECK] 프로필 이미지
+ // party.getUser().getProfileImages(),
+ "",
+ party.getPartySubject(),
+ userCnt
+ );
+ }
+}
diff --git a/src/main/java/meltingpot/server/chat/dto/ChatRoomsGetResponse.java b/src/main/java/meltingpot/server/chat/dto/ChatRoomsGetResponse.java
new file mode 100644
index 0000000..60bb368
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/dto/ChatRoomsGetResponse.java
@@ -0,0 +1,32 @@
+package meltingpot.server.chat.dto;
+
+import meltingpot.server.domain.entity.party.Party;
+
+import java.time.LocalDateTime;
+
+public record ChatRoomsGetResponse(
+ Long chatRoomId,
+ String leaderName,
+ String imageKey,
+ String partySubject,
+ String partyStatus,
+ String partyLocationAddress,
+ LocalDateTime partyStartTime,
+ int userCnt,
+ int messageCnt
+) {
+ // [CHECK] 유저 프로필 이미지
+ public static ChatRoomsGetResponse of(Party party, int userCnt, int messageCnt) {
+// return new ChatRoomsGetResponse(
+// party.getChatRoom().getId(),
+// party.getUser().getUsername(),
+// party.getUser().getProfileImages(),
+// party.getPartySubject(),
+// party.getPartyLocationAddress(),
+// party.getPartyStartTime(),
+// userCnt,
+// messageCnt
+// );
+ return null;
+ }
+}
diff --git a/src/main/java/meltingpot/server/chat/service/ChatRoomQueryService.java b/src/main/java/meltingpot/server/chat/service/ChatRoomQueryService.java
new file mode 100644
index 0000000..7dbe8be
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/service/ChatRoomQueryService.java
@@ -0,0 +1,51 @@
+package meltingpot.server.chat.service;
+
+import lombok.RequiredArgsConstructor;
+import meltingpot.server.chat.dto.ChatMessageGetResponse;
+import meltingpot.server.chat.dto.ChatMessageListQuery;
+import meltingpot.server.chat.dto.ChatRoomDetailGetResponse;
+import meltingpot.server.chat.dto.ChatRoomsGetResponse;
+import meltingpot.server.domain.entity.chat.ChatRoom;
+import meltingpot.server.domain.entity.party.Party;
+import meltingpot.server.domain.repository.chat.ChatMessageRepository;
+import meltingpot.server.domain.repository.chat.ChatRoomRepository;
+import meltingpot.server.domain.repository.chat.ChatRoomUserRepository;
+import meltingpot.server.domain.repository.party.PartyRepository;
+import meltingpot.server.util.PageResponse;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional(readOnly = true)
+@RequiredArgsConstructor
+public class ChatRoomQueryService {
+ private final ChatRoomUserRepository chatRoomUserRepository;
+ private final ChatRoomRepository chatRoomRepository;
+ private final ChatMessageRepository chatMessageRepository;
+ private final PartyRepository partyRepository;
+
+ public ChatRoomDetailGetResponse getRoomDetail(Long chatRoomId) {
+ Party party = partyRepository.findByChatRoomId(chatRoomId);
+ return ChatRoomDetailGetResponse.of(party, chatRoomUserRepository.countChatRoomUsersByChatRoomId(chatRoomId));
+ }
+
+ // [CHECK]
+ public PageResponse> getChatMessage(ChatMessageListQuery query) {
+ ChatRoom chatRoom = chatRoomRepository.findById(query.chatRoomId())
+ .orElseThrow(() -> new IllegalArgumentException("ChatRoom not found"));
+ PageRequest pageRequest = PageRequest.of(query.page(), query.size(), Sort.by("chatMessageId").descending());
+ List chatMessages = chatMessageRepository.findAllByChatRoom(chatRoom, pageRequest)
+ .stream().map(ChatMessageGetResponse::from).toList();
+
+ // return PageResponse.of(chatMessages, pageRequest);
+ return null;
+ }
+
+ public PageResponse> getChatRooms() {
+ return null;
+ }
+}
diff --git a/src/main/java/meltingpot/server/chat/service/ChatRoomService.java b/src/main/java/meltingpot/server/chat/service/ChatRoomService.java
new file mode 100644
index 0000000..f70419b
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/service/ChatRoomService.java
@@ -0,0 +1,21 @@
+package meltingpot.server.chat.service;
+
+import lombok.RequiredArgsConstructor;
+import meltingpot.server.domain.entity.chat.ChatRoomUser;
+import meltingpot.server.domain.repository.chat.ChatRoomUserRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional
+@RequiredArgsConstructor
+public class ChatRoomService {
+ private final ChatRoomUserRepository chatRoomUserRepository;
+
+ public void updateAlarmStatus(Long userId, Long chatRoomId) {
+ ChatRoomUser chatRoomUser = chatRoomUserRepository.findChatRoomUserByUserIdAndChatRoomId(userId, chatRoomId)
+ .orElseThrow(() -> new IllegalArgumentException("ChatRoomUser not found"));
+ chatRoomUser.toggleAlarm();
+ chatRoomUserRepository.save(chatRoomUser);
+ }
+}
diff --git a/src/main/java/meltingpot/server/chat/service/ChatService.java b/src/main/java/meltingpot/server/chat/service/ChatService.java
new file mode 100644
index 0000000..7b754eb
--- /dev/null
+++ b/src/main/java/meltingpot/server/chat/service/ChatService.java
@@ -0,0 +1,43 @@
+package meltingpot.server.chat.service;
+
+import lombok.RequiredArgsConstructor;
+import meltingpot.server.chat.dto.ChatMessageCreateRequest;
+import meltingpot.server.chat.dto.ChatMessageCreateResponse;
+import meltingpot.server.domain.entity.chat.ChatMessage;
+import meltingpot.server.domain.entity.chat.ChatRoom;
+import meltingpot.server.domain.entity.chat.enums.Role;
+import meltingpot.server.domain.repository.chat.ChatMessageRepository;
+import meltingpot.server.domain.repository.chat.ChatRoomRepository;
+import meltingpot.server.domain.repository.party.PartyRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional(readOnly = true)
+@RequiredArgsConstructor
+public class ChatService {
+ private final ChatMessageRepository chatMessageRepository;
+ private final ChatRoomRepository chatRoomRepository;
+ private final PartyRepository partyRepository;
+
+ @Transactional
+ public ChatMessageCreateResponse createChatMessage(Long chatRoomId, ChatMessageCreateRequest request) {
+ ChatRoom chatRoom = chatRoomRepository.findById(chatRoomId)
+ .orElseThrow(() -> new IllegalArgumentException("error"));
+
+
+ Role role = (partyRepository.findByChatRoomId(chatRoomId).getAccount().getId().equals(request.userId()))
+ ? Role.LEADER
+ : Role.MEMBER;
+
+ ChatMessage newChatMessage = ChatMessage.builder()
+ .chatRoom(chatRoom)
+ .content(request.content())
+ .userId(request.userId())
+ .role(role)
+ .build();
+
+ ChatMessage chatMessageEntity = chatMessageRepository.save(newChatMessage);
+ return new ChatMessageCreateResponse(chatMessageEntity.getId());
+ }
+}
diff --git a/src/main/java/meltingpot/server/config/AmazonConfig.java b/src/main/java/meltingpot/server/config/AmazonConfig.java
new file mode 100644
index 0000000..8bf803c
--- /dev/null
+++ b/src/main/java/meltingpot/server/config/AmazonConfig.java
@@ -0,0 +1,52 @@
+package meltingpot.server.config;
+
+import com.amazonaws.auth.*;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3ClientBuilder;
+import jakarta.annotation.PostConstruct;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@Getter
+public class AmazonConfig {
+
+ private AWSCredentials awsCredentials;
+
+ @Value("${cloud.aws.credentials.accessKey}")
+ private String accessKey;
+
+ @Value("${cloud.aws.credentials.secretKey}")
+ private String secretKey;
+
+ @Value("${cloud.aws.region.static}")
+ private String region;
+
+ @Value("${cloud.aws.s3.bucket}")
+ private String bucket;
+
+ @Value("${cloud.aws.s3.path.post}")
+ private String postPath;
+
+ @PostConstruct
+ public void init() {
+ this.awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
+ }
+
+ @Bean
+ public AmazonS3 amazonS3() {
+ AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
+ return AmazonS3ClientBuilder.standard()
+ .withRegion(region)
+ .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
+ .build();
+ }
+
+ @Bean
+ public AWSCredentialsProvider awsCredentialsProvider() {
+ return new AWSStaticCredentialsProvider(awsCredentials);
+ }
+}
+
diff --git a/src/main/java/meltingpot/server/config/WebSocketConfig.java b/src/main/java/meltingpot/server/config/WebSocketConfig.java
new file mode 100644
index 0000000..e18d762
--- /dev/null
+++ b/src/main/java/meltingpot/server/config/WebSocketConfig.java
@@ -0,0 +1,26 @@
+package meltingpot.server.config;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+@Configuration
+@RequiredArgsConstructor
+@EnableWebSocketMessageBroker
+public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry registry) {
+ registry.setApplicationDestinationPrefixes("/app"); // 클라이언트에서 보낸 메세지를 받을 prefix
+ registry.enableSimpleBroker("/topic"); // 해당 주소를 구독하고 있는 클라이언트들에게 메세지 전달
+ }
+
+ @Override
+ public void registerStompEndpoints(StompEndpointRegistry registry) {
+ // 주소 : ws://localhost:8080/chat
+ registry.addEndpoint("/chat") // socket 연결 url
+ .setAllowedOriginPatterns("*"); // CORS 허용 범위
+ }
+}
diff --git a/src/main/java/meltingpot/server/domain/entity/AccountProfileImage.java b/src/main/java/meltingpot/server/domain/entity/AccountProfileImage.java
index bdbf7a3..e451a94 100644
--- a/src/main/java/meltingpot/server/domain/entity/AccountProfileImage.java
+++ b/src/main/java/meltingpot/server/domain/entity/AccountProfileImage.java
@@ -36,4 +36,4 @@ public class AccountProfileImage {
@JoinColumn(name = "account_id")
private Account account;
-}
+}
\ No newline at end of file
diff --git a/src/main/java/meltingpot/server/domain/entity/Post.java b/src/main/java/meltingpot/server/domain/entity/Post.java
index a0b355a..e4929fb 100644
--- a/src/main/java/meltingpot/server/domain/entity/Post.java
+++ b/src/main/java/meltingpot/server/domain/entity/Post.java
@@ -4,7 +4,7 @@
import jakarta.persistence.*;
import lombok.*;
import meltingpot.server.domain.entity.common.BaseEntity;
-import meltingpot.server.domain.entity.enums.Type;
+import meltingpot.server.domain.entity.enums.PostType;
import java.util.ArrayList;
import java.util.List;
@@ -15,6 +15,7 @@
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@Getter
+@Setter
public class Post extends BaseEntity {
@Id
@@ -27,7 +28,7 @@ public class Post extends BaseEntity {
private String content;
@Enumerated(EnumType.STRING)
- private Type type;
+ private PostType postType;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
@@ -36,10 +37,11 @@ public class Post extends BaseEntity {
@OneToMany(mappedBy = "post")
private List comments = new ArrayList<>();
- @OneToMany(mappedBy = "post")
- private List Images = new ArrayList<>();
+ @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
+ private List postImages = new ArrayList<>();
@OneToMany(mappedBy = "post")
private List reports = new ArrayList<>();
-}
+
+ }
diff --git a/src/main/java/meltingpot/server/domain/entity/Image.java b/src/main/java/meltingpot/server/domain/entity/PostImage.java
similarity index 89%
rename from src/main/java/meltingpot/server/domain/entity/Image.java
rename to src/main/java/meltingpot/server/domain/entity/PostImage.java
index b7b297a..2039d6c 100644
--- a/src/main/java/meltingpot/server/domain/entity/Image.java
+++ b/src/main/java/meltingpot/server/domain/entity/PostImage.java
@@ -9,7 +9,7 @@
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@Getter
-public class Image extends BaseEntity {
+public class PostImage extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -17,7 +17,7 @@ public class Image extends BaseEntity {
private Long id;
@Column(name = "image_url")
- private String imageURl;
+ private String imageUrl;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
diff --git a/src/main/java/meltingpot/server/domain/entity/chat/ChatMessage.java b/src/main/java/meltingpot/server/domain/entity/chat/ChatMessage.java
new file mode 100644
index 0000000..cacec9d
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/entity/chat/ChatMessage.java
@@ -0,0 +1,37 @@
+package meltingpot.server.domain.entity.chat;
+
+import jakarta.persistence.*;
+import lombok.*;
+import meltingpot.server.domain.entity.chat.enums.Role;
+import org.springframework.data.annotation.CreatedDate;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Getter
+@Builder
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+@Table(name = "chat_message")
+public class ChatMessage {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "chat_message_id")
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "chat_room_id")
+ private ChatRoom chatRoom;
+
+ @Column(name = "content")
+ private String content;
+
+ @Column(name = "user_id")
+ private Long userId;
+
+ @Column(name = "is_leader")
+ private Role role;
+
+ @CreatedDate
+ private LocalDateTime createdAt;
+}
diff --git a/src/main/java/meltingpot/server/domain/entity/chat/ChatRoom.java b/src/main/java/meltingpot/server/domain/entity/chat/ChatRoom.java
index 76a0d90..b47d49a 100644
--- a/src/main/java/meltingpot/server/domain/entity/chat/ChatRoom.java
+++ b/src/main/java/meltingpot/server/domain/entity/chat/ChatRoom.java
@@ -13,18 +13,23 @@
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
+@Table(name = "chat_room")
public class ChatRoom extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
- @ManyToOne(fetch = FetchType.LAZY)
+ @OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "party_id")
private Party party;
@OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL)
- private List chatUserList = new ArrayList<>();
+ private List chatRoomUserList = new ArrayList<>();
@OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL)
- private List chatList = new ArrayList<>();
+ private List chatMessageList = new ArrayList<>();
+
+ public void createMessage(ChatMessage chatMessage){
+ chatMessageList.add(chatMessage);
+ }
}
diff --git a/src/main/java/meltingpot/server/domain/entity/chat/ChatUser.java b/src/main/java/meltingpot/server/domain/entity/chat/ChatRoomUser.java
similarity index 74%
rename from src/main/java/meltingpot/server/domain/entity/chat/ChatUser.java
rename to src/main/java/meltingpot/server/domain/entity/chat/ChatRoomUser.java
index fd7c634..4d52194 100644
--- a/src/main/java/meltingpot/server/domain/entity/chat/ChatUser.java
+++ b/src/main/java/meltingpot/server/domain/entity/chat/ChatRoomUser.java
@@ -11,12 +11,15 @@
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
-public class ChatUser extends BaseEntity {
+@Table(name = "chat_room_user")
+public class ChatRoomUser extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "chat_room_user_id")
private Long id;
@Enumerated(EnumType.STRING)
+ @Column(name = "chat_room_alarm_status")
private Alarm alarm;
@ManyToOne(fetch = FetchType.LAZY)
@@ -26,4 +29,8 @@ public class ChatUser extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "chat_room_id")
private ChatRoom chatRoom;
+
+ public void toggleAlarm() {
+ this.alarm = this.alarm.toggle();
+ }
}
diff --git a/src/main/java/meltingpot/server/domain/entity/chat/enums/Alarm.java b/src/main/java/meltingpot/server/domain/entity/chat/enums/Alarm.java
index c245200..4f4868c 100644
--- a/src/main/java/meltingpot/server/domain/entity/chat/enums/Alarm.java
+++ b/src/main/java/meltingpot/server/domain/entity/chat/enums/Alarm.java
@@ -1,5 +1,8 @@
package meltingpot.server.domain.entity.chat.enums;
public enum Alarm {
- ON, OFF
+ ON, OFF;
+ public Alarm toggle() {
+ return this == ON ? OFF : ON;
+ }
}
diff --git a/src/main/java/meltingpot/server/domain/entity/chat/enums/Role.java b/src/main/java/meltingpot/server/domain/entity/chat/enums/Role.java
new file mode 100644
index 0000000..d5dac71
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/entity/chat/enums/Role.java
@@ -0,0 +1,5 @@
+package meltingpot.server.domain.entity.chat.enums;
+
+public enum Role {
+ LEADER, MEMBER
+}
diff --git a/src/main/java/meltingpot/server/domain/entity/common/AmazonS3Manager.java b/src/main/java/meltingpot/server/domain/entity/common/AmazonS3Manager.java
new file mode 100644
index 0000000..6ecc6b5
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/entity/common/AmazonS3Manager.java
@@ -0,0 +1,59 @@
+package meltingpot.server.domain.entity.common;
+
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.model.ObjectMetadata;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import meltingpot.server.config.AmazonConfig;
+import meltingpot.server.util.apiPayload.code.ErrorStatus;
+import meltingpot.server.util.apiPayload.exception.S3Exception;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class AmazonS3Manager {
+ private final AmazonS3 amazonS3;
+ private final AmazonConfig amazonConfig;
+ private final UuidRepository uuidRepository;
+
+ public String uploadFile(String keyName, MultipartFile file) {
+ ObjectMetadata metadata = new ObjectMetadata();
+ metadata.setContentLength(file.getSize());
+ try {
+ amazonS3.putObject(new PutObjectRequest(amazonConfig.getBucket(), keyName, file.getInputStream(), metadata));
+ } catch (IOException e) {
+ log.error("error at AmazonS3Manager uploadFile : {}", (Object) e.getStackTrace());
+ }
+
+ return amazonS3.getUrl(amazonConfig.getBucket(), keyName).toString();
+ }
+
+ public void deleteFile(String keyName) throws S3Exception {
+ try {
+ String modifiedKeyName = modifyDeleteKeyName(keyName);
+ System.out.println(modifiedKeyName);
+ if (amazonS3.doesObjectExist(amazonConfig.getBucket(), modifiedKeyName)) {
+ amazonS3.deleteObject(amazonConfig.getBucket(), modifiedKeyName);
+ } else {
+ throw new IOException();
+ }
+ } catch (Exception e) {
+ throw new S3Exception(ErrorStatus.S3_OBJECT_NOT_FOUND);
+ }
+ }
+
+ private String modifyDeleteKeyName(String keyName) {
+ return keyName.split("/")[3] + '/' + keyName.split("/")[4];
+ }
+
+
+ public String generatePostKeyName(Uuid uuid, String filename) {
+ return amazonConfig.getPostPath() + '/' + uuid.getUuid() + "_" + filename;
+ }
+}
diff --git a/src/main/java/meltingpot/server/domain/entity/common/BaseEntity.java b/src/main/java/meltingpot/server/domain/entity/common/BaseEntity.java
index 1d29e97..a88f6be 100644
--- a/src/main/java/meltingpot/server/domain/entity/common/BaseEntity.java
+++ b/src/main/java/meltingpot/server/domain/entity/common/BaseEntity.java
@@ -2,6 +2,7 @@
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
+import lombok.Builder;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
@@ -13,6 +14,7 @@
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Getter
+
public class BaseEntity {
@CreatedDate
diff --git a/src/main/java/meltingpot/server/domain/entity/common/Uuid.java b/src/main/java/meltingpot/server/domain/entity/common/Uuid.java
new file mode 100644
index 0000000..499bdb8
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/entity/common/Uuid.java
@@ -0,0 +1,26 @@
+package meltingpot.server.domain.entity.common;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Entity
+@Builder
+@Getter
+@AllArgsConstructor(access = AccessLevel.PROTECTED)
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+public class Uuid extends BaseEntity {
+
+ @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(unique = true)
+ private String uuid;
+}
\ No newline at end of file
diff --git a/src/main/java/meltingpot/server/domain/entity/common/UuidRepository.java b/src/main/java/meltingpot/server/domain/entity/common/UuidRepository.java
new file mode 100644
index 0000000..f23f16e
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/entity/common/UuidRepository.java
@@ -0,0 +1,6 @@
+package meltingpot.server.domain.entity.common;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UuidRepository extends JpaRepository {
+}
diff --git a/src/main/java/meltingpot/server/domain/entity/enums/Type.java b/src/main/java/meltingpot/server/domain/entity/enums/PostType.java
similarity index 75%
rename from src/main/java/meltingpot/server/domain/entity/enums/Type.java
rename to src/main/java/meltingpot/server/domain/entity/enums/PostType.java
index a5af1df..9e1a8f5 100644
--- a/src/main/java/meltingpot/server/domain/entity/enums/Type.java
+++ b/src/main/java/meltingpot/server/domain/entity/enums/PostType.java
@@ -1,5 +1,5 @@
package meltingpot.server.domain.entity.enums;
-public enum Type {
+public enum PostType {
POSTING,QUESTION
}
diff --git a/src/main/java/meltingpot/server/domain/repository/AccountRepositroy.java b/src/main/java/meltingpot/server/domain/repository/AccountRepositroy.java
new file mode 100644
index 0000000..25641d0
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/AccountRepositroy.java
@@ -0,0 +1,8 @@
+package meltingpot.server.domain.repository;
+
+import meltingpot.server.domain.entity.Account;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+// post 구현때문에 만들어놓은 것이니 마음대로 수정하셔도 됩니다,,!
+public interface AccountRepositroy extends JpaRepository {
+}
diff --git a/src/main/java/meltingpot/server/domain/repository/PostImageRepository.java b/src/main/java/meltingpot/server/domain/repository/PostImageRepository.java
new file mode 100644
index 0000000..3b6219c
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/PostImageRepository.java
@@ -0,0 +1,7 @@
+package meltingpot.server.domain.repository;
+
+import meltingpot.server.domain.entity.PostImage;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface PostImageRepository extends JpaRepository {
+}
diff --git a/src/main/java/meltingpot/server/domain/repository/PostRepository.java b/src/main/java/meltingpot/server/domain/repository/PostRepository.java
new file mode 100644
index 0000000..e26e09a
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/PostRepository.java
@@ -0,0 +1,8 @@
+package meltingpot.server.domain.repository;
+
+import meltingpot.server.domain.entity.Post;
+import meltingpot.server.domain.entity.PostImage;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface PostRepository extends JpaRepository {
+}
diff --git a/src/main/java/meltingpot/server/domain/repository/chat/ChatMessageRepository.java b/src/main/java/meltingpot/server/domain/repository/chat/ChatMessageRepository.java
new file mode 100644
index 0000000..b8c040f
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/chat/ChatMessageRepository.java
@@ -0,0 +1,13 @@
+package meltingpot.server.domain.repository.chat;
+
+import meltingpot.server.domain.entity.chat.ChatMessage;
+import meltingpot.server.domain.entity.chat.ChatRoom;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface ChatMessageRepository extends JpaRepository {
+ Slice findAllByChatRoom(ChatRoom chatRoom, PageRequest pageRequest);
+}
diff --git a/src/main/java/meltingpot/server/domain/repository/chat/ChatRoomRepository.java b/src/main/java/meltingpot/server/domain/repository/chat/ChatRoomRepository.java
new file mode 100644
index 0000000..6be8f58
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/chat/ChatRoomRepository.java
@@ -0,0 +1,7 @@
+package meltingpot.server.domain.repository.chat;
+
+import meltingpot.server.domain.entity.chat.ChatRoom;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ChatRoomRepository extends JpaRepository {
+}
diff --git a/src/main/java/meltingpot/server/domain/repository/chat/ChatRoomUserRepository.java b/src/main/java/meltingpot/server/domain/repository/chat/ChatRoomUserRepository.java
new file mode 100644
index 0000000..b8130b4
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/chat/ChatRoomUserRepository.java
@@ -0,0 +1,11 @@
+package meltingpot.server.domain.repository.chat;
+
+import meltingpot.server.domain.entity.chat.ChatRoomUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface ChatRoomUserRepository extends JpaRepository {
+ int countChatRoomUsersByChatRoomId(Long chatRoomId);
+ Optional findChatRoomUserByUserIdAndChatRoomId(Long userId, Long chatRoomId);
+}
diff --git a/src/main/java/meltingpot/server/domain/repository/party/PartyParticipantRepository.java b/src/main/java/meltingpot/server/domain/repository/party/PartyParticipantRepository.java
new file mode 100644
index 0000000..7c47c24
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/party/PartyParticipantRepository.java
@@ -0,0 +1,13 @@
+package meltingpot.server.domain.repository.party;
+
+import meltingpot.server.domain.entity.party.Party;
+import meltingpot.server.domain.entity.party.PartyParticipant;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface PartyParticipantRepository extends JpaRepository {
+ int countByPartyId(Long partyId);
+ int countByUserId(Long userId);
+ List findAllByUserId(Long userId);
+}
diff --git a/src/main/java/meltingpot/server/domain/repository/party/PartyRepository.java b/src/main/java/meltingpot/server/domain/repository/party/PartyRepository.java
new file mode 100644
index 0000000..3242e92
--- /dev/null
+++ b/src/main/java/meltingpot/server/domain/repository/party/PartyRepository.java
@@ -0,0 +1,9 @@
+package meltingpot.server.domain.repository.party;
+
+import meltingpot.server.domain.entity.party.Party;
+import meltingpot.server.domain.entity.party.PartyParticipant;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface PartyRepository extends JpaRepository {
+ Party findByChatRoomId(Long chatRoomId);
+}
diff --git a/src/main/java/meltingpot/server/post/controller/PostController.java b/src/main/java/meltingpot/server/post/controller/PostController.java
new file mode 100644
index 0000000..e8b6f6e
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/controller/PostController.java
@@ -0,0 +1,33 @@
+package meltingpot.server.post.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import lombok.RequiredArgsConstructor;
+import meltingpot.server.post.dto.PostRequestDto;
+import meltingpot.server.post.dto.PostResponseDto;
+import meltingpot.server.post.service.PostService;
+import meltingpot.server.util.ResponseCode;
+import meltingpot.server.util.ResponseData;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+import static meltingpot.server.util.ResponseCode.CREATE_POST_SUCCESS;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/v1/posts")
+public class PostController {
+ private final PostService postService;
+
+ @Operation(summary = "게시물 작성")
+ @PostMapping("")
+ public ResponseEntity createPost( @RequestBody PostRequestDto.CreatePostDTO createPostDTO) {
+ postService.createPost(createPostDTO);
+ return ResponseData.toResponseEntity(ResponseCode.CREATE_POST_SUCCESS);
+ }
+}
diff --git a/src/main/java/meltingpot/server/post/converter/PostConverter.java b/src/main/java/meltingpot/server/post/converter/PostConverter.java
new file mode 100644
index 0000000..59c1286
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/converter/PostConverter.java
@@ -0,0 +1,28 @@
+package meltingpot.server.post.converter;
+
+import meltingpot.server.domain.entity.Post;
+import meltingpot.server.post.dto.PostImageDto;
+import meltingpot.server.post.dto.PostRequestDto;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PostConverter {
+ public static Post toPost(PostRequestDto.CreatePostDTO createPostDTO) {
+
+ return Post.builder()
+ .title(createPostDTO.getTitle())
+ .content(createPostDTO.getContent())
+ .postType(createPostDTO.getPostType())
+ .build();
+ }
+
+ public static List toPostImageDto(Post post) {
+ return post.getPostImages().stream()
+ .map(p -> PostImageDto.builder()
+ .id(p.getId())
+ .imgUrl(p.getImageUrl())
+ .build())
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/meltingpot/server/post/converter/PostImageConverter.java b/src/main/java/meltingpot/server/post/converter/PostImageConverter.java
new file mode 100644
index 0000000..70fdc21
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/converter/PostImageConverter.java
@@ -0,0 +1,14 @@
+package meltingpot.server.post.converter;
+
+import meltingpot.server.domain.entity.Post;
+import meltingpot.server.domain.entity.PostImage;
+import org.springframework.web.multipart.MultipartFile;
+
+public class PostImageConverter {
+ public static PostImage toPostImage(Post post, MultipartFile file, String pictureUrl) {
+ return PostImage.builder()
+ .post(post)
+ .imageUrl(pictureUrl)
+ .build();
+ }
+}
diff --git a/src/main/java/meltingpot/server/post/dto/PostImageDto.java b/src/main/java/meltingpot/server/post/dto/PostImageDto.java
new file mode 100644
index 0000000..8856b4e
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/dto/PostImageDto.java
@@ -0,0 +1,16 @@
+package meltingpot.server.post.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+public class PostImageDto {
+ @JsonProperty("id")
+ private Long id;
+
+ @JsonProperty("imgUrl")
+ private String imgUrl;
+
+}
diff --git a/src/main/java/meltingpot/server/post/dto/PostRequestDto.java b/src/main/java/meltingpot/server/post/dto/PostRequestDto.java
new file mode 100644
index 0000000..821962f
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/dto/PostRequestDto.java
@@ -0,0 +1,18 @@
+package meltingpot.server.post.dto;
+
+import lombok.Getter;
+import meltingpot.server.domain.entity.PostImage;
+import meltingpot.server.domain.entity.enums.PostType;
+
+import java.util.List;
+
+public class PostRequestDto {
+
+ @Getter
+ public static class CreatePostDTO {
+ private String title;
+ private String content;
+ private PostType postType;
+// private List postImageList;
+ }
+}
diff --git a/src/main/java/meltingpot/server/post/dto/PostResponseDto.java b/src/main/java/meltingpot/server/post/dto/PostResponseDto.java
new file mode 100644
index 0000000..b102f0d
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/dto/PostResponseDto.java
@@ -0,0 +1,19 @@
+package meltingpot.server.post.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+public class PostResponseDto {
+ @Getter
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Builder
+ public static class CreatePostResultDTO {
+ private Long postId;
+ private LocalDateTime createAt;
+ }
+}
diff --git a/src/main/java/meltingpot/server/post/service/PostService.java b/src/main/java/meltingpot/server/post/service/PostService.java
new file mode 100644
index 0000000..6759d66
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/service/PostService.java
@@ -0,0 +1,16 @@
+package meltingpot.server.post.service;
+
+import meltingpot.server.domain.entity.Account;
+import meltingpot.server.domain.repository.AccountRepositroy;
+import meltingpot.server.post.dto.PostRequestDto;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+public interface PostService {
+
+ void createPost (PostRequestDto.CreatePostDTO createPostDTO);
+ }
+
+
+
diff --git a/src/main/java/meltingpot/server/post/service/PostServiceImpl.java b/src/main/java/meltingpot/server/post/service/PostServiceImpl.java
new file mode 100644
index 0000000..1f8067d
--- /dev/null
+++ b/src/main/java/meltingpot/server/post/service/PostServiceImpl.java
@@ -0,0 +1,57 @@
+package meltingpot.server.post.service;
+
+import lombok.RequiredArgsConstructor;
+import meltingpot.server.domain.entity.Account;
+import meltingpot.server.domain.entity.Post;
+import meltingpot.server.domain.entity.PostImage;
+import meltingpot.server.domain.entity.common.AmazonS3Manager;
+import meltingpot.server.domain.entity.common.Uuid;
+import meltingpot.server.domain.entity.common.UuidRepository;
+import meltingpot.server.domain.repository.AccountRepositroy;
+import meltingpot.server.domain.repository.PostImageRepository;
+import meltingpot.server.domain.repository.PostRepository;
+import meltingpot.server.post.converter.PostImageConverter;
+import meltingpot.server.post.dto.PostRequestDto;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.UUID;
+
+import static meltingpot.server.post.converter.PostConverter.toPost;
+
+@Service
+@RequiredArgsConstructor
+@Transactional
+public class PostServiceImpl implements PostService {
+ private final AccountRepositroy accountRepositroy;
+ private final PostRepository postRepository;
+ private final PostImageRepository postImageRepository;
+ private final UuidRepository uuidRepository;
+ private final AmazonS3Manager s3Manager;
+
+ @Override
+ public void createPost(PostRequestDto.CreatePostDTO createPostDTO){
+
+ Post post = toPost(createPostDTO);
+ Post savedPost = postRepository.save(post);
+
+// for (MultipartFile file : multipartFileList) {
+// String uuid = UUID.randomUUID().toString();
+// Uuid savedUuid = uuidRepository.save(Uuid.builder()
+// .uuid(uuid).build());
+//
+// String pictureUrl = s3Manager.uploadFile(s3Manager.generatePostKeyName(savedUuid, file.getOriginalFilename()), file);
+//
+// PostImage postImage = PostImageConverter.toPostImage(savedPost, file, pictureUrl);
+// postImageRepository.save(postImage);
+// }
+ }
+
+ private Account findAccountById(Long accountId) {
+ return accountRepositroy.findById(accountId)
+ .orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다."));
+ }
+}
+
diff --git a/src/main/java/meltingpot/server/util/PageResponse.java b/src/main/java/meltingpot/server/util/PageResponse.java
new file mode 100644
index 0000000..1bc587e
--- /dev/null
+++ b/src/main/java/meltingpot/server/util/PageResponse.java
@@ -0,0 +1,23 @@
+package meltingpot.server.util;
+
+import org.springframework.data.domain.Page;
+
+import java.util.List;
+
+public record PageResponse(
+ List content,
+ int page,
+ int size,
+ int totalPage,
+ long totalCount
+) {
+ public static PageResponse of(Page data) {
+ return new PageResponse<>(
+ data.getContent(),
+ data.getPageable().getPageNumber(),
+ data.getSize(),
+ data.getTotalPages(),
+ data.getTotalElements()
+ );
+ }
+}
diff --git a/src/main/java/meltingpot/server/util/ResponseCode.java b/src/main/java/meltingpot/server/util/ResponseCode.java
index d26991f..79536d2 100644
--- a/src/main/java/meltingpot/server/util/ResponseCode.java
+++ b/src/main/java/meltingpot/server/util/ResponseCode.java
@@ -20,6 +20,7 @@ public enum ResponseCode {
/* 201 CREATED : 요청 성공, 자원 생성 */
SIGNUP_SUCCESS(CREATED, "회원가입 성공"),
CREATE_CHAT_ROOM_SUCCESS(CREATED, "채팅방 생성 성공"),
+ CREATE_POST_SUCCESS(CREATED,"게시물 작성 성공"),
/* 400 BAD_REQUEST : 잘못된 요청 */
@@ -42,7 +43,7 @@ public enum ResponseCode {
BLACKLIST_MEMBER(FORBIDDEN, "접근할 수 없는 계정입니다"),
HOLDING_WITHDRAWAL(FORBIDDEN, "30일 이내에 탈퇴한 계정입니다"),
SIGNOUT_FAIL_REFRESH_TOKEN(FORBIDDEN, "본인의 REFRESH 토큰으로만 로그아웃할 수 있습니다"),
-
+ S3_OBJECT_NOT_FOUND(NOT_FOUND, "REFRESH 토큰 정보를 찾을 수 없습니다"),
/* 404 NOT_FOUND : Resource 를 찾을 수 없음 */
ACCOUNT_NOT_FOUND(NOT_FOUND, "계정 정보를 찾을 수 없습니다"),
@@ -58,4 +59,5 @@ public enum ResponseCode {
private final HttpStatus httpStatus;
private final String detail;
+
}
\ No newline at end of file
diff --git a/src/main/java/meltingpot/server/util/ResponseData.java b/src/main/java/meltingpot/server/util/ResponseData.java
index e3e9d2e..bf2cf63 100644
--- a/src/main/java/meltingpot/server/util/ResponseData.java
+++ b/src/main/java/meltingpot/server/util/ResponseData.java
@@ -71,4 +71,8 @@ public static ResponseEntity> toResponseEntity(ResponseCode
);
}
+
+
+
+
}
\ No newline at end of file
diff --git a/src/main/java/meltingpot/server/util/apiPayload/ErrorReasonDTO.java b/src/main/java/meltingpot/server/util/apiPayload/ErrorReasonDTO.java
new file mode 100644
index 0000000..2ceaef1
--- /dev/null
+++ b/src/main/java/meltingpot/server/util/apiPayload/ErrorReasonDTO.java
@@ -0,0 +1,14 @@
+package meltingpot.server.util.apiPayload;
+
+import lombok.Builder;
+import lombok.Getter;
+import org.springframework.http.HttpStatus;
+
+@Getter
+@Builder
+public class ErrorReasonDTO {
+ private final HttpStatus httpStatus;
+ private final String code;
+ private final String message;
+ private final boolean isSuccess;
+}
diff --git a/src/main/java/meltingpot/server/util/apiPayload/code/BaseErrorCode.java b/src/main/java/meltingpot/server/util/apiPayload/code/BaseErrorCode.java
new file mode 100644
index 0000000..63c9c1b
--- /dev/null
+++ b/src/main/java/meltingpot/server/util/apiPayload/code/BaseErrorCode.java
@@ -0,0 +1,10 @@
+package meltingpot.server.util.apiPayload.code;
+
+import meltingpot.server.util.apiPayload.ErrorReasonDTO;
+
+public interface BaseErrorCode {
+
+ public ErrorReasonDTO getReason();
+
+ public ErrorReasonDTO getReasonHttpStatus();
+}
\ No newline at end of file
diff --git a/src/main/java/meltingpot/server/util/apiPayload/code/ErrorStatus.java b/src/main/java/meltingpot/server/util/apiPayload/code/ErrorStatus.java
new file mode 100644
index 0000000..9ad7941
--- /dev/null
+++ b/src/main/java/meltingpot/server/util/apiPayload/code/ErrorStatus.java
@@ -0,0 +1,33 @@
+package meltingpot.server.util.apiPayload.code;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import meltingpot.server.util.apiPayload.ErrorReasonDTO;
+import org.springframework.http.HttpStatus;
+
+@Getter
+@AllArgsConstructor
+public enum ErrorStatus implements BaseErrorCode {
+
+ //S3 관련
+ S3_OBJECT_NOT_FOUND(HttpStatus.NOT_FOUND, "이미지가 존재하지 않습니다.");
+
+ private final HttpStatus httpStatus;
+ private final String detail;
+
+
+ @Override
+ public ErrorReasonDTO getReason() {
+ return ErrorReasonDTO.builder().message(detail).isSuccess(false).build();
+ }
+ @Override
+ public ErrorReasonDTO getReasonHttpStatus() {
+ return ErrorReasonDTO.builder()
+ .code(name())
+ .message(detail)
+ .isSuccess(false)
+ .httpStatus(httpStatus)
+ .build();
+ }
+}
diff --git a/src/main/java/meltingpot/server/util/apiPayload/exception/GeneralException.java b/src/main/java/meltingpot/server/util/apiPayload/exception/GeneralException.java
new file mode 100644
index 0000000..ab8323e
--- /dev/null
+++ b/src/main/java/meltingpot/server/util/apiPayload/exception/GeneralException.java
@@ -0,0 +1,21 @@
+package meltingpot.server.util.apiPayload.exception;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import meltingpot.server.util.apiPayload.ErrorReasonDTO;
+import meltingpot.server.util.apiPayload.code.BaseErrorCode;
+
+@Getter
+@AllArgsConstructor
+public class GeneralException extends RuntimeException {
+
+ private BaseErrorCode code;
+
+ public ErrorReasonDTO getErrorReason() {
+ return this.code.getReason();
+ }
+
+ public ErrorReasonDTO getErrorReasonHttpStatus() {
+ return this.code.getReasonHttpStatus();
+ }
+}
diff --git a/src/main/java/meltingpot/server/util/apiPayload/exception/S3Exception.java b/src/main/java/meltingpot/server/util/apiPayload/exception/S3Exception.java
new file mode 100644
index 0000000..546f08c
--- /dev/null
+++ b/src/main/java/meltingpot/server/util/apiPayload/exception/S3Exception.java
@@ -0,0 +1,10 @@
+package meltingpot.server.util.apiPayload.exception;
+import meltingpot.server.util.apiPayload.code.BaseErrorCode;
+
+
+public class S3Exception extends GeneralException{
+
+ public S3Exception(BaseErrorCode code) {
+ super(code);
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 90fd980..54b8145 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -26,3 +26,16 @@ jwt:
# token-validity-in-seconds: 86400
token-validity-in-seconds: 1209600 # 테스트용 14일 유효기간
+cloud:
+ aws:
+ s3:
+ bucket: meltingpot
+ path:
+ post : post
+ region:
+ static: ap-northeast-2
+ stack:
+ auto: false
+ credentials:
+ accessKey: ${AWS_ACCESS_KEY}
+ secretKey: ${AWS_SECRET_KEY}