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

[새기능] 어드민 분석 기능 #99

Merged
merged 62 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
3e7d631
feat(#79): 원서 도메인에 school_address 컬럼 추가
cabbage16 Jun 13, 2024
09a4ca0
test(#79): FormFixture, FormControllerTest
cabbage16 Jun 13, 2024
1a8bcc1
feat(#79): 전형별 지원자 수 조회
cabbage16 Jun 13, 2024
292a7c4
feat(#79): 성적 분포 조회
cabbage16 Jun 13, 2024
5b55d31
feat(#79): 지원자 성비 분석
cabbage16 Jun 13, 2024
21a1e0f
feat(#79): 지원자 출신 학교 현황 조회
cabbage16 Jun 13, 2024
15a0edf
build: application.yml - debug
cabbage16 Jun 13, 2024
46b9426
feat(#79): 원서 도메인에 school_address 컬럼 추가
cabbage16 Jun 13, 2024
3fb0159
test(#79): FormFixture, FormControllerTest
cabbage16 Jun 13, 2024
3907f2e
feat(#79): 전형별 지원자 수 조회
cabbage16 Jun 13, 2024
18b3166
feat(#79): 성적 분포 조회
cabbage16 Jun 13, 2024
4f72824
feat(#79): 지원자 성비 분석
cabbage16 Jun 13, 2024
aa61c90
feat(#79): 지원자 출신 학교 현황 조회
cabbage16 Jun 13, 2024
b767c28
build: application.yml - debug
cabbage16 Jun 13, 2024
5a90a36
fix(#79): 원서 조회 기능 수정
cabbage16 Jun 14, 2024
cf41d3c
Merge branch 'feat/#79' of https://github.com/Bamdoliro/marubase into…
cabbage16 Jun 14, 2024
5bf9d99
perf(#79): 지원자 성적 분포 조회 0점 표시
cabbage16 Jun 16, 2024
5ba936a
refactor(#79): 주석 삭제
cabbage16 Jun 16, 2024
19f3a00
test(#79): AnalysisControllerTest
cabbage16 Jun 16, 2024
b027354
docs(#79): analysis.adoc
cabbage16 Jun 16, 2024
c70c17d
refactor(#79): 사용되지 않는 import문 제거
cabbage16 Jun 16, 2024
65e6e31
fix(#79): SchoolResponse 수정
cabbage16 Jun 17, 2024
d9bb4ff
refactor(#79): Parameter를 사용하도록 변경
cabbage16 Jun 18, 2024
47cfff7
fix(#79): 성비 분석 오류 해결
cabbage16 Jun 20, 2024
dbaaddd
perf(#79): 정원 외 전형 조회 수정
cabbage16 Jun 20, 2024
4b56e9e
feat(#79): 원서 도메인에 school_address 컬럼 추가
cabbage16 Jun 13, 2024
88fbd9c
test(#79): FormFixture, FormControllerTest
cabbage16 Jun 13, 2024
a1c0cc9
feat(#79): 전형별 지원자 수 조회
cabbage16 Jun 13, 2024
1b7d7e3
feat(#79): 성적 분포 조회
cabbage16 Jun 13, 2024
a9b897c
feat(#79): 지원자 성비 분석
cabbage16 Jun 13, 2024
8b8064c
feat(#79): 지원자 출신 학교 현황 조회
cabbage16 Jun 13, 2024
3ac51e4
build: application.yml - debug
cabbage16 Jun 13, 2024
1f34c4d
fix(#79): 원서 조회 기능 수정
cabbage16 Jun 14, 2024
0cac965
perf(#79): 지원자 성적 분포 조회 0점 표시
cabbage16 Jun 16, 2024
029d2d4
refactor(#79): 주석 삭제
cabbage16 Jun 16, 2024
fa41bc5
test(#79): AnalysisControllerTest
cabbage16 Jun 16, 2024
51ebfe3
docs(#79): analysis.adoc
cabbage16 Jun 16, 2024
a07f682
refactor(#79): 사용되지 않는 import문 제거
cabbage16 Jun 16, 2024
d3ab871
fix(#79): SchoolResponse 수정
cabbage16 Jun 17, 2024
4706e82
refactor(#79): Parameter를 사용하도록 변경
cabbage16 Jun 18, 2024
808cbe5
fix(#79): 성비 분석 오류 해결
cabbage16 Jun 20, 2024
5aadebd
perf(#79): 정원 외 전형 조회 수정
cabbage16 Jun 20, 2024
87ea2a6
Merge branch 'feat/#79' of https://github.com/Bamdoliro/marubase into…
cabbage16 Jul 7, 2024
76353f9
feat(#79): 원서 도메인에 school_address 컬럼 추가
cabbage16 Jun 13, 2024
f4ff219
test(#79): FormFixture, FormControllerTest
cabbage16 Jun 13, 2024
87ad37d
feat(#79): 전형별 지원자 수 조회
cabbage16 Jun 13, 2024
0d52d2a
feat(#79): 성적 분포 조회
cabbage16 Jun 13, 2024
a2ee973
feat(#79): 지원자 성비 분석
cabbage16 Jun 13, 2024
4375966
feat(#79): 지원자 출신 학교 현황 조회
cabbage16 Jun 13, 2024
e58c759
build: application.yml - debug
cabbage16 Jun 13, 2024
0bc5f0b
fix(#79): 원서 조회 기능 수정
cabbage16 Jun 14, 2024
fb3af0c
perf(#79): 지원자 성적 분포 조회 0점 표시
cabbage16 Jun 16, 2024
a867ed8
refactor(#79): 주석 삭제
cabbage16 Jun 16, 2024
3a31610
test(#79): AnalysisControllerTest
cabbage16 Jun 16, 2024
fd4941c
docs(#79): analysis.adoc
cabbage16 Jun 16, 2024
e7c2a12
refactor(#79): 사용되지 않는 import문 제거
cabbage16 Jun 16, 2024
daaa891
fix(#79): SchoolResponse 수정
cabbage16 Jun 17, 2024
a3370be
refactor(#79): Parameter를 사용하도록 변경
cabbage16 Jun 18, 2024
21a6ae5
fix(#79): 성비 분석 오류 해결
cabbage16 Jun 20, 2024
00002e4
perf(#79): 정원 외 전형 조회 수정
cabbage16 Jun 20, 2024
148fc47
test(#79): QueryNumberOfApplicantsUseCaseTest
cabbage16 Jul 8, 2024
97113cb
Merge branch 'feat/#79' of https://github.com/Bamdoliro/marubase into…
cabbage16 Jul 8, 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
92 changes: 92 additions & 0 deletions src/docs/asciidoc/analysis.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
== 분석 Analysis

=== 전형별 지원자 수 조회
전형별 지원자들의 수를 조회할 수 있습니다.

=== 요청 형식

==== Request Header
include::{snippets}/analysis-controller-test/전형별_지원자수를_조회한다/request-headers.adoc[]

==== 요청
include::{snippets}/analysis-controller-test/전형별_지원자수를_조회한다/http-request.adoc[]

==== 응답
include::{snippets}/analysis-controller-test/전형별_지원자수를_조회한다/http-response.adoc[]

=== 전형별 성적 분포 조회
1차 합격자, 2차 전형자, 최종 합격자들의 전형별 성적 분포를 조회할 수 있습니다.

=== 요청 형식

==== Request Header
include::{snippets}/analysis-controller-test/_1차_합격자들의_성적_분포를_조회한다/request-headers.adoc[]

==== Query Parameter
include::{snippets}/analysis-controller-test/_1차_합격자들의_성적_분포를_조회한다/query-parameters.adoc[]

==== 요청

===== 1차 합격자
include::{snippets}/analysis-controller-test/_1차_합격자들의_성적_분포를_조회한다/http-request.adoc[]

===== 2차 전형자
include::{snippets}/analysis-controller-test/_2차_전형자들의_성적_분포를_조회한다/http-request.adoc[]

===== 최종 합격자
include::{snippets}/analysis-controller-test/최종_합격자들의_성적_분포를_조회한다/http-request.adoc[]

==== 응답

===== 정상 응답
include::{snippets}/analysis-controller-test/최종_합격자들의_성적_분포를_조회한다/http-response.adoc[]

=== 전형별 성비 조회
1차 합격자, 2차 전형자, 최종 합격자들의 전형별, 지역별 성비를 조회할 수 있습니다.

=== 요청 형식

==== Request Header
include::{snippets}/analysis-controller-test/전형별_성비를_조회한다/request-headers.adoc[]

==== Query Parameter
include::{snippets}/analysis-controller-test/전형별_성비를_조회한다/query-parameters.adoc[]

==== 요청
include::{snippets}/analysis-controller-test/전형별_성비를_조회한다/http-request.adoc[]

==== 응답

===== 정상 응답
include::{snippets}/analysis-controller-test/전형별_성비를_조회한다/http-response.adoc[]

=== 전형별 출신학교 조회
1차 합격자, 2차 전형자, 최종 합격자들의 출신학교를 조회할 수 있습니다.

=== 요청 형식

==== Request Header
include::{snippets}/analysis-controller-test/부산_특정구_출신_지원자들의_출신학교_통계를_조회한다/request-headers.adoc[]

==== Query Parameter
include::{snippets}/analysis-controller-test/부산_특정구_출신_지원자들의_출신학교_통계를_조회한다/query-parameters.adoc[]

==== 요청
===== 부산 특정구 출신
include::{snippets}/analysis-controller-test/부산_특정구_출신_지원자들의_출신학교_통계를_조회한다/http-request.adoc[]

==== 부산 출신
include::{snippets}/analysis-controller-test/부산_출신_지원자들의_출신학교_통계를_조회한다/http-request.adoc[]

==== 타지역 출신
include::{snippets}/analysis-controller-test/타지역_출신_지원자들의_출신학교_통계를_조회한다/http-request.adoc[]

==== 응답
==== 부산 특정구 출신 정상 응답
include::{snippets}/analysis-controller-test/부산_특정구_출신_지원자들의_출신학교_통계를_조회한다/http-response.adoc[]

==== 부산 출신 정상 응답
include::{snippets}/analysis-controller-test/부산_출신_지원자들의_출신학교_통계를_조회한다/http-response.adoc[]

==== 타지역 출신 정상 응답
include::{snippets}/analysis-controller-test/타지역_출신_지원자들의_출신학교_통계를_조회한다/http-response.adoc[]
2 changes: 2 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ include::fair.adoc[]

include::message.adoc[]

include::analysis.adoc[]

include::enum.adoc[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.bamdoliro.maru.application.analysis;

import com.bamdoliro.maru.domain.form.domain.Form;
import com.bamdoliro.maru.domain.form.domain.type.FormType;
import com.bamdoliro.maru.domain.form.domain.type.Gender;
import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.presentation.analysis.dto.request.GenderRatioRequest;
import com.bamdoliro.maru.presentation.analysis.dto.response.GenderRatioResponse;
import com.bamdoliro.maru.shared.annotation.UseCase;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@UseCase
public class QueryGenderRatioUseCase {
private final FormRepository formRepository;

public List<GenderRatioResponse> execute(GenderRatioRequest request) {
FormType.Category mainCategory = request.getMainCategory();
List<GenderRatioResponse> result = new ArrayList<>();
List<FormType.Category> subCategories = new ArrayList<>();

if (mainCategory.equals(FormType.Category.REGULAR))
subCategories.add(FormType.Category.REGULAR);
else if (mainCategory.equals(FormType.Category.SPECIAL))
subCategories.addAll(List.of(
FormType.Category.MEISTER_TALENT,
FormType.Category.SOCIAL_INTEGRATION));
else if (mainCategory.equals(FormType.Category.SUPERNUMERARY))
subCategories.addAll(List.of(
FormType.Category.NATIONAL_VETERANS_EDUCATION,
FormType.Category.SPECIAL_ADMISSION));

Map<FormType.Category, List<Form>> formLists = subCategories.stream()
.collect(Collectors.toMap(
category -> category,
category -> formRepository.findByCategory(category).stream()
.filter(form -> request.getStatusList().contains(form.getStatus()))
.collect(Collectors.toList())
));

for(Map.Entry<FormType.Category, List<Form>> entry : formLists.entrySet()) {
FormType.Category category = entry.getKey();
List<Form> formList = entry.getValue();

long busanMale = formList.stream().filter(this::isBusan).filter(this::isMale).count();
long busanFemale = formList.stream().filter(this::isBusan).filter(this::isFemale).count();
long otherLocationMale = formList.stream().filter(this::isNotBusan).filter(this::isMale).count();
long otherLocationFemale = formList.stream().filter(this::isNotBusan).filter(this::isFemale).count();

result.add(new GenderRatioResponse(category, busanMale, busanFemale, otherLocationMale, otherLocationFemale));
}

return result;
}

private boolean isBusan(Form form) {
return form.getEducation().getSchool().isBusan();
}

private boolean isNotBusan(Form form) {
return !isBusan(form);
}

private boolean isMale(Form form) {
return form.getApplicant().getGender().equals(Gender.MALE);
}

private boolean isFemale(Form form) {
return !isMale(form);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.bamdoliro.maru.application.analysis;

import com.bamdoliro.maru.domain.form.domain.type.FormType;
import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.presentation.analysis.dto.request.GradeDistributionRequest;
import com.bamdoliro.maru.presentation.analysis.dto.response.GradeDistributionResponse;
import com.bamdoliro.maru.shared.annotation.UseCase;
import lombok.RequiredArgsConstructor;

import java.util.List;

@RequiredArgsConstructor
@UseCase
public class QueryGradeDistributionUseCase {

private final FormRepository formRepository;

public List<GradeDistributionResponse> execute(GradeDistributionRequest request) {
List<GradeDistributionResponse> result = new java.util.ArrayList<>(formRepository.findGradeGroupByTypeAndStatus(request.getStatusList())
.stream()
.map(GradeDistributionResponse::new)
.toList());

List<FormType> existingTypes = result
.stream()
.map(GradeDistributionResponse::getType)
.toList();

for (FormType formType : FormType.values()) {
if (!existingTypes.contains(formType)) {
result.add(new GradeDistributionResponse(formType, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
}
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.bamdoliro.maru.application.analysis;

import com.bamdoliro.maru.domain.form.domain.type.FormType;
import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.presentation.analysis.dto.response.NumberOfApplicantsResponse;
import com.bamdoliro.maru.shared.annotation.UseCase;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@UseCase
public class QueryNumberOfApplicantsUseCase {

private final FormRepository formRepository;

public List<NumberOfApplicantsResponse> execute() {
List<NumberOfApplicantsResponse> result = formRepository.findTypeAndCountGroupByType()
.stream()
.map(NumberOfApplicantsResponse::new)
.collect(Collectors.toList());

List<FormType> existingTypes = result
.stream()
.map(NumberOfApplicantsResponse::getType)
.toList();

for (FormType formType: FormType.values()) {
if (!existingTypes.contains(formType)) {
result.add(new NumberOfApplicantsResponse(formType, 0L));
}
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.bamdoliro.maru.application.analysis;

import com.bamdoliro.maru.infrastructure.persistence.form.FormRepository;
import com.bamdoliro.maru.presentation.analysis.dto.request.SchoolStatusRequest;
import com.bamdoliro.maru.presentation.analysis.dto.response.SchoolStatusResponse;
import com.bamdoliro.maru.shared.annotation.UseCase;
import lombok.RequiredArgsConstructor;

import java.util.List;

@RequiredArgsConstructor
@UseCase
public class QuerySchoolStatusUseCase {

private final FormRepository formRepository;

public List<SchoolStatusResponse> execute(SchoolStatusRequest request) {
if (request.getIsBusan()) {
String keyword = "부산광역시";
keyword += request.getGu() == null ? "" : (" " + request.getGu());

return formRepository.findSchoolByAddress(request.getStatusList(), keyword)
.stream()
.map(SchoolStatusResponse::new)
.toList();
}

return formRepository.findNotBusanSchool(request.getStatusList())
.stream()
.map(SchoolStatusResponse::new)
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public enum FormType implements EnumProperty {
MULTI_CHILDREN("다자녀가정자녀", Category.SPECIAL, Category.SOCIAL_INTEGRATION, Category.SOCIETY_DIVERSITY),
FARMING_AND_FISHING("농어촌지역출신자", Category.SPECIAL, Category.SOCIAL_INTEGRATION, Category.SOCIETY_DIVERSITY),

NATIONAL_VETERANS_EDUCATION("국가보훈대상자 중 교육지원대상자녀", Category.SUPERNUMERARY, null, null),
SPECIAL_ADMISSION("특례입학대상자", Category.SUPERNUMERARY, null, null),
NATIONAL_VETERANS_EDUCATION("국가보훈대상자 중 교육지원대상자녀", Category.SUPERNUMERARY, Category.NATIONAL_VETERANS_EDUCATION, null),
SPECIAL_ADMISSION("특례입학대상자", Category.SUPERNUMERARY, Category.SPECIAL_ADMISSION, null),
;


Expand All @@ -46,6 +46,8 @@ public enum Category implements EnumProperty {
// Middle Category
SOCIAL_INTEGRATION("사회통합전형"),
MEISTER_TALENT("마이스터인재전형"),
NATIONAL_VETERANS_EDUCATION("국가보훈대상자 중 교육지원대상자녀"),
SPECIAL_ADMISSION("특례입학대상자"),

// Sub Category
EQUAL_OPPORTUNITY("기회균등전형"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ public class School {
@Column(name = "school_location", nullable = false, length = 20)
private String location;

@Column(name = "school_address", nullable = false, length = 40)
private String address;

@Column(name = "school_code", nullable = false, length = 10)
private String code;

public boolean isBusan() {
return location.equals("부산광역시");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public List<SchoolResponse> execute(String q) throws JsonProcessingException {
.map(s -> SchoolResponse.builder()
.name(s.getSchoolName())
.location(s.getLocation())
.address((s.getAddress()))
.code(s.getStandardSchoolCode())
.build())
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

import com.bamdoliro.maru.domain.form.domain.Form;
import com.bamdoliro.maru.domain.form.domain.type.FormStatus;
import com.bamdoliro.maru.domain.form.domain.type.FormType;
import com.bamdoliro.maru.infrastructure.persistence.form.vo.NumberOfApplicantsVo;
import com.bamdoliro.maru.infrastructure.persistence.form.vo.FormUrlVo;
import com.bamdoliro.maru.infrastructure.persistence.form.vo.GradeVo;
import com.bamdoliro.maru.infrastructure.persistence.form.vo.SchoolStatusVo;

import java.util.List;

public interface FormRepositoryCustom {

List<Form> findByStatus(FormStatus status);
List<Form> findByType(FormType type);
List<Form> findByCategory(FormType.Category category);
List<Form> findReceivedSpecialForm();
List<Form> findReceivedRegularOrSupernumeraryForm();
List<Form> findFirstRoundForm();
Expand All @@ -18,4 +24,8 @@ public interface FormRepositoryCustom {
List<Form> findSecondRoundForm();
List<Form> findByFormIdList(List<Long> idList);
List<FormUrlVo> findFormUrlByFormIdList(List<Long> idList);
}
List<NumberOfApplicantsVo> findTypeAndCountGroupByType();
List<GradeVo> findGradeGroupByTypeAndStatus(List<FormStatus> round);
List<SchoolStatusVo> findSchoolByAddress(List<FormStatus> round, String keyword);
List<SchoolStatusVo> findNotBusanSchool(List<FormStatus> round);
}
Loading
Loading