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

[FEAT] 카테고리 자동 생성 스케줄러 구현 (TICO-334) #92

Merged
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
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling // 스케줄러 활성화
public class PomoroDoApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public interface CategoryRepository extends JpaRepository<Category, Long> {
List<Category> findAllByHostAndTypeAndDate(User host, CategoryType type, LocalDate date);

Optional<Category> findById(Long categoryId);

List<Category> findByDate(LocalDate date);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,4 @@ public interface GroupMemberRepository extends JpaRepository<GroupMember, Long>

List<GroupMember> findAllByCategoryAndStatus(Category category, GroupInvitationStatus status);


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import com.tico.pomoro_do.domain.category.dto.request.CategoryCreationDTO;
import com.tico.pomoro_do.domain.category.dto.response.*;
import com.tico.pomoro_do.domain.category.entity.Category;
import com.tico.pomoro_do.domain.category.entity.GroupMember;
import com.tico.pomoro_do.domain.user.entity.User;
import com.tico.pomoro_do.global.enums.CategoryType;
import com.tico.pomoro_do.global.enums.CategoryVisibility;
import com.tico.pomoro_do.global.enums.GroupInvitationStatus;
import com.tico.pomoro_do.global.enums.GroupRole;

import java.time.LocalDate;
import java.util.List;
Expand All @@ -29,4 +32,12 @@ public interface CategoryService {

// 카테고리 상세 조회
CategoryDetailDTO getCategoryDetail(Long categoryId, String username);

// 해당 날짜에 속한 모든 카테고리 조회
List<Category> findByDate(LocalDate targetDate);

// 그룹멤버 생성
void createGroupMember(Category category, User member, GroupInvitationStatus status, GroupRole role);
// 그룹멤버 조회
List<GroupMember> findAcceptedMembersByCategory(Category category);
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ private void createGroupMembers(Category category, User host, Set<Long> memberId
* @param status 그룹 초대 상태 (ACCEPTED, INVITED 등)
* @param role 그룹 내 유저의 역할 (HOST, MEMBER 등)
*/
private void createGroupMember(Category category, User member, GroupInvitationStatus status, GroupRole role){
@Override
public void createGroupMember(Category category, User member, GroupInvitationStatus status, GroupRole role){
GroupMember groupMember = GroupMember.builder()
.category(category)
.user(member)
Expand Down Expand Up @@ -341,4 +342,27 @@ private InvitedGroupDTO convertToInvitedGroup(GroupMember groupMember) {
.build();
}

/**
* 해당 날짜에 속하는 모든 카테고리 조회
*
* @param targetDate 조회할 날짜
* @return 해당 날짜에 속하는 모든 카테고리 리스트
*/
@Override
public List<Category> findByDate(LocalDate targetDate) {
// DB에서 한번에 해당 날짜의 일반 카테고리를 조회
return categoryRepository.findByDate(targetDate);
}

/**
* 해당 카테고리에 속하는 모든 승인된 그룹 멤버 조회
*
* @param category 조회할 카테고리
* @return 해당 카테고리에 속하는 모든 승인된 그룹 멤버 리스트
*/
@Override
public List<GroupMember> findAcceptedMembersByCategory(Category category) {
return groupMemberRepository.findAllByCategoryAndStatus(category, GroupInvitationStatus.ACCEPTED);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.tico.pomoro_do.global.scheduler;

import com.tico.pomoro_do.domain.category.entity.Category;
import com.tico.pomoro_do.domain.category.entity.GroupMember;
import com.tico.pomoro_do.domain.category.service.CategoryService;
import com.tico.pomoro_do.global.enums.CategoryType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.List;

@Component
@RequiredArgsConstructor
@Slf4j
public class CategoryScheduler {

private final CategoryService categoryService;

// 한국 표준시 (KST) ZoneId를 상수로 정의
private static final ZoneId KOREA_ZONE_ID = ZoneId.of("Asia/Seoul");

// 카테고리 자동 생성
@Scheduled(cron = "0 0 5 * * *") // 매일 새벽 5시에 실행
public void createTodayCategories(){
// 오늘 날짜 설정
LocalDate today = LocalDate.now(KOREA_ZONE_ID);
// 전날 날짜 설정
LocalDate yesterday = today.minusDays(1);

// 전날 존재하는 모든 카테고리 조회
List<Category> yesterdayCategories = categoryService.findByDate(yesterday);

// 오늘 날짜로 복사하여 새로운 카테고리 생성
for (Category category : yesterdayCategories) {

Category newCategory = categoryService.createNewCategory(
category.getHost(),
today,
category.getTitle(),
category.getColor(),
category.getVisibility(),
category.getType()
);

// 그룹 카테고리면 그룹 멤버도 복사하여 생성
if (category.getType() == CategoryType.GROUP){
// 승낙한 멤버만 생성
List<GroupMember> groupMembers= categoryService.findAcceptedMembersByCategory(category);

for (GroupMember groupMember : groupMembers) {

categoryService.createGroupMember(
newCategory,
groupMember.getUser(),
groupMember.getStatus(),
groupMember.getRole()
);
}
}
}
}

}
Loading