Skip to content

Commit c0eea18

Browse files
committed
Merge branch 'dev' of https://github.com/CommitField/commitField into Feature/89
2 parents 622ada5 + 0f07b9a commit c0eea18

File tree

20 files changed

+293
-157
lines changed

20 files changed

+293
-157
lines changed

src/main/java/cmf/commitField/domain/commit/scheduler/CommitScheduler.java

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55
import cmf.commitField.domain.user.repository.UserRepository;
66
import lombok.RequiredArgsConstructor;
77
import lombok.extern.slf4j.Slf4j;
8+
import org.springframework.context.ApplicationEventPublisher;
89
import org.springframework.data.redis.core.StringRedisTemplate;
910
import org.springframework.scheduling.annotation.Scheduled;
1011
import org.springframework.stereotype.Service;
1112

1213
import java.time.LocalDateTime;
13-
import java.time.format.DateTimeFormatter;
14-
import java.time.format.DateTimeParseException;
1514
import java.util.Set;
1615
import java.util.concurrent.TimeUnit;
1716
import java.util.concurrent.atomic.AtomicInteger;
@@ -21,11 +20,13 @@
2120
@RequiredArgsConstructor
2221
public class CommitScheduler {
2322
private final TotalCommitService totalCommitService;
24-
private final CommitCacheService commitCacheService;
2523
private final UserRepository userRepository;
2624
private final StringRedisTemplate redisTemplate;
2725
private final AtomicInteger counter = new AtomicInteger(0);
2826

27+
private final ApplicationEventPublisher eventPublisher;
28+
29+
2930
@Scheduled(fixedRate = 60000) // 1분마다 실행
3031
public void updateUserCommits() {
3132
log.info("🔍 updateUserCommits 실행중");
@@ -43,62 +44,43 @@ public void updateUserCommits() {
4344
String lastcmKey = "commit_lastCommitted:" + username; // active유저의 key
4445
String lastCommitted = redisTemplate.opsForValue().get(lastcmKey); // 마지막 커밋 시간
4546

46-
System.out.println("username: "+username);
47-
System.out.println("user lastCommitted: "+lastCommitted);
47+
System.out.println("username: "+username+"/ user lastCommitted: "+lastCommitted);
4848
if(username!=null && lastCommitted!=null) processUserCommit(username);
4949
}
5050
}
5151

5252
// 🔹 유저 커밋 검사 및 반영
5353
private void processUserCommit(String username) {
5454
// 유저가 접속한 동안 추가한 commit수를 확인.
55-
String key = "commit_active:" + username; // active유저의 key
55+
String activeKey = "commit_active:" + username; // active유저의 key
5656
String lastcmKey = "commit_lastCommitted:" + username; // active유저의 key
57-
String currentCommit = redisTemplate.opsForValue().get(key); // 현재까지 확인한 커밋 개수
57+
Long currentCommit = Long.parseLong(redisTemplate.opsForValue().get(activeKey)); // 현재까지 확인한 커밋 개수
5858
String lastcommitted = redisTemplate.opsForValue().get(lastcmKey); // 마지막 커밋 시간
5959
long updateTotalCommit, newCommitCount;
6060

61+
// 현재 커밋 개수 조회
62+
updateTotalCommit = totalCommitService.getTotalCommitCount(
63+
username
64+
).getTotalCommitContributions();
6165

62-
LocalDateTime lastCommittedTime;
63-
try {
64-
lastCommittedTime = LocalDateTime.parse(lastcommitted, DateTimeFormatter.ISO_DATE_TIME);
65-
} catch (DateTimeParseException e) {
66-
System.out.println("lastcommitted 값이 올바르지 않음: " + lastcommitted);
67-
lastCommittedTime = LocalDateTime.now().minusHours(1);
68-
}
66+
newCommitCount = updateTotalCommit - currentCommit; // 새로 추가된 커밋 수
6967

70-
// 현재 커밋 개수 조회
71-
updateTotalCommit = totalCommitService.getUpdateCommits(
72-
username,
73-
lastCommittedTime, // 🚀 Redis에 저장된 lastCommitted 기준으로 조회
74-
LocalDateTime.now()
75-
).getCommits();
76-
System.out.println("커밋 개수 불러들이기 완료, 현재까지 업데이트 된 커밋 수 : "+updateTotalCommit);
77-
78-
if(currentCommit.equals("0") && updateTotalCommit > 0){
68+
if(newCommitCount > 0){
7969
User user = userRepository.findByUsername(username).get();
8070
LocalDateTime now = LocalDateTime.now();
81-
//이번 기간에 처음으로 커밋 수가 갱신된 경우, 이 시간을 기점으로 commitCount를 계산한다.
71+
//커밋 수가 갱신된 경우, 이 시간을 기점으로 lastCommitted를 변경한다.
8272
user.setLastCommitted(now);
8373
userRepository.save(user);
8474

85-
String redisKey = "commit_update:" + username; // 변경 알림을 위한 변수
86-
redisTemplate.opsForValue().set(redisKey, String.valueOf(updateTotalCommit), 3, TimeUnit.HOURS);
87-
75+
redisTemplate.opsForValue().set(activeKey, String.valueOf(updateTotalCommit), 3, TimeUnit.HOURS);
8876
redisTemplate.opsForValue().set(lastcmKey, String.valueOf(now), 3, TimeUnit.HOURS);
89-
}
90-
91-
//기존 커밋이 있고 커밋 수에 변화가 있는 경우 처리
92-
newCommitCount = updateTotalCommit - Long.parseLong(currentCommit); // 새로 추가된 커밋 수
93-
if(newCommitCount>0){
94-
String redisKey = "commit_update:" + username; // 변경 알림을 위한 변수
95-
redisTemplate.opsForValue().set(redisKey, String.valueOf(newCommitCount), 3, TimeUnit.HOURS);
9677

97-
updateTotalCommit+=newCommitCount;
98-
redisTemplate.opsForValue().set(key, String.valueOf(updateTotalCommit), 3, TimeUnit.HOURS);
78+
CommitUpdateEvent event = new CommitUpdateEvent(this, username, newCommitCount);
79+
eventPublisher.publishEvent(event); // 이벤트 발생
80+
System.out.println("CommitCreatedEvent published for user: " + username);
9981
}
10082

10183
// FIXME: 차후 리팩토링 필요
102-
log.info("🔍 User: {}, LastCommitted: {}, New Commits: {}, Total Commits: {}", username, lastcommitted, newCommitCount, currentCommit);
84+
log.info("🔍 User: {}, LastCommitted: {}, New Commits: {}, Total Commits: {}", username, lastcommitted, newCommitCount, updateTotalCommit);
10385
}
10486
}
Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
11
package cmf.commitField.domain.commit.scheduler;
22

3+
import lombok.Getter;
34
import org.springframework.context.ApplicationEvent;
45

6+
@Getter
57
public class CommitUpdateEvent extends ApplicationEvent {
6-
private final Long userId;
7-
private final int commitCount;
8+
private final String username;
9+
private final long newCommitCount;
810

9-
public CommitUpdateEvent(Object source, Long userId, int commitCount) {
11+
public CommitUpdateEvent(Object source, String username, long newCommitCount) {
1012
super(source);
11-
this.userId = userId;
12-
this.commitCount = commitCount;
13-
}
14-
15-
public Long getUserId() {
16-
return userId;
17-
}
18-
19-
public int getCommitCount() {
20-
return commitCount;
13+
this.username = username;
14+
this.newCommitCount = newCommitCount;
2115
}
2216
}
Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,44 @@
11
package cmf.commitField.domain.commit.scheduler;
22

3+
import cmf.commitField.domain.pet.service.PetService;
4+
import cmf.commitField.domain.user.service.UserService;
5+
import lombok.RequiredArgsConstructor;
36
import org.springframework.context.event.EventListener;
4-
import org.springframework.stereotype.Service;
7+
import org.springframework.stereotype.Component;
58

6-
@Service
9+
@Component
10+
@RequiredArgsConstructor
711
public class CommitUpdateListener {
12+
private final UserService userService;
13+
private final PetService petService;
14+
private final CommitUpdateService commitUpdateService;
815

916
@EventListener
10-
public void handleCommitUpdateEvent(CommitUpdateEvent event) {
17+
public void handleCommitUserUpdateEvent(CommitUpdateEvent event) {
18+
String username = event.getUsername();
19+
long commitCount = event.getNewCommitCount();
20+
21+
System.out.println("유저 시즌 경험치 업데이트: " + event.getUsername());
22+
// 이벤트 처리 로직
23+
boolean levelUp = userService.getExpUser(username,commitCount);
24+
if(levelUp) commitUpdateService.updateUserTier(username);
25+
26+
// 모든 작업이 끝났다면
27+
userService.updateUserCommitCount(username, commitCount);
28+
// 커밋 갱신 후에 다른 서비스에서 필요한 작업 수행 (예: DB 업데이트, 상태 갱신 등)
29+
System.out.println("유저명: " + username + " has updated " + commitCount + " commits.");
30+
}
31+
32+
@EventListener
33+
public void handleCommitPetUpdateEvent(CommitUpdateEvent event) {
34+
String username = event.getUsername();
35+
long commitCount = event.getNewCommitCount();
36+
37+
System.out.println("유저 펫 경험치 업데이트: " + event.getUsername());
1138
// 이벤트 처리 로직
12-
Long userId = event.getUserId();
13-
int commitCount = event.getCommitCount();
39+
petService.getExpPet(username,commitCount);
1440

1541
// 커밋 갱신 후에 다른 서비스에서 필요한 작업 수행 (예: DB 업데이트, 상태 갱신 등)
16-
System.out.println("User ID: " + userId + " has updated " + commitCount + " commits.");
42+
System.out.println("유저명: " + username + "'s pet has updated " + commitCount + " commits.");
1743
}
1844
}

src/main/java/cmf/commitField/domain/commit/scheduler/CommitUpdateService.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import cmf.commitField.domain.user.entity.User;
77
import cmf.commitField.domain.user.repository.UserRepository;
88
import lombok.RequiredArgsConstructor;
9-
import org.springframework.context.ApplicationEventPublisher;
109
import org.springframework.stereotype.Service;
1110

1211
import java.time.LocalDateTime;
@@ -18,14 +17,12 @@ public class CommitUpdateService {
1817
private final UserRepository userRepository;
1918
private final PetService petService;
2019

21-
private final ApplicationEventPublisher eventPublisher;
22-
2320
public UserInfoDto updateUserTier(String username){
2421
User user = userRepository.findByUsername(username).get();
2522
long seasonCommitCount;
26-
// seasonCommitCount = totalCommitService.getSeasonCommits(user.getUsername(), LocalDateTime.of(2024,12,01,0,0), LocalDateTime.of(2025,2,28,23,59)).getTotalCommitContributions();
27-
seasonCommitCount = totalCommitService.getSeasonCommits(user.getUsername(), LocalDateTime.of(2025,03,01,0,0), LocalDateTime.of(2025,05,31,23,59)).getTotalCommitContributions();
23+
seasonCommitCount = totalCommitService.getSeasonCommits(user.getUsername(), LocalDateTime.of(2025,03,01,0,0), LocalDateTime.of(2025,05,31,23,59)).getTotalCommitContributions();
2824
user.setTier(User.Tier.getLevelByExp((int)seasonCommitCount));
25+
System.out.println(username+"유저 레벨 업! 현재 티어: "+user.getTier());
2926
userRepository.save(user);
3027

3128
return UserInfoDto.builder()

src/main/java/cmf/commitField/domain/commit/totalCommit/service/TotalCommitService.java

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cmf.commitField.domain.commit.totalCommit.service;
22

3-
import cmf.commitField.domain.commit.totalCommit.dto.CommitUpdateDTO;
43
import cmf.commitField.domain.commit.totalCommit.dto.TotalCommitGraphQLResponse;
54
import cmf.commitField.domain.commit.totalCommit.dto.TotalCommitResponseDto;
65
import lombok.RequiredArgsConstructor;
@@ -216,24 +215,25 @@ private StreakResult calculateStreaks(List<LocalDate> commitDates) {
216215
}
217216

218217
// 시간별 커밋 분석
219-
public CommitUpdateDTO getUpdateCommits(String username, LocalDateTime since, LocalDateTime until) {
218+
public long getUpdateCommits(String username, LocalDateTime since, LocalDateTime until) {
220219
String query = String.format("""
221220
query {
222221
user(login: "%s") {
223222
contributionsCollection(from: "%s", to: "%s") {
224223
commitContributionsByRepository {
225224
contributions(first: 100) {
226225
nodes {
227-
occurredAt # 시간 정보 포함
226+
occurredAt
228227
}
229228
}
230229
}
231230
}
232231
}
233-
}""", username, since.format(DateTimeFormatter.ISO_DATE_TIME), until.format(DateTimeFormatter.ISO_DATE_TIME));
232+
}
233+
""", username, since.format(DateTimeFormatter.ISO_DATE_TIME), until.format(DateTimeFormatter.ISO_DATE_TIME));
234234

235235
Map<String, String> requestBody = Map.of("query", query);
236-
236+
System.out.println(username);
237237
TotalCommitGraphQLResponse response = webClient.post()
238238
.header("Authorization", "bearer " + PAT)
239239
.bodyValue(requestBody)
@@ -244,14 +244,52 @@ public CommitUpdateDTO getUpdateCommits(String username, LocalDateTime since, Lo
244244
if (response == null || response.getData() == null || response.getData().getUser() == null) {
245245
throw new RuntimeException("Failed to fetch GitHub data");
246246
}
247+
System.out.println(response);
247248

248-
249-
System.out.println("메소드 작동 확인 : "+response.getData().getUser());
250249
TotalCommitGraphQLResponse.ContributionsCollection contributions =
251250
response.getData().getUser().getContributionsCollection();
251+
// 커밋 발생 시간 리스트 추출
252+
List<LocalDateTime> commitTimes = extractCommitTimes(contributions.getContributionCalendar());
252253

253-
return new CommitUpdateDTO(
254-
contributions.getTotalCommitContributions()
255-
);
254+
// 초 단위로 커밋 수 계산
255+
long commitCount = calculateCommitsInTimeRange(commitTimes, since, until);
256+
257+
return commitCount;
258+
}
259+
260+
// 커밋 발생 시간을 LocalDateTime 형식으로 추출하는 메서드
261+
private List<LocalDateTime> extractCommitTimes(TotalCommitGraphQLResponse.ContributionCalendar contributionCalendar) {
262+
List<LocalDateTime> commitTimes = new ArrayList<>();
263+
264+
if (contributionCalendar == null) {
265+
System.out.println("contributionCalendar is null");
266+
return commitTimes; // 빈 리스트 반환
267+
}
268+
269+
// contributionCalendar에서 각 주 단위로 데이터 추출
270+
contributionCalendar.getWeeks().forEach(week -> {
271+
week.getContributionDays().forEach(contributionDay -> {
272+
if (contributionDay.getContributionCount() > 0) {
273+
// 각 날짜에 커밋이 있는 경우 그 날짜를 커밋 시간으로 추가
274+
LocalDate commitDate = LocalDate.parse(contributionDay.getDate());
275+
// LocalDate를 LocalDateTime으로 변환 (시간은 00:00:00로 설정)
276+
LocalDateTime commitTime = commitDate.atStartOfDay();
277+
commitTimes.add(commitTime);
278+
}
279+
});
280+
});
281+
282+
return commitTimes;
256283
}
284+
285+
286+
287+
// 커밋 시간 리스트에서 since와 until 사이에 발생한 커밋 수 계산
288+
private long calculateCommitsInTimeRange(List<LocalDateTime> commitTimes, LocalDateTime since, LocalDateTime until) {
289+
return commitTimes.stream()
290+
.filter(commitTime -> !commitTime.isBefore(since) && !commitTime.isAfter(until))
291+
.count();
292+
}
293+
294+
257295
}
Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package cmf.commitField.domain.noti.noti.controller;
22

33
import cmf.commitField.domain.noti.noti.dto.NotiDto;
4-
import cmf.commitField.domain.noti.noti.entity.Noti;
54
import cmf.commitField.domain.noti.noti.service.NotiService;
65
import cmf.commitField.domain.user.entity.User;
76
import cmf.commitField.domain.user.repository.UserRepository;
8-
import cmf.commitField.domain.user.service.CustomOAuth2UserService;
97
import cmf.commitField.global.error.ErrorCode;
108
import cmf.commitField.global.exception.CustomException;
119
import cmf.commitField.global.globalDto.GlobalResponse;
@@ -16,40 +14,39 @@
1614
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
1715
import org.springframework.security.oauth2.core.user.OAuth2User;
1816
import org.springframework.web.bind.annotation.GetMapping;
17+
import org.springframework.web.bind.annotation.PostMapping;
1918
import org.springframework.web.bind.annotation.RequestMapping;
2019
import org.springframework.web.bind.annotation.RestController;
2120

2221
import java.util.List;
2322
import java.util.Map;
24-
import java.util.stream.Collectors;
2523

2624
@RestController
2725
@RequestMapping("/api/notifications")
2826
@RequiredArgsConstructor
2927
@Slf4j
3028
public class ApiV1NotiController {
3129
private final NotiService notiService;
32-
private final CustomOAuth2UserService customOAuth2UserService;
3330
private final UserRepository userRepository;
3431

3532
@GetMapping("")
3633
public GlobalResponse<List<NotiDto>> getNoti() {
3734
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
38-
log.info("getNoti - userRequest: {}", authentication);
3935

4036
if (authentication instanceof OAuth2AuthenticationToken) {
4137
OAuth2User principal = (OAuth2User) authentication.getPrincipal();
4238
Map<String, Object> attributes = principal.getAttributes();
4339
String username = (String) attributes.get("login"); // GitHub ID
4440
User user = userRepository.findByUsername(username).orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));
45-
List<Noti> notis = notiService.getNotReadNoti(user);
46-
47-
List<NotiDto> notiDtos = notis.stream()
48-
.map(NotiDto::new)
49-
.collect(Collectors.toList());
50-
return GlobalResponse.success(notiDtos);
41+
List<NotiDto> notis = notiService.getNotReadNoti(user);
42+
return GlobalResponse.success(notis);
5143
}
5244

5345
return GlobalResponse.error(ErrorCode.LOGIN_REQUIRED);
5446
}
47+
48+
@PostMapping("")
49+
public void createNoti() {
50+
51+
}
5552
}

0 commit comments

Comments
 (0)