Skip to content
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
@@ -1,16 +1,20 @@
package com.jootalkpia.workspace_server.controller;


import com.jootalkpia.aop.JootalkpiaAuthenticationContext;
//import com.jootalkpia.aop.JootalkpiaAuthenticationContext;
import com.jootalkpia.workspace_server.dto.ChannelListDTO;
import com.jootalkpia.workspace_server.dto.SimpleChannel;
import com.jootalkpia.workspace_server.entity.Channels;
import com.jootalkpia.workspace_server.service.WorkSpaceService;
import com.jootalkpia.workspace_server.util.ValidationUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
Expand All @@ -20,7 +24,7 @@
public class WorkSpaceController {

private final WorkSpaceService workSpaceService;
private final Long userId = JootalkpiaAuthenticationContext.getUserInfo().userId();
private final Long userId = 1L;//JootalkpiaAuthenticationContext.getUserInfo().userId();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트용인거죠?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 로컬에서 테스트할 때는 일단 이런 식으로 해야해요! 근데 배포 환경에서 어떻게 해야할지 보람님과 이야기하긴 했는데 정하진 못해서 나중에 논의합시당!


@GetMapping("/{workspaceId}/channels")
public ResponseEntity<ChannelListDTO> getChannels(@PathVariable Long workspaceId) {
Expand All @@ -31,4 +35,14 @@ public ResponseEntity<ChannelListDTO> getChannels(@PathVariable Long workspaceId
ChannelListDTO channelListDTO = workSpaceService.getChannels(userId, workspaceId);
return ResponseEntity.ok().body(channelListDTO);
}

@PostMapping("/{workspaceId}/channels")
public ResponseEntity<SimpleChannel> createChannel(@PathVariable Long workspaceId, @RequestParam String channelName) {
// 유효성 검증
ValidationUtils.validateWorkSpaceId(workspaceId);
log.info("Creating channels for workspace with id: {}", workspaceId);

SimpleChannel channel = workSpaceService.createChannel(workspaceId, channelName);
return ResponseEntity.ok().body(channel);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.jootalkpia.workspace_server.dto;

import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class SimpleChannel {
private Long channelId;
private String channelName;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.jootalkpia.workspace_server.entity;

import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
import lombok.Getter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

@Getter
@MappedSuperclass
public abstract class BaseEntity {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ID 필드는 넣지 않은 이유가 있을까요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아이디는 그냥 id로 이름짓지말고 channel_id 이런 식으로 하라고 캠프장님이 말씀하셨어서 base entity로 따로 빼기가 애매하다고 판단했기 때문입니다!


@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

@Entity
@Table(name = "channels")
@Getter
public class Channels {
@NoArgsConstructor
public class Channels extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "channel_id", nullable = false)
Expand All @@ -33,14 +36,12 @@ public class Channels {
@OneToMany(mappedBy = "channels", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserChannel> userChannel = new ArrayList<>();

@Column(name = "name", length = 100, nullable = false)
@Column(name = "name", length = 100, nullable = false, unique = true)
private String name;

@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@Builder
public Channels(WorkSpace workSpace, String name) {
this.workSpace = workSpace;
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@Entity
@Table(name = "mention")
@Getter
public class Mention {
public class Mention extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "mention_id", nullable = false)
Expand All @@ -32,11 +32,4 @@ public class Mention {
@Column(name = "is_unread", nullable = false)
private Boolean isUnread;

@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
@Entity
@Table(name = "user_channel")
@Getter
public class UserChannel {
public class UserChannel extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_channel_id", nullable = false)
Expand All @@ -40,11 +40,4 @@ public class UserChannel {
@Column(name = "mute", nullable = false)
private Boolean mute;

@CreationTimestamp
@Column(name = "createdAt", updatable = false)
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "updatedAt")
private LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@Table(name = "users")
@Getter
@Setter
public class Users {
public class Users extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -38,11 +38,4 @@ public class Users {
@Column(name = "profile_image", length = 100)
private String profileImage;

@CreationTimestamp
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@Entity
@Table(name = "work_space")
@Getter
public class WorkSpace {
public class WorkSpace extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "workspace_id", nullable = false)
Expand All @@ -33,11 +33,4 @@ public class WorkSpace {
@OneToMany(mappedBy = "workSpace", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Channels> channels = new ArrayList<>();

@CreationTimestamp
@Column(name = "createdAt", updatable = false)
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "updatedAt")
private LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
public class CustomException extends RuntimeException {

private final String code;
private final String message;

public CustomException(String code, String message) {
super(message);
this.code = code;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ public enum ErrorCode {
VALIDATION_FAILED("W40002", "유효성 검증에 실패했습니다."),
MISSING_PARAMETER("W40003", "필수 파라미터가 누락되었습니다."),
INVALID_PARAMETER("W40004", "잘못된 파라미터가 포함되었습니다."),
DUPLICATE_CHANNEL_NAME("W40005", "동일한 채널명이 이미 해당 워크스페이스에 존재합니다."),

// 404 Not Found
_NOT_FOUND("W40401", "등록되지 않은 ~~입니다."),
WORKSPACE_NOT_FOUND("W40401", "등록되지 않은 워크스페이스입니다."),


// 500 Internal Server Error
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.jootalkpia.workspace_server.exception.common;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class ErrorResponse {
private String code;
private String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.jootalkpia.workspace_server.exception.common;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(CustomException.class)
public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex) {
ErrorResponse errorResponse = new ErrorResponse(ex.getCode(), ex.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
ErrorResponse errorResponse = new ErrorResponse("UNKNOWN_ERROR", "An unexpected error occurred.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import com.jootalkpia.workspace_server.entity.UserChannel;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserChannelRepository extends JpaRepository<UserChannel, Long> {
Optional<UserChannel> findByUsersUserIdAndChannelsChannelId(Long userId, Long channelId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import com.jootalkpia.workspace_server.dto.ChannelListDTO;
import com.jootalkpia.workspace_server.dto.SimpleChannel;
import com.jootalkpia.workspace_server.entity.Channels;
import com.jootalkpia.workspace_server.entity.WorkSpace;
import com.jootalkpia.workspace_server.exception.common.CustomException;
import com.jootalkpia.workspace_server.exception.common.ErrorCode;
import com.jootalkpia.workspace_server.repository.ChannelRepository;
import com.jootalkpia.workspace_server.repository.UserChannelRepository;
import com.jootalkpia.workspace_server.repository.WorkSpaceRepository;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -21,39 +23,79 @@ public class WorkSpaceService {

private final ChannelRepository channelRepository;
private final UserChannelRepository userChannelRepository;
private final WorkSpaceRepository workSpaceRepository;

public ChannelListDTO getChannels(Long userId, Long workspaceId) {
// workspaceId로 모든 채널 조회
List<Channels> channelList = fetchAllChannels(workspaceId);

// 채널 분류
List<SimpleChannel> joinedChannels = classifyChannels(userId, channelList, true);
List<SimpleChannel> unjoinedChannels = classifyChannels(userId, channelList, false);

return createChannelListDTO(joinedChannels, unjoinedChannels);
}

private List<Channels> fetchAllChannels(Long workspaceId) {
List<Channels> channelList = channelRepository.findByWorkSpaceWorkspaceId(workspaceId);
if (channelList.isEmpty()) {
throw new CustomException(ErrorCode.DATABASE_ERROR.getCode(), ErrorCode.DATABASE_ERROR.getMsg());
}
return channelList;
}

// 가입된 채널과 가입되지 않은 채널을 분류
List<SimpleChannel> joinedChannels = new ArrayList<>();
List<SimpleChannel> unjoinedChannels = new ArrayList<>();

for (Channels channels : channelList) {
SimpleChannel simpleChannel = new SimpleChannel();
simpleChannel.setChannelId(channels.getChannelId());
simpleChannel.setChannelName(channels.getName());
simpleChannel.setCreatedAt(channels.getCreatedAt());

if (isJoinedChannel(userId, channels)) {
joinedChannels.add(simpleChannel);
} else {
unjoinedChannels.add(simpleChannel);
private List<SimpleChannel> classifyChannels(Long userId, List<Channels> channelList, boolean isJoined) {
List<SimpleChannel> classifiedChannels = new ArrayList<>();
for (Channels channel : channelList) {
boolean joined = isJoinedChannel(userId, channel);
if (joined == isJoined) {
classifiedChannels.add(new SimpleChannel(channel.getChannelId(), channel.getName(), channel.getCreatedAt()));
}
}
return classifiedChannels;
}

private boolean isJoinedChannel(Long userId, Channels channels) {
return userChannelRepository.findByUsersUserIdAndChannelsChannelId(userId, channels.getChannelId()).isPresent();
}

private ChannelListDTO createChannelListDTO(List<SimpleChannel> joinedChannels, List<SimpleChannel> unjoinedChannels) {
ChannelListDTO channelListDTO = new ChannelListDTO();
channelListDTO.setJoinedChannels(joinedChannels);
channelListDTO.setUnjoinedChannels(unjoinedChannels);

return channelListDTO;
}

private boolean isJoinedChannel(Long userId, Channels channels) {
return userChannelRepository.findByUsersUserIdAndChannelsChannelId(userId, channels.getChannelId()).isPresent();
public SimpleChannel createChannel(Long workspaceId, String channelName) {
// WorkSpace 객체 조회
WorkSpace workSpace = fetchWorkSpace(workspaceId);

// 채널명 unique한지 확인
if (isChannelNameDuplicate(workspaceId, channelName)) {
throw new CustomException(ErrorCode.DUPLICATE_CHANNEL_NAME.getCode(), ErrorCode.DUPLICATE_CHANNEL_NAME.getMsg());
}
Channels channel = Channels.builder()
.workSpace(workSpace)
.name(channelName)
.build();

channelRepository.save(channel);

return new SimpleChannel(channel.getChannelId(), channel.getName(), channel.getCreatedAt());
}

private boolean isChannelNameDuplicate(Long workspaceId, String channelName) {
List<Channels> channelList = fetchAllChannels(workspaceId);
for (Channels channel : channelList) {
if (channel.getName().equals(channelName)) {
return true;
}
}
return false;
}

private WorkSpace fetchWorkSpace(Long workspaceId) {
return workSpaceRepository.findById(workspaceId)
.orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_NOT_FOUND.getCode(), ErrorCode.WORKSPACE_NOT_FOUND.getMsg()));
}
}
Loading