Skip to content

feat: 실시간 경매장 정보 fetcher and sheduler 및 거대한 외침의 뿔피리 엘라스틱 서치 구현#91

Merged
dev-ant merged 8 commits intodevfrom
feat/auction-realtime-sheduler
Jan 28, 2026
Merged

feat: 실시간 경매장 정보 fetcher and sheduler 및 거대한 외침의 뿔피리 엘라스틱 서치 구현#91
dev-ant merged 8 commits intodevfrom
feat/auction-realtime-sheduler

Conversation

@dev-ant
Copy link
Contributor

@dev-ant dev-ant commented Jan 28, 2026

📋 상세 설명

📊 체크리스트

  • PR 제목이 형식에 맞나요 e.g. feat: PR을 등록한다
  • 코드가 테스트 되었나요 pass
  • 문서는 업데이트 되었나요
  • 불필요한 코드를 제거했나요
  • 이슈와 라벨이 등록되었나요 이슈만 등록

📆 마감일

@dev-ant dev-ant requested a review from Copilot January 28, 2026 14:45
@dev-ant dev-ant self-assigned this Jan 28, 2026
@dev-ant dev-ant added the ✨feature 새로운 기능 추가 label Jan 28, 2026
@github-actions
Copy link

github-actions bot commented Jan 28, 2026

✅ 테스트 결과 for PR

Build: success

🧪 테스트 실행 with Gradle
📈 Coverage: -0.00%

📁 테스트 결과
📁 커버리지 보고서 (HTML)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements real-time auction data fetching/scheduling and Elasticsearch integration for Horn Bugle search functionality in the Mabinogi Open API batch server.

Changes:

  • Adds real-time auction data collection with 10-minute interval scheduling and duplicate detection logic
  • Implements Elasticsearch integration with Korean full-text search (Ngram parser) for Horn Bugle history
  • Refactors auction table structure, separating history (auction_history_item_option) from realtime (auction_realtime_item, auction_realtime_item_option)

Reviewed changes

Copilot reviewed 157 out of 158 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
V15__refactor_auction_tables_for_realtime_history_separation.sql Database migration to separate auction history and realtime tables
V16__update_unknown_item_name_and_segong_option_level.sql Updates unknown item names and parses segong option levels
V17__add_fulltext_index_to_horn_bugle_world_history.sql Adds MySQL FULLTEXT index for Horn Bugle search
HornBugleIndexService.java Elasticsearch indexing service for Horn Bugle data
AuctionRealtimeScheduler.java Scheduler for real-time auction data collection (10-minute intervals)
AuctionRealtimeFetcher.java Fetcher with cursor-based pagination and duplicate detection
HornBugleService.java Updated to support both Elasticsearch and MySQL FULLTEXT search
docker-compose-*.yml Docker configurations updated with Elasticsearch services
build.gradle.kts Added Elasticsearch dependency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

-Xmx${JAVA_OPTS_XMX:-512m}
-XX:MaxMetaspaceSize=${JAVA_OPTS_MAX_METASPACE_SIZE:-150m}
-XX:ReservedCodeCacheSize=${JAVA_OPTS_RESERVED_CODE_CACHE_SIZE:-48m}
-XX:ReservedCodeCacheSize=${JAVA_OPTS_RESERVED_CODE_CACHE_SIZE:-48m}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate line: -XX:ReservedCodeCacheSize=${JAVA_OPTS_RESERVED_CODE_CACHE_SIZE:-48m} appears on both line 59 and line 60. Remove the duplicate.

Suggested change
-XX:ReservedCodeCacheSize=${JAVA_OPTS_RESERVED_CODE_CACHE_SIZE:-48m}

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +43
@AfterMapping
default void afterMapping(
OpenApiAuctionRealtimeResponse dto, @MappingTarget AuctionRealtimeItem entity) {
// item_name이 "(Unknown)"인 경우 item_display_name으로 대체
if (UNKNOWN_ITEM_NAME.equals(entity.getItemName())) {
entity.setItemName(dto.itemDisplayName());
}
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mapper is using @AfterMapping to replace "(Unknown)" item names with display names. However, this logic exists in both OpenApiAuctionHistoryMapper and OpenApiAuctionRealtimeMapper with identical implementation. Consider extracting this to a shared helper method or abstract mapper to follow DRY principles.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +56

@AfterMapping
default void afterMapping(
OpenApiAuctionItemOptionResponse dto, @MappingTarget AuctionRealtimeItemOption entity) {
// option_type이 "세공 옵션"인 경우에만 파싱 수행
if (!SEGONG_OPTION_TYPE.equals(entity.getOptionType()) || entity.getOptionValue() == null) {
return;
}

String originalValue = entity.getOptionValue();

// 패턴 1: "스킬명 숫자 레벨" 또는 "스킬명 숫자레벨" 형식
Matcher matcher1 = PATTERN_LEVEL_SUFFIX.matcher(originalValue);
if (matcher1.matches()) {
entity.setOptionValue(matcher1.group(1));
entity.setOptionValue2(matcher1.group(3));
entity.setOptionDesc(matcher1.group(2));
return;
}

// 패턴 2: "스킬명(숫자레벨:효과)" 형식
Matcher matcher2 = PATTERN_LEVEL_PARENTHESIS.matcher(originalValue);
if (matcher2.matches()) {
entity.setOptionValue(matcher2.group(1));
entity.setOptionValue2(matcher2.group(3));
entity.setOptionDesc(matcher2.group(2));
}
// 두 패턴 모두 매칭되지 않으면 원본 값 유지
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The segong option parsing logic using regex patterns is duplicated across OpenApiItemOptionMapper and OpenApiRealtimeItemOptionMapper. Both mappers have identical Pattern constants (PATTERN_LEVEL_SUFFIX, PATTERN_LEVEL_PARENTHESIS) and afterMapping logic. Consider extracting this common parsing logic to a shared utility class to improve maintainability and avoid duplication.

Copilot uses AI. Check for mistakes.

@OneToMany(mappedBy = "auctionHistory", cascade = CascadeType.ALL, orphanRemoval = true)
private List<AuctionItemOption> auctionItemOptions;
private List<AuctionHistoryItemOption> auctionHistoryItemOptions;
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getAuctionHistoryItemOptions exposes the internal representation stored in field auctionHistoryItemOptions. The value may be modified after this call to getAuctionHistoryItemOptions.
getAuctionHistoryItemOptions exposes the internal representation stored in field auctionHistoryItemOptions. The value may be modified after this call to getAuctionHistoryItemOptions.

Copilot uses AI. Check for mistakes.
private String itemTopCategory;

@OneToMany(mappedBy = "auctionRealtimeItem", cascade = CascadeType.ALL, orphanRemoval = true)
private List<AuctionRealtimeItemOption> auctionRealtimeItemOptions;
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getAuctionRealtimeItemOptions exposes the internal representation stored in field auctionRealtimeItemOptions. The value may be modified after this call to getAuctionRealtimeItemOptions.
getAuctionRealtimeItemOptions exposes the internal representation stored in field auctionRealtimeItemOptions. The value may be modified after this call to getAuctionRealtimeItemOptions.

Copilot uses AI. Check for mistakes.
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default toString(): AuctionRealtimeItem inherits toString() from Object, and so is not suitable for printing.

Copilot uses AI. Check for mistakes.
@dev-ant dev-ant merged commit adb87a1 into dev Jan 28, 2026
1 of 2 checks passed
@dev-ant dev-ant deleted the feat/auction-realtime-sheduler branch January 28, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨feature 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant