Skip to content
Open
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 @@ -35,6 +35,7 @@ public class UserController {
private final RegionGetUseCase regionGetUseCase;
private final BlockUserCreateUseCase blockUserCreateUseCase;
private final BlockCheckUseCase blockCheckUseCase;
private final BlockUseCase blockUseCase;

@GetMapping
@Operation(summary = "사용자 정보 조회 API", description = "특정 사용자의 상세 정보를 조회하는 API (Token 기준)")
Expand Down Expand Up @@ -174,10 +175,9 @@ public ResponseEntity<ResponseDTO<Void>> followUser(
@UserId Long userId,
@RequestBody UserFollowRequestDTO requestDTO
) {
UserFollowCommand command = new UserFollowCommand(
userId,
requestDTO.targetUserId()
);
blockUseCase.follow(userId, requestDTO.targetUserId());

UserFollowCommand command = new UserFollowCommand(userId,requestDTO.targetUserId());
userFollowUseCase.createFollow(command);

return ResponseEntity.ok(ResponseDTO.success(null));
Expand All @@ -192,11 +192,8 @@ public ResponseEntity<ResponseDTO<Void>> unfollowUser(
@UserId Long userId,
@RequestBody UserFollowRequestDTO requestDTO
) {
UserFollowCommand command = new UserFollowCommand(
userId,
requestDTO.targetUserId()
);
userFollowUseCase.deleteFollow(command);

blockUseCase.unfollow(userId, requestDTO.targetUserId());
return ResponseEntity.ok(ResponseDTO.success(null));
}

Expand Down Expand Up @@ -230,11 +227,7 @@ public ResponseEntity<ResponseDTO<Void>> unBlockUser(
@UserId Long userId,
@RequestBody UserBlockRequestDTO requestDTO
) {
BlockUserCommand command = new BlockUserCommand(
userId,
requestDTO.targetUserId()
);
blockUserCreateUseCase.deleteUserBlock(command);
blockUseCase.unblock(userId, requestDTO.targetUserId());
return ResponseEntity.ok(ResponseDTO.success(null));
}

Expand All @@ -256,4 +249,14 @@ public ResponseEntity<ResponseDTO<RegionListResponseDTO>> getRegion() {
RegionListResponseDTO regionListResponseDTO = regionGetUseCase.getRegionList();
return ResponseEntity.status(HttpStatus.OK).body(ResponseDTO.success(regionListResponseDTO));
}

@PostMapping("/report")
@Operation(summary = "유저 신고 API", description = "다른 사용자를 신고합니다.")
public ResponseEntity<ResponseDTO<Void>> reportUser(
@UserId Long userId,
@RequestBody UserBlockRequestDTO requestDTO
) {
blockUseCase.report(userId, requestDTO.targetUserId()); //
return ResponseEntity.ok(ResponseDTO.success(null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,108 +2,179 @@

import com.spoony.spoony_server.adapter.out.persistence.block.db.BlockEntity;
import com.spoony.spoony_server.adapter.out.persistence.block.db.BlockRepository;
import com.spoony.spoony_server.adapter.out.persistence.block.db.BlockStatus;
import com.spoony.spoony_server.adapter.out.persistence.user.db.UserEntity;
import com.spoony.spoony_server.domain.user.BlockStatus;
import com.spoony.spoony_server.adapter.out.persistence.user.db.UserRepository;
import com.spoony.spoony_server.adapter.out.persistence.user.mapper.BlockMapper;
import com.spoony.spoony_server.application.port.out.user.BlockPort;
import com.spoony.spoony_server.global.exception.BusinessException;
import com.spoony.spoony_server.global.message.business.UserErrorMessage;
import com.spoony.spoony_server.domain.user.Block;

import lombok.RequiredArgsConstructor;

import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Repository
@Transactional
@RequiredArgsConstructor
public class BlockPersistenceAdapter implements BlockPort {

private final UserRepository userRepository;
private final BlockRepository blockRepository;

@Override
public void saveUserBlockRelation(Long fromUserId, Long toUserId, BlockStatus status) {
UserEntity fromUserEntity = userRepository.findById(fromUserId).orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));
UserEntity toUserEntity = userRepository.findById(toUserId).orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));

BlockEntity blockEntity = BlockEntity.builder()
.blocker(fromUserEntity)
.blocked(toUserEntity)
.status(status)
.build();

blockRepository.save(blockEntity);
public Optional<Block> findByBlockerAndBlocked(Long blockerId, Long blockedId) {
return blockRepository.findByBlocker_UserIdAndBlocked_UserId(blockerId, blockedId)
.map(BlockMapper::toDomain);
}

@Override
public boolean existsBlockUserRelation(Long fromUserId, Long toUserId) {
return blockRepository.findActiveBlockByUsers(fromUserId, toUserId).isPresent();
public void saveBlock(Block block) {
blockRepository.save(BlockMapper.toEntity(block));
}

@Override
public List<Long> getBlockedUserIds(Long userId) { //user에게 차단당한 사람들
return blockRepository.findUserIdsBlockedByBlockOrReport(userId);
public List<Block> findExpiredBlocks(List<BlockStatus> statuses, LocalDateTime now, Pageable pageable) {
return blockRepository.findExpiredBlocks(statuses, now, pageable)
.stream().map(BlockMapper::toDomain).toList();
}

@Override
public List<Long> getBlockerUserIds(Long userId) { //user를 차단하고있는 사람들
return blockRepository.findUserIdsBlockingByBlockOrReport(userId);
public void markFeedPurgedAt(Long blockerId, Long blockedId, LocalDateTime now) {
blockRepository.markFeedPurgedAt(blockerId, blockedId, now);
}

@Override
public List<Long> getUnfollowedUserIds(Long userId) {
return blockRepository.findUnfollowedUserIds(userId);
public boolean existsBlockUserRelation(Long fromUserId, Long toUserId) {
return blockRepository.findActiveBlockByUsers(fromUserId, toUserId).isPresent();
}

@Override
public Optional<BlockStatus> getBlockRelationStatus(Long fromUserId, Long toUserId) {
return blockRepository.findByBlocker_UserIdAndBlocked_UserId(fromUserId, toUserId).map(BlockEntity::getStatus);
public void deleteUserBlockRelation(Long fromUserId, Long toUserId, BlockStatus status) {
blockRepository.deleteByBlockerUserIdAndBlockedUserIdAndStatus(fromUserId, toUserId, status);
}

@Override
public void updateUserBlockRelation(Long userId, Long targetUserId, BlockStatus status) {
// 차단 관계를 찾고, 상태를 업데이트하는 쿼리 작성
BlockEntity blockEntity = blockRepository.findByBlocker_UserIdAndBlocked_UserId(userId, targetUserId)
.orElseThrow(() -> new BusinessException(UserErrorMessage.BLOCK_RELATION_NOT_FOUND));

BlockEntity updatedBlockEntity = blockEntity.changeStatus(status);
blockRepository.save(updatedBlockEntity); // 상태 저장
public List<Long> getBlockedUserIds(Long userId) {
return blockRepository.findUserIdsBlockedByBlockOrReport(userId);
}

@Override
public void saveOrUpdateUserBlockRelation(Long fromUserId, Long toUserId, BlockStatus status) {
Optional<BlockEntity> optionalBlock = blockRepository.findByBlocker_UserIdAndBlocked_UserId(fromUserId, toUserId);

if (optionalBlock.isPresent()) {
BlockEntity blockEntity = optionalBlock.get();
if (blockEntity.getStatus() != status) {
blockEntity.updateStatus(status);
}
} else {
UserEntity fromUser = userRepository.findById(fromUserId)
.orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));
UserEntity toUser = userRepository.findById(toUserId)
.orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));

BlockEntity newBlock = BlockEntity.builder()
.blocker(fromUser)
.blocked(toUser)
.status(status)
.build();

blockRepository.save(newBlock);
}
public List<Long> getBlockerUserIds(Long userId) {
return blockRepository.findUserIdsBlockingByBlockOrReport(userId);
}

@Override
public void deleteUserBlockRelation(Long fromUserId, Long toUserId, BlockStatus status) {
blockRepository.deleteByBlockerUserIdAndBlockedUserIdAndStatus(fromUserId, toUserId, status);
public List<Long> getUnfollowedUserIds(Long userId) {
return blockRepository.findUnfollowedUserIds(userId);
}

@Override
public Optional<BlockStatus> getBlockRelationStatus(Long fromUserId, Long toUserId) {
return blockRepository.findByBlocker_UserIdAndBlocked_UserId(fromUserId, toUserId)
.map(BlockEntity::getStatus);
}

@Override
public List<Long> getRelatedUserIdsByReportStatus(Long userId) {
return blockRepository.findRelatedUserIdsByReportStatus(userId,BlockStatus.REPORT);
return blockRepository.findRelatedUserIdsByReportStatus(userId, BlockStatus.REPORT);
}
// private final UserRepository userRepository;
// private final BlockRepository blockRepository;
//
// @Override
// public void saveUserBlockRelation(Long fromUserId, Long toUserId, BlockStatus status) {
// UserEntity fromUserEntity = userRepository.findById(fromUserId).orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));
// UserEntity toUserEntity = userRepository.findById(toUserId).orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));
//
// BlockEntity blockEntity = BlockEntity.builder()
// .blocker(fromUserEntity)
// .blocked(toUserEntity)
// .status(status)
// .build();
//
// blockRepository.save(blockEntity);
// }
//
// @Override
// public boolean existsBlockUserRelation(Long fromUserId, Long toUserId) {
// return blockRepository.findActiveBlockByUsers(fromUserId, toUserId).isPresent();
// }
//
// @Override
// public List<Long> getBlockedUserIds(Long userId) { //user에게 차단당한 사람들
// return blockRepository.findUserIdsBlockedByBlockOrReport(userId);
// }
//
// @Override
// public List<Long> getBlockerUserIds(Long userId) { //user를 차단하고있는 사람들
// return blockRepository.findUserIdsBlockingByBlockOrReport(userId);
// }
//
// @Override
// public List<Long> getUnfollowedUserIds(Long userId) {
// return blockRepository.findUnfollowedUserIds(userId);
// }
//
// @Override
// public Optional<BlockStatus> getBlockRelationStatus(Long fromUserId, Long toUserId) {
// return blockRepository.findByBlocker_UserIdAndBlocked_UserId(fromUserId, toUserId).map(BlockEntity::getStatus);
// }
//
//
// @Override
// public void saveOrUpdateUserBlockRelation(Long fromUserId, Long toUserId, BlockStatus status) {
// Optional<BlockEntity> optionalBlock = blockRepository.findByBlocker_UserIdAndBlocked_UserId(fromUserId, toUserId);
//
// if (optionalBlock.isEmpty()) {
// UserEntity fromUser = userRepository.findById(fromUserId)
// .orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));
// UserEntity toUser = userRepository.findById(toUserId)
// .orElseThrow(() -> new BusinessException(UserErrorMessage.USER_NOT_FOUND));
//
// BlockEntity newBlock = BlockEntity.builder()
// .blocker(fromUser)
// .blocked(toUser)
// .status(status)
// .build();
//
// blockRepository.save(newBlock);
// }
//
// }
//
// @Override
// public void deleteUserBlockRelation(Long fromUserId, Long toUserId, BlockStatus status) {
// blockRepository.deleteByBlockerUserIdAndBlockedUserIdAndStatus(fromUserId, toUserId, status);
//
// }
// @Override
// public List<Long> getRelatedUserIdsByReportStatus(Long userId) {
// return blockRepository.findRelatedUserIdsByReportStatus(userId,BlockStatus.REPORT);
// }
//
// @Override
// public List<Block> findExpiredBlocks(List<BlockStatus> statuses, LocalDateTime now, Pageable pageable) {
// return blockRepository.findExpiredBlocks(statuses,now,pageable)
// .stream().map(BlockMapper::toDomain).toList();
// }
//
// @Override
// public Optional<Block> findByBlockerAndBlocked(Long blockerId, Long blockedId) {
// return Optional.empty();
// }
//
// @Override
// public void saveBlock(Block block) {
//
// }
//
// @Override
// public void markFeedPurgedAt(Long blockerId, Long blockedId, LocalDateTime now) {
// blockRepository.markFeedPurgedAt(blockerId,blockedId,now);
//
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,56 @@


import com.spoony.spoony_server.adapter.out.persistence.user.db.UserEntity;
import com.spoony.spoony_server.domain.user.BlockStatus;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "block")
@Table(name = "block",
uniqueConstraints = @UniqueConstraint(columnNames = {"blocker_id", "blocked_id"}))
public class BlockEntity {


@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long blockId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "blocker_id")
@JoinColumn(name = "blocker_id", nullable = false)
private UserEntity blocker;


@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "blocked_id")
@JoinColumn(name = "blocked_id", nullable = false)
private UserEntity blocked;



@Enumerated(EnumType.STRING)
@Column(length = 50)
@Column(length = 50, nullable = false)
private BlockStatus status;

Copy link
Contributor

Choose a reason for hiding this comment

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

status도 nullable=true가 들어갔음 싶네요

@Column(nullable = false)
private LocalDateTime time;

@Column(name = "status_changed_at", nullable = false)
private LocalDateTime statusChangedAt;

@Column(name = "expire_at")
private LocalDateTime expireAt;

@Column(name = "feed_purged_at")
private LocalDateTime feedPurgedAt;

@Builder
public BlockEntity(UserEntity blocker,UserEntity blocked,BlockStatus status){
public BlockEntity(Long blockId, UserEntity blocker, UserEntity blocked, BlockStatus status,
LocalDateTime statusChangedAt, LocalDateTime expireAt, LocalDateTime feedPurgedAt) {
this.blockId = blockId;
this.blocker = blocker;
this.blocked = blocked;
this.status = status;
this.time = LocalDateTime.now();

}

public void updateStatus(BlockStatus status) {
this.status = status;
this.time = LocalDateTime.now();
}
public BlockEntity changeStatus(BlockStatus status) {
return BlockEntity.builder()
.blocker(this.blocker)
.blocked(this.blocked)
.status(status)
.build();
this.statusChangedAt = statusChangedAt;
this.expireAt = expireAt;
this.feedPurgedAt = feedPurgedAt;
}
}
Loading