Skip to content
This repository was archived by the owner on Jan 11, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9624ca0
[SPOT-138][REFACTOR] Refactor Domains for Test
dvlp-sy Jan 31, 2025
bef4e93
[SPOT-138][MODIFY] Modify Services by Domain Update
dvlp-sy Jan 31, 2025
2d919d2
[SPOT-138][REFACTOR] Refactor Domains
dvlp-sy Feb 2, 2025
ec5c97d
[SPOT-138][FIX] Add Error Handling to getAllPosts
dvlp-sy Feb 2, 2025
233e1a7
[SPOT-138][TEST] Create Tests for getAllPosts
dvlp-sy Feb 2, 2025
82d0313
[SPOT-138][TEST] Modify Test by StudyPost Refactoring
dvlp-sy Feb 2, 2025
292e724
[SPOT-138][TEST] Create Tests for getPost
dvlp-sy Feb 2, 2025
95aeac4
[SPOT-138][TEST] Create Tests for getAllComments
dvlp-sy Feb 2, 2025
fee993d
[SPOT-138][FIX] Fix createStudy Error
dvlp-sy Feb 2, 2025
306903e
[SPOT-138][FIX] Fix createComment Error
dvlp-sy Feb 2, 2025
e0c4a39
[SPOT-138][TEST] Initialize StudyPostCommandServiceTest
dvlp-sy Feb 2, 2025
a036169
[SPOT-138][CHORE] Update Domain and DTO Codes
dvlp-sy Feb 2, 2025
f733700
[SPOT-138][TEST] Create Tests for createPost
dvlp-sy Feb 2, 2025
f07d1b5
[SPOT-138][MODIFY] Add ErrorHandling of deletePost
dvlp-sy Feb 2, 2025
598e94a
[SPOT-138][TEST] Create Tests for deletePost
dvlp-sy Feb 2, 2025
531f4b0
[SPOT-138][TEST] Create Tests for likePost
dvlp-sy Feb 2, 2025
e66c85b
[SPOT-171][REFACTOR] 추천 스터디 내부 로직 변경
msk226 Feb 3, 2025
dc7f3e6
[SPOT-171][TEST] 바뀐 로직 테스트 코드에 반영
msk226 Feb 3, 2025
504ee7a
[MERGE] Merge pull request #338 from SPOTeam/SPOT-171/refactor
msk226 Feb 3, 2025
3c17b34
[SPOT-138][TEST] Create Tests for cancelPostLike
dvlp-sy Feb 4, 2025
5811a1e
[SPOT-138][CHORE] Change MemberInfoDTO to Public
dvlp-sy Feb 8, 2025
b38a60a
[SPOT-138][TEST] Create Tests for createComment and createReply
dvlp-sy Feb 8, 2025
f1db055
[SPOT-138][TEST] Create Tests for likeComment
dvlp-sy Feb 8, 2025
3f55c7f
[SPOT-138][TEST] Create Tests for dislikeComment
dvlp-sy Feb 8, 2025
bbef903
[SPOT-138][TEST] Create Tests for cancelCommentLike
dvlp-sy Feb 8, 2025
5b65a62
[SPOT-138][TEST] Create Tests for cancelCommendDislike
dvlp-sy Feb 8, 2025
b60ee82
[SPOT-138][TEST] Add Repositories for Test
dvlp-sy Feb 8, 2025
1291dcd
[SPOT-138][TEST] Modify Tests by Domain Update
dvlp-sy Feb 8, 2025
af80790
[SPOT-138][TEST] Modify Tests by Domain Update
dvlp-sy Feb 8, 2025
5e2782d
[MERGE] 스터디 게시글 API 테스트 코드 작성
dvlp-sy Feb 8, 2025
884ea15
[SPOT-187][MODIFY] Update StudyScheduleDTO
dvlp-sy Feb 8, 2025
6197d5d
[SPOT-187][CHORE] Remove Whitespace
dvlp-sy Feb 8, 2025
0054475
[MERGE] 다가오는 스터디 모임 일정 조회 API 수정
dvlp-sy Feb 8, 2025
7db5506
[SPOT-150][FIX] Fix Study Member Error Handling
dvlp-sy Feb 8, 2025
7a29516
[SPOT-150][TEST] Create Tests for withdrawFromStudy
dvlp-sy Feb 8, 2025
8ee78dd
[SPOT-150][FIX] Apply Error Handlings to terminateStudy
dvlp-sy Feb 8, 2025
a9d47e9
[SPOT-150][TEST] Create Tests for terminateStudy
dvlp-sy Feb 8, 2025
d2ce129
[MERGE] 진행중인 스터디 API 테스트 코드 작성
dvlp-sy Feb 10, 2025
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 @@ -75,6 +75,8 @@ public enum ErrorStatus implements BaseErrorCode {
_ONLY_STUDY_MEMBER_CAN_ACCESS_SCHEDULE(HttpStatus.FORBIDDEN, "STUDY4015", "스터디 멤버만 일정에 접근할 수 있습니다."),
_ONLY_STUDY_MEMBER_CAN_ACCESS_MEMBERS(HttpStatus.FORBIDDEN, "STUDY4016", "스터디 멤버만 회원 목록에 접근할 수 있습니다."),
_ALREADY_STUDY_MEMBER(HttpStatus.BAD_REQUEST, "STUDY4017", "이미 스터디 멤버입니다."),
_STUDY_OWNER_ONLY_CAN_TERMINATE(HttpStatus.BAD_REQUEST, "STUDY4018", "스터디장만 스터디를 종료할 수 있습니다."),
_STUDY_ALREADY_TERMINATED(HttpStatus.BAD_REQUEST, "STUDY4019", "이미 종료된 스터디입니다."),

//스터디 게시글 관련 에러
_STUDY_POST_NOT_FOUND(HttpStatus.NOT_FOUND, "POST4001", "스터디 게시글을 찾을 수 없습니다."),
Expand All @@ -90,7 +92,7 @@ public enum ErrorStatus implements BaseErrorCode {
_STUDY_POST_COMMENT_ALREADY_DISLIKED(HttpStatus.BAD_REQUEST, "POST4011", "이미 싫어요 한 댓글입니다."),
_STUDY_LIKED_COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "POST4012", "좋아요를 누르지 않은 게시글의 좋아요를 취소할 수 없습니다."),
_STUDY_DISLIKED_COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "POST4013", "싫어요를 누르지 않은 게시글의 싫어요를 취소할 수 없습니다."),
_STUDY_POST_DELETION_INVALID(HttpStatus.FORBIDDEN, "POST4014", "게시글 작성자만 삭제 가능합니다."),
_STUDY_POST_DELETION_INVALID(HttpStatus.FORBIDDEN, "POST4014", "게시글 작성자 및 스터디장만 삭제 가능합니다."),
_STUDY_POST_NULL(HttpStatus.BAD_REQUEST, "POST4015", "게시글 아이디가 입력되지 않았습니다."),
_STUDY_POST_COMMENT_NULL(HttpStatus.BAD_REQUEST, "POST4016", "댓글 아이디가 입력되지 않았습니다."),
_STUDY_POST_COMMENT_REACTIOM_ID_NULL(HttpStatus.BAD_REQUEST, "POST4017", "댓글 반응 아이디가 입력되지 않았습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

@Entity
@Getter
@Builder
@DynamicUpdate
@DynamicInsert
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class StudyLikedComment extends BaseEntity {

Expand All @@ -31,13 +33,4 @@ public class StudyLikedComment extends BaseEntity {
@JoinColumn(name = "member_id", nullable = false)
private Member member;

/* ----------------------------- 생성자 ------------------------------------- */

@Builder
public StudyLikedComment(StudyPostComment studyPostComment, Member member, Boolean isLiked) {
this.studyPostComment = studyPostComment;
this.member = member;
this.isLiked = isLiked;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

@Entity
@Getter
@Builder
@DynamicUpdate
@DynamicInsert
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class StudyLikedPost extends BaseEntity {

Expand All @@ -35,11 +37,4 @@ public class StudyLikedPost extends BaseEntity {
@JoinColumn(name = "member_id", nullable = false)
private Member member;

/* ----------------------------- 생성자 ------------------------------------- */

@Builder
public StudyLikedPost(Member member, StudyPost studyPost) {
this.member = member;
this.studyPost = studyPost;
}
}
52 changes: 13 additions & 39 deletions src/main/java/com/example/spot/domain/study/Study.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@

@Entity
@Getter
@DynamicUpdate
@DynamicInsert
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Study extends BaseEntity {

Expand Down Expand Up @@ -62,7 +62,7 @@ public class Study extends BaseEntity {
@Column(nullable = false)
private Boolean isOnline;

@Column(nullable = false, columnDefinition = "BIGINT DEFAULT 0")
@Column(nullable = false, columnDefinition = "INTEGER DEFAULT 0")
private Integer heartCount;

@Column(nullable = false)
Expand All @@ -85,72 +85,46 @@ public class Study extends BaseEntity {
@Column(nullable = false)
private Long maxPeople;

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<Schedule> schedules = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<StudyPost> posts = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<Vote> votes = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<StudyTheme> studyThemes = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<MemberStudy> memberStudies = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<RegionStudy> regionStudies = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<PreferredStudy> preferredStudies = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<StudyPost> studyPosts = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<ToDoList> toDoLists = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "study", cascade = CascadeType.ALL)
private List<Notification> notifications = new ArrayList<>();


/* ----------------------------- 생성자 ------------------------------------- */

@Builder
public Study(Gender gender, Integer minAge, Integer maxAge, Integer fee,
String profileImage, boolean hasFee,
Boolean isOnline, String goal, String introduction,
String title, Long maxPeople) {
this.gender = gender;
this.minAge = minAge;
this.maxAge = maxAge;
this.fee = fee;
this.profileImage = profileImage;
this.studyState = StudyState.RECRUITING;
this.isOnline = isOnline;
this.heartCount = 0;
this.hasFee = hasFee;
this.goal = goal;
this.introduction = introduction;
this.title = title;
this.status = Status.ON;
this.hitNum = 0L;
this.maxPeople = maxPeople;
this.schedules = new ArrayList<>();
this.posts = new ArrayList<>();
this.votes = new ArrayList<>();
this.studyThemes = new ArrayList<>();
this.preferredStudies = new ArrayList<>();
this.memberStudies = new ArrayList<>();
this.regionStudies = new ArrayList<>();
this.studyPosts = new ArrayList<>();
this.toDoLists = new ArrayList<>();
this.notifications = new ArrayList<>();

}

/* ----------------------------- 연관관계 메소드 ------------------------------------- */

public void addMemberStudy(MemberStudy memberStudy) {
Expand Down
44 changes: 15 additions & 29 deletions src/main/java/com/example/spot/domain/study/StudyPost.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@
import java.util.List;

import lombok.*;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Getter
@DynamicUpdate
@DynamicInsert
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class StudyPost extends BaseEntity {

Expand Down Expand Up @@ -50,47 +48,35 @@ public class StudyPost extends BaseEntity {
@Column(nullable = false)
private String title;

@Column(nullable = false)
@Column(nullable = false, columnDefinition = "text")
private String content;

@Column(nullable = false)
@Column(columnDefinition = "INTEGER DEFAULT 0")
private Integer likeNum;

@Column(nullable = false)
@Column(columnDefinition = "INTEGER DEFAULT 0")
private Integer hitNum;

@Setter
@Column(nullable = false)
@Column(columnDefinition = "INTEGER DEFAULT 0")
private Integer commentNum;

@Builder.Default
@OneToMany(mappedBy = "studyPost", cascade = CascadeType.ALL)
private List<StudyPostImage> images;
private List<StudyPostImage> images = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "studyPost", cascade = CascadeType.ALL)
private List<StudyPostComment> comments;
private List<StudyPostComment> comments = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "studyPost", cascade = CascadeType.ALL)
private List<StudyLikedPost> likedPosts;
private List<StudyLikedPost> likedPosts = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "studyPost", cascade = CascadeType.ALL)
private List<StudyPostReport> studyPostReports;

/* ----------------------------- 생성자 ------------------------------------- */

@Builder
public StudyPost(Boolean isAnnouncement, Theme theme, String title, String content) {
this.isAnnouncement = isAnnouncement;
this.theme = theme;
this.title = title;
this.content = content;
this.likeNum = 0;
this.hitNum = 0;
this.commentNum = 0;
this.images = new ArrayList<>();
this.comments = new ArrayList<>();
this.likedPosts = new ArrayList<>();
this.studyPostReports = new ArrayList<>();
}
private List<StudyPostReport> studyPostReports = new ArrayList<>();

/* ----------------------------- 연관관계 메소드 ------------------------------------- */

public void addImage(StudyPostImage image) {
Expand Down
32 changes: 8 additions & 24 deletions src/main/java/com/example/spot/domain/study/StudyPostComment.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

@Entity
@Getter
@DynamicUpdate
@DynamicInsert
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class StudyPostComment extends BaseEntity {

Expand All @@ -36,10 +36,10 @@ public class StudyPostComment extends BaseEntity {
@Column(nullable = false)
private String content;

@Column(nullable = false)
@Column(columnDefinition = "INTEGER DEFAULT 0")
private Integer likeCount;

@Column(nullable = false)
@Column(columnDefinition = "INTEGER DEFAULT 0")
private Integer dislikeCount;

@Column(nullable = false, columnDefinition = "BIT DEFAULT 0")
Expand All @@ -56,29 +56,13 @@ public class StudyPostComment extends BaseEntity {
@JoinColumn(name = "parent_comment_id")
private StudyPostComment parentComment;

@Builder.Default
@OneToMany(mappedBy = "parentComment", cascade = CascadeType.ALL)
private List<StudyPostComment> childrenComment;
private List<StudyPostComment> childrenComment = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "studyPostComment", cascade = CascadeType.ALL)
private List<StudyLikedComment> likedComments;

/* ----------------------------- 생성자 ------------------------------------- */

@Builder
public StudyPostComment(StudyPost studyPost, Member member, String content,
Boolean isAnonymous, Integer anonymousNum, StudyPostComment parentComment) {
this.studyPost = studyPost;
this.member = member;
this.content = content;
this.likeCount = 0;
this.dislikeCount = 0;
this.isAnonymous = isAnonymous;
this.anonymousNum = anonymousNum;
this.isDeleted = Boolean.FALSE;
this.parentComment = parentComment;
this.childrenComment = new ArrayList<>();
this.likedComments = new ArrayList<>();
}
private List<StudyLikedComment> likedComments = new ArrayList<>();

/* ----------------------------- 연관관계 메소드 ------------------------------------- */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public interface StudyRepositoryCustom {
List<Study> findByStudyTheme(List<StudyTheme> studyThemes);

List<Study> findByStudyThemeAndNotInIds(List<StudyTheme> studyThemes, List<Long> studyIds);
List<Study> findByRegionStudyAndNotInIds(List<RegionStudy> regionStudies, List<Long> studyIds);

// 모집중 스터디 조회
List<Study> findRecruitingStudyByConditions(Map<String, Object> search, StudySortBy sortBy, Pageable pageable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,18 @@ public List<Study> findByStudyThemeAndNotInIds(List<StudyTheme> studyThemes,
return queryFactory.selectFrom(study)
.where(study.studyThemes.any().in(studyThemes))
.where(study.id.notIn(studyIds))
.orderBy(study.createdAt.desc())
.orderBy(study.hitNum.desc())
.offset(0)
.limit(3)
.fetch();
}

@Override
public List<Study> findByRegionStudyAndNotInIds(List<RegionStudy> regionStudies, List<Long> studyIds) {
return queryFactory.selectFrom(study)
.where(study.regionStudies.any().in(regionStudies))
.where(study.id.notIn(studyIds))
.orderBy(study.heartCount.desc())
.offset(0)
.limit(3)
.fetch();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public StudyWithdrawalResponseDTO.WithdrawalDTO withdrawFromStudy(Long studyId)
.orElseThrow(() -> new StudyHandler(ErrorStatus._STUDY_MEMBER_NOT_FOUND));

// 참여가 승인되지 않은 스터디는 탈퇴할 수 없음
if (memberStudy.getStatus().equals(ApplicationStatus.APPLIED)) {
if (!memberStudy.getStatus().equals(ApplicationStatus.APPROVED)) {
throw new StudyHandler(ErrorStatus._STUDY_NOT_APPROVED);
}
// 스터디장은 스터디를 탈퇴할 수 없음
Expand All @@ -107,10 +107,24 @@ public StudyWithdrawalResponseDTO.WithdrawalDTO withdrawFromStudy(Long studyId)
*/
public StudyTerminationResponseDTO.TerminationDTO terminateStudy(Long studyId) {

// Authorization
Long memberId = SecurityUtils.getCurrentUserId();
memberRepository.findById(memberId)
.orElseThrow(() -> new MemberHandler(ErrorStatus._MEMBER_NOT_FOUND));
Study study = studyRepository.findById(studyId)
.orElseThrow(() -> new StudyHandler(ErrorStatus._STUDY_NOT_FOUND));
MemberStudy memberStudy = memberStudyRepository.findByMemberIdAndStudyIdAndStatus(memberId, studyId, ApplicationStatus.APPROVED)
.orElseThrow(() -> new StudyHandler(ErrorStatus._STUDY_MEMBER_NOT_FOUND));

// 스터디장이 아니면 스터디를 종료할 수 없음
if (memberStudy.getIsOwned().equals(false)) {
throw new StudyHandler(ErrorStatus._STUDY_OWNER_ONLY_CAN_TERMINATE);
}

// 스터디장 확인 로직 빠짐
// 이미 종료된 스터디는 종료할 수 없음
if (study.getStatus().equals(Status.OFF)) {
throw new StudyHandler(ErrorStatus._STUDY_ALREADY_TERMINATED);
}

study.setStatus(Status.OFF);
studyRepository.save(study);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,14 @@ public StudyScheduleResponseDTO findStudySchedule(Long studyId, Pageable pageabl

// 스터디 일정이 존재하지 않는 경우
if (schedules.isEmpty())
throw new GeneralException(ErrorStatus._STUDY_SCHEDULE_NOT_FOUND);
throw new GeneralException(ErrorStatus._STUDY_SCHEDULE_NOT_FOUND);

// DTO로 변환하여 반환
List<StudyScheduleDTO> scheduleDTOS = schedules.stream().map(schedule -> StudyScheduleDTO.builder()
.title(schedule.getTitle())
.location(schedule.getLocation())
.staredAt(schedule.getStartedAt())
.startedAt(schedule.getStartedAt())
.finishedAt(schedule.getFinishedAt())
.build()).toList();

// 페이징 처리
Expand Down
Loading
Loading