-
Notifications
You must be signed in to change notification settings - Fork 35
[volume-10] Collect, Stack, Zip #245
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
base: sky980221
Are you sure you want to change the base?
Changes from all commits
ad3d421
15d43ec
2a66999
2aa4b68
ed457e3
baaf961
5587a98
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,24 +2,35 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.loopers.domain.product.Product; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.loopers.domain.product.ProductRepository; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.loopers.infrastructure.rank.MonthlyRankJpaRepository; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.loopers.infrastructure.rank.WeeklyRankJpaRepository; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.data.domain.PageRequest; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.data.redis.core.ZSetOperations; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.stereotype.Component; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.transaction.annotation.Transactional; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.math.BigDecimal; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.LocalDate; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.format.DateTimeFormatter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.HashMap; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Set; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.concurrent.atomic.AtomicInteger; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.function.Function; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.function.ToIntFunction; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Component | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class RankingFacade { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final RankingService rankingService; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final ProductRepository productRepository; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final WeeklyRankJpaRepository weeklyRankJpaRepository; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final MonthlyRankJpaRepository monthlyRankJpaRepository; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional(readOnly = true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public List<RankingProductInfo> getDailyRanking(String yyyymmdd, int page, int size) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -48,27 +59,101 @@ public List<RankingProductInfo> getDailyRanking(String yyyymmdd, int page, int s | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productMap.put(pdt.getId(), pdt); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int baseRank = (int) start + 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AtomicInteger rankCounter = new AtomicInteger(baseRank); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (ZSetOperations.TypedTuple<String> t : tuples) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String member = t.getValue(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (member == null || member.isBlank()) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long productId = Long.valueOf(member); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Product product = productMap.get(productId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (product == null) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result.add(toInfo(productId, product)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int rank = rankCounter.getAndIncrement(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Double score = t.getScore(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result.add(toInfo(productId, product, rank, score)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return result; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private RankingProductInfo toInfo(Long productId, Product product) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional(readOnly = true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public List<RankingProductInfo> getWeeklyRanking(String weekStartYyyymmdd, int page, int size) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int p = Math.max(1, page); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int s = Math.max(1, size); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LocalDate periodStart = LocalDate.parse(weekStartYyyymmdd, DATE_FORMATTER); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var rows = weeklyRankJpaRepository.findByPeriodStartOrderByRankPositionAsc( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| periodStart, PageRequest.of(p - 1, s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return buildRanking( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rows, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r -> r.getProductId(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r -> r.getRankPosition() != null ? r.getRankPosition() : 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r -> r.getTotalScore() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+77
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. λ μ§ νμ± μ μμΈ μ²λ¦¬κ° νμν©λλ€.
π μμΈ μ²λ¦¬ μΆκ° μ μFacade λ μ΄μ΄μμ μ²λ¦¬νκ±°λ, Controller λ μ΄μ΄μμ @DateTimeFormat λ±μ νμ©ν μ μμ΅λλ€: public List<RankingProductInfo> getWeeklyRanking(String weekStartYyyymmdd, int page, int size) {
int p = Math.max(1, page);
int s = Math.max(1, size);
- LocalDate periodStart = LocalDate.parse(weekStartYyyymmdd, DATE_FORMATTER);
+ LocalDate periodStart;
+ try {
+ periodStart = LocalDate.parse(weekStartYyyymmdd, DATE_FORMATTER);
+ } catch (DateTimeParseException e) {
+ throw new IllegalArgumentException("Invalid date format. Expected yyyyMMdd", e);
+ }
...
}π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional(readOnly = true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public List<RankingProductInfo> getMonthlyRanking(String monthStartYyyymmdd, int page, int size) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int p = Math.max(1, page); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int s = Math.max(1, size); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LocalDate periodStart = LocalDate.parse(monthStartYyyymmdd, DATE_FORMATTER); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var rows = monthlyRankJpaRepository.findByPeriodStartOrderByRankPositionAsc( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| periodStart, PageRequest.of(p - 1, s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return buildRanking( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rows, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r -> r.getProductId(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r -> r.getRankPosition() != null ? r.getRankPosition() : 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r -> r.getTotalScore() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private RankingProductInfo toInfo(Long productId, Product product, int rank, Double score) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new RankingProductInfo( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rank, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| score, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product.getName(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product.getPrice() != null ? product.getPrice().getAmount() : BigDecimal.ZERO, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product.getStockQuantity(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product.getLikeCount() != null ? product.getLikeCount() : 0L | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private <T> List<RankingProductInfo> buildRanking( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<T> rows, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Function<T, Long> productIdExtractor, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ToIntFunction<T> rankExtractor, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Function<T, Double> scoreExtractor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (rows == null || rows.isEmpty()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return List.of(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Long> productIds = rows.stream() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map(productIdExtractor) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .toList(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Product> products = productRepository.findByIdIn(productIds); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Map<Long, Product> productMap = new HashMap<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (Product prd : products) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| productMap.put(prd.getId(), prd); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<RankingProductInfo> result = new ArrayList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (T row : rows) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long productId = productIdExtractor.apply(row); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Product product = productMap.get(productId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (product == null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int rank = rankExtractor.applyAsInt(row); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Double score = scoreExtractor.apply(row); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result.add(toInfo(productId, product, rank, score)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return result; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package com.loopers.config; | ||
|
|
||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||
|
|
||
| import java.util.concurrent.Executor; | ||
| import java.util.concurrent.ThreadPoolExecutor; | ||
|
|
||
| @Configuration | ||
| public class AsyncConfig { | ||
|
|
||
| @Bean(name = "eventTaskExecutor") | ||
| public Executor eventTaskExecutor() { | ||
| ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); | ||
| executor.setCorePoolSize(4); | ||
| executor.setMaxPoolSize(16); | ||
| executor.setQueueCapacity(1000); | ||
| executor.setKeepAliveSeconds(60); | ||
| executor.setThreadNamePrefix("event-async-"); | ||
| executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); | ||
| executor.setWaitForTasksToCompleteOnShutdown(true); | ||
| executor.setAwaitTerminationSeconds(10); | ||
| executor.initialize(); | ||
| return executor; | ||
| } | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package com.loopers.domain.rank; | ||
|
|
||
| import jakarta.persistence.Column; | ||
| import jakarta.persistence.Entity; | ||
| import jakarta.persistence.GeneratedValue; | ||
| import jakarta.persistence.GenerationType; | ||
| import jakarta.persistence.Id; | ||
| import jakarta.persistence.Table; | ||
| import java.math.BigDecimal; | ||
| import java.time.LocalDate; | ||
| import java.time.LocalDateTime; | ||
| import lombok.AccessLevel; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
| import org.hibernate.annotations.Immutable; | ||
|
|
||
| @Entity | ||
| @Table(name = "mv_product_rank_monthly") | ||
| @Getter | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @Immutable | ||
| public class MonthlyProductRankView { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| @Column(name = "product_id", nullable = false) | ||
| private Long productId; | ||
|
|
||
| @Column(name = "period_start", nullable = false) | ||
| private LocalDate periodStart; | ||
|
|
||
| @Column(name = "rank_position", nullable = false) | ||
| private Integer rankPosition; | ||
|
|
||
| @Column(name = "total_score", nullable = false) | ||
| private Double totalScore; | ||
|
|
||
| @Column(name = "like_count", nullable = false) | ||
| private Integer likeCount; | ||
|
|
||
| @Column(name = "view_count", nullable = false) | ||
| private Integer viewCount; | ||
|
|
||
| @Column(name = "order_count", nullable = false) | ||
| private Integer orderCount; | ||
|
|
||
| @Column(name = "sales_amount", nullable = false, precision = 15, scale = 2) | ||
| private BigDecimal salesAmount; | ||
|
|
||
| @Column(name = "created_at", nullable = false, updatable = false) | ||
| private LocalDateTime createdAt; | ||
|
|
||
| @Column(name = "updated_at", nullable = false) | ||
| private LocalDateTime updatedAt; | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package com.loopers.domain.rank; | ||
|
|
||
| import jakarta.persistence.Column; | ||
| import jakarta.persistence.Entity; | ||
| import jakarta.persistence.GeneratedValue; | ||
| import jakarta.persistence.GenerationType; | ||
| import jakarta.persistence.Id; | ||
| import jakarta.persistence.Table; | ||
| import java.math.BigDecimal; | ||
| import java.time.LocalDate; | ||
| import java.time.LocalDateTime; | ||
| import lombok.AccessLevel; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
| import org.hibernate.annotations.Immutable; | ||
|
|
||
| @Entity | ||
| @Table(name = "mv_product_rank_weekly") | ||
| @Getter | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @Immutable | ||
| public class WeeklyProductRankView { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| @Column(name = "product_id", nullable = false) | ||
| private Long productId; | ||
|
|
||
| @Column(name = "period_start", nullable = false) | ||
| private LocalDate periodStart; | ||
|
|
||
| @Column(name = "rank_position", nullable = false) | ||
| private Integer rankPosition; | ||
|
|
||
| @Column(name = "total_score", nullable = false) | ||
| private Double totalScore; | ||
|
|
||
| @Column(name = "like_count", nullable = false) | ||
| private Integer likeCount; | ||
|
|
||
| @Column(name = "view_count", nullable = false) | ||
| private Integer viewCount; | ||
|
|
||
| @Column(name = "order_count", nullable = false) | ||
| private Integer orderCount; | ||
|
|
||
| @Column(name = "sales_amount", nullable = false, precision = 15, scale = 2) | ||
| private BigDecimal salesAmount; | ||
|
|
||
| @Column(name = "created_at", nullable = false, updatable = false) | ||
| private LocalDateTime createdAt; | ||
|
|
||
| @Column(name = "updated_at", nullable = false) | ||
| private LocalDateTime updatedAt; | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.loopers.infrastructure.rank; | ||
|
|
||
| import com.loopers.domain.rank.MonthlyProductRankView; | ||
| import java.time.LocalDate; | ||
| import java.util.List; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.stereotype.Repository; | ||
|
|
||
| @Repository | ||
| public interface MonthlyRankJpaRepository extends JpaRepository<MonthlyProductRankView, Long> { | ||
| List<MonthlyProductRankView> findByPeriodStartOrderByRankPositionAsc(LocalDate periodStart, Pageable pageable); | ||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π§© Analysis chain
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 6652
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 1692
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 1816
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 70
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 985
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 12161
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 258
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 364
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 524
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 17299
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 70
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 985
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 70
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 612
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 72
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 985
π Script executed:
Repository: Loopers-dev-lab/loopers-spring-java-template
Length of output: 70
eventTaskExecutorλΉμ΄ μ μλμ§ μμμ΅λλ€. λ°νμ μ€λ₯κ° λ°μν©λλ€.@Async("eventTaskExecutor")λ₯Ό μ¬μ©νλ 7κ° λ©μλ(ProductEventHandler, PaymentEventHandler, DataPlatformEventHandler)μμ μ°Έμ‘°νλeventTaskExecutorλΉμ΄ μ μλμ΄ μμ§ μμ΅λλ€. μ΄λ‘ μΈν΄ λ°νμμNoSuchBeanDefinitionExceptionμ΄ λ°μν©λλ€.λ€μ μ€ νλλ₯Ό μννμΈμ:
eventTaskExecutorλΉμ μ μνλ μ€μ ν΄λμ€λ₯Ό μμ±νμ¬ThreadPoolTaskExecutorλ‘ κ΅¬μ±@Asyncμ£Όμμμ λͺ μμ executor μ΄λ¦μ μ κ±°νκ³ κΈ°λ³Έ executor μ€μ μΆκ°π€ Prompt for AI Agents