Skip to content

[fix/#133-register-property] 매물 등록 로직 수정#134

Open
HUIJAEKO wants to merge 2 commits into
devfrom
fix/#133-register-property
Open

[fix/#133-register-property] 매물 등록 로직 수정#134
HUIJAEKO wants to merge 2 commits into
devfrom
fix/#133-register-property

Conversation

@HUIJAEKO

@HUIJAEKO HUIJAEKO commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

🔍️ 이 PR을 통해 해결하려는 문제가 무엇인가요?

✨ 이 PR에서 핵심적으로 변경된 사항은 무엇일까요?

문제를 해결하면서 주요하게 변경된 사항들을 적어 주세요

  • 매물 등록 후 점수 계산, AI요약이 가능하도록 비동기 처리를 합니다.

🙏 Reviewer 분들이 이런 부분을 신경써서 봐 주시면 좋겠어요

개발 과정에서 다른 분들의 의견은 어떠한지 궁금했거나 크로스 체크가 필요하다고 느껴진 코드가 있다면 남겨주세요

🩺 이 PR에서 테스트 혹은 검증이 필요한 부분이 있을까요?

테스트가 필요한 항목이나 테스트 코드가 추가되었다면 함께 적어주세요

📌 PR 진행 시 이러한 점들을 참고해 주세요

  • Reviewer 분들은 코드 리뷰 시 좋은 코드의 방향을 제시하되, 코드 수정을 강제하지 말아 주세요.
  • Reviewer 분들은 좋은 코드를 발견한 경우, 칭찬과 격려를 아끼지 말아 주세요.
  • Comment 작성 시 Prefix로 P1, P2, P3 를 적어 주시면 Assignee가 보다 명확하게 Comment에 대해 대응할 수 있어요
    • P1 : 꼭 반영해 주세요 - 이슈가 발생하거나 취약점이 발견되는 케이스 등
    • P2 : 반영을 적극적으로 고려해 주시면 좋을 것 같아요
    • P3 : 이런 방법도 있을 것 같아요~ 등의 사소한 의견입니다

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능
    • RabbitMQ 기반 이벤트 전파가 추가되어 등록된 부동산 생성 이벤트를 메시지로 발행/수신합니다.
    • 부동산 등록이 생성된 리소스의 ID를 반환하도록 변경되었습니다.
    • 등록 후 처리 작업이 별도의 비동기 오케스트레이션으로 병렬 실행되어 처리 속도와 확장성이 향상됩니다.
    • 로컬 개발 환경에 메시지 브로커 및 라우팅 관련 설정이 추가되었습니다.

@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

RabbitMQ 기반 이벤트 드리븐 처리 추가: AMQP 의존성 추가, 로컬 docker-compose에 RabbitMQ 서비스 추가, 교환/큐/바인딩 및 메시지 컨버터 설정, 이벤트 DTO/발행자/중계자/소비자 및 비동기 오케스트레이터 도입으로 매물 등록 후 비동기 점수측정 흐름을 구현함.

Changes

Cohort / File(s) Summary
빌드·인프라
build.gradle, docker-compose.local.yml
Spring AMQP 의존성 추가; 로컬에 rabbitmq:3-management 서비스·볼륨 추가 및 앱 컨테이너 네이밍/Traefik 라벨 변경
RabbitMQ 구성
src/main/java/.../RabbitConfig.java
DirectExchange, Queue, RoutingKey, Binding, Jackson2JsonMessageConverter, RabbitTemplate 및 SimpleRabbitListenerContainerFactory 빈 추가
이벤트 정의·발행
src/main/java/.../PropertyCreatedEvent.java, src/main/java/.../PropertyService.java, src/main/java/.../PropertyController.java
PropertyCreatedEvent DTO 추가; PropertyService.register 반환타입을 Long으로 변경하고 등록 후 ApplicationEventPublisher로 이벤트 발행; 컨트롤러에 관련 임포트 추가
이벤트 중계·발송
src/main/java/.../PropertyEventRelay.java
트랜잭션 커밋(AFTER_COMMIT) 이후 수신한 애플리케이션 이벤트를 RabbitTemplate으로 설정된 교환·라우팅키로 전송
이벤트 소비·처리 오케스트레이션
src/main/java/.../PropertyCreatedConsumer.java, src/main/java/.../PropertyAsyncOrchestrator.java
큐에서 PropertyCreatedEvent 수신하는 리스너 추가; 가상 스레드 기반으로 5개 설명 서비스(e.g., environment, convenience, accessibility, noise, safety)를 병렬 호출하여 결과를 집계하는 오케스트레이터 추가

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant PropertyService as PropertyService
    participant EventPublisher as ApplicationEventPublisher
    participant PropertyEventRelay as PropertyEventRelay
    participant RabbitMQ as RabbitMQ
    participant PropertyCreatedConsumer as Consumer
    participant PropertyAsyncOrchestrator as Orchestrator
    participant ExplanationServices as ExplanationServices

    Client->>PropertyService: register(request)
    PropertyService->>PropertyService: DB에 매물 저장
    PropertyService->>EventPublisher: publishEvent(PropertyCreatedEvent)
    PropertyService-->>Client: return propertyId

    EventPublisher->>PropertyEventRelay: on(PropertyCreatedEvent)
    PropertyEventRelay->>RabbitMQ: convertAndSend(exchange, routingKey, event)

    RabbitMQ->>PropertyCreatedConsumer: 메시지 전달
    PropertyCreatedConsumer->>PropertyAsyncOrchestrator: process(propertyId)

    Orchestrator->>ExplanationServices: evaluateAndDescribe(propertyId) (5개 병렬 호출)
    ExplanationServices-->>Orchestrator: 점수/설명 반환
    Orchestrator->>Orchestrator: 모든 작업 완료 대기 및 처리
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

💡feature

Poem

🐰 큐에 띄운 작은 소식 하나,
깡충깡충 달려가는 가상 스레드들,
다섯 점수 모여 노래하네,
이벤트가 춤추고 서비스가 답하니,
비동기 향연, 우후! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 이슈 번호와 매물 등록 로직 수정을 명확히 나타내며, 실제 변경사항(비동기 처리를 통한 매물 등록 로직 수정)을 잘 요약하고 있습니다.
Description check ✅ Passed PR 설명은 템플릿의 주요 섹션을 포함하고 있으며, 해결할 문제(#133), 핵심 변경사항(비동기 처리를 통한 점수 계산 및 AI 요약)이 명확히 기술되어 있습니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경사항이 이슈 #133의 목표를 충족합니다: (1) 매물 등록 로직 수정 및 PropertyService에서 ID 반환 [PropertyService.java], (2) 비동기 처리 구현 [PropertyAsyncOrchestrator, PropertyEventRelay, PropertyCreatedConsumer], (3) RabbitMQ 기반 이벤트 처리 [RabbitConfig, docker-compose.local.yml].
Out of Scope Changes check ✅ Passed 모든 코드 변경사항이 이슈 #133의 범위 내에 있습니다. 추가된 RabbitMQ 의존성, 이벤트 기반 비동기 처리, 각 설명 서비스의 비동기 호출은 모두 명시된 목표에 부합합니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#133-register-property

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.

@HUIJAEKO HUIJAEKO changed the title fix: 매물 등록 비동기 처리 [fix/#133-register-property] 매물 등록 로직 수정 Mar 3, 2026
@HUIJAEKO HUIJAEKO self-assigned this Mar 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/main/java/com/example/Dingle/global/config/RabbitConfig.java (1)

27-30: Dead Letter Queue(DLQ) 설정을 고려해 보세요.

현재 큐 설정은 기본적이며 동작합니다. 프로덕션 환경에서는 메시지 처리 실패 시 재시도 및 DLQ를 통한 실패 메시지 추적을 위해 추가 설정을 고려해 보세요.

💡 DLQ 설정 예시
`@Bean`
public Queue propertyCreatedQueue() {
    return QueueBuilder.durable(QUEUE)
            .withArgument("x-dead-letter-exchange", EXCHANGE)
            .withArgument("x-dead-letter-routing-key", "property.created.dlq")
            .build();
}

`@Bean`
public Queue deadLetterQueue() {
    return QueueBuilder.durable("property.created.dlq").build();
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/example/Dingle/global/config/RabbitConfig.java` around
lines 27 - 30, Add a Dead Letter Queue (DLQ) configuration to the existing
propertyCreatedQueue bean so failed messages are routed for inspection: update
propertyCreatedQueue() (which currently returns
QueueBuilder.durable(QUEUE).build()) to add arguments "x-dead-letter-exchange"
and "x-dead-letter-routing-key" pointing to your DLX/route (use EXCHANGE and a
DLQ routing key like "property.created.dlq"), and add a new bean
deadLetterQueue() that builds the durable DLQ (e.g., "property.created.dlq");
ensure any bindings for the DLQ route are created so messages routed to the DLQ
are consumable.
src/main/java/com/example/Dingle/property/controller/PropertyController.java (1)

5-5: 사용되지 않는 import 문이 있습니다.

PropertyCreatedEvent, ApplicationEventPublisher, LocalDate import가 컨트롤러에서 사용되지 않습니다. AI 요약에 따르면 이벤트 발행은 PropertyService에서 처리됩니다. 이 import들은 리팩토링 과정에서 남은 것으로 보입니다.

♻️ 사용되지 않는 import 제거
 import com.example.Dingle.global.dto.ResponseDTO;
 import com.example.Dingle.property.dto.PropertyCompareDTO;
-import com.example.Dingle.property.dto.PropertyCreatedEvent;
 import com.example.Dingle.property.dto.PropertyListDTO;
 import com.example.Dingle.property.dto.PropertyRegisterRequestDTO;
 import com.example.Dingle.property.service.PropertyListService;
 import com.example.Dingle.property.service.PropertyService;
 import com.example.Dingle.user.dto.CustomUserDetails;
 import io.swagger.v3.oas.annotations.Operation;
 import lombok.RequiredArgsConstructor;
-import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;

-import java.time.LocalDate;
 import java.util.List;

Also applies to: 13-13, 18-18

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/example/Dingle/property/controller/PropertyController.java`
at line 5, Remove the leftover unused imports and any related unused injections
from the controller: delete the import lines for PropertyCreatedEvent,
ApplicationEventPublisher, and LocalDate, and if the PropertyController class
contains an ApplicationEventPublisher field or constructor parameter, remove
that field/parameter and its assignment; keep PropertyService usage intact since
event publishing moved to PropertyService. Ensure no other references to those
symbols remain in PropertyController after removal.
src/main/java/com/example/Dingle/property/service/PropertyAsyncOrchestrator.java (3)

55-56: 예외 처리 시 원인 체인이 손실될 수 있습니다.

Exception을 광범위하게 catch하면 InterruptedException의 인터럽트 상태가 복원되지 않습니다. 또한 첫 번째 실패 이후 나머지 태스크의 예외 정보가 손실됩니다.

♻️ 인터럽트 처리 개선
-        } catch (Exception e) {
-            throw new RuntimeException("Property async processing failed", e);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Property async processing interrupted", e);
+        } catch (ExecutionException e) {
+            throw new RuntimeException("Property async processing failed", e.getCause());
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/example/Dingle/property/service/PropertyAsyncOrchestrator.java`
around lines 55 - 56, In PropertyAsyncOrchestrator, avoid catching Exception
broadly: change the try/catch so InterruptedException is caught separately, call
Thread.currentThread().interrupt() and rethrow (or wrap) to preserve interrupt
status; for other failures collect task exceptions instead of discarding
them—when aggregating results from your async tasks (e.g., the
CompletableFuture/ExecutorFlow used in this method), capture the primary
exception and call addSuppressed(...) for remaining task exceptions or wrap them
in a CompletionException so none are lost before throwing the
RuntimeException("Property async processing failed", e); ensure the catch block
references InterruptedException and the general Exception handler uses
suppressed exceptions from the individual futures.

20-21: ExecutorService를 메서드 호출마다 생성합니다.

process() 호출마다 새로운 ExecutorService를 생성하고 종료합니다. Virtual thread executor는 가볍지만, 이 패턴은 여전히 불필요한 오버헤드를 발생시킵니다.

♻️ 싱글톤 ExecutorService 사용 고려
 `@Service`
 `@RequiredArgsConstructor`
 public class PropertyAsyncOrchestrator {
+    private final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
+
     private final EnvironmentExplanationService environmentExplanationService;
     // ... other services

     public void process(Long propertyId) {
-        ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
-
         try {
             // ... submit tasks
-        } finally {
-            executor.close();
-        }
+        } catch (Exception e) {
+            throw new RuntimeException("Property async processing failed", e);
+        }
     }
 }

또는 Spring의 @AsyncTaskExecutor 빈을 활용하는 것도 고려해 보세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/example/Dingle/property/service/PropertyAsyncOrchestrator.java`
around lines 20 - 21, The process() method in PropertyAsyncOrchestrator creates
a new ExecutorService via Executors.newVirtualThreadPerTaskExecutor() on every
call; change this to use a shared/singleton executor instead of per-call
creation: add a private final ExecutorService field in PropertyAsyncOrchestrator
initialized once (or accept/inject a TaskExecutor/@Async-managed executor) and
reuse it inside process(Long propertyId); ensure proper lifecycle management by
shutting down the executor on application stop (or rely on Spring bean
lifecycle) and remove per-call executor creation and shutdown from process().

24-53: CompletableFuture를 사용하면 더 간결하게 작성할 수 있습니다.

현재 구현은 동작하지만, CompletableFuture.allOf()를 사용하면 코드가 더 간결해지고 예외 처리도 개선됩니다.

♻️ CompletableFuture 활용 예시
public void process(Long propertyId) {
    CompletableFuture<?>[] futures = {
        CompletableFuture.runAsync(() -> environmentExplanationService.evaluateAndDescribe(propertyId)),
        CompletableFuture.runAsync(() -> convenienceExplanationService.evaluateAndDescribe(propertyId)),
        CompletableFuture.runAsync(() -> accessibilityExplanationService.evaluateAndDescribe(propertyId)),
        CompletableFuture.runAsync(() -> noiseExplanationService.evaluateAndDescribe(propertyId)),
        CompletableFuture.runAsync(() -> safetyExplanationService.evaluateAndDescribe(propertyId))
    };
    
    try {
        CompletableFuture.allOf(futures).join();
    } catch (CompletionException e) {
        throw new RuntimeException("Property async processing failed", e.getCause());
    }
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/example/Dingle/property/service/PropertyAsyncOrchestrator.java`
around lines 24 - 53, The current PropertyAsyncOrchestrator submits five
callables to an Executor and blocks on each Future.get(); replace this with
CompletableFuture to simplify and improve exception handling: create
CompletableFuture.runAsync tasks for
environmentExplanationService.evaluateAndDescribe(propertyId),
convenienceExplanationService.evaluateAndDescribe(propertyId),
accessibilityExplanationService.evaluateAndDescribe(propertyId),
noiseExplanationService.evaluateAndDescribe(propertyId), and
safetyExplanationService.evaluateAndDescribe(propertyId) (optionally passing the
existing executor), collect them into an array and use
CompletableFuture.allOf(...).join(); wrap join in try/catch to translate
CompletionException into a runtime exception with the cause so failures are
propagated cleanly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docker-compose.local.yml`:
- Around line 37-38: The docker-compose references a named volume rabbitmq-data
in the rabbitmq service but does not declare it at the top-level; add a
top-level volumes: section that declares rabbitmq-data (e.g., include a volumes
block with rabbitmq-data:) so the named volume is explicitly defined; update the
docker-compose file to include this volumes entry to match the referenced
rabbitmq-data volume.

---

Nitpick comments:
In `@src/main/java/com/example/Dingle/global/config/RabbitConfig.java`:
- Around line 27-30: Add a Dead Letter Queue (DLQ) configuration to the existing
propertyCreatedQueue bean so failed messages are routed for inspection: update
propertyCreatedQueue() (which currently returns
QueueBuilder.durable(QUEUE).build()) to add arguments "x-dead-letter-exchange"
and "x-dead-letter-routing-key" pointing to your DLX/route (use EXCHANGE and a
DLQ routing key like "property.created.dlq"), and add a new bean
deadLetterQueue() that builds the durable DLQ (e.g., "property.created.dlq");
ensure any bindings for the DLQ route are created so messages routed to the DLQ
are consumable.

In
`@src/main/java/com/example/Dingle/property/controller/PropertyController.java`:
- Line 5: Remove the leftover unused imports and any related unused injections
from the controller: delete the import lines for PropertyCreatedEvent,
ApplicationEventPublisher, and LocalDate, and if the PropertyController class
contains an ApplicationEventPublisher field or constructor parameter, remove
that field/parameter and its assignment; keep PropertyService usage intact since
event publishing moved to PropertyService. Ensure no other references to those
symbols remain in PropertyController after removal.

In
`@src/main/java/com/example/Dingle/property/service/PropertyAsyncOrchestrator.java`:
- Around line 55-56: In PropertyAsyncOrchestrator, avoid catching Exception
broadly: change the try/catch so InterruptedException is caught separately, call
Thread.currentThread().interrupt() and rethrow (or wrap) to preserve interrupt
status; for other failures collect task exceptions instead of discarding
them—when aggregating results from your async tasks (e.g., the
CompletableFuture/ExecutorFlow used in this method), capture the primary
exception and call addSuppressed(...) for remaining task exceptions or wrap them
in a CompletionException so none are lost before throwing the
RuntimeException("Property async processing failed", e); ensure the catch block
references InterruptedException and the general Exception handler uses
suppressed exceptions from the individual futures.
- Around line 20-21: The process() method in PropertyAsyncOrchestrator creates a
new ExecutorService via Executors.newVirtualThreadPerTaskExecutor() on every
call; change this to use a shared/singleton executor instead of per-call
creation: add a private final ExecutorService field in PropertyAsyncOrchestrator
initialized once (or accept/inject a TaskExecutor/@Async-managed executor) and
reuse it inside process(Long propertyId); ensure proper lifecycle management by
shutting down the executor on application stop (or rely on Spring bean
lifecycle) and remove per-call executor creation and shutdown from process().
- Around line 24-53: The current PropertyAsyncOrchestrator submits five
callables to an Executor and blocks on each Future.get(); replace this with
CompletableFuture to simplify and improve exception handling: create
CompletableFuture.runAsync tasks for
environmentExplanationService.evaluateAndDescribe(propertyId),
convenienceExplanationService.evaluateAndDescribe(propertyId),
accessibilityExplanationService.evaluateAndDescribe(propertyId),
noiseExplanationService.evaluateAndDescribe(propertyId), and
safetyExplanationService.evaluateAndDescribe(propertyId) (optionally passing the
existing executor), collect them into an array and use
CompletableFuture.allOf(...).join(); wrap join in try/catch to translate
CompletionException into a runtime exception with the cause so failures are
propagated cleanly.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 103acaa and c5f1448.

📒 Files selected for processing (9)
  • build.gradle
  • docker-compose.local.yml
  • src/main/java/com/example/Dingle/global/config/RabbitConfig.java
  • src/main/java/com/example/Dingle/property/controller/PropertyController.java
  • src/main/java/com/example/Dingle/property/dto/PropertyCreatedEvent.java
  • src/main/java/com/example/Dingle/property/service/PropertyAsyncOrchestrator.java
  • src/main/java/com/example/Dingle/property/service/PropertyService.java
  • src/main/java/com/example/Dingle/property/util/PropertyCreatedConsumer.java
  • src/main/java/com/example/Dingle/property/util/PropertyEventRelay.java

Comment thread docker-compose.local.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
docker-compose.local.yml (1)

29-29: rabbitmq:3-management 대신 고정 태그 또는 다이제스트를 사용하여 재현성 확보

3-management는 가변 태그로서, 로컬 환경에서 패치 업데이트에 따라 다른 이미지가 풀될 수 있습니다. 재현 가능한 배포를 위해 다음 중 하나를 권장합니다:

  • 패치 레벨 태그: rabbitmq:3.13.1-management
  • 태그 + 다이제스트 (최상): rabbitmq:3.13.1-management@sha256:abc...

다이제스트 방식이 정확한 이미지 콘텐츠를 보장하므로 가장 안정적입니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker-compose.local.yml` at line 29, Replace the mutable image tag
"rabbitmq:3-management" with a fixed patch-level tag or an image digest to
ensure reproducible pulls; update the "image: rabbitmq:3-management" entry to
something like "rabbitmq:3.13.1-management" or, preferably,
"rabbitmq:3.13.1-management@sha256:<actual-digest>" so the exact image content
is pinned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docker-compose.local.yml`:
- Around line 31-36: Change the port bindings from "5672:5672" and "15672:15672"
to bind only to localhost by using "127.0.0.1:5672:5672" and
"127.0.0.1:15672:15672", and stop hardcoding credentials by replacing
RABBITMQ_DEFAULT_USER: guest and RABBITMQ_DEFAULT_PASS: guest with environment
variable references like RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER} and
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS}; then add the actual values to
your .env (e.g. RABBITMQ_DEFAULT_USER=guest, RABBITMQ_DEFAULT_PASS=guest) and
ensure the .env is excluded from version control.

---

Nitpick comments:
In `@docker-compose.local.yml`:
- Line 29: Replace the mutable image tag "rabbitmq:3-management" with a fixed
patch-level tag or an image digest to ensure reproducible pulls; update the
"image: rabbitmq:3-management" entry to something like
"rabbitmq:3.13.1-management" or, preferably,
"rabbitmq:3.13.1-management@sha256:<actual-digest>" so the exact image content
is pinned.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5f1448 and eb76bd9.

📒 Files selected for processing (1)
  • docker-compose.local.yml

Comment thread docker-compose.local.yml
Comment on lines +31 to +36
ports:
- "5672:5672" # AMQP
- "15672:15672" # Management UI
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1. 파일 존재 확인
if [ -f "docker-compose.local.yml" ]; then
  echo "[✓] docker-compose.local.yml 파일 발견"
  
  # 2. 파일 크기 확인
  wc -l docker-compose.local.yml
  
  # 3. RabbitMQ 섹션 확인 (28-40 라인 범위)
  echo -e "\n[RabbitMQ 섹션 확인]"
  sed -n '28,40p' docker-compose.local.yml
  
  # 4. 포트 바인딩 패턴 확인
  echo -e "\n[포트 바인딩 패턴]"
  grep -n "5672\|15672" docker-compose.local.yml || echo "RabbitMQ 포트 미발견"
  
  # 5. RABBITMQ 환경변수 확인
  echo -e "\n[RABBITMQ 환경변수]"
  grep -n "RABBITMQ_DEFAULT" docker-compose.local.yml || echo "RABBITMQ 환경변수 미발견"
  
  # 6. .env 파일 확인
  echo -e "\n[.env 파일 확인]"
  if [ -f ".env" ] || [ -f ".env.local" ]; then
    echo ".env 파일 발견"
    [ -f ".env" ] && head -10 .env
    [ -f ".env.local" ] && head -10 .env.local
  else
    echo ".env 파일 미발견"
  fi
else
  echo "[✗] docker-compose.local.yml 파일 미발견"
  echo "사용 가능한 compose 파일:"
  find . -name "docker-compose*.yml" -o -name "docker-compose*.yaml"
fi

Repository: D-ingle/backend

Length of output: 669


RabbitMQ 자격증명과 포트 바인딩 설정 개선 필요

Lines 32-33의 포트가 모든 인터페이스(0.0.0.0)에 바인딩되어 있고, Lines 35-36의 guest/guest 자격증명이 하드코딩되어 있습니다. 로컬 개발환경에서도 다음을 권장합니다:

  1. 포트 바인딩을 127.0.0.1로 제한하여 로컬호스트 접근만 허용
  2. 자격증명을 .env 파일로 분리하여 버전 제어 대상에서 제외
권장 수정안
     ports:
-      - "5672:5672"    # AMQP
-      - "15672:15672"  # Management UI
+      - "127.0.0.1:5672:5672"    # AMQP (로컬 접근만)
+      - "127.0.0.1:15672:15672"  # Management UI (로컬 접근만)
     environment:
-      RABBITMQ_DEFAULT_USER: guest
-      RABBITMQ_DEFAULT_PASS: guest
+      RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-guest}
+      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-guest}

.env 파일에 추가:

RABBITMQ_DEFAULT_USER=guest
RABBITMQ_DEFAULT_PASS=guest
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker-compose.local.yml` around lines 31 - 36, Change the port bindings from
"5672:5672" and "15672:15672" to bind only to localhost by using
"127.0.0.1:5672:5672" and "127.0.0.1:15672:15672", and stop hardcoding
credentials by replacing RABBITMQ_DEFAULT_USER: guest and RABBITMQ_DEFAULT_PASS:
guest with environment variable references like RABBITMQ_DEFAULT_USER:
${RABBITMQ_DEFAULT_USER} and RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS};
then add the actual values to your .env (e.g. RABBITMQ_DEFAULT_USER=guest,
RABBITMQ_DEFAULT_PASS=guest) and ensure the .env is excluded from version
control.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[fix] 매물 등록 및 점수 측정 로직 수정

1 participant