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

유저 통계와 전체 통계 분리 리팩토링(#104) #113

Open
wants to merge 23 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
65d30de
refactor: Statistics를 dashboard 도메인으로 이동(#104)
eun-seong Mar 5, 2024
e678c00
refactor: 유저통계량과 전체통계량 계산 로직 분리(#104)
eun-seong Mar 5, 2024
2a02638
refactor: Statistic 구현체 생성자 protected로 변경(#104)
eun-seong Mar 5, 2024
40d646b
refactor: DashboardComponent 생성자 인자를 statistic 리스트로 변경(#104)
eun-seong Mar 5, 2024
8f60a9e
refactor: DashboardComponent 생성 로직 Entity로 이동(#104)
eun-seong Mar 5, 2024
e13bb2c
refactor: RadioStatistic 대시보드 컴포넌트 정렬하여 반환하도록 수정(#104)
eun-seong Mar 6, 2024
070b4c1
test: character 대시보드 타입 테스트 코드 작성(#104)
eun-seong Mar 6, 2024
c70e7b0
test: money 대시보드 타입 테스트 코드 작성(#104)
eun-seong Mar 6, 2024
245443a
test: RatioStatistic 테스트 코드 작성(#104)
eun-seong Mar 6, 2024
43b783c
test: AverageStatistic 테스트 코드 작성(#104)
eun-seong Mar 6, 2024
bc7da8a
refactor: dto 변환 방식 별 대시보드 컴포넌트 클래스 추가(#104)
eun-seong Mar 6, 2024
568f363
refactor: 대시보드통계타입 별 클래스 생성(#104)
eun-seong Mar 6, 2024
3de35d4
refactor: DashboardComponent Factory 구현(#104)
eun-seong Mar 6, 2024
4e444af
refactor: 대시보드 타입을 key로 한 statistic map 조회 메소드 추가(#104)
eun-seong Mar 6, 2024
2127de5
refactor: Dashboard 생성을 DashboardFactory로 교체(#104)
eun-seong Mar 6, 2024
360adf3
refactor: BorrowingLimitEntireStatistic을 AverageEntireStatistic으로 변경(…
eun-seong Mar 6, 2024
d95bc0e
rename: StatisticsType -> StatisticsCalculationType 으로 이름 변경(#104)
eun-seong Mar 6, 2024
82e60ec
rename: DashboareType에 AnalysisType 추가(#104)
eun-seong Mar 6, 2024
32b6c77
rename: Dashboard를 유저와 전체로 분리하여 조회하도록 수정(#104)
eun-seong Mar 6, 2024
e767efc
rename: Option을 통해 Legend 생성 메소드 추가(#104)
eun-seong Mar 6, 2024
7e8cc34
fix: DashboareType에 NONE 추가(#104)
eun-seong Mar 6, 2024
3069d78
fix: Map value에 항상 새로운 List 들어가던 오류 수정(#104)
eun-seong Mar 6, 2024
d70ab43
Resolve conflicts from dev
eun-seong Mar 15, 2024
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,29 +2,24 @@

import com.dnd.namuiwiki.common.exception.ApplicationErrorException;
import com.dnd.namuiwiki.common.exception.ApplicationErrorType;
import com.dnd.namuiwiki.domain.dashboard.model.BestWorthDashboardComponent;
import com.dnd.namuiwiki.domain.dashboard.model.CharacterDashboardComponent;
import com.dnd.namuiwiki.domain.dashboard.model.DashboardComponent;
import com.dnd.namuiwiki.domain.dashboard.model.HappyDashboardComponent;
import com.dnd.namuiwiki.domain.dashboard.model.MoneyDashboardComponent;
import com.dnd.namuiwiki.domain.dashboard.model.SadDashboardComponent;
import com.dnd.namuiwiki.domain.dashboard.model.dto.DashboardDto;
import com.dnd.namuiwiki.domain.dashboard.model.entity.Dashboard;
import com.dnd.namuiwiki.domain.dashboard.type.DashboardType;
import com.dnd.namuiwiki.domain.jwt.dto.TokenUserInfoDto;
import com.dnd.namuiwiki.domain.question.QuestionRepository;
import com.dnd.namuiwiki.domain.question.entity.Question;
import com.dnd.namuiwiki.domain.question.type.QuestionName;
import com.dnd.namuiwiki.domain.statistic.StatisticsService;
import com.dnd.namuiwiki.domain.statistic.model.BorrowingLimitEntireStatistic;
import com.dnd.namuiwiki.domain.statistic.model.Statistics;
import com.dnd.namuiwiki.domain.statistic.model.entity.PopulationStatistic;
import com.dnd.namuiwiki.domain.survey.model.entity.Answer;
import com.dnd.namuiwiki.domain.survey.model.entity.Survey;
import com.dnd.namuiwiki.domain.survey.type.Period;
import com.dnd.namuiwiki.domain.survey.type.Relation;
import com.dnd.namuiwiki.domain.user.UserRepository;
import com.dnd.namuiwiki.domain.user.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

Expand All @@ -34,42 +29,25 @@ public class DashboardService {
private final UserRepository userRepository;
private final DashboardRepository dashboardRepository;
private final StatisticsService statisticsService;
private final QuestionRepository questionRepository;

public DashboardDto getDashboard(TokenUserInfoDto tokenUserInfoDto, Period period, Relation relation) {
validateFilterCategory(period, relation);

User user = findByWikiId(tokenUserInfoDto.getWikiId());
Optional<Dashboard> dashboard = dashboardRepository.findByUserAndPeriodAndRelation(user, period, relation);
if (dashboard.isEmpty()) {
Optional<Dashboard> optionalDashboard = dashboardRepository.findByUserAndPeriodAndRelation(user, period, relation);
if (optionalDashboard.isEmpty()) {
return null;
}
Dashboard dashboard = optionalDashboard.get();

List<Question> questions = questionRepository.findAll();

Statistics statistics = dashboard.get().getStatistics();
List<DashboardComponent> dashboardComponents = List.of(
new BestWorthDashboardComponent(statistics, getQuestionIdByQuestionNAme(questions, QuestionName.CORE_VALUE)),
new HappyDashboardComponent(statistics, getQuestionIdByQuestionNAme(questions, QuestionName.HAPPY_BEHAVIOR)),
new SadDashboardComponent(statistics, getQuestionIdByQuestionNAme(questions, QuestionName.SAD_ANGRY_BEHAVIOR)),
new CharacterDashboardComponent(statistics),
getMoneyDashboardComponent(statistics, period, relation, getQuestionIdByQuestionNAme(questions, QuestionName.BORROWING_LIMIT))
);
return new DashboardDto(dashboardComponents);
}

private String getQuestionIdByQuestionNAme(List<Question> questions, QuestionName questionName) {
return questions.stream().filter(q -> q.getName() == questionName)
.findFirst().orElseThrow(() -> new ApplicationErrorException(ApplicationErrorType.INVALID_QUESTION_ID))
.getId();
}

private MoneyDashboardComponent getMoneyDashboardComponent(Statistics statistics, Period period, Relation relation, String questionId) {
List<DashboardComponent> userDashboards = dashboard.getUserDashboards();
PopulationStatistic populationStatistic = statisticsService.getPopulationStatistic(period, relation, QuestionName.BORROWING_LIMIT);
BorrowingLimitEntireStatistic statistic = (BorrowingLimitEntireStatistic) populationStatistic.getStatistic();
long entireAverage = statistic.getBorrowingMoneyLimitEntireAverage();
DashboardComponent populationDashboard = dashboard.getPopulationDashboard(populationStatistic, DashboardType.MONEY);

return new MoneyDashboardComponent(statistics, entireAverage, questionId);
List<DashboardComponent> components = new ArrayList<>(userDashboards);
components.add(populationDashboard);

return new DashboardDto(components);
}

private void validateFilterCategory(Period period, Relation relation) {
Expand All @@ -83,4 +61,30 @@ private User findByWikiId(String wikiId) {
.orElseThrow(() -> new ApplicationErrorException(ApplicationErrorType.NOT_FOUND_USER));
}


public void updateStatistics(Survey survey) {
User owner = survey.getOwner();
Period period = survey.getPeriod();
Relation relation = survey.getRelation();

var statisticalAnswers = survey.getAnswers().stream()
.filter(answer -> answer.getQuestion().getDashboardType().getStatisticsCalculationType().isNotNone())
.toList();

updateDashboards(owner, period, relation, statisticalAnswers);
}

private void updateDashboards(User owner, Period period, Relation relation, List<Answer> statisticalAnswers) {
updateDashboardByCategory(owner, null, null, statisticalAnswers);
updateDashboardByCategory(owner, period, null, statisticalAnswers);
updateDashboardByCategory(owner, null, relation, statisticalAnswers);
}

private void updateDashboardByCategory(User owner, Period period, Relation relation, List<Answer> answers) {
Dashboard dashboard = dashboardRepository.findByUserAndPeriodAndRelation(owner, period, relation)
.orElseGet(() -> dashboardRepository.save(Dashboard.createNew(owner, period, relation, answers)));
dashboard.updateStatistics(answers);
dashboardRepository.save(dashboard);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.dnd.namuiwiki.domain.dashboard.model;

import com.dnd.namuiwiki.domain.dashboard.type.DashboardType;
import com.dnd.namuiwiki.domain.statistic.model.AverageEntireStatistic;
import com.dnd.namuiwiki.domain.statistic.model.entity.PopulationStatistic;
import lombok.Getter;

@Getter
public class AverageDashboardComponent extends DashboardComponent {
private final String questionId;
private final long peopleCount;
private final long average;
private final long entireAverage;

public AverageDashboardComponent(DashboardType dashboardType, Statistic statistic, PopulationStatistic populationStatistic) {
super(dashboardType);
AverageEntireStatistic entireStatistic = (AverageEntireStatistic) populationStatistic.getStatistic();
AverageStatistic averageStatistic = (AverageStatistic) statistic;

this.entireAverage = entireStatistic.getEntireAverage();
this.questionId = statistic.getQuestionId();
this.peopleCount = averageStatistic.getTotalCount();
this.average = averageStatistic.getAverage();
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.dnd.namuiwiki.domain.statistic.model;
package com.dnd.namuiwiki.domain.dashboard.model;

import com.dnd.namuiwiki.common.exception.ApplicationErrorException;
import com.dnd.namuiwiki.common.exception.ApplicationErrorType;
Expand Down Expand Up @@ -48,7 +48,7 @@ public void updateAverage(Long newNumber) {
average = ArithmeticUtils.calculateAverage(totalCount, average, newNumber);
}

public static AverageStatistic create(Question question) {
protected static AverageStatistic create(Question question) {
return new AverageStatistic(
question.getId(),
question.getName(),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,39 @@
import com.dnd.namuiwiki.common.exception.ApplicationErrorType;
import com.dnd.namuiwiki.domain.dashboard.type.DashboardType;
import com.dnd.namuiwiki.domain.question.type.QuestionName;
import com.dnd.namuiwiki.domain.statistic.model.Legend;
import com.dnd.namuiwiki.domain.statistic.model.RatioStatistic;
import com.dnd.namuiwiki.domain.statistic.model.Statistic;
import com.dnd.namuiwiki.domain.statistic.model.Statistics;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.List;

@Getter
public class CharacterDashboardComponent extends DashboardComponent {
private List<Character> characters;
public class BinaryDashboardComponent extends DashboardComponent {
private List<BinaryMetric> characters;

public CharacterDashboardComponent(Statistics statistics) {
super(DashboardType.CHARACTER);
public BinaryDashboardComponent(DashboardType dashboardType, List<Statistic> statistics) {
super(dashboardType);
this.characters = new ArrayList<>();
calculate(statistics);
initiate(statistics);
}

@Override
public void calculate(Statistics statistics) {
List<Statistic> character = statistics.getStatisticsByDashboardType(this.dashboardType);
this.characters = character.stream().map(Character::from).toList();
public void initiate(List<Statistic> character) {
this.characters = character.stream().map(BinaryMetric::from).toList();
}

@RequiredArgsConstructor
@Getter
static class Character {
static class BinaryMetric {
private final String name;
private final boolean value;
private final String questionId;

private static Character from(Statistic statistic) {
private static BinaryMetric from(Statistic statistic) {
RatioStatistic ratioStatistic = (RatioStatistic) statistic;
List<Legend> legends = ratioStatistic.getLegends();
QuestionName questionName = ratioStatistic.getQuestionName();

return new Character(
return new BinaryMetric(
questionName.name(),
getCharacterRatioResult(legends),
statistic.getQuestionId()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
package com.dnd.namuiwiki.domain.dashboard.model;

import com.dnd.namuiwiki.domain.dashboard.type.DashboardType;
import com.dnd.namuiwiki.domain.statistic.model.Statistics;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Schema(description = "대시보드 타입", oneOf = {
BestWorthDashboardComponent.class,
CharacterDashboardComponent.class,
HappyDashboardComponent.class,
MoneyDashboardComponent.class,
SadDashboardComponent.class})
AverageDashboardComponent.class,
BinaryDashboardComponent.class,
RatioDashboardComponent.class})
@AllArgsConstructor
@Getter
public abstract class DashboardComponent {

protected final DashboardType dashboardType;

public abstract void calculate(Statistics statistics);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.dnd.namuiwiki.domain.dashboard.model;

import com.dnd.namuiwiki.domain.dashboard.type.DashboardStatisticType;
import com.dnd.namuiwiki.domain.dashboard.type.DashboardType;
import com.dnd.namuiwiki.domain.statistic.model.entity.PopulationStatistic;

import java.util.List;

public abstract class DashboardFactory {

public static DashboardComponent create(DashboardType dashboardType, List<Statistic> statistics) {
DashboardStatisticType type = dashboardType.getDashboardStatisticType();
switch (type) {
case RATIO -> {
validateStatisticsSize(statistics, 1);
return new RatioDashboardComponent(dashboardType, statistics.get(0));
}
case BINARY -> {
return new BinaryDashboardComponent(dashboardType, statistics);
}
default -> throw new IllegalArgumentException("Not supported type: " + type);
}
}

public static DashboardComponent create(DashboardType dashboardType, List<Statistic> statistics, PopulationStatistic populationStatistic) {
DashboardStatisticType type = dashboardType.getDashboardStatisticType();
switch (type) {
case AVERAGE -> {
validateStatisticsSize(statistics, 1);
return new AverageDashboardComponent(dashboardType, statistics.get(0), populationStatistic);
}
default -> throw new IllegalArgumentException("Not supported type: " + type);
}
}

private static void validateStatisticsSize(List<Statistic> statistics, int size) {
if (statistics.size() != size) {
throw new IllegalArgumentException(String.format("This Dashboard type should have only %d statistic", size));
}
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dnd.namuiwiki.domain.statistic.model;
package com.dnd.namuiwiki.domain.dashboard.model;

import com.dnd.namuiwiki.domain.option.entity.Option;
import lombok.AllArgsConstructor;
import lombok.Getter;

Expand All @@ -14,4 +15,8 @@ public class Legend {
public Long increaseCount() {
return ++count;
}

public static Legend from(Option option) {
return new Legend(option.getId(), option.getText(), option.getValue(), 0L);
}
}
Loading