Skip to content

Commit

Permalink
Merge pull request #20 from Leets-Official/19-fearture-tier
Browse files Browse the repository at this point in the history
19 fearture Tier 객채 생성
  • Loading branch information
yechan-kim authored Jul 29, 2024
2 parents 1ec05d5 + e86ca4d commit 701705c
Show file tree
Hide file tree
Showing 30 changed files with 221 additions and 175 deletions.
4 changes: 3 additions & 1 deletion scripts/after-deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ else
sleep 5
fi

source ~/.bashrc

echo "> Deploy - $JAR_PATH "
nohup java -jar $JAR_PATH > /dev/null 2> /dev/null < /dev/null &
nohup java -jar $JAR_PATH > commitato.log 2>&1 &
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.UUID;

Expand All @@ -28,7 +29,7 @@ public class Commit extends BaseTimeEntity {
private LocalDateTime commitDate;

@ManyToOne
@JoinColumn(name="user_id")
@JoinColumn(name = "user_id")
@JsonBackReference
private User user;

Expand All @@ -52,7 +53,23 @@ public Commit(LocalDateTime commitDate, Integer cnt, User user) {

public void updateCnt(Integer cnt) {
this.cnt = this.cnt + cnt;
this.isCalculated=false;
markAsUncalculated();
}

public void markAsCalculated() {
isCalculated = true;
}

public void markAsUncalculated() {
isCalculated = false;
}

public int calculateExp(int dailyBonusExp, int consecutiveDays, int bonusExpIncrease) {
int bonusExp = dailyBonusExp + consecutiveDays * bonusExpIncrease;
return this.cnt * 5 + bonusExp;
}

public boolean commitDateIsToday() {
return this.commitDate.toLocalDate().isEqual(LocalDate.now());
}
public void updateStatusToCalculated(boolean calculated){isCalculated=calculated;}//isCalculated 필드 설정
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ public interface CommitRepository extends JpaRepository<Commit, UUID> {
Optional<Commit> findByCommitDateAndUser(LocalDateTime commitDate, User user);

List<Commit> findAllByUserOrderByCommitDateAsc(User user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public ApiResponse<CommitResponse> fetchCommits(HttpServletRequest request) {

@Operation(
summary = "커밋 기록 불러오기 (테스트)",
description = "commit/fetch가 정상적으로 실행이 될 동안 사용할 임시 API")
description = "테스트를 위해, 7월 1일부터 커밋 기록을 가져와 DB에 저장합니다.")
@PostMapping("test/fetch")
public ApiResponse<CommitResponse> fetchCommits(HttpServletRequest request, @RequestHeader String accessToken) {
return ApiResponse.onSuccess(fetchCommitsTest.execute(request, accessToken));
public ApiResponse<CommitResponse> fetchCommitsTest(HttpServletRequest request) {
return ApiResponse.onSuccess(fetchCommitsTest.execute(request));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import com.leets.commitatobe.domain.tier.domain.repository.TierRepository;
import com.leets.commitatobe.domain.user.domain.User;
import com.leets.commitatobe.domain.user.domain.repository.UserRepository;
import com.leets.commitatobe.global.exception.ApiException;
import com.leets.commitatobe.global.response.code.status.ErrorStatus;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
Expand All @@ -25,46 +26,50 @@ public class ExpService {
private final UserRepository userRepository;
private final TierRepository tierRepository;

public void calculateAndSaveExp(String githubId){
User user=userRepository.findByGithubId(githubId)
.orElseThrow(()->new UsernameNotFoundException("해당하는 깃허브 닉네임과 일치하는 유저를 찾을 수 없음: " +githubId));
List<Commit> commits=commitRepository.findAllByUserOrderByCommitDateAsc(user);//사용자의 모든 커밋을 날짜 오름차순으로 불러온다.
int DAILY_BONUS_EXP = 100;
int BONUS_EXP_INCREASE = 10;

int consecutiveDays=0;//연속 커밋 일수
LocalDateTime lastCommitDate=null;//마지막 커밋 날짜
int totalExp=user.getExp()!=null?user.getExp():0;//사용자의 현재 경험치, user.getExp()가 null인 경우 0으로 초기화
int dailyBonusExp=100;//데일리 보너스 경험치
int bonusExpIncrease=10;//보너스 경험치 증가량
int totalCommitCount=0;//총 커밋 횟수
int todayCommitCount=0;//오늘 커밋 횟수
public void calculateAndSaveExp(String githubId) {
User user = userRepository.findByGithubId(githubId)
.orElseThrow(() -> new UsernameNotFoundException("해당하는 깃허브 닉네임과 일치하는 유저를 찾을 수 없음: " + githubId));
List<Commit> commits = commitRepository.findAllByUserOrderByCommitDateAsc(user); //사용자의 모든 커밋을 날짜 오름차순으로 불러온다.

LocalDate today=LocalDate.now();//오늘 날짜
int consecutiveDays = user.getConsecutiveCommitDays(); //연속 커밋 일수
LocalDateTime lastCommitDate = null; //마지막 커밋 날짜
int totalExp = user.getExp(); //사용자의 현재 경험치
int totalCommitCount = user.getTotalCommitCount(); //총 커밋 횟수
int todayCommitCount = user.getTodayCommitCount(); //오늘 커밋 횟수

for(Commit commit:commits){//각 커밋을 반복해서 계산
if(commit.isCalculated()) continue;//이미 계산된 커밋
LocalDateTime commitDate=commit.getCommitDate();//커밋날짜를 가져와 시간 설정
for (Commit commit : commits) {//각 커밋을 반복해서 계산
if (commit.isCalculated()) continue;//이미 계산된 커밋
LocalDateTime commitDate = commit.getCommitDate();//커밋날짜를 가져와 시간 설정

if(lastCommitDate != null && commitDate.isEqual(lastCommitDate.plusDays(1))){
if (lastCommitDate != null && commitDate.isEqual(lastCommitDate.plusDays(1))) {
// 마지막 커밋 날짜가 존재하고, 현재 커밋 날짜가 마지막 커밋 날짜의 다음 날과 같으면 연속 커밋으로 간주합니다.
consecutiveDays++;//연속 커밋 일수 1 증가
} else {
if (lastCommitDate == null) { // 연속 커밋 일수는 전날 커밋이 없을 경우에 초기화
consecutiveDays = 0;//연속 커밋 일수 초기화
}
}
else{
consecutiveDays=0;//연속 커밋 일수 초기화
}
int commitExp=commit.getCnt()*5;//하루 커밋 경험치
int bonusExp=dailyBonusExp+consecutiveDays*bonusExpIncrease;//보너스 경험치 계산
totalExp+=commitExp+bonusExp;//총 경험치 업데이트
totalCommitCount+=commit.getCnt();//총 커밋 횟수

if(commitDate.toLocalDate().isEqual(today)){
todayCommitCount=commit.getCnt();//오늘날짜의 커밋 개수 카운트
totalExp += commit.calculateExp(DAILY_BONUS_EXP, consecutiveDays, BONUS_EXP_INCREASE);//총 경험치 업데이트
totalCommitCount += commit.getCnt();//총 커밋 횟수

if (commit.commitDateIsToday()) {
todayCommitCount = commit.getCnt();//오늘날짜의 커밋 개수 카운트
}

commit.updateStatusToCalculated(true);//커밋 계산 여부를 true로 해서 다음 게산에서 제외
lastCommitDate=commitDate;//마지막 커밋날짜를 현재 커밋날짜로 업데이트
commit.markAsCalculated();//커밋 계산 여부를 true로 해서 다음 게산에서 제외
lastCommitDate = commitDate;//마지막 커밋날짜를 현재 커밋날짜로 업데이트
}

if (lastCommitDate != null && lastCommitDate.isBefore(LocalDateTime.now().minusDays(1))) {
consecutiveDays = 0;//마지막 커밋날짜가 어제보다 이전이면 연속 커밋 일수 초기화
}

user.updateExp(totalExp);//사용자 경험치 업데이트
Tier tier=determineTier(user.getExp());//경험치에 따른 티어 결정
Tier tier = determineTier(user.getExp());//경험치에 따른 티어 결정
user.updateTier(tier);
user.updateConsecutiveCommitDays(consecutiveDays);
user.updateTotalCommitCount(totalCommitCount);
Expand All @@ -85,11 +90,12 @@ public void calculateAndSaveExp(String githubId){
commitRepository.saveAll(commits);//변경된 커밋 정보 데이터베이스에 저장
userRepository.save(user);//변경된 사용자 정보 데이터베이스에 저장
}
private Tier determineTier(Integer exp){

private Tier determineTier(Integer exp) {
return tierRepository.findAll()
.stream()
.filter(tier->tier.getRequiredExp()!=null&&tier.getRequiredExp()<=exp)
.filter(tier -> tier.isValid(exp))
.max(Comparator.comparing(Tier::getRequiredExp))
.orElseThrow(()->new RuntimeException("해당 경험치의 티어가 없음"+exp));
.orElseThrow(() -> new ApiException(ErrorStatus._TIER_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ public CommitResponse execute(HttpServletRequest request) {
// gitHubService.updateToken(loginCommandService.gitHubLogin(gitHubId));

//변경: DB에서 엑세스 토큰 불러오도록 방식 변경
String gitHubaccessToken = userQueryService.getUserGitHubAccessToken(gitHubId);
gitHubService.updateToken(gitHubaccessToken);
gitHubService.updateToken(userQueryService.getUserGitHubAccessToken(gitHubId));

List<String> repos = gitHubService.fetchRepos(gitHubId);
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.leets.commitatobe.domain.commit.domain.Commit;
import com.leets.commitatobe.domain.commit.domain.repository.CommitRepository;
import com.leets.commitatobe.domain.commit.presentation.dto.response.CommitResponse;
import com.leets.commitatobe.domain.login.usecase.LoginCommandServiceImpl;
import com.leets.commitatobe.domain.login.usecase.LoginQueryService;
import com.leets.commitatobe.domain.user.domain.User;
import com.leets.commitatobe.domain.user.domain.repository.UserRepository;
import com.leets.commitatobe.domain.user.usecase.UserQueryService;
import com.leets.commitatobe.global.exception.ApiException;
import com.leets.commitatobe.global.response.code.status.ErrorStatus;
import com.leets.commitatobe.global.response.code.status.SuccessStatus;
Expand All @@ -16,10 +18,7 @@

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand All @@ -30,9 +29,12 @@ public class FetchCommitsTest {
private final CommitRepository commitRepository;
private final UserRepository userRepository;
private final GitHubService gitHubService; // GitHub API 통신
private final LoginCommandServiceImpl loginCommandService;
private final LoginQueryService loginQueryService;
private final ExpService expService;
private final UserQueryService userQueryService;

public CommitResponse execute(HttpServletRequest request, String accessToken) {
public CommitResponse execute(HttpServletRequest request) {
String gitHubId = loginQueryService.getGitHubId(request);
User user = userRepository.findByGithubId(gitHubId)
.orElseThrow(() -> new UsernameNotFoundException("해당하는 깃허브 닉네임과 일치하는 유저를 찾을 수 없음: " + gitHubId));
Expand All @@ -49,7 +51,7 @@ public CommitResponse execute(HttpServletRequest request, String accessToken) {

try {
// Github API Access Token 저장
gitHubService.updateToken(accessToken);
gitHubService.updateToken(userQueryService.getUserGitHubAccessToken(gitHubId));

List<String> repos = gitHubService.fetchRepos(gitHubId);
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Expand All @@ -74,6 +76,8 @@ public CommitResponse execute(HttpServletRequest request, String accessToken) {

saveCommits(user);

expService.calculateAndSaveExp(gitHubId);//커밋 가져온 후 경험치 계산 및 저장

} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public class GitHubService {
private final Map<LocalDateTime, Integer> commitsByDate = new HashMap<>();
@Value("${domain-uri}")
private String DOMAIN_URI;
private String loginURL = DOMAIN_URI + "/login/github";

// GitHub repository 이름 저장
public List<String> fetchRepos(String gitHubUsername) throws IOException {
Expand Down Expand Up @@ -134,7 +133,7 @@ private HttpURLConnection getConnection(URL url) throws IOException {
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
// AUTH_TOKEN이 유효하지 않으면 리다이렉트
URL loginUrl = new URL(loginURL);
URL loginUrl = new URL(DOMAIN_URI + "/login/github");
connection = (HttpURLConnection) loginUrl.openConnection();
connection.setInstanceFollowRedirects(true);
connection.connect();
Expand Down Expand Up @@ -193,4 +192,4 @@ private String formatToISO8601(LocalDateTime dateTime) {
public void updateToken(String accessToken) {
this.AUTH_TOKEN = accessToken;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,3 @@ public GitHubDto getGitHubDto() {
return new GitHubDto(this.githubId);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -74,5 +73,4 @@ public ApiResponse<GitHubDto> test(HttpServletRequest request) {
log.info("깃허브 엑세스 토큰: {}", gitHubAccessToken);
return ApiResponse.onSuccess(user);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx
);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,3 @@ public String decrypt(String token) {
return new String(decrypted, StandardCharsets.UTF_8);
}
}


25 changes: 5 additions & 20 deletions src/main/java/com/leets/commitatobe/domain/tier/domain/Tier.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,28 @@
package com.leets.commitatobe.domain.tier.domain;

import com.leets.commitatobe.domain.user.domain.User;
import com.leets.commitatobe.global.shared.entity.BaseTimeEntity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.UUID;

@Entity
@Getter
@Builder
@NoArgsConstructor
public class Tier extends BaseTimeEntity {
public class Tier {

@Id @GeneratedValue(strategy = GenerationType.UUID)
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column(name = "tier_id")
private UUID id;

private String tierName;
private String characterUrl;
private String badgeUrl;

@Column(nullable = false)
private Integer requiredExp;

@OneToMany(mappedBy = "tier")
private List<User> userList;

public Tier(UUID id,String tierName, String characterUrl, String badgeUrl, Integer requiredExp, List<User>userList){
this.id=id;
this.tierName=tierName;
this.characterUrl=characterUrl;
this.badgeUrl=badgeUrl;
this.requiredExp=requiredExp;
this.userList=userList;
public boolean isValid(Integer exp) {
return this.getRequiredExp() != null && this.getRequiredExp() <= exp;
}

}
Loading

0 comments on commit 701705c

Please sign in to comment.