Skip to content

[김태희] sprint6 #248

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 36 commits into
base: part2-김태희
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4ea25ca
refactor: HTTP 응답 상태 코드를 HttpStatus 상수로 변경
WaiCat Apr 14, 2025
c42b5fe
refactor: Dto class -> record로 변경
WaiCat Apr 14, 2025
3581f21
feat: BinaryContentListResponse 생성
WaiCat Apr 14, 2025
fa88c03
refactor: builder 사용으로 휴먼에러 방지
WaiCat Apr 14, 2025
f713ceb
refactor: builder 사용에 필요한 AllArgsConstructor 추가
WaiCat Apr 14, 2025
dfabe66
refactor: NPE위험 예방 위한 Objects.equals 사용
WaiCat Apr 14, 2025
897ca59
refactor: 공통속성 추상클래스로 정의 및 상속
WaiCat Apr 14, 2025
ed6031c
refactor: Dto 요구사항 변경
WaiCat Apr 14, 2025
42bb43f
feat: 각종 설정파일, 프론트코드 업데이트 및 sql문 추가
WaiCat Apr 14, 2025
e1d0625
refactor: JPA 주요 어노테이션을 활용해 ERD, 연관관계 매핑 정보를 도메인 모델에 반영
WaiCat Apr 14, 2025
2bf2c57
fix: 각Entity 어노테이션 문제 수정
WaiCat Apr 15, 2025
c76cf92
refactor: User-UserStatus 참조에 따른 DTO 수정
WaiCat Apr 15, 2025
cbf39ee
feat: Repository Jpa로 정의 및 기존 repository, service 수정및 삭제
WaiCat Apr 16, 2025
87fc560
feat: Dto from메서드 mapper클래스로 분리
WaiCat Apr 16, 2025
db2ef41
fix: mapper 컴포넌트 final 선언
WaiCat Apr 16, 2025
b362771
refactor: mapper구현에 따른 코드 수정
WaiCat Apr 16, 2025
1490a24
refactor: API명세에 맞게 각 파일 수정
WaiCat Apr 16, 2025
f50ca3c
refactor: service로직 cotroller에서 분리
WaiCat Apr 16, 2025
ff2e20e
feat: BinaryContentStorage 구현
WaiCat Apr 16, 2025
44b64fe
refactor: BinaryContentStorage 구현에 따른 bytes 제거
WaiCat Apr 16, 2025
360cae3
feat: Message paging 처리
WaiCat Apr 16, 2025
758b771
fix: N+1문제 해결
WaiCat Apr 17, 2025
63567ff
docs: mapper 패키지명 변경
WaiCat Apr 18, 2025
a731ce5
refactor: 오프셋 페이지네이션을 커서 페이지네이션으로 리팩토링
WaiCat Apr 18, 2025
fb1a4e0
fix: sql에 잘못된 notnull 수정
WaiCat Apr 18, 2025
7e1e635
refactor: api명세에 따른 수정
WaiCat Apr 18, 2025
da42731
refactor: gradle 정ㄹ
WaiCat Apr 18, 2025
6a1016d
refactor: yaml정리
WaiCat Apr 18, 2025
1acd635
refactor: api명세에 따른 수정
WaiCat Apr 18, 2025
a5d5674
feat: cursor사용을 위한 메서드 구현
WaiCat Apr 18, 2025
e1048d3
docs: 프론트 파일 갱신
WaiCat Apr 18, 2025
97bcb58
fix: user save 순서에따른 id 오류 수정
WaiCat Apr 18, 2025
4a3cdbf
fix: binary save순서에 따른 id 오류 수정
WaiCat Apr 18, 2025
dbe2d3c
fix: id설정 오류 수정
WaiCat Apr 18, 2025
c1722ac
fix: attributePaths에 profile추가
WaiCat Apr 18, 2025
0b74e52
fix: message로딩 오류 해결 etc..
WaiCat Apr 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,35 @@ repositories {
}

dependencies {
// Spring Boot Core
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'org.postgresql:postgresql' // PostgreSQL JDBC 드라이버

// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok:1.18.36'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.36'

// OpenAPI / Swagger UI
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'

// JWT (토큰 인증)
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

// BCrypt 암호화를 위한 의존성
// 비밀번호 암호화용
implementation 'org.mindrot:jbcrypt:0.4'

// 테스트 관련
testImplementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mockito:mockito-core:5.11.0'
testImplementation 'org.mockito:mockito-junit-jupiter:5.11.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation 'com.h2database:h2' // 테스트용 인메모리 DB
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.sprint.mission.discodeit.controller;

import com.sprint.mission.discodeit.dto.user.LoginRequest;
import com.sprint.mission.discodeit.entity.User;
import com.sprint.mission.discodeit.dto.user.UserDto;
import com.sprint.mission.discodeit.service.AuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -18,9 +18,9 @@ public class AuthController {
private final AuthService authService;

@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<User> login(@RequestBody LoginRequest request) {
public ResponseEntity<UserDto> login(@RequestBody LoginRequest request) {

User user = authService.login(request);
UserDto user = authService.login(request);
return ResponseEntity.ok(user);
}
}
Original file line number Diff line number Diff line change
@@ -1,46 +1,53 @@
package com.sprint.mission.discodeit.controller;


import com.sprint.mission.discodeit.entity.BinaryContent;
import com.sprint.mission.discodeit.dto.binaryContent.BinaryContentDto;
import com.sprint.mission.discodeit.service.BinaryContentService;
import com.sprint.mission.discodeit.storage.BinaryContentStorage;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/api/binaryContents")
@RequiredArgsConstructor
public class BinaryContentController {

private final BinaryContentService binaryContentService;
private final BinaryContentStorage binaryContentStorage;

@RequestMapping(value = "/upload", method = RequestMethod.PUT)
public ResponseEntity<?> upload(@RequestParam("file") MultipartFile multipartFile) {
UUID binaryId = binaryContentService.createBinaryContent(multipartFile);

return ResponseEntity.ok(binaryId);
@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<List<BinaryContentDto>> getBinaryContents(
@RequestParam("binaryContentIds") List<UUID> binaryIds) {
return ResponseEntity.ok(binaryContentService.findAllByIdIn(binaryIds));
}

@RequestMapping(value = "{binaryContentId}", method = RequestMethod.GET)
public ResponseEntity<BinaryContent> getBinaryContent(
@RequestMapping(value = "/{binaryContentId}", method = RequestMethod.GET)
public ResponseEntity<BinaryContentDto> getBinaryContent(
@PathVariable("binaryContentId") UUID binaryContentId) {
return ResponseEntity.ok(binaryContentService.findBinaryContent(binaryContentId));
}

@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<List<BinaryContent>> getBinaryContents(
@RequestParam("binaryContentIds") List<UUID> binaryIds) {
List<BinaryContent> binaryContents = binaryIds.stream()
.map(binaryContentService::findBinaryContent)
.toList();

return ResponseEntity.ok(binaryContents);
// @RequestMapping(value = "/upload", method = RequestMethod.PUT)
// public ResponseEntity<BinaryContentDto> upload(
// @RequestParam("file") MultipartFile multipartFile) {
// BinaryContentDto binaryContent = binaryContentService.createBinaryContent(multipartFile);
//
// return ResponseEntity.ok(binaryContent);
// }

@GetMapping(value = "/{binaryContentId}/download")
public ResponseEntity<?> downloadBinaryContent(
@PathVariable("binaryContentId") UUID binaryContentId
) {
return binaryContentStorage.download(binaryContentService.findBinaryContent(binaryContentId));
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.sprint.mission.discodeit.controller;

import com.sprint.mission.discodeit.dto.channel.ChannelInfoDto;
import com.sprint.mission.discodeit.dto.channel.ChannelDto;
import com.sprint.mission.discodeit.dto.channel.CreatePrivateChannelRequest;
import com.sprint.mission.discodeit.dto.channel.CreatePublicChannelRequest;
import com.sprint.mission.discodeit.dto.channel.UpdateChannelRequest;
import com.sprint.mission.discodeit.entity.Channel;
import com.sprint.mission.discodeit.service.ChannelService;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -25,42 +25,35 @@ public class ChannelController {
private final ChannelService channelService;

@RequestMapping(value = "/private", method = RequestMethod.POST)
public ResponseEntity<Channel> createPrivateChannel(
@RequestBody CreatePrivateChannelRequest channelDto
public ResponseEntity<ChannelDto> createPrivateChannel(
@RequestBody CreatePrivateChannelRequest request
) {
Channel channel = channelService.createPrivateChannel(channelDto);

return ResponseEntity.status(201).body(channel);
return ResponseEntity.status(HttpStatus.CREATED)
.body(channelService.createPrivateChannel(request));
}

@RequestMapping(value = "/public", method = RequestMethod.POST)
public ResponseEntity<Channel> createPublicChannel(
@RequestBody CreatePublicChannelRequest channelDto) {
Channel channel = channelService.createPublicChannel(channelDto);

return ResponseEntity.status(201).body(channel);
public ResponseEntity<ChannelDto> createPublicChannel(
@RequestBody CreatePublicChannelRequest request) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(channelService.createPublicChannel(request));
}

@RequestMapping(value = "/{channelId}", method = RequestMethod.PATCH)
public ResponseEntity<Channel> updateChannel(@PathVariable("channelId") UUID channelId,
@RequestBody UpdateChannelRequest channelDto) {
Channel channel = channelService.updateChannel(channelId, channelDto);

return ResponseEntity.ok(channel);
public ResponseEntity<ChannelDto> updateChannel(@PathVariable("channelId") UUID channelId,
@RequestBody UpdateChannelRequest request) {
return ResponseEntity.ok(channelService.updateChannel(channelId, request));
}

@RequestMapping(value = "/{channelId}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteChannel(@PathVariable("channelId") UUID channelId) {
channelService.deleteChannel(channelId);

return ResponseEntity.status(204).body("Channel이 성공적으로 삭제됨");
return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Channel이 성공적으로 삭제됨");
}

@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<List<ChannelInfoDto>> getAllChannels(
public ResponseEntity<List<ChannelDto>> getAllChannels(
@RequestParam(name = "userId") UUID userId) {
List<ChannelInfoDto> channels = channelService.findAllByUserId(userId);

return ResponseEntity.ok(channels);
return ResponseEntity.ok(channelService.findAllByUserId(userId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@


import com.sprint.mission.discodeit.dto.Message.CreateMessageRequest;
import com.sprint.mission.discodeit.dto.Message.MessageDto;
import com.sprint.mission.discodeit.dto.Message.UpdateMessageRequest;
import com.sprint.mission.discodeit.entity.Message;
import com.sprint.mission.discodeit.dto.response.PageResponse;
import com.sprint.mission.discodeit.service.BinaryContentService;
import com.sprint.mission.discodeit.service.MessageService;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -27,43 +31,46 @@ public class MessageController {
private final MessageService messageService;
private final BinaryContentService binaryContentService;

@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<PageResponse<MessageDto>> findAllByChannelId(
@RequestParam("channelId") UUID channelId,
@RequestParam(value = "cursor", required = false) Instant cursor,
Pageable pageable
) {
PageResponse<MessageDto> messageDtoPageResponse = messageService.findMessagesByCursor(channelId,
cursor, pageable);
return ResponseEntity.ok(messageDtoPageResponse);
}

@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity<Message> createMessage(
public ResponseEntity<MessageDto> createMessage(
@RequestPart("messageCreateRequest") CreateMessageRequest request,
@RequestPart(value = "attachments", required = false) List<MultipartFile> attachments
) {
Message message = messageService.createMessage(request);
if (!attachments.isEmpty()) {
MessageDto messageDto = messageService.createMessage(request);
if (attachments != null && !attachments.isEmpty()) {
attachments.stream()
.map(binaryContentService::createBinaryContent)
.forEach(binaryId -> messageService.addAttachment(message.getId(), binaryId));
.forEach(binaryId -> messageService.addAttachment(messageDto.id(), binaryId));
}

return ResponseEntity.status(201).body(message);
return ResponseEntity.status(HttpStatus.CREATED).body(messageDto);
}

@RequestMapping(value = "/{messageId}", method = RequestMethod.PATCH)
public ResponseEntity<Message> updateMessage(
public ResponseEntity<MessageDto> updateMessage(
@PathVariable("messageId") UUID messageId,
@RequestBody UpdateMessageRequest request) {
Message message = messageService.updateMessage(messageId, request);

return ResponseEntity.ok(message);
return ResponseEntity.ok(messageService.updateMessage(messageId, request));
}

@RequestMapping(value = "/{messageId}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteMessage(
@PathVariable("messageId") UUID messageId) {
messageService.deleteMessage(messageId);

return ResponseEntity.status(204).body("Message가 성공적으로 삭제됨");
return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Message가 성공적으로 삭제됨");
}

@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<List<Message>> getChannelMessage(
@RequestParam("channelId") UUID channelId) {
List<Message> messages = messageService.findallByChannelId(channelId);

return ResponseEntity.ok(messages);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.sprint.mission.discodeit.controller;

import com.sprint.mission.discodeit.dto.readStatus.CreateReadStatusRequest;
import com.sprint.mission.discodeit.dto.readStatus.ReadStatusDto;
import com.sprint.mission.discodeit.dto.readStatus.UpdateReadStatusRequest;
import com.sprint.mission.discodeit.entity.ReadStatus;
import com.sprint.mission.discodeit.service.ReadStatusService;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -23,46 +24,37 @@ public class ReadStatusController {
private final ReadStatusService readStatusService;

@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity<ReadStatus> createReadStatus(
public ResponseEntity<ReadStatusDto> createReadStatus(
@RequestBody CreateReadStatusRequest request
) {
System.out.println(11);

ReadStatus readStatus = readStatusService.createReadStatus(request);
return ResponseEntity.status(HttpStatus.CREATED)
.body(readStatusService.createReadStatus(request));
}

return ResponseEntity.status(201).body(readStatus);
@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<List<ReadStatusDto>> findAllByUserId(
@RequestParam("userId") UUID userId
) {
return ResponseEntity.ok(readStatusService.findAllByUserId(userId));
}

@RequestMapping(value = "/{readStatusId}", method = RequestMethod.PATCH)
public ResponseEntity<ReadStatus> updateReadStatus(
public ResponseEntity<ReadStatusDto> updateReadStatus(
@PathVariable("readStatusId") UUID readStatusId,
@RequestBody UpdateReadStatusRequest request
) {
ReadStatus readStatus = readStatusService.updateReadStatus(readStatusId, request);

return ResponseEntity.ok(readStatus);
return ResponseEntity.ok(readStatusService.updateReadStatus(readStatusId, request));
}

@RequestMapping(value = "/{channelId}", method = RequestMethod.GET)
public ResponseEntity<ReadStatus> getReadStatus(
public ResponseEntity<ReadStatusDto> getReadStatus(
@RequestParam("userId") UUID userId,
@PathVariable("channelId") UUID channelId
) {
ReadStatus readStatus = readStatusService.findReadStatusByUserIdAndChannelId(userId, channelId);

return ResponseEntity.ok(readStatus);
return ResponseEntity.ok(
readStatusService.findReadStatusByUserIdAndChannelId(userId, channelId));
}

@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<List<ReadStatus>> findAllByUserId(
@RequestParam("userId") UUID userId
) {

List<ReadStatus> readStatuses = readStatusService.findAll().stream()
.filter(readStatus -> readStatus.getUserId().equals(userId))
.toList();

return ResponseEntity.ok(readStatuses);
}

}
Loading