Skip to content

Commit

Permalink
GETP-175 feat: 프로젝트 지원자 목록 조회 기능 구현 (#121)
Browse files Browse the repository at this point in the history
* GETP-175 feat: 프로젝트 지원자 목록 조회 기능 구현

* GETP-175 rename: description.response에서 description으로 이동

* GETP-175 test: 프로젝트 지원자 목록 조회 단위 테스트 작성

* GETP-175 docs: 프로젝트 지원자 목록 조회 API 문서 작성

* GETP-175 fix: 의뢰한 프로젝트 목록 조회 API 문서 스니펫 경로 오류 수정
  • Loading branch information
scv1702 authored Aug 14, 2024
1 parent d7c5fc1 commit 0804d48
Show file tree
Hide file tree
Showing 27 changed files with 586 additions and 148 deletions.
44 changes: 25 additions & 19 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,33 @@ include::{docdir}/auth/reissue-access-token.adoc[]

== 사용자

=== 내 회원 정보 조회
=== [회원] 내 회원 정보 조회

회원은 자신의 회원 정보를 조회할 수 있습니다.

include::{docdir}/member/get-my-member.adoc[]

=== 내 프로필 사진 등록
=== [회원] 내 프로필 사진 등록

회원은 자신의 프로필 사진을 등록할 수 있습니다.

include::{docdir}/member/upload-profile-image.adoc[]

== 의뢰자

=== 내 의뢰자 정보 등록
=== [의뢰자] 내 의뢰자 정보 등록

의뢰자는 자신의 의뢰자 정보를 등록할 수 있습니다.

include::{docdir}/my-client/register-my-client.adoc[]

=== 내 의뢰자 정보 조회
=== [의뢰자] 내 의뢰자 정보 조회

의뢰자는 자신의 의뢰자 정보를 조회할 수 있습니다.

include::{docdir}/my-client/get-my-client.adoc[]

=== 내 의뢰자 정보 수정
=== [의뢰자] 내 의뢰자 정보 수정

의뢰자는 자신의 의뢰자 정보를 수정할 수 있습니다.

Expand All @@ -83,37 +83,37 @@ include::{docdir}/people/get-people.adoc[]

include::{docdir}/people/get-card-people-page.adoc[]

=== 내 피플 정보 등록
=== [피플] 내 피플 정보 등록

피플은 자신의 피플 정보를 등록할 수 있습니다.

include::{docdir}/my-people/create-my-people.adoc[]

=== 내 피플 정보 조회
=== [피플] 내 피플 정보 조회

피플은 자신의 피플 정보를 조회할 수 있습니다.

include::{docdir}/my-people/get-my-people.adoc[]

=== 내 피플 정보 수정
=== [피플] 내 피플 정보 수정

피플은 자신의 피플 정보를 수정할 수 있습니다.

include::{docdir}/my-people/update-my-people.adoc[]

=== 내 피플 프로필 등록
=== [피플] 내 피플 프로필 등록

피플은 자신의 프로필을 등록할 수 있습니다.

include::{docdir}/my-people-profile/write-my-people-profile.adoc[]

=== 내 피플 프로필 조회
=== [피플] 내 피플 프로필 조회

피플은 자신의 프로필을 조회할 수 있습니다.

include::{docdir}/my-people-profile/get-my-people-profile.adoc[]

=== 내 피플 프로필 수정
=== [피플] 내 피플 프로필 수정

피플은 자신의 프로필을 수정할 수 있습니다.

Expand All @@ -133,42 +133,48 @@ include::{docdir}/project/get-project-by-project-Id.adoc[]

include::{docdir}/project/get-projects.adoc[]

=== 프로젝트 좋아요
=== [피플] 프로젝트 좋아요

피플은 마음에 드는 프로젝트에 좋아요를 누를 수 있습니다.

include::{docdir}/project/like-project.adoc[]

=== 프로젝트 좋아요 취소
=== [피플] 프로젝트 좋아요 취소

피플은 마음에 드는 프로젝트에 눌렀던 좋아요를 취소할 수 있습니다.

include::{docdir}/project/unlike-project.adoc[]

=== 프로젝트 의뢰
=== [의뢰자] 프로젝트 의뢰

의뢰자는 프로젝트를 의뢰할 수 있습니다.

include::{docdir}/project/commission-project.adoc[]

== 프로젝트 관리

=== 의뢰한 프로젝트 목록 조회
=== [의뢰자] 의뢰한 프로젝트 목록 조회

의뢰자는 자신이 의뢰한 프로젝트 목록을 조회할 수 있습니다.

include::{docdir}/project/get-my-projects.adoc[]
include::{docdir}/project/get-my-commissioned-projects.adoc[]

=== 프로젝트 미팅 신청
=== [의뢰자] 프로젝트 지원자 목록 조회

의뢰자는 자신의 프로젝트에 지원한 지원자 목록을 조회할 수 있습니다.

include::{docdir}/project/get-applicants-by-project-id.adoc[]

=== [의뢰자] 프로젝트 미팅 신청

의뢰자는 프로젝트 지원자에게 미팅을 신청할 수 있습니다.

include::{docdir}/project/schedule-meeting.adoc[]

== 스토리지

=== 파일 업로드
=== [회원] 파일 업로드

사용자는 파일을 업로드할 수 있습니다. 업로드할 수 있는 파일 확장자는 `pdf`, `zip`, `ppt`, `docx`, `hwp`, `jpg`, `png` 입니다.
회원은 파일을 업로드할 수 있습니다. 업로드할 수 있는 파일 확장자는 `pdf`, `zip`, `ppt`, `docx`, `hwp`, `jpg`, `png` 입니다.

include::{docdir}/storage/upload-file.adoc[]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
operation::/get-applicants-by-project-id/get-applicants-by-project-id[snippets="http-request,request-headers,path-parameters,query-parameters,http-response,response-fields-data"]
28 changes: 28 additions & 0 deletions src/docs/asciidoc/project/get-my-commissioned-projects.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
==== HTTP request
include::{snippets}/get-my-commissioned-projects/get-my-commissioned-projects/http-request.adoc[]

==== Request headers
include::{snippets}/get-my-commissioned-projects/get-my-commissioned-projects/request-headers.adoc[]

==== Query parameters

include::{snippets}/get-my-commissioned-projects/get-my-commissioned-projects/query-parameters.adoc[]

==== Sort parameters
[cols=2*]
|===
|최신순 정렬
|`sort=createdAt,desc`

|높은 가격 순 정렬
|`sort=payment,desc`

|마감 임박 순 정렬
|`sort=applicationDuration,desc`
|===

==== HTTP response
include::{snippets}/get-my-commissioned-projects/get-my-commissioned-projects/http-response.adoc[]

==== Response fields
include::{snippets}/get-my-commissioned-projects/get-my-commissioned-projects/response-fields-data.adoc[]
28 changes: 0 additions & 28 deletions src/docs/asciidoc/project/get-my-projects.adoc

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import es.princip.getp.domain.people.command.domain.People;
import es.princip.getp.domain.people.command.domain.PeopleOrder;
import org.springframework.data.domain.Sort;

import java.util.List;

import static com.querydsl.core.types.Order.ASC;
import static com.querydsl.core.types.Order.DESC;
import static es.princip.getp.domain.people.command.domain.QPeople.people;

class PeoplePaginationHelper {
public class PeopleDaoUtil {

private static Order convertTo(final Sort.Order order) {
return order.isAscending() ? ASC : DESC;
Expand All @@ -24,9 +27,15 @@ private static OrderSpecifier<?> getPeopleOrderSpecifier(final Sort.Order order,
};
}

static OrderSpecifier<?>[] getPeopleOrderSpecifiers(Sort sort) {
public static OrderSpecifier<?>[] orderSpecifiersFromSort(Sort sort) {
return sort.stream()
.map(order -> getPeopleOrderSpecifier(order, PeopleOrder.get(order.getProperty())))
.toArray(OrderSpecifier[]::new);
}

public static Long[] toPeopleIds(final List<People> peoples) {
return peoples.stream()
.map(People::getPeopleId)
.toArray(Long[]::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@

import static es.princip.getp.domain.member.command.domain.model.QMember.member;
import static es.princip.getp.domain.people.command.domain.QPeople.people;
import static es.princip.getp.domain.people.query.dao.PeoplePaginationHelper.getPeopleOrderSpecifiers;
import static es.princip.getp.domain.people.query.dao.PeopleDaoUtil.orderSpecifiersFromSort;
import static es.princip.getp.domain.people.query.dao.PeopleDaoUtil.toPeopleIds;
import static java.util.stream.Collectors.toMap;

@Repository
Expand Down Expand Up @@ -71,14 +72,12 @@ private Optional<Tuple> findMemberAndPeopleByPeopleId(final Long peopleId) {
private List<CardPeopleResponse> getCardPeopleContent(final Pageable pageable) {
final List<People> result = queryFactory.selectFrom(people)
.where(people.profile.isNotNull())
.orderBy(getPeopleOrderSpecifiers(pageable.getSort()))
.orderBy(orderSpecifiersFromSort(pageable.getSort()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();

final Long[] peopleIds = result.stream()
.map(People::getPeopleId)
.toArray(Long[]::new);
final Long[] peopleIds = toPeopleIds(result);

final Map<Long, Long> likesCounts = peopleLikeDao.countByLikedIds(peopleIds);
final Map<Long, Tuple> memberAndPeople = findMemberAndPeopleByPeopleId(peopleIds);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package es.princip.getp.domain.project.command.domain;

import es.princip.getp.domain.client.command.domain.Client;
import es.princip.getp.domain.common.domain.BaseTimeEntity;
import es.princip.getp.domain.common.domain.Duration;
import es.princip.getp.domain.common.domain.Hashtag;
Expand Down Expand Up @@ -129,6 +130,10 @@ public boolean isApplicationClosed(final Clock clock) {
return applicationDuration.isEnded(clock) || status != ProjectStatus.APPLYING;
}

public boolean isClient(final Client client) {
return clientId.equals(client.getClientId());
}

@Override
public Long getId() {
return projectId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.project.exception;

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

public class NotMyProjectException extends ForbiddenException {

private static final String code = "NOT_MY_PROJECT";
private static final String message = "해당 프로젝트의 의뢰자가 아닙니다.";

public NotMyProjectException() {
super(ErrorDescription.of(code, message));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package es.princip.getp.domain.project.query.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.member.command.domain.model.Member;
import es.princip.getp.domain.people.query.dto.people.DetailPeopleResponse;
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 es.princip.getp.domain.project.exception.NotMyProjectException;
import es.princip.getp.domain.project.query.dao.ProjectApplicantDao;
import es.princip.getp.infra.dto.response.PageResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ProjectApplicantService {

private final ProjectApplicantDao projectApplicantDao;
private final ClientRepository clientRepository;
private final ProjectRepository projectRepository;

public PageResponse<DetailPeopleResponse> getApplicants(
final Long projectId,
final Member member,
final Pageable pageable
) {
final Long memberId = member.getMemberId();
final Client client = clientRepository.findByMemberId(memberId).orElseThrow(NotFoundClientException::new);
final Project project = projectRepository.findById(projectId).orElseThrow(NotFoundProjectException::new);
if (!project.isClient(client)) {
throw new NotMyProjectException();
}
return PageResponse.from(projectApplicantDao.findPagedApplicantByProjectId(projectId, pageable));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package es.princip.getp.domain.project.query.dao;

import es.princip.getp.domain.people.query.dto.people.DetailPeopleResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface ProjectApplicantDao {

Page<DetailPeopleResponse> findPagedApplicantByProjectId(Long projectId, Pageable pageable);
}
Loading

0 comments on commit 0804d48

Please sign in to comment.