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

관심 없음 기능 추가 #47

Merged
merged 6 commits into from
Jan 27, 2024
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
@@ -0,0 +1,32 @@
package com.sickgyun.server.interest.domain;

import com.sickgyun.server.interest.domain.type.Type;

import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class NotInterested {

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

Long userId;
Long partyId;
Comment on lines +21 to +23
Copy link
Contributor

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.

관심없음과 관련해서는 graphQL 복잡한 쿼리만 날아가는데 그럴 때에는 ID만 매핑하고 쓰는게 훨씬 편하더라구요. 사실 이것보다 저거 두개 복합키로 쓰려고 했는데 따로 클래스 빼자고 하니, 필드가 ID하나인 객체가 만들어져서 일단 저렇게 했습니다 😃

@Enumerated(EnumType.STRING)
Type partyType;

public NotInterested(Long userId, Long partyId, Type partyType) {
this.userId = userId;
this.partyId = partyId;
this.partyType = partyType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sickgyun.server.interest.domain.repository;

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

import com.sickgyun.server.interest.domain.NotInterested;
import com.sickgyun.server.interest.domain.type.Type;

public interface NotInterestedRepository extends JpaRepository<NotInterested, Long> {
boolean existsByUserIdAndPartyIdAndPartyType(Long userId, Long partyId, Type partyType);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sickgyun.server.interest.domain.type;

public enum Type {
REQRUIT
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.sickgyun.server.interest.exception;

import org.springframework.http.HttpStatus;

import com.sickgyun.server.common.exception.SickgyunException;

public class AlreadyNotInterestedException extends SickgyunException {
public AlreadyNotInterestedException(Long partyId) {
super(HttpStatus.BAD_REQUEST, partyId + "를 이미 관심없음으로 분류하였습니다");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sickgyun.server.interest.exception;

import org.springframework.http.HttpStatus;

import com.sickgyun.server.common.exception.SickgyunException;
import com.sickgyun.server.interest.domain.type.Type;

public class TypeNotExistException extends SickgyunException {
public TypeNotExistException(Type partyType) {
super(HttpStatus.BAD_REQUEST, partyType + "타입은 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.sickgyun.server.interest.presentation;

import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.sickgyun.server.auth.annotation.LoginRequired;
import com.sickgyun.server.auth.service.implementation.AuthReader;
import com.sickgyun.server.interest.presentation.dto.CreatNotInterestRequest;
import com.sickgyun.server.interest.service.CommandInterestService;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/interest")
@RequiredArgsConstructor
public class InterestController {
private final CommandInterestService commandInterestService;
private final AuthReader authReader;

Comment on lines +22 to +24
Copy link
Contributor

Choose a reason for hiding this comment

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

생각을 해보니 Reader는 서비스에서 사용하는 구현체라 프레젠테이션에서 바로 쓰지 말고 서비스를 구현해서 사용하는 게 어떤가요????

Copy link
Member Author

Choose a reason for hiding this comment

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

이건 나중에 몰아서 개선하죠!

@PostMapping("/not")
@ResponseStatus(HttpStatus.CREATED)
@LoginRequired
public void createNotInterested(@Validated @RequestBody CreatNotInterestRequest request) {
commandInterestService.createNotInterest(authReader.getCurrentUser(), request.partyId(), request.partyType());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.sickgyun.server.interest.presentation.dto;

import com.sickgyun.server.interest.domain.type.Type;

import jakarta.validation.constraints.NotNull;

public record CreatNotInterestRequest(
@NotNull(message = "partyId는 null일 수 없습니다.")
Long partyId,

@NotNull(message = "partyType은 null일 수 없습니다.")
Type partyType
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.sickgyun.server.interest.service;

import org.springframework.stereotype.Service;

import com.sickgyun.server.interest.domain.type.Type;
import com.sickgyun.server.interest.service.implementation.InterestCreator;
import com.sickgyun.server.interest.service.implementation.InterestValidator;
import com.sickgyun.server.user.domain.User;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class CommandInterestService {
private final InterestCreator interestCreator;
private final InterestValidator interestValidator;

public void createNotInterest(User user, Long partyId, Type partyType) {
interestValidator.shouldPartyBeExist(partyId, partyType);
interestValidator.shouldNotAlreadyNotInterested(user, partyId, partyType);
interestCreator.createNotInterest(
user.getId(),
partyId,
partyType
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.sickgyun.server.interest.service.implementation;

import org.springframework.stereotype.Service;

import com.sickgyun.server.interest.domain.NotInterested;
import com.sickgyun.server.interest.domain.repository.NotInterestedRepository;
import com.sickgyun.server.interest.domain.type.Type;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class InterestCreator {
private final NotInterestedRepository notInterestedRepository;

public void createNotInterest(Long userId, Long partyId, Type partyType) {
notInterestedRepository.save(
new NotInterested(
userId,
partyId,
partyType
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.sickgyun.server.interest.service.implementation;

import org.springframework.stereotype.Service;

import com.sickgyun.server.interest.domain.repository.NotInterestedRepository;
import com.sickgyun.server.interest.domain.type.Type;
import com.sickgyun.server.interest.exception.AlreadyNotInterestedException;
import com.sickgyun.server.interest.exception.TypeNotExistException;
import com.sickgyun.server.reqruit.service.implementation.ReqruitValidator;
import com.sickgyun.server.user.domain.User;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class InterestValidator {
private final ReqruitValidator reqruitValidator;
private final NotInterestedRepository notInterestedRepository;

public void shouldPartyBeExist(Long partyId, Type partyType) {
if (partyType == Type.REQRUIT) {
reqruitValidator.requiredShouldBeExist(partyId);
return;
}

throw new TypeNotExistException(partyType);
}

public void shouldNotAlreadyNotInterested(User user, Long partyId, Type partyType) {
boolean isAlreadyExist = notInterestedRepository.existsByUserIdAndPartyIdAndPartyType(user.getId(), partyId,
Copy link
Contributor

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.

읭 어떻게요??

Copy link
Contributor

Choose a reason for hiding this comment

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

저거 레파지토리의 메소드 네이밍 말한거였어요!!

partyType);

if (isAlreadyExist) {
throw new AlreadyNotInterestedException(partyId);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.sickgyun.server.reqruit.exception;

import org.springframework.http.HttpStatus;

import com.sickgyun.server.common.exception.SickgyunException;

public class ReqruitIsNotExistException extends SickgyunException {
public ReqruitIsNotExistException(Long requireId) {
super(HttpStatus.NOT_FOUND, requireId + "이 아이디인 채용공고가 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.sickgyun.server.reqruit.service.implementation;

import org.springframework.stereotype.Service;

import com.sickgyun.server.reqruit.domain.repository.ReqruitRepository;
import com.sickgyun.server.reqruit.exception.ReqruitIsNotExistException;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class ReqruitValidator {
private final ReqruitRepository reqruitRepository;

public void requiredShouldBeExist(Long requireId) {
boolean isExist = reqruitRepository.existsById(requireId);

if (!isExist) {
throw new ReqruitIsNotExistException(requireId);
}
}
}
Loading