Skip to content

Commit

Permalink
[FEATURE] 채팅 세션 RUD API (#29)
Browse files Browse the repository at this point in the history
* feat: 채팅 세션 조회 API (#23)

* feat: 채팅 세션 수정 API (#23)

* feat: 채팅 세션 삭제 API (#23)

* refactor: 메서드 리팩토링 (#23)

* refactor: 메서드 순서 변경 (#23)

* refactor: 회원 삭제 validation 추가 (#23)

* chore: local db 명 변경 (#23)

* chore: 로컬 DB 명 변경 (#23)
  • Loading branch information
hyunmin0317 authored Nov 30, 2024
1 parent 7b64ee1 commit e23de8e
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.hyunmin.gpt.domain.chat.dto.ChatGptRequestDto;
import com.hyunmin.gpt.domain.chat.dto.ChatRequestDto;
import com.hyunmin.gpt.domain.chat.dto.ChatResponseDto;
import com.hyunmin.gpt.domain.chat.dto.ChatUpdateRequestDto;
import com.hyunmin.gpt.domain.chat.service.ChatCommandService;
import com.hyunmin.gpt.domain.chat.service.ChatGptService;
import com.hyunmin.gpt.domain.chat.service.ChatQueryService;
Expand All @@ -28,6 +29,12 @@ public class ChatController {
private final ChatGptService chatGptService;
private final MessageQueryService messageQueryService;

@GetMapping
public ResponseEntity<Slice<ChatResponseDto>> readChats(@AuthMember Long memberId, @ParameterObject Pageable pageable) {
Slice<ChatResponseDto> responseDtoSlice = chatQueryService.readChats(memberId, pageable);
return ResponseEntity.ok(responseDtoSlice);
}

@PostMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public ResponseEntity<Flux<String>> streamChat(@AuthMember Long memberId, @RequestBody @Valid ChatRequestDto requestDto) {
String chatId = chatCommandService.getOrCreateChatId(memberId, requestDto);
Expand All @@ -38,9 +45,22 @@ public ResponseEntity<Flux<String>> streamChat(@AuthMember Long memberId, @Reque
.body(responseFlux);
}

@GetMapping
public ResponseEntity<Slice<ChatResponseDto>> readChats(@AuthMember Long memberId, @ParameterObject Pageable pageable) {
Slice<ChatResponseDto> responseDtoSlice = chatQueryService.readChats(memberId, pageable);
return ResponseEntity.ok(responseDtoSlice);
@GetMapping("/{chatId}")
public ResponseEntity<ChatResponseDto> readChat(@AuthMember Long memberId, @PathVariable String chatId) {
ChatResponseDto responseDto = chatQueryService.readChat(memberId, chatId);
return ResponseEntity.ok(responseDto);
}

@PutMapping("/{chatId}")
public ResponseEntity<ChatResponseDto> updateChat(@AuthMember Long memberId, @PathVariable String chatId,
@RequestBody @Valid ChatUpdateRequestDto requestDto) {
ChatResponseDto responseDto = chatCommandService.updateChat(memberId, chatId, requestDto);
return ResponseEntity.ok(responseDto);
}

@DeleteMapping("/{chatId}")
public ResponseEntity<Void> deleteChat(@AuthMember Long memberId, @PathVariable String chatId) {
chatCommandService.deleteChat(memberId, chatId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.hyunmin.gpt.domain.chat.dto;

import jakarta.validation.constraints.NotBlank;

public record ChatUpdateRequestDto(
@NotBlank(message = "내용을 입력해주세요.")
String name
) {

}
4 changes: 4 additions & 0 deletions src/main/java/com/hyunmin/gpt/domain/chat/entity/Chat.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ public void setMember(Member member) {
this.member = member;
member.getChats().add(this);
}

public void update(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.hyunmin.gpt.domain.chat.dto.ChatRequestDto;
import com.hyunmin.gpt.domain.chat.dto.ChatResponseDto;
import com.hyunmin.gpt.domain.chat.dto.ChatUpdateRequestDto;
import com.hyunmin.gpt.domain.chat.entity.Chat;
import com.hyunmin.gpt.domain.chat.repository.ChatRepository;
import com.hyunmin.gpt.global.common.entity.Member;
Expand All @@ -21,7 +22,26 @@ public class ChatCommandService {
private final ChatRepository chatRepository;
private final MemberRepository memberRepository;

public ChatResponseDto createChat(Long memberId, ChatRequestDto requestDto) {
public String getOrCreateChatId(Long memberId, ChatRequestDto requestDto) {
return requestDto.chatId() != null ?
chatQueryService.readChat(memberId, requestDto.chatId()).id() :
createChat(memberId, requestDto).id();
}

public ChatResponseDto updateChat(Long memberId, String chatId, ChatUpdateRequestDto requestDto) {
Chat chat = chatRepository.findByIdAndMemberId(chatId, memberId)
.orElseThrow(() -> new GeneralException(ErrorCode.CHAT_NOT_FOUND));
chat.update(requestDto.name());
return ChatResponseDto.from(chat);
}

public void deleteChat(Long memberId, String chatId) {
Chat chat = chatRepository.findByIdAndMemberId(chatId, memberId)
.orElseThrow(() -> new GeneralException(ErrorCode.CHAT_NOT_FOUND));
chatRepository.delete(chat);
}

private ChatResponseDto createChat(Long memberId, ChatRequestDto requestDto) {
Chat chat = requestDto.toEntity();
if (memberId != null) {
Member member = memberRepository.findById(memberId)
Expand All @@ -30,10 +50,4 @@ public ChatResponseDto createChat(Long memberId, ChatRequestDto requestDto) {
}
return ChatResponseDto.from(chatRepository.save(chat));
}

public String getOrCreateChatId(Long memberId, ChatRequestDto requestDto) {
return requestDto.chatId() != null ?
chatQueryService.readChat(memberId, requestDto.chatId()).id() :
createChat(memberId, requestDto).id();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@ public ResponseEntity<MemberInfoResponseDto> getMemberInfo(@AuthMember Long memb
return ResponseEntity.ok(responseDto);
}

@DeleteMapping("/me")
public ResponseEntity<Void> deleteMember(@AuthMember Long memberId) {
memberCommandService.deleteMember(memberId);
return ResponseEntity.noContent().build();
}

@PutMapping("/me")
@PatchMapping("/me")
public ResponseEntity<MemberInfoResponseDto> changePassword(@AuthMember Long memberId,
@RequestBody @Valid ChangePasswordRequestDto requestDto) {
MemberInfoResponseDto responseDto = memberCommandService.changePassword(memberId, requestDto);
return ResponseEntity.ok(responseDto);
}

@DeleteMapping("/me")
public ResponseEntity<Void> deleteMember(@AuthMember Long memberId) {
memberCommandService.deleteMember(memberId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.hyunmin.gpt.domain.member.service;

import com.hyunmin.gpt.domain.member.dto.ChangePasswordRequestDto;
import com.hyunmin.gpt.domain.member.dto.MemberInfoResponseDto;
import com.hyunmin.gpt.global.common.entity.Member;
import com.hyunmin.gpt.global.common.repository.MemberRepository;
import com.hyunmin.gpt.global.exception.GeneralException;
import com.hyunmin.gpt.global.exception.code.ErrorCode;
import com.hyunmin.gpt.domain.member.dto.ChangePasswordRequestDto;
import com.hyunmin.gpt.domain.member.dto.MemberInfoResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
Expand All @@ -19,14 +19,15 @@ public class MemberCommandService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;

public void deleteMember(Long id) {
memberRepository.deleteById(id);
}

public MemberInfoResponseDto changePassword(Long id, ChangePasswordRequestDto requestDto) {
Member member = memberRepository.findById(id).orElseThrow(() -> new GeneralException(ErrorCode.MEMBER_NOT_FOUND));
String newEncodedPw = passwordEncoder.encode(requestDto.password());
member.changePassword(newEncodedPw);
return MemberInfoResponseDto.from(member);
}

public void deleteMember(Long id) {
Member member = memberRepository.findById(id).orElseThrow(() -> new GeneralException(ErrorCode.MEMBER_NOT_FOUND));
memberRepository.delete(member);
}
}
2 changes: 1 addition & 1 deletion src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
spring:
datasource:
url: jdbc:h2:file:~/db
url: jdbc:h2:file:~/db/gpt
username: sa
password:
driver-class-name: org.h2.Driver
Expand Down

0 comments on commit e23de8e

Please sign in to comment.