Skip to content
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

[FEAT] university board 기능 구현 #20

Merged
merged 17 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.springframework.web.bind.annotation.RestController;

import com.cotato.kampus.domain.board.application.BoardService;
import com.cotato.kampus.domain.board.dto.response.BoardListResponse;
import com.cotato.kampus.domain.board.dto.response.BoardResponse;
import com.cotato.kampus.domain.board.dto.response.FavoriteBoardResponse;
import com.cotato.kampus.global.common.dto.DataResponse;
Expand All @@ -24,17 +25,26 @@ public class BoardController {
private final BoardService boardService;

@GetMapping("")
public ResponseEntity<DataResponse<BoardResponse>> getBoardList(){
public ResponseEntity<DataResponse<BoardListResponse>> getBoardList(){
return ResponseEntity.ok(DataResponse.from(
BoardResponse.of(
BoardListResponse.of(
boardService.getBoardList()))
);
}

@GetMapping("/favorite")
public ResponseEntity<DataResponse<BoardResponse>> getFavoriteBoardList(){
@GetMapping("/university")
public ResponseEntity<DataResponse<BoardResponse>> getUniversityBoard(){
return ResponseEntity.ok(DataResponse.from(
BoardResponse.of(
boardService.getUniversityBoard()
)
));
}

@GetMapping("/favorite")
public ResponseEntity<DataResponse<BoardListResponse>> getFavoriteBoardList(){
return ResponseEntity.ok(DataResponse.from(
BoardListResponse.of(
boardService.getFavoriteBoardList()
)
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@
import java.util.List;
import java.util.Set;

import com.cotato.kampus.domain.board.dto.BoardDto;
import com.cotato.kampus.domain.board.dto.BoardWithFavoriteStatusDto;

public class BoardDtoEnhancer {

public static List<BoardDto> updateFavoriteStatus(List<BoardDto> boardDtos, Set<Long> favoriteBoardIds) {
return boardDtos.stream()
.map(boardDto -> BoardDto.of(
public static List<BoardWithFavoriteStatusDto> updateFavoriteStatus(List<BoardWithFavoriteStatusDto> boardWithFavoriteStatusDtos, Set<Long> favoriteBoardIds) {
return boardWithFavoriteStatusDtos.stream()
.map(boardDto -> BoardWithFavoriteStatusDto.of(
boardDto.boardId(),
boardDto.boardName(),
favoriteBoardIds.contains(boardDto.boardId())
))
.toList();
}

public static List<BoardDto> filterFavoriteBoards(List<BoardDto> boardDtos, Set<Long> favoriteBoardIds) {
return boardDtos.stream()
public static List<BoardWithFavoriteStatusDto> filterFavoriteBoards(List<BoardWithFavoriteStatusDto> boardWithFavoriteStatusDtos, Set<Long> favoriteBoardIds) {
return boardWithFavoriteStatusDtos.stream()
.filter(boardDto -> favoriteBoardIds.contains(boardDto.boardId()))
.map(boardDto -> BoardDto.of(
.map(boardDto -> BoardWithFavoriteStatusDto.of(
boardDto.boardId(),
boardDto.boardName(),
true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.cotato.kampus.domain.board.application;

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

Expand Down Expand Up @@ -30,4 +29,4 @@ public Set<Long> read() {
.map(BoardFavorite::getBoardId)
.collect(Collectors.toSet());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.springframework.transaction.annotation.Transactional;

import com.cotato.kampus.domain.board.dao.BoardRepository;
import com.cotato.kampus.domain.board.dto.BoardDto;
import com.cotato.kampus.domain.board.dto.BoardWithFavoriteStatusDto;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
Expand All @@ -17,9 +17,9 @@
public class BoardReader {
private final BoardRepository boardRepository;

public List<BoardDto> readAll(){
public List<BoardWithFavoriteStatusDto> readAll(){
return boardRepository.findAll().stream()
.map(board -> BoardDto.of(
.map(board -> BoardWithFavoriteStatusDto.of(
board.getId(),
board.getBoardName(),
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import org.springframework.stereotype.Service;

import com.cotato.kampus.domain.board.dto.BoardDto;
import com.cotato.kampus.domain.board.dto.BoardWithFavoriteStatusDto;
import com.cotato.kampus.domain.user.application.UserValidator;

import lombok.RequiredArgsConstructor;

Expand All @@ -14,29 +16,31 @@
public class BoardService {

private final BoardReader boardReader;
private final UniversityBoardReader universityBoardReader;
private final BoardValidator boardValidator;
private final BoardFavoriteReader boardFavoriteReader;
private final BoardFavoriteAppender boardFavoriteAppender;
private final BoardFavoriteDeleter boardFavoriteDeleter;
private final UserValidator userValidator;

public List<BoardDto> getBoardList(){
public List<BoardWithFavoriteStatusDto> getBoardList(){

// 즐겨찾는 게시판 조회
Set<Long> favoriteBoardIds = boardFavoriteReader.read();

// 전체 게시판 조회
List<BoardDto> boards = boardReader.readAll();
List<BoardWithFavoriteStatusDto> boards = boardReader.readAll();

// 즐겨찾기 여부 매핑
return BoardDtoEnhancer.updateFavoriteStatus(boards, favoriteBoardIds);
}

public List<BoardDto> getFavoriteBoardList() {
public List<BoardWithFavoriteStatusDto> getFavoriteBoardList() {
// 즐겨찾는 게시판 조회
Set<Long> favoriteBoardIds = boardFavoriteReader.read();

// 전체 게시판 조회
List<BoardDto> boards = boardReader.readAll();
List<BoardWithFavoriteStatusDto> boards = boardReader.readAll();

// 즐겨찾는 게시판만 필터링
return BoardDtoEnhancer.filterFavoriteBoards(boards, favoriteBoardIds);
Expand All @@ -55,4 +59,10 @@ public Long removeFavoriteBoard(Long boardId) {
return boardId;
}

public BoardDto getUniversityBoard(){
userValidator.validateStudentVerification();

return universityBoardReader.read();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@
public class BoardValidator {
private final BoardRepository boardRepository;


public void validateBoardExists(Long boardId){
if(!boardRepository.existsById(boardId))
throw new AppException(ErrorCode.BOARD_NOT_FOUND);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.cotato.kampus.domain.board.application;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.cotato.kampus.domain.board.dao.UniversityBoardRepository;
import com.cotato.kampus.domain.board.domain.UniversityBoard;
import com.cotato.kampus.domain.board.dto.BoardDto;
import com.cotato.kampus.domain.common.application.ApiUserResolver;
import com.cotato.kampus.domain.user.domain.User;
import com.cotato.kampus.global.error.ErrorCode;
import com.cotato.kampus.global.error.exception.AppException;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;

@Component
@Transactional(readOnly = true)
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public class UniversityBoardReader {
private final UniversityBoardRepository universityBoardRepository;
private final ApiUserResolver apiUserResolver;

public BoardDto read(){
User user = apiUserResolver.getUser();

Long universityId = user.getUniversityId();

UniversityBoard universityBoard = universityBoardRepository.findByUniversityId(universityId)
.orElseThrow(() -> new AppException(ErrorCode.UNIVERSITY_NOT_FOUND));

return BoardDto.of(
universityBoard.getId(),
universityBoard.getBoardName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.cotato.kampus.domain.board.dao;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import com.cotato.kampus.domain.board.domain.UniversityBoard;

public interface UniversityBoardRepository extends JpaRepository<UniversityBoard, Long> {
Optional<UniversityBoard> findByUniversityId(Long universityId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "board")
@Inheritance(strategy = InheritanceType.JOINED)
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Board extends BaseTimeEntity {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.cotato.kampus.domain.board.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class UniversityBoard extends Board {

@Column(name = "university_id", nullable = false)
private Long universityId;

public UniversityBoard(Long universityId, String boardName) {
super(boardName);
this.universityId = universityId;
}
}
11 changes: 5 additions & 6 deletions src/main/java/com/cotato/kampus/domain/board/dto/BoardDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

public record BoardDto(
Long boardId,
String boardName,
boolean isFavorite
){
public static BoardDto of(Long boardId, String boardName, boolean isFavorite) {
return new BoardDto(boardId, boardName, isFavorite);
String boardName
) {
public static BoardDto of(Long boardId, String boardName) {
return new BoardDto(boardId, boardName);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.cotato.kampus.domain.board.dto;

public record BoardWithFavoriteStatusDto(
Long boardId,
String boardName,
boolean isFavorite
){
public static BoardWithFavoriteStatusDto of(Long boardId, String boardName, boolean isFavorite) {
return new BoardWithFavoriteStatusDto(boardId, boardName, isFavorite);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.cotato.kampus.domain.board.dto.response;

import java.util.List;

import com.cotato.kampus.domain.board.dto.BoardWithFavoriteStatusDto;

public record BoardListResponse(
List<BoardWithFavoriteStatusDto> boards
) {
public static BoardListResponse of(List<BoardWithFavoriteStatusDto> boards){
return new BoardListResponse(boards);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.cotato.kampus.domain.board.dto.response;

import java.util.List;

import com.cotato.kampus.domain.board.dto.BoardDto;

public record BoardResponse(
List<BoardDto> boards
BoardDto boardDto
) {
public static BoardResponse of(List<BoardDto> boards){
return new BoardResponse(boards);
public static BoardResponse of(BoardDto boardDto) {
return new BoardResponse(boardDto);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ public record FavoriteBoardResponse(
public static FavoriteBoardResponse of(Long boardId) {
return new FavoriteBoardResponse(boardId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.springframework.stereotype.Component;

import com.cotato.kampus.domain.user.application.UserFinder;
import com.cotato.kampus.domain.user.dao.UserRepository;
import com.cotato.kampus.domain.user.domain.User;
import com.cotato.kampus.global.auth.nativeapp.AppUserDetails;
import com.cotato.kampus.global.error.ErrorCode;
import com.cotato.kampus.global.error.exception.AppException;
Expand All @@ -18,6 +20,7 @@
public class ApiUserResolver {

private final UserFinder userFinder;
private final UserRepository userRepository;

public Long getUserId() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Expand All @@ -29,4 +32,16 @@ public Long getUserId() {
throw new AppException(ErrorCode.USER_NOT_FOUND);
}
}

public User getUser(){
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof AppUserDetails userDetails) {
Long userId = userFinder.findByUniqueId(userDetails.getUniqueId()).getId();
return userRepository.findById(userId)
.orElseThrow(() -> new AppException(ErrorCode.USER_NOT_FOUND));
} else {
throw new AppException(ErrorCode.USER_NOT_FOUND);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.stereotype.Component;

import com.cotato.kampus.domain.common.application.ApiUserResolver;
import com.cotato.kampus.domain.user.dao.UserRepository;
import com.cotato.kampus.domain.user.domain.User;
import com.cotato.kampus.global.error.ErrorCode;
Expand All @@ -20,4 +21,5 @@ public User findByUniqueId(String uniqueId) {
return userRepository.findByUniqueId(uniqueId)
.orElseThrow(() -> new AppException(ErrorCode.USER_NOT_FOUND));
}

}
Loading