Skip to content

Commit

Permalink
GETP-168 feat: 피플 조회 기능의 피플 좋아요 수 조회 구현 (#111)
Browse files Browse the repository at this point in the history
* GETP-168 refactor: 좋아요 / 좋아요 취소 서비스를 추상화

* GETP-168 remove: 현재 의미 없는 응용 레이어 테스트 삭제

* GETP-168 rename: 피플 좋아요 애그리거트를 like 패키지로 이동

* GETP-168 feat: 피플 조회 기능의 피플 좋아요 수 조회 구현

* GETP-168 refactor: 프로젝트 좋아요 / 좋아요 취소 서비스를 추상화에 대한 구현체로 변경
  • Loading branch information
scv1702 committed Aug 6, 2024
1 parent 4780524 commit 4c93464
Show file tree
Hide file tree
Showing 61 changed files with 774 additions and 500 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package es.princip.getp.domain.client.command.domain;

import es.princip.getp.domain.common.domain.BaseTimeEntity;
import es.princip.getp.domain.like.command.domain.Likeable;
import es.princip.getp.domain.member.command.domain.model.Email;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.HashSet;
import java.util.Set;

@Entity
@Getter
@Table(name = "client")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Client extends BaseTimeEntity {
public class Client extends BaseTimeEntity implements Likeable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -35,13 +33,6 @@ public class Client extends BaseTimeEntity {
@Column(name = "member_id")
private Long memberId;

@ElementCollection
@CollectionTable(
name = "client_people_like",
joinColumns = @JoinColumn(name = "client_id")
)
private Set<Long> peopleLikes = new HashSet<>();

@Builder
public Client(
final Email email,
Expand Down Expand Up @@ -82,21 +73,8 @@ public void edit(final Email email, final Address address, final BankAccount ban
setBankAccount(bankAccount);
}

private boolean alreadyLikedPeople(final Long peopleId) {
return peopleLikes.contains(peopleId);
}

public void likePeople(final Long peopleId) {
if (alreadyLikedPeople(peopleId)) {
throw new IllegalArgumentException("이미 좋아요를 누른 사람입니다.");
}
peopleLikes.add(peopleId);
}

public void unlikePeople(final Long peopleId) {
if (!alreadyLikedPeople(peopleId)) {
throw new IllegalArgumentException("좋아요를 누르지 않은 사람입니다.");
}
peopleLikes.remove(peopleId);
@Override
public Long getId() {
return this.clientId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.client.exception;

import es.princip.getp.infra.exception.ErrorDescription;
import es.princip.getp.infra.exception.NotFoundException;

public class NotFoundClientException extends NotFoundException {

private static final String code = "NOT_FOUND_CLIENT";
private static final String message = "존재하지 않는 의뢰자입니다.";

public NotFoundClientException() {
super(ErrorDescription.of(code, message));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package es.princip.getp.domain.common.domain;

public interface Identifiable {

Long getId();
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
package es.princip.getp.domain.people.command.application;
package es.princip.getp.domain.like.command.application;

import es.princip.getp.domain.client.command.domain.Client;
import es.princip.getp.domain.client.command.domain.ClientRepository;
import es.princip.getp.domain.client.exception.NotFoundClientException;
import es.princip.getp.domain.like.command.domain.people.PeopleLiker;
import es.princip.getp.domain.like.command.domain.people.PeopleUnliker;
import es.princip.getp.domain.people.command.domain.People;
import es.princip.getp.domain.people.command.domain.PeopleRepository;
import es.princip.getp.domain.people.exception.NotFoundPeopleException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PeopleLikeService {

private final PeopleRepository peopleRepository;
private final PeopleLiker peopleLiker;
private final PeopleUnliker peopleUnliker;

private final ClientRepository clientRepository;
private final PeopleRepository peopleRepository;

/**
* 피플에게 좋아요를 누른다.
Expand All @@ -25,11 +32,12 @@ public class PeopleLikeService {
*/
@Transactional
public void like(final Long memberId, final Long peopleId) {
if (!peopleRepository.existsById(peopleId)) {
throw new NotFoundPeopleException();
}
final Client client = clientRepository.findByMemberId(memberId).orElseThrow();
client.likePeople(peopleId);
final Client client = clientRepository.findByMemberId(memberId)
.orElseThrow(NotFoundClientException::new);
final People people = peopleRepository.findById(peopleId)
.orElseThrow(NotFoundPeopleException::new);

peopleLiker.like(client, people);
}

/**
Expand All @@ -41,10 +49,11 @@ public void like(final Long memberId, final Long peopleId) {
*/
@Transactional
public void unlike(final Long memberId, final Long peopleId) {
if (!peopleRepository.existsById(peopleId)) {
throw new NotFoundPeopleException();
}
final Client client = clientRepository.findByMemberId(memberId).orElseThrow();
client.unlikePeople(peopleId);
final Client client = clientRepository.findByMemberId(memberId)
.orElseThrow(NotFoundClientException::new);
final People people = peopleRepository.findById(peopleId)
.orElseThrow(NotFoundPeopleException::new);

peopleUnliker.unlike(client, people);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package es.princip.getp.domain.project.command.application;
package es.princip.getp.domain.like.command.application;

import es.princip.getp.domain.like.command.domain.project.ProjectLiker;
import es.princip.getp.domain.like.command.domain.project.ProjectUnliker;
import es.princip.getp.domain.people.command.domain.People;
import es.princip.getp.domain.people.command.domain.PeopleRepository;
import es.princip.getp.domain.people.exception.NotFoundPeopleException;
import es.princip.getp.domain.project.command.domain.*;
import es.princip.getp.domain.project.command.domain.Project;
import es.princip.getp.domain.project.command.domain.ProjectRepository;
import es.princip.getp.domain.project.exception.NotFoundProjectException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -16,7 +19,6 @@ public class ProjectLikeService {

private final ProjectRepository projectRepository;
private final PeopleRepository peopleRepository;
private final ProjectLikeRepository projectLikeRepository;

private final ProjectLiker projectLiker;
private final ProjectUnliker projectUnliker;
Expand All @@ -34,9 +36,7 @@ public void like(final Long memberId, final Long projectId) {
final Project project = projectRepository.findById(projectId)
.orElseThrow(NotFoundProjectException::new);

final ProjectLike like = projectLiker.like(people, project);

projectLikeRepository.save(like);
projectLiker.like(people, project);
}

/**
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/es/princip/getp/domain/like/command/domain/Like.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package es.princip.getp.domain.like.command.domain;

import es.princip.getp.domain.common.domain.BaseTimeEntity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@MappedSuperclass
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class Like extends BaseTimeEntity {

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

private Long likerId;

private Long likedId;

protected Like(final Long likerId, final Long likedId) {
this.likerId = likerId;
this.likedId = likedId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package es.princip.getp.domain.like.command.domain;

import es.princip.getp.domain.common.domain.Identifiable;

public interface LikeReceivable extends Identifiable {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package es.princip.getp.domain.like.command.domain;

public interface LikeRepository {

boolean existsByLikerIdAndLikedId(Long likerId, Long likedId);

void deleteByLikerIdAndLikedId(Long likerId, Long likedId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package es.princip.getp.domain.like.command.domain;

import es.princip.getp.domain.common.domain.Identifiable;

public interface Likeable extends Identifiable {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package es.princip.getp.domain.like.command.domain;

import es.princip.getp.domain.like.exception.AlreadyLikedException;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public abstract class Liker<T extends Like> {

private final LikeRepository likeRepository;

protected void checkAlreadyLiked(final Long likerId, final Long likedId) {
if (likeRepository.existsByLikerIdAndLikedId(likerId, likedId)) {
throw new AlreadyLikedException();
}
}

public abstract T like(final Likeable likeable, final LikeReceivable likeReceivable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package es.princip.getp.domain.like.command.domain;

import es.princip.getp.domain.like.exception.NeverLikedException;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public abstract class Unliker {

private final LikeRepository likeRepository;

protected void checkNeverLiked(final Long likerId, final Long likedId) {
if (!likeRepository.existsByLikerIdAndLikedId(likerId, likedId)) {
throw new NeverLikedException();
}
}

public void unlike(final Likeable likeable, final LikeReceivable likeReceivable) {
checkNeverLiked(likeable.getId(), likeReceivable.getId());
likeRepository.deleteByLikerIdAndLikedId(likeable.getId(), likeReceivable.getId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package es.princip.getp.domain.like.command.domain.people;

import es.princip.getp.domain.like.command.domain.Like;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Entity
@DiscriminatorColumn
@Table(name = "people_like")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@AttributeOverrides(
{
@AttributeOverride(name = "id", column = @Column(name = "people_like_id")),
@AttributeOverride(name = "likerId", column = @Column(name = "client_id")),
@AttributeOverride(name = "likedId", column = @Column(name = "people_id"))
}
)
public class PeopleLike extends Like {

private PeopleLike(final Long clientId, final Long peopleId) {
super(clientId, peopleId);
}

public static PeopleLike of(final Long clientId, final Long peopleId) {
return new PeopleLike(clientId, peopleId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package es.princip.getp.domain.like.command.domain.people;

import es.princip.getp.domain.like.command.domain.LikeRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PeopleLikeRepository extends JpaRepository<PeopleLike, Long>, LikeRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package es.princip.getp.domain.like.command.domain.people;

import es.princip.getp.domain.like.command.domain.LikeReceivable;
import es.princip.getp.domain.like.command.domain.Likeable;
import es.princip.getp.domain.like.command.domain.Liker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class PeopleLiker extends Liker<PeopleLike> {

private final PeopleLikeRepository peopleLikeRepository;

@Autowired
public PeopleLiker(final PeopleLikeRepository peopleLikeRepository) {
super(peopleLikeRepository);
this.peopleLikeRepository = peopleLikeRepository;
}

@Override
public PeopleLike like(final Likeable liker, final LikeReceivable liked) {
checkAlreadyLiked(liker.getId(), liked.getId());
final PeopleLike like = PeopleLike.of(liker.getId(), liked.getId());
peopleLikeRepository.save(like);
return like;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.like.command.domain.people;

import es.princip.getp.domain.like.command.domain.Unliker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class PeopleUnliker extends Unliker {

@Autowired
public PeopleUnliker(final PeopleLikeRepository peopleLikeRepository) {
super(peopleLikeRepository);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package es.princip.getp.domain.like.command.domain.project;

import es.princip.getp.domain.like.command.domain.Like;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Entity
@DiscriminatorColumn
@Table(name = "project_like")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@AttributeOverrides(
{
@AttributeOverride(name = "id", column = @Column(name = "project_like_id")),
@AttributeOverride(name = "likerId", column = @Column(name = "people_id")),
@AttributeOverride(name = "likedId", column = @Column(name = "project_id"))
}
)
public class ProjectLike extends Like {

private ProjectLike(final Long peopleId, final Long projectId) {
super(peopleId, projectId);
}

public static ProjectLike of(final Long peopleId, final Long projectId) {
return new ProjectLike(peopleId, projectId);
}
}
Loading

0 comments on commit 4c93464

Please sign in to comment.