Skip to content

Commit

Permalink
[refactor] 스터디 출석 정보 관련 쿼리 수정 및 특정 API에 대한 Token Required를 해제한다 (#224)
Browse files Browse the repository at this point in the history
* refactor: 출석률 Optional 처리 수정

* refactor: 신청, 참여 스터디 조회 시 closed=false 조건 추가

* refactor: QueryProjection 응답 id, writeDate 추가 및 쿼리 수정

* refactor: StudyThumbnail 수정

* refactor: 출석 정보 응답 관련 StudyAttendanceMember -> StudyMember 수정

* refactor: 현재 참여자들에 대한 출석 정보만 응답하도록 수정

* refactor: 사용자 기본 정보, 참여중인 스터디에 대한 token required 해제

* chore: REST Docs 문서 Title 수정
  • Loading branch information
sjiwon committed Jun 11, 2023
1 parent 5cfbee3 commit 5415448
Show file tree
Hide file tree
Showing 21 changed files with 218 additions and 228 deletions.
39 changes: 14 additions & 25 deletions src/docs/asciidoc/member-information.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:toc: left
:toclevels: 2

== 사용자 기본 정보 [AccessToken 필수]
== 사용자 기본 정보
HTTP Request
include::{snippets}/MemberApi/Information/Basic/http-request.adoc[]
include::{snippets}/MemberApi/Information/Basic/request-headers.adoc[]
Expand Down Expand Up @@ -36,27 +36,6 @@ HTTP Response
include::{snippets}/MemberApi/Information/RelatedStudy/Apply/Success/response-body.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Apply/Success/response-fields.adoc[]

== 사용자가 참여중인 스터디 리스트 [AccessToken 필수]
=== 1. Private한 사용자 정보는 타인이 조회할 수 없다 (Token PayloadId != PathVariable memberId)
HTTP Request
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Failure/http-request.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Failure/request-headers.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Failure/path-parameters.adoc[]

HTTP Response
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Failure/response-body.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Failure/response-fields.adoc[]

=== 2. 사용자가 참여중인 스터디 리스트를 조회한다
HTTP Request
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Success/http-request.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Success/request-headers.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Success/path-parameters.adoc[]

HTTP Response
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Success/response-body.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/Success/response-fields.adoc[]

== 사용자가 찜한 스터디 리스트 [AccessToken 필수]
=== 1. Private한 사용자 정보는 타인이 조회할 수 없다 (Token PayloadId != PathVariable memberId)
HTTP Request
Expand All @@ -78,7 +57,17 @@ HTTP Response
include::{snippets}/MemberApi/Information/RelatedStudy/Favorite/Success/response-body.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Favorite/Success/response-fields.adoc[]

== 사용자가 졸업한 스터디 리스트 [AccessToken 필수]
== 사용자가 참여중인 스터디 리스트
HTTP Request
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/http-request.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/request-headers.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/path-parameters.adoc[]

HTTP Response
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/response-body.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Participate/response-fields.adoc[]

== 사용자가 졸업한 스터디 리스트
HTTP Request
include::{snippets}/MemberApi/Information/RelatedStudy/Graduated/http-request.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Graduated/request-headers.adoc[]
Expand All @@ -88,7 +77,7 @@ HTTP Response
include::{snippets}/MemberApi/Information/RelatedStudy/Graduated/response-body.adoc[]
include::{snippets}/MemberApi/Information/RelatedStudy/Graduated/response-fields.adoc[]

== 사용자의 피어리뷰 조회 [AccessToken 필수]
== 사용자의 피어리뷰 조회
HTTP Request
include::{snippets}/MemberApi/Information/PeerReview/http-request.adoc[]
include::{snippets}/MemberApi/Information/PeerReview/request-headers.adoc[]
Expand All @@ -98,7 +87,7 @@ HTTP Response
include::{snippets}/MemberApi/Information/PeerReview/response-body.adoc[]
include::{snippets}/MemberApi/Information/PeerReview/response-fields.adoc[]

== 사용자 출석률 조회 [AccessToken 필수]
== 사용자 출석률 조회
HTTP Request
include::{snippets}/MemberApi/Information/Attendances/http-request.adoc[]
include::{snippets}/MemberApi/Information/Attendances/request-headers.adoc[]
Expand Down
2 changes: 1 addition & 1 deletion src/docs/asciidoc/member-signup.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ include::{snippets}/MemberApi/SignUp/Success/request-fields.adoc[]
HTTP Response
include::{snippets}/MemberApi/SignUp/Success/http-response.adoc[]

== 정보 수정 [AccessToken 필수]
== 사용자 정보 수정 [AccessToken 필수]
HTTP Request
include::{snippets}/MemberApi/Update/http-request.adoc[]
include::{snippets}/MemberApi/Update/request-headers.adoc[]
Expand Down
2 changes: 1 addition & 1 deletion src/docs/asciidoc/oauth.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ HTTP Response
include::{snippets}/OAuthApi/Login/Success/response-body.adoc[]
include::{snippets}/OAuthApi/Login/Success/response-fields.adoc[]

== 로그아웃 [AccessToken 필수]
== 사용자 로그아웃 [AccessToken 필수]
HTTP Request
include::{snippets}/OAuthApi/Logout/http-request.adoc[]
include::{snippets}/OAuthApi/Logout/request-headers.adoc[]
Expand Down
6 changes: 3 additions & 3 deletions src/docs/asciidoc/study-information.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ HTTP Response
include::{snippets}/StudyApi/Information/Participants/response-body.adoc[]
include::{snippets}/StudyApi/Information/Participants/response-fields.adoc[]

== 스터디 주차별 출석 정보 조회 [AccessToken 필수]
=== 1. 스터디 참여자가 아니라면 스터디 주차별 출석 정보를 조회할 수 없다
== 스터디 사용자별 출석 정보 조회 [AccessToken 필수]
=== 1. 스터디 참여자가 아니라면 스터디 사용자별 출석 정보를 조회할 수 없다
HTTP Request
include::{snippets}/StudyApi/Information/Attendances/Failure/http-request.adoc[]
include::{snippets}/StudyApi/Information/Attendances/Failure/request-headers.adoc[]
Expand All @@ -81,7 +81,7 @@ include::{snippets}/StudyApi/Information/Attendances/Failure/path-parameters.ado
HTTP Response
include::{snippets}/StudyApi/Information/Attendances/Failure/response-body.adoc[]

=== 2. 스터디 주차별 출석 정보를 조회한다
=== 2. 스터디 사용자별 출석 정보를 조회한다
HTTP Request
include::{snippets}/StudyApi/Information/Attendances/Success/http-request.adoc[]
include::{snippets}/StudyApi/Information/Attendances/Success/path-parameters.adoc[]
Expand Down
2 changes: 1 addition & 1 deletion src/docs/asciidoc/study-review.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ include::{snippets}/StudyApi/Review/Remove/Success/path-parameters.adoc[]
HTTP Response
include::{snippets}/StudyApi/Review/Remove/Success/http-response.adoc[]

== 리뷰 수정 [AccessToken 필수]
== 스터디 리뷰 수정 [AccessToken 필수]
=== 1. 작성자가 아니면 리뷰를 수정할 수 없다
HTTP Request
include::{snippets}/StudyApi/Review/Update/Failure/http-request.adoc[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class MemberInformationApiController {
private final MemberInformationService memberInformationService;

@GetMapping
public ResponseEntity<MemberInformation> getInformation(@ExtractPayload Long payloadId, @PathVariable Long memberId) {
public ResponseEntity<MemberInformation> getInformation(@PathVariable Long memberId) {
MemberInformation response = memberInformationService.getInformation(memberId);
return ResponseEntity.ok(response);
}
Expand All @@ -30,34 +30,33 @@ public ResponseEntity<RelatedStudy> getApplyStudy(@ExtractPayload Long payloadId
return ResponseEntity.ok(response);
}

@CheckMemberIdentity
@GetMapping("/studies/participate")
public ResponseEntity<RelatedStudy> getParticipateStudy(@ExtractPayload Long payloadId, @PathVariable Long memberId) {
RelatedStudy response = memberInformationService.getParticipateStudy(memberId);
return ResponseEntity.ok(response);
}

@CheckMemberIdentity
@GetMapping("/studies/favorite")
public ResponseEntity<RelatedStudy> getFavoriteStudy(@ExtractPayload Long payloadId, @PathVariable Long memberId) {
RelatedStudy response = memberInformationService.getFavoriteStudy(memberId);
return ResponseEntity.ok(response);
}

@GetMapping("/studies/participate")
public ResponseEntity<RelatedStudy> getParticipateStudy(@PathVariable Long memberId) {
RelatedStudy response = memberInformationService.getParticipateStudy(memberId);
return ResponseEntity.ok(response);
}

@GetMapping("/studies/graduated")
public ResponseEntity<GraduatedStudy> getGraduatedStudy(@ExtractPayload Long payloadId, @PathVariable Long memberId) {
public ResponseEntity<GraduatedStudy> getGraduatedStudy(@PathVariable Long memberId) {
GraduatedStudy response = memberInformationService.getGraduatedStudy(memberId);
return ResponseEntity.ok(response);
}

@GetMapping("/reviews")
public ResponseEntity<PeerReviewAssembler> getReviews(@ExtractPayload Long payloadId, @PathVariable Long memberId) {
public ResponseEntity<PeerReviewAssembler> getReviews(@PathVariable Long memberId) {
PeerReviewAssembler response = memberInformationService.getPeerReviews(memberId);
return ResponseEntity.ok(response);
}

@GetMapping("/attendances")
public ResponseEntity<AttendanceRatioAssembler> getAttendanceRatio(@ExtractPayload Long payloadId, @PathVariable Long memberId) {
public ResponseEntity<AttendanceRatioAssembler> getAttendanceRatio(@PathVariable Long memberId) {
AttendanceRatioAssembler response = memberInformationService.getAttendanceRatio(memberId);
return ResponseEntity.ok(response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,9 @@ private List<AttendanceRatio> includeMissingAttendanceStatus(List<AttendanceRati
AttendanceRatio specificAttendanceRatio = fetchResult.stream()
.filter(ratio -> ratio.status() == status)
.findFirst()
.orElse(null);
.orElse(new AttendanceRatio(status, 0));

result.add(
specificAttendanceRatio != null
? specificAttendanceRatio
: new AttendanceRatio(status, 0)
);
result.add(specificAttendanceRatio);
}

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ public enum StudyThumbnail {
IMAGE_LANGUAGE_005("language_TEPS.png", "#FFFBE8"),
IMAGE_LANGUAGE_006("language_TOEFL.png", "#FFFFFF"),
IMAGE_LANGUAGE_007("language_TOEIC.png", "#FFFFFF"),
IMAGE_LANGUAGE_008("language_001.png", "#E7E7E7"),
IMAGE_LANGUAGE_009("language_toeic.png", "#E7E7E7"),

IMAGE_INTERVIEW_001("interview_samsung.png", "#E3EDFF"),
IMAGE_INTERVIEW_002("interview_hyundai.png", "#EFF1FF"),
Expand All @@ -33,7 +31,6 @@ public enum StudyThumbnail {
IMAGE_PROGRAMMING_005("programming_Baekjoon.png", "#FFFFFF"),
IMAGE_PROGRAMMING_006("programming_CSS.png", "#E5F9FF"),
IMAGE_PROGRAMMING_007("programming_HTML.png", "#FFEEDB"),
IMAGE_PROGRAMMING_008("programming_baekjoon.png", "#E7E7E7"),

IMAGE_APTITUDE_NCS_001("aptitude_ncs_001.png", "#FF0000"),
IMAGE_APTITUDE_NCS_002("aptitude_ncs_002.png", "#FF0000"),
Expand All @@ -46,7 +43,6 @@ public enum StudyThumbnail {
IMAGE_CERTIFICATION_003("certification_CSSD.png", "#E7E7E7"),
IMAGE_CERTIFICATION_004("certification_KH.png", "#E7E7E7"),
IMAGE_CERTIFICATION_005("certification_GTQ.png", "#E7E7E7"),
IMAGE_CERTIFICATION_006("certification_computerLiteracy.png", "#E7E7E7"),

IMAGE_ETC_001("etc_teacherExam.png", "#FFFFFF"),
IMAGE_ETC_002("etc_002.png", "#FF0000"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;

import static com.kgu.studywithme.member.domain.QMember.member;
import static com.kgu.studywithme.study.domain.QStudy.study;
import static com.kgu.studywithme.study.domain.attendance.QAttendance.attendance;
import static com.kgu.studywithme.study.domain.notice.QNotice.notice;
import static com.kgu.studywithme.study.domain.notice.comment.QComment.comment;
import static com.kgu.studywithme.study.domain.participant.ParticipantStatus.APPLY;
import static com.kgu.studywithme.study.domain.participant.ParticipantStatus.GRADUATED;
import static com.kgu.studywithme.study.domain.participant.ParticipantStatus.*;
import static com.kgu.studywithme.study.domain.participant.QParticipant.participant;
import static com.kgu.studywithme.study.domain.review.QReview.review;
import static com.kgu.studywithme.study.domain.week.submit.QSubmit.submit;
Expand All @@ -38,7 +40,7 @@ public int getGraduatedParticipantCountByStudyId(Long studyId) {
@Override
public List<ReviewInformation> findReviewByStudyId(Long studyId) {
return query
.select(new QReviewInformation(member.id, member.nickname, review.content, review.modifiedAt))
.select(new QReviewInformation(review.id, review.content, review.modifiedAt, member.id, member.nickname))
.from(review)
.innerJoin(review.writer, member)
.where(review.study.id.eq(studyId))
Expand All @@ -51,7 +53,8 @@ public List<NoticeInformation> findNoticeWithCommentsByStudyId(Long studyId) {
List<NoticeInformation> noticeResult = query
.select(new QNoticeInformation(
notice.id, notice.title, notice.content, notice.createdAt, notice.modifiedAt,
member.id, member.nickname))
member.id, member.nickname
))
.from(notice)
.innerJoin(notice.writer, member)
.where(notice.study.id.eq(studyId))
Expand All @@ -64,9 +67,13 @@ public List<NoticeInformation> findNoticeWithCommentsByStudyId(Long studyId) {

private void applyCommentsInNotice(List<NoticeInformation> noticeResult) {
List<CommentInformation> commentResult = query
.select(new QCommentInformation(comment.id, comment.notice.id, comment.content, member.id, member.nickname))
.select(new QCommentInformation(
comment.id, comment.notice.id, comment.content, comment.modifiedAt,
member.id, member.nickname
))
.from(comment)
.innerJoin(comment.writer, member)
.orderBy(comment.id.asc())
.fetch();

noticeResult.forEach(notice -> notice.applyComments(
Expand All @@ -83,19 +90,40 @@ public List<StudyApplicantInformation> findApplicantByStudyId(Long studyId) {
.from(participant)
.innerJoin(participant.member, member)
.where(studyIdEq(studyId), applyStatus())
.orderBy(participant.id.desc())
.orderBy(member.id.desc())
.fetch();
}

@Override
public List<AttendanceInformation> findAttendanceByStudyId(Long studyId) {
Long hostId = query
.select(study.participants.host.id)
.from(study)
.where(study.id.eq(studyId))
.fetchOne();

List<Long> participantIds = query
.select(participant.member.id)
.from(participant)
.where(
participant.study.id.eq(studyId),
participant.status.eq(APPROVE)
)
.fetch();

List<Long> totalIds = Stream.of(List.of(hostId), participantIds)
.flatMap(Collection::stream)
.toList();

return query
.select(new QAttendanceInformation(member.id, member.nickname, participant.status, attendance.week, attendance.status))
.select(new QAttendanceInformation(member.id, member.nickname, attendance.week, attendance.status))
.from(attendance)
.innerJoin(attendance.participant, member)
.leftJoin(participant).on(participant.member.id.eq(member.id))
.where(attendance.study.id.eq(studyId))
.orderBy(attendance.week.asc(), member.id.asc())
.where(
attendance.study.id.eq(studyId),
member.id.in(totalIds)
)
.orderBy(member.id.asc(), attendance.week.asc())
.fetch();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ public List<SimpleStudy> findApplyStudyByMemberId(Long memberId) {
.selectDistinct(new QSimpleStudy(study.id, study.name, study.category, study.thumbnail))
.from(study)
.innerJoin(participant).on(participant.study.id.eq(study.id))
.where(memberIdEq(memberId), participateStatusEq(APPLY))
.where(
memberIdEq(memberId),
participateStatusEq(APPLY),
studyIsNotClosed()
)
.orderBy(study.id.desc())
.fetch();
}
Expand All @@ -49,7 +53,10 @@ public List<SimpleStudy> findParticipateStudyByMemberId(Long memberId) {
.from(study)
.innerJoin(study.participants.host, host)
.leftJoin(participant).on(participant.study.id.eq(study.id))
.where(hostIdEq(memberId).or(participantIdEqAndApproveStatus(memberId)))
.where(
hostIdEq(memberId).or(participantIdEqAndApproveStatus(memberId)),
studyIsNotClosed()
)
.orderBy(study.id.desc())
.fetch();
}
Expand Down Expand Up @@ -213,4 +220,8 @@ private BooleanExpression hostIdEq(Long memberId) {
private BooleanExpression isMemberInParticipant(Long memberId, List<Long> participantIds) {
return !CollectionUtils.isEmpty(participantIds) ? Expressions.asNumber(memberId).in(participantIds) : null;
}

private BooleanExpression studyIsNotClosed() {
return study.closed.eq(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,21 @@

import com.kgu.studywithme.member.domain.Nickname;
import com.kgu.studywithme.study.domain.attendance.AttendanceStatus;
import com.kgu.studywithme.study.domain.participant.ParticipantStatus;
import com.kgu.studywithme.study.service.dto.response.StudyAttendanceMember;
import com.kgu.studywithme.study.service.dto.response.StudyMember;
import com.querydsl.core.annotations.QueryProjection;
import lombok.AllArgsConstructor;
import lombok.Getter;

import static com.kgu.studywithme.study.domain.participant.ParticipantStatus.APPROVE;

@Getter
@AllArgsConstructor
public class AttendanceInformation {
private final StudyAttendanceMember participant;
private final StudyMember participant;
private final int week;
private final String attendanceStatus;

@QueryProjection
public AttendanceInformation(
Long id, Nickname nickname, ParticipantStatus participantStatus,
int week, AttendanceStatus attendanceStatus
) {
this.participant = new StudyAttendanceMember(
id,
nickname.getValue(),
(participantStatus == null) ? APPROVE : participantStatus
);
public AttendanceInformation(Long id, Nickname nickname, int week, AttendanceStatus attendanceStatus) {
this.participant = new StudyMember(id, nickname.getValue());
this.week = week;
this.attendanceStatus = attendanceStatus.getDescription();
}
Expand Down
Loading

0 comments on commit 5415448

Please sign in to comment.