Skip to content
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
1 change: 0 additions & 1 deletion app/api/mathrank-rank-read-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ dependencies {

implementation project(':domain:mathrank-rank-domain')
implementation project(':client:internal:mathrank-member-client')
implementation project(':client:external:mathrank-school')

implementation project(':app:api:mathrank-api-common')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import kr.co.mathrank.app.api.common.authentication.Authorization;
import kr.co.mathrank.client.external.school.RequestType;
import kr.co.mathrank.client.external.school.SchoolClient;
import kr.co.mathrank.client.external.school.SchoolInfo;
import kr.co.mathrank.client.internal.member.MemberClient;
import kr.co.mathrank.common.page.PageResult;
import kr.co.mathrank.domain.rank.service.RankPageQueryService;
Expand All @@ -26,7 +23,6 @@ public class RankReadController {
private final RankPageQueryService rankPageQueryService;
private final MemberClient memberClient;
private final SchoolRankQueryService schoolRankQueryService;
private final SchoolClient schoolClient;

@Operation(summary = "내 랭크 조회 API", description = "사용자의 랭크를 조회합니다. 사용자 문제 풀이 기록에 맞춰 실시간으로 반영됩니다.")
@GetMapping("/api/v1/rank")
Expand All @@ -53,11 +49,6 @@ public ResponseEntity<PageResult<SchoolRankPageResponse>> querySchoolRankPage(
@RequestParam(defaultValue = "1") final Integer pageNumber
) {
return ResponseEntity.ok(schoolRankQueryService.querySchoolRanks(pageSize, pageNumber)
.map(schoolRankQueryResult -> SchoolRankPageResponse.from(
schoolRankQueryResult,
schoolClient.getSchool(RequestType.JSON.getType(), schoolRankQueryResult.schoolCode())
.orElseGet(SchoolInfo::none)
.SCHUL_NM()
)));
.map(SchoolRankPageResponse::from));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package kr.co.mathrank.rank.read;

import kr.co.mathrank.domain.rank.dto.SchoolRankQueryResult;
import kr.co.mathrank.domain.rank.dto.SchoolRankPageResult;

public record SchoolRankPageResponse(
String schoolCode,
Expand All @@ -9,10 +9,10 @@ public record SchoolRankPageResponse(
Long rank,
Long memberCount
) {
public static SchoolRankPageResponse from(final SchoolRankQueryResult result, final String schoolName) {
public static SchoolRankPageResponse from(final SchoolRankPageResult result) {
return new SchoolRankPageResponse(
result.schoolCode(),
schoolName,
result.schoolName(),
result.score(),
result.rank(),
result.memberCount()
Expand Down
1 change: 1 addition & 0 deletions domain/mathrank-rank-domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies {
implementation project(':common:mathrank-cache')
implementation project(':client:internal:mathrank-problem-client')
implementation project(':client:internal:mathrank-member-client')
implementation project(':client:external:mathrank-school')

testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ public class RankDomainConfiguration {
public static final String USER_RANK_CACHE_NAME = "mathrank::domain::rank::user";
public static final String RANK_BOARD_CACHE_NAME = "mathrank::domain::rank::board";
public static final String SCHOOL_RANK_BOARD_CACHE_NAME = "mathrank::domain::rank::school::board";
public static final String SCHOOL_NAME_CACHE = "mathrank::domain::rank::school";

@Bean
RequiredCacheSpec rankDomainSchoolNameCacheSpec() {
return new RequiredCacheSpec() {
@Override
public String moduleName() {
return "mathrank-domain-rank";
}

@Override
public String cacheName() {
return SCHOOL_NAME_CACHE;
}

@Override
public Duration ttl() {
return Duration.ofMinutes(10L); // 잘 업데이트 되지 않는 데이터
}
};
}

@Bean
RequiredCacheSpec userRankCacheSpec() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kr.co.mathrank.domain.rank.dto;

public record SchoolRankPageResult(
String schoolCode,
String schoolName,
Long score,
Long rank,
Long memberCount
) {
public static SchoolRankPageResult from(final SchoolRankQueryResult result, final String schoolName) {
return new SchoolRankPageResult(
result.schoolCode(),
schoolName,
result.score(),
result.rank(),
result.memberCount()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package kr.co.mathrank.domain.rank.service;

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import kr.co.mathrank.client.external.school.RequestType;
import kr.co.mathrank.client.external.school.SchoolClient;
import kr.co.mathrank.client.external.school.SchoolInfo;
import kr.co.mathrank.domain.rank.RankDomainConfiguration;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class RankSchoolManager {
private final SchoolClient schoolClient;

@Cacheable(
cacheNames = RankDomainConfiguration.SCHOOL_NAME_CACHE,
key = "'schoolCode::' + #schoolCode",
unless = "#result == null" // 결과가 null이면 캐싱하지 않음 ( 다음에 다시 호출 )
)
public String getSchoolNameByCode(@NotNull @Valid final String schoolCode) {
return schoolClient.getSchool(RequestType.JSON.getType(), schoolCode)
.orElseGet(() -> SchoolInfo.none()).SCHUL_NM();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import org.springframework.validation.annotation.Validated;

import jakarta.validation.constraints.NotNull;
import kr.co.mathrank.client.external.school.SchoolClient;
import kr.co.mathrank.common.page.PageResult;
import kr.co.mathrank.common.page.PageUtil;
import kr.co.mathrank.domain.rank.RankDomainConfiguration;
import kr.co.mathrank.domain.rank.dto.SchoolRankPageResult;
import kr.co.mathrank.domain.rank.dto.SchoolRankQueryResult;
import kr.co.mathrank.domain.rank.repository.SolverRepository;
import lombok.RequiredArgsConstructor;
Expand All @@ -22,12 +24,13 @@
@CacheConfig(cacheNames = RankDomainConfiguration.SCHOOL_RANK_BOARD_CACHE_NAME)
public class SchoolRankQueryService {
private final SolverRepository solverRepository;
private final RankSchoolManager rankSchoolManager;

@Cacheable(
key = "'pageNumber::' + #pageNumber + '::pageSize::' + #pageSize",
condition = "#pageNumber <= 4"
)
public PageResult<SchoolRankQueryResult> querySchoolRanks(
public PageResult<SchoolRankPageResult> querySchoolRanks(
@NotNull final Integer pageSize,
@NotNull final Integer pageNumber
) {
Expand All @@ -36,14 +39,16 @@ public PageResult<SchoolRankQueryResult> querySchoolRanks(
final Long countSchoolCode = solverRepository.countDistinctSchools();

return PageResult.of(
schoolRankQueryResults,
pageNumber,
pageSize,
PageUtil.getNextPages(
pageSize,
schoolRankQueryResults,
pageNumber,
countSchoolCode,
schoolRankQueryResults.size()
));
pageSize,
PageUtil.getNextPages(
pageSize,
pageNumber,
countSchoolCode,
schoolRankQueryResults.size()
))
.map(queryResult -> SchoolRankPageResult.from(queryResult,
rankSchoolManager.getSchoolNameByCode(queryResult.schoolCode())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ client.problem.read-timeout-seconds=10
client.member.connection-timeout-seconds=100
client.member.read-timeout-seconds=1000

client.school.connection-timeout-seconds=100
client.school.read-timeout-seconds=100

spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create