Skip to content

Spm 441#38

Merged
yangjiseonn merged 2 commits into
mainfrom
SPM-441
Nov 7, 2025
Merged

Spm 441#38
yangjiseonn merged 2 commits into
mainfrom
SPM-441

Conversation

@yangjiseonn
Copy link
Copy Markdown
Contributor

@yangjiseonn yangjiseonn commented Nov 7, 2025

📝 Summary

  • 기준수량 추가해서 이벤트 발행 다시함

🙏 Question & PR point

📬 Reference

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 자재 및 부품 이벤트에 표준 수량 필드 추가
  • Improvements

    • 이벤트 처리 구조 개선으로 더 완전한 메타데이터 캡처
    • 대기열 처리 시스템의 재시도 로직 강화 (최대 재시도 횟수 제한 추가)
    • 실패한 이벤트의 효율적인 처리로 시스템 안정성 향상

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 7, 2025

Walkthrough

이 PR은 Material과 Part 이벤트 시스템을 개선하여 standardQuantity 필드를 추가하고, 이벤트 페이로드를 전체 이벤트 객체로 래핑하며, Outbox 저장소와 발행자를 업데이트하여 재시도 로직과 상태 필터링을 처리합니다.

Changes

Cohort / File(s) Summary
이벤트 DTO 필드 추가
src/main/java/com/sampoom/backend/api/material/event/dto/MaterialEvent.java, src/main/java/com/sampoom/backend/api/part/event/dto/PartEvent.java
Payload 내부 클래스에 standardQuantity Integer 필드 추가
이벤트 생성 리팩토링
src/main/java/com/sampoom/backend/api/material/event/service/MaterialEventBatchService.java, src/main/java/com/sampoom/backend/api/part/event/service/PartEventBatchService.java
Payload만 생성하는 방식에서 전체 MaterialEvent/PartEvent 객체 생성으로 변경, eventId, eventType, version, occurredAt 메타데이터 추가, standardQuantity 기본값 처리
서비스 레이어 이벤트 처리
src/main/java/com/sampoom/backend/api/material/service/MaterialService.java, src/main/java/com/sampoom/backend/api/part/service/PartService.java
모든 생명주기 이벤트(Created, Updated, Deleted)에서 전체 MaterialEvent/PartEvent 객체로 페이로드 구성, standardQuantity 기본값 설정(null일 경우 1로 기본값), outboxService 호출 업데이트
Outbox 저장소 쿼리 개선
src/main/java/com/sampoom/backend/common/outbox/repository/OutboxRepository.java
세 개의 메서드를 단일 커스텀 JPQL 쿼리로 통합: findTop10ByStatusReadyOrFailedWithRetryLimitOrderByCreatedAtAsc 추가, READY 또는 재시도 횟수 제한 내의 FAILED 상태 레코드 조회
Outbox 이벤트 처리
src/main/java/com/sampoom/backend/common/outbox/service/OutboxEventProcessor.java
Part와 Material 처리에서 빌더 수동 구성을 페이로드의 직접 역직렬화로 변경
Outbox 발행자 재시도 로직
src/main/java/com/sampoom/backend/common/outbox/service/OutboxPublisher.java
MAX_RETRY_COUNT = 10 상수 추가, publishReadyEvents()publishReadyAndFailedEvents() 메서드명 변경, READY 및 FAILED 재시도 이벤트 처리 포함, 로그 메시지 확장

Sequence Diagram(s)

sequenceDiagram
    participant Service as Material/PartService
    participant OutboxService as OutboxService
    participant Repo as OutboxRepository
    participant Publisher as OutboxPublisher
    participant Processor as OutboxEventProcessor
    participant Kafka as Kafka Topic

    Service->>Service: Build MaterialEvent/PartEvent<br/>(eventId, eventType, version,<br/>occurredAt, payload)
    Service->>OutboxService: saveEvent(fullEvent)
    OutboxService->>Repo: save(Outbox with<br/>serialized event)
    
    Note over Publisher: Scheduled Task
    Publisher->>Repo: findTop10ByStatusReadyOrFailedWith<br/>RetryLimitOrderByCreatedAtAsc(10)
    Repo-->>Publisher: List<Outbox>
    
    loop For each Outbox record
        Publisher->>Processor: Deserialize payload
        Processor->>Processor: Deserialize to<br/>MaterialEvent/PartEvent class
        Processor->>Kafka: Send event
        Publisher->>Repo: Update status to PUBLISHED
    end
    
    Note over Repo: Failed records within retry limit<br/>are included in query result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 주의 필요 영역:
    • OutboxRepository의 JPQL 쿼리 로직 검증 필요 (READY 또는 FAILED 필터링 조건 확인)
    • 모든 이벤트 생성 경로에서 standardQuantity 기본값 처리 일관성 확인 (Material/Part 서비스)
    • 기존 코드를 직접 역직렬화로 변경한 부분에서 예외 처리 및 형식 호환성 검증
    • OutboxPublisher의 재시도 로직과 MAX_RETRY_COUNT 상수값 검증

Possibly related PRs

  • PR #23: Part 이벤트 페이로드(PartEvent.Payload)와 이벤트 발행 수정으로 추가 수량/리드타임 필드 포함
  • PR #37: Material/Part 도메인 객체 및 서비스 이벤트 페이로드에 standardQuantity 필드 추가 및 전파
  • PR #25: MaterialEvent, MaterialEventBatchService, MaterialService, OutboxEventProcessor 수정으로 전체 MaterialEvent 페이로드 래핑 도입

Suggested labels

ready-to-merge

Suggested reviewers

  • Lee-Jong-Jin
  • CHOOSLA
  • Sangyoon98
  • vivivim

Poem

🐰 표준 수량이 담긴 이벤트 래퍼,
재시도의 한계를 정하며 흐르는 파이프,
Material과 Part의 조화로운 춤,
Outbox는 더욱 똑똑해지고,
작은 변화가 모여 큰 흐름을 만든다 ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive PR 제목이 매우 모호하며 변경사항을 구체적으로 설명하지 않습니다. 'Spm 441'은 이슈 번호일 뿐 실제 변경 내용을 전달하지 않습니다. PR 제목을 더 명확하게 수정하세요. 예: 'Add standardQuantity field and refactor event publishing' 또는 한국어로는 '기준수량 필드 추가 및 이벤트 발행 리팩토링'
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed PR 설명이 부분적으로 작성되었습니다. 요약은 제공되었으나 상세하지 않으며, Question & PR point와 Reference 섹션이 비어있습니다.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SPM-441

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@taemin3 taemin3 left a comment

Choose a reason for hiding this comment

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

쩐다

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/sampoom/backend/api/part/service/PartService.java (1)

215-244: 심각: 이벤트 직렬화/역직렬화 불일치 (updatePart)

createPart와 동일한 문제가 있습니다. 전체 PartEvent를 생성하지만 payload만 전달하여 역직렬화 실패가 발생합니다.

다음과 같이 수정하세요:

         outboxService.saveEvent(
                 "PART",
                 part.getId(),
                 "PartUpdated",
                 part.getVersion(),
-                partEvent.getPayload()
+                partEvent
         );
🧹 Nitpick comments (2)
src/main/java/com/sampoom/backend/common/outbox/service/OutboxEventProcessor.java (1)

91-95: MATERIAL 이벤트 역직렬화 개선 완료, 패턴 통일 고려 가능

전체 MaterialEvent 객체를 직접 역직렬화하는 방식으로 변경되어 PART와 일관된 패턴을 따릅니다.

다만, PART_GROUP, PART_CATEGORY, BOM, MATERIAL_CATEGORY는 여전히 이전 패턴(Payload 역직렬화 + 이벤트 빌더 구성)을 사용하고 있습니다. 향후 유지보수성을 위해 모든 aggregate type이 동일한 패턴을 따르도록 통일하는 것을 고려해보세요.

src/main/java/com/sampoom/backend/api/material/service/MaterialService.java (1)

113-130: 코드 중복 개선 고려

MaterialEvent 생성 로직이 3군데에서 반복됩니다. PartService와 유사한 헬퍼 메서드 추가를 고려해보세요.

private MaterialEvent buildMaterialEvent(Material material, String eventType, boolean deleted) {
    return MaterialEvent.builder()
            .eventId(UUID.randomUUID().toString())
            .eventType(eventType)
            .version(material.getVersion())
            .occurredAt(OffsetDateTime.now().toString())
            .payload(MaterialEvent.Payload.builder()
                    .materialId(material.getId())
                    .materialCode(material.getMaterialCode())
                    .name(material.getName())
                    .materialUnit(material.getMaterialUnit())
                    .baseQuantity(material.getBaseQuantity())
                    .standardQuantity(material.getStandardQuantity() != null ? material.getStandardQuantity() : 1)
                    .leadTime(material.getLeadTime())
                    .deleted(deleted)
                    .materialCategoryId(material.getMaterialCategory().getId())
                    .standardCost(material.getStandardCost())
                    .build())
            .build();
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c67c45 and 1cdd24a.

📒 Files selected for processing (9)
  • src/main/java/com/sampoom/backend/api/material/event/dto/MaterialEvent.java (1 hunks)
  • src/main/java/com/sampoom/backend/api/material/event/service/MaterialEventBatchService.java (1 hunks)
  • src/main/java/com/sampoom/backend/api/material/service/MaterialService.java (3 hunks)
  • src/main/java/com/sampoom/backend/api/part/event/dto/PartEvent.java (1 hunks)
  • src/main/java/com/sampoom/backend/api/part/event/service/PartEventBatchService.java (1 hunks)
  • src/main/java/com/sampoom/backend/api/part/service/PartService.java (5 hunks)
  • src/main/java/com/sampoom/backend/common/outbox/repository/OutboxRepository.java (1 hunks)
  • src/main/java/com/sampoom/backend/common/outbox/service/OutboxEventProcessor.java (2 hunks)
  • src/main/java/com/sampoom/backend/common/outbox/service/OutboxPublisher.java (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (10)
src/main/java/com/sampoom/backend/common/outbox/service/OutboxEventProcessor.java (1)

49-52: PART 이벤트 역직렬화 방식 개선 완료

전체 PartEvent 객체를 직접 역직렬화하는 방식으로 변경되어 코드가 간결해졌습니다. PartService에서 전체 이벤트 객체를 직렬화하는 방식과 일치합니다.

src/main/java/com/sampoom/backend/api/part/event/dto/PartEvent.java (1)

27-29: standardQuantity 필드 추가 완료

기준수량(standardQuantity) 필드가 적절히 추가되었으며, 안전재고(baseQuantity)와 함께 재고 관리에 필요한 정보를 제공합니다.

src/main/java/com/sampoom/backend/api/material/event/dto/MaterialEvent.java (1)

30-30: standardQuantity 필드 추가 완료

PartEvent와 동일한 패턴으로 기준수량 필드가 추가되어 일관성이 유지됩니다.

src/main/java/com/sampoom/backend/api/material/event/service/MaterialEventBatchService.java (1)

32-61: 올바른 이벤트 직렬화 구현

전체 MaterialEvent 객체를 생성하고 직렬화하여(line 57) OutboxEventProcessor의 역직렬화와 일치합니다. standardQuantity 기본값 처리도 적절합니다.

src/main/java/com/sampoom/backend/api/part/event/service/PartEventBatchService.java (1)

45-76: 올바른 이벤트 직렬화 구현

전체 PartEvent 객체를 생성하고 직렬화하여(line 71) OutboxEventProcessor의 역직렬화와 일치합니다. MaterialEventBatchService와 동일한 패턴을 따릅니다.

src/main/java/com/sampoom/backend/api/material/service/MaterialService.java (3)

112-138: 올바른 이벤트 직렬화 구현 (createMaterial)

전체 MaterialEvent 객체를 OutboxService에 전달하여(line 137) OutboxEventProcessor의 역직렬화와 일치합니다. 이것이 올바른 패턴입니다.

참고: PartService.java는 현재 payload만 전달하는 잘못된 패턴을 사용하고 있으므로 수정이 필요합니다.


174-200: 올바른 이벤트 직렬화 구현 (updateMaterial)

전체 MaterialEvent 객체를 전달하는 올바른 패턴을 따릅니다.


211-237: 올바른 이벤트 직렬화 구현 (deleteMaterial)

전체 MaterialEvent 객체를 전달하는 올바른 패턴을 따릅니다.

src/main/java/com/sampoom/backend/common/outbox/service/OutboxPublisher.java (1)

22-43: 재시도 로직 개선 완료

최대 10회 재시도 로직이 추가되어 일시적 장애에 대한 복원력이 향상되었습니다. FAILED 이벤트의 재시도 로그(lines 40-43)는 디버깅에 유용합니다.

5초 간격으로 10회 재시도는 합리적인 설정이며, 이후에는 수동 개입이 필요한 것으로 간주됩니다.

src/main/java/com/sampoom/backend/common/outbox/repository/OutboxRepository.java (1)

6-7: LGTM!

커스텀 쿼리에 필요한 import가 올바르게 추가되었습니다.

Comment thread src/main/java/com/sampoom/backend/api/part/service/PartService.java
Comment thread src/main/java/com/sampoom/backend/api/part/service/PartService.java
Comment thread src/main/java/com/sampoom/backend/api/part/service/PartService.java
Comment thread src/main/java/com/sampoom/backend/api/part/service/PartService.java
@yangjiseonn yangjiseonn merged commit 703e8c1 into main Nov 7, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants