Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b8e547a
chore: 배포 파이프라인 트리거
Lee-Han-Jun Mar 26, 2025
c657420
Merge remote-tracking branch 'origin/dev' into feature/95/EC2test
Lee-Han-Jun Mar 26, 2025
2257b78
chore: 배포 파이프라인 트리거
Lee-Han-Jun Mar 26, 2025
e920ace
Merge pull request #101 from RealPawParazzi/feature/95/EC2test
Lee-Han-Jun Mar 26, 2025
7b18416
chore: 배포 파이프라인 트리거
Lee-Han-Jun Mar 26, 2025
8b55200
Merge pull request #102 from RealPawParazzi/feature/95/EC2test
Lee-Han-Jun Mar 26, 2025
fb9b1ab
[FIX] refreshToken 발급 방식으로 변경
geg222 Mar 28, 2025
8201e15
Merge pull request #104 from RealPawParazzi/feature/103/FixLogin
geg222 Mar 28, 2025
2ea547a
[FIX] 회원 정보 수정 오류 수정
geg222 Mar 28, 2025
93ab834
Merge pull request #106 from RealPawParazzi/feature/105/FixMemberMe
geg222 Mar 28, 2025
688484b
[FIX] 401 오류로 변경
geg222 Mar 28, 2025
5a7ff62
Merge pull request #108 from RealPawParazzi/feature/107/Fix401
geg222 Mar 28, 2025
287c142
[FIX] 대댓글 401 에러
geg222 Mar 28, 2025
5265e20
[FIX] 401 UNAUTHORIZED 수정
geg222 Mar 28, 2025
acabf0b
[FIX] kakao 로그인 refresh토큰 발급
geg222 Mar 30, 2025
0b5de9d
Merge pull request #110 from RealPawParazzi/feature/109/KakaoRefreshT…
geg222 Mar 30, 2025
9747e75
[Refactor] 멤버, 게시물, 좋아요 controller, service 분리
geg222 Mar 31, 2025
d6f2979
Merge pull request #112 from RealPawParazzi/feature/111/RefactorCode
geg222 Mar 31, 2025
2acd88e
[Refactor] Comment, pet controller 로직 분리
geg222 Mar 31, 2025
5dd5576
[FIX] member, pet 이전 코드로 변경
geg222 Apr 2, 2025
44bb585
Merge pull request #114 from RealPawParazzi/feature/113/RefactorCode2
geg222 Apr 2, 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
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Deploy to EC2

on:
push:
branches: [ dev ] # dev 브랜치에 푸시될 때만 실행
branches: [ dev ]

jobs:
deploy:
Expand Down
46 changes: 11 additions & 35 deletions src/main/java/pawparazzi/back/board/controller/BoardController.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package pawparazzi.back.board.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import pawparazzi.back.board.dto.BoardCreateRequestDto;
import pawparazzi.back.board.dto.BoardListResponseDto;
import pawparazzi.back.board.dto.BoardDetailDto;
import pawparazzi.back.board.dto.BoardUpdateRequestDto;
import pawparazzi.back.board.service.BoardService;
import pawparazzi.back.security.util.JwtUtil;
import pawparazzi.back.security.user.CustomUserDetails;

import java.util.List;

Expand All @@ -22,32 +19,21 @@
public class BoardController {

private final BoardService boardService;
private final JwtUtil jwtUtil;
private final ObjectMapper objectMapper;

/**
* 게시물 등록
*/
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<BoardDetailDto> createBoard(
@RequestHeader("Authorization") String token,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestPart("userData") String userDataJson,
@RequestPart(value = "mediaFiles", required = false) List<MultipartFile> mediaFiles,
@RequestPart(value = "titleImage", required = false) MultipartFile titleImageFile,
@RequestPart(value = "titleContent", required = false) String titleContent) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();

BoardCreateRequestDto requestDto;
try {
requestDto = objectMapper.readValue(userDataJson, BoardCreateRequestDto.class);
requestDto.setMediaFiles(mediaFiles);
requestDto.setTitleContent(titleContent);
} catch (JsonProcessingException e) {
return ResponseEntity.badRequest().body(null);
}

BoardDetailDto response = boardService.createBoard(requestDto, memberId, titleImageFile);
BoardDetailDto response = boardService.createBoard(userDataJson, memberId, titleImageFile, mediaFiles, titleContent);
return ResponseEntity.ok(response);
}

Expand Down Expand Up @@ -75,25 +61,16 @@ public ResponseEntity<List<BoardListResponseDto>> getBoardList() {
@PutMapping(value = "/{boardId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<BoardDetailDto> updateBoard(
@PathVariable Long boardId,
@RequestHeader("Authorization") String token,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestPart("userData") String userDataJson,
@RequestPart(value = "mediaFiles", required = false) List<MultipartFile> mediaFiles,
@RequestPart(value = "titleImage", required = false) MultipartFile titleImageFile,
@RequestPart(value = "titleContent", required = false) String titleContent) {

try {
Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));

BoardUpdateRequestDto requestDto = objectMapper.readValue(userDataJson, BoardUpdateRequestDto.class);

requestDto.setTitleContent(titleContent);
Long memberId = userDetails.getId();

BoardDetailDto updatedBoard = boardService.updateBoard(boardId, memberId, requestDto, mediaFiles, titleImageFile).join();

return ResponseEntity.ok(updatedBoard);
} catch (JsonProcessingException e) {
return ResponseEntity.badRequest().body(null);
}
BoardDetailDto updatedBoard = boardService.updateBoard(boardId, memberId, userDataJson, mediaFiles, titleImageFile, titleContent).join();
return ResponseEntity.ok(updatedBoard);
}

/**
Expand All @@ -109,11 +86,10 @@ public ResponseEntity<List<BoardListResponseDto>> getBoardsByMember(@PathVariabl
* 게시물 삭제
*/
@DeleteMapping("/{boardId}")
public ResponseEntity<Void> deleteBoard(@PathVariable Long boardId, @RequestHeader("Authorization") String token) {
Long userId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
public ResponseEntity<Void> deleteBoard(@PathVariable Long boardId, @AuthenticationPrincipal CustomUserDetails userDetails) {
Long userId = userDetails.getId();

boardService.deleteBoard(boardId, userId).join();

return ResponseEntity.noContent().build();
}
}
26 changes: 21 additions & 5 deletions src/main/java/pawparazzi/back/board/service/BoardService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package pawparazzi.back.board.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -48,7 +50,16 @@ public class BoardService {
* 게시물 등록
*/
@Transactional
public BoardDetailDto createBoard(BoardCreateRequestDto requestDto, Long userId, MultipartFile titleImageFile) {
public BoardDetailDto createBoard(String userDataJson, Long userId, MultipartFile titleImageFile, List<MultipartFile> mediaFiles, String titleContent) {
BoardCreateRequestDto requestDto;
try {
requestDto = new ObjectMapper().readValue(userDataJson, BoardCreateRequestDto.class);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Invalid JSON format", e);
}
requestDto.setMediaFiles(mediaFiles);
requestDto.setTitleContent(titleContent);

Member member = memberRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다."));

Expand Down Expand Up @@ -131,10 +142,15 @@ private String getTitleImageUrl(MultipartFile titleImageFile, List<String> uploa
* 게시물 수정
*/
@Transactional
public CompletableFuture<BoardDetailDto> updateBoard(Long boardId, Long userId,
BoardUpdateRequestDto requestDto,
List<MultipartFile> mediaFiles,
MultipartFile titleImageFile) {
public CompletableFuture<BoardDetailDto> updateBoard(Long boardId, Long userId, String userDataJson, List<MultipartFile> mediaFiles, MultipartFile titleImageFile, String titleContent) {
BoardUpdateRequestDto requestDto;
try {
requestDto = new ObjectMapper().readValue(userDataJson, BoardUpdateRequestDto.class);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Invalid JSON format", e);
}
requestDto.setTitleContent(titleContent);

Board board = boardRepository.findById(boardId)
.orElseThrow(() -> new EntityNotFoundException("게시물을 찾을 수 없습니다."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import pawparazzi.back.comment.dto.response.CommentListResponseDto;
import pawparazzi.back.comment.service.CommentLikeService;
import pawparazzi.back.comment.service.CommentService;
import pawparazzi.back.security.util.JwtUtil;
import pawparazzi.back.security.user.CustomUserDetails;
import org.springframework.security.core.annotation.AuthenticationPrincipal;


import java.util.Map;

Expand All @@ -22,18 +24,17 @@ public class CommentController {

private final CommentService commentService;
private final CommentLikeService commentLikeService;
private final JwtUtil jwtUtil;

/**
* 댓글 작성
*/
@PostMapping("/{boardId}")
public ResponseEntity<CommentResponseDto> createComment(
@PathVariable Long boardId,
@RequestHeader("Authorization") String token,
@RequestBody @Valid CommentRequestDto requestDto) { // DTO 적용
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody @Valid CommentRequestDto requestDto) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
CommentResponseDto response = commentService.createComment(boardId, memberId, requestDto);
return ResponseEntity.ok(response);
}
Expand All @@ -44,10 +45,10 @@ public ResponseEntity<CommentResponseDto> createComment(
@PutMapping("/{commentId}")
public ResponseEntity<CommentResponseDto> updateComment(
@PathVariable Long commentId,
@RequestHeader("Authorization") String token,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody Map<String, String> request) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
String content = request.get("content");
CommentResponseDto response = commentService.updateComment(commentId, memberId, content);
return ResponseEntity.ok(response);
Expand All @@ -59,9 +60,9 @@ public ResponseEntity<CommentResponseDto> updateComment(
@DeleteMapping("/{commentId}")
public ResponseEntity<Map<String, String>> deleteComment(
@PathVariable Long commentId,
@RequestHeader("Authorization") String token) {
@AuthenticationPrincipal CustomUserDetails userDetails) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
commentService.deleteComment(commentId, memberId);

return ResponseEntity.ok(Map.of("message", "댓글이 삭제되었습니다."));
Expand All @@ -81,9 +82,9 @@ public ResponseEntity<CommentListResponseDto> getComments(@PathVariable Long boa
@PostMapping("/{commentId}/like")
public ResponseEntity<CommentLikeResponseDto> toggleCommentLike(
@PathVariable Long commentId,
@RequestHeader("Authorization") String token) {
@AuthenticationPrincipal CustomUserDetails userDetails) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
CommentLikeResponseDto response = commentLikeService.toggleCommentLike(commentId, memberId);

return ResponseEntity.ok(response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import pawparazzi.back.comment.dto.request.ReplyRequestDto;
import pawparazzi.back.comment.dto.response.ReplyLikeResponseDto;
import pawparazzi.back.comment.dto.response.ReplyLikesResponseDto;
import pawparazzi.back.comment.dto.response.ReplyResponseDto;
import pawparazzi.back.comment.dto.response.ReplyListResponseDto;
import pawparazzi.back.comment.service.ReplyLikeService;
import pawparazzi.back.comment.service.ReplyService;
import pawparazzi.back.security.util.JwtUtil;

import pawparazzi.back.security.user.CustomUserDetails;

import java.util.Map;

Expand All @@ -23,18 +23,16 @@ public class ReplyController {

private final ReplyService replyService;
private final ReplyLikeService replyLikeService;
private final JwtUtil jwtUtil;

/**
* 대댓글 작성
*/
@PostMapping("/{commentId}")
public ResponseEntity<ReplyResponseDto> createReply(
@PathVariable Long commentId,
@RequestHeader("Authorization") String token,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody @Valid ReplyRequestDto requestDto) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
ReplyResponseDto response = replyService.createReply(commentId, memberId, requestDto);
return ResponseEntity.ok(response);
}
Expand All @@ -45,10 +43,9 @@ public ResponseEntity<ReplyResponseDto> createReply(
@PutMapping("/{replyId}")
public ResponseEntity<ReplyResponseDto> updateReply(
@PathVariable Long replyId,
@RequestHeader("Authorization") String token,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody Map<String, String> request) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
String content = request.get("content");
ReplyResponseDto response = replyService.updateReply(replyId, memberId, content);
return ResponseEntity.ok(response);
Expand All @@ -60,11 +57,9 @@ public ResponseEntity<ReplyResponseDto> updateReply(
@DeleteMapping("/{replyId}")
public ResponseEntity<Map<String, String>> deleteReply(
@PathVariable Long replyId,
@RequestHeader("Authorization") String token) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
@AuthenticationPrincipal CustomUserDetails userDetails) {
Long memberId = userDetails.getId();
replyService.deleteReply(replyId, memberId);

return ResponseEntity.ok(Map.of("message", "대댓글이 삭제되었습니다."));
}

Expand All @@ -76,18 +71,16 @@ public ResponseEntity<ReplyListResponseDto> getReplies(@PathVariable Long commen
return ResponseEntity.ok(replyService.getRepliesByComment(commentId));
}


/**
* 대댓글 좋아요 등록/삭제 (토글)
*/
@PostMapping("/{replyId}/like")
public ResponseEntity<ReplyLikeResponseDto> toggleReplyLike(
@PathVariable Long replyId,
@RequestHeader("Authorization") String token) {
@AuthenticationPrincipal CustomUserDetails userDetails) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
ReplyLikeResponseDto response = replyLikeService.toggleReplyLike(replyId, memberId);

return ResponseEntity.ok(response);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import pawparazzi.back.member.repository.MemberRepository;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package pawparazzi.back.follow.controller;

import io.jsonwebtoken.JwtException;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import pawparazzi.back.follow.dto.FollowResponseDto;
Expand All @@ -22,16 +24,24 @@ public class FollowController {
public ResponseEntity<FollowResponseDto> follow(
@PathVariable Long targetId,
@RequestHeader("Authorization") String token){
FollowResponseDto response = followService.follow(targetId, token);
return ResponseEntity.ok(response);
try {
FollowResponseDto response = followService.follow(targetId, token);
return ResponseEntity.ok(response);
} catch (JwtException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}

@DeleteMapping("/{targetId}")
public ResponseEntity<UnfollowResponseDto> unfollow(
@PathVariable Long targetId,
@RequestHeader("Authorization") String token){
UnfollowResponseDto response = followService.unfollow(targetId, token);
return ResponseEntity.ok(response);
try {
UnfollowResponseDto response = followService.unfollow(targetId, token);
return ResponseEntity.ok(response);
} catch (JwtException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}

@GetMapping("/followers/{targetId}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package pawparazzi.back.likes.controller;

import io.jsonwebtoken.JwtException;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import pawparazzi.back.likes.dto.LikeResponseDto;
import pawparazzi.back.likes.dto.LikeToggleResponseDto;
import pawparazzi.back.likes.service.LikeService;
import pawparazzi.back.security.util.JwtUtil;
import pawparazzi.back.security.user.CustomUserDetails;

import java.util.List;
import java.util.Map;
Expand All @@ -18,17 +20,16 @@
public class LikeController {

private final LikeService likeService;
private final JwtUtil jwtUtil;

/**
* 좋아요 등록/삭제
*/
@PostMapping("/{boardId}/like")
public ResponseEntity<LikeToggleResponseDto> toggleLike(
@PathVariable Long boardId,
@RequestHeader("Authorization") String token) {
@AuthenticationPrincipal CustomUserDetails userDetails) {

Long memberId = jwtUtil.extractMemberId(token.replace("Bearer ", ""));
Long memberId = userDetails.getId();
LikeToggleResponseDto response = likeService.toggleLike(boardId, memberId);

return ResponseEntity.ok(response);
Expand Down
Loading