Skip to content

[OT-335] [FEAT]: 트랜스코딩 이벤트 아웃박스 추가#203

Merged
phonil merged 8 commits intodevelopfrom
OT-335-feature/transcoding-outbox-pattern
Mar 18, 2026
Merged

[OT-335] [FEAT]: 트랜스코딩 이벤트 아웃박스 추가#203
phonil merged 8 commits intodevelopfrom
OT-335-feature/transcoding-outbox-pattern

Conversation

@phonil
Copy link
Copy Markdown
Contributor

@phonil phonil commented Mar 18, 2026

📝 작업 내용

이번 PR에서 작업한 내용을 적어주세요

  • 트랜스코딩 이벤트 아웃박스 추가
  • 다중 서버 ShedLock 추가

📷 스크린샷

☑️ 체크 리스트

체크 리스트를 확인해주세요

  • 테스트는 잘 통과했나요?
  • 충돌을 해결했나요?
  • 이슈는 등록했나요?
  • 라벨은 등록했나요?

#️⃣ 연관된 이슈

ex) # 이슈번호

closes #183

💬 리뷰 요구사항

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

ex) 예외 처리를 이렇게 해도 괜찮을까요? / ~~부분 주의 깊게 봐주세요

1. 발행 쪽 유실 방지를 위한 아웃박스 패턴 도입

  • 최근 순, PENDING 상태인 것들을 50개씩 뽑습니다.

2. 다중 서버 환경 스케줄러 중복 실행 방지

  • ShedLock으로 하나만 실행되도록 구성했습니다.
  • 노션 트러블슈팅에 다른 방안 써놨습니다.

Summary by CodeRabbit

  • 새로운 기능

    • 분산 잠금 기반 스케줄링이 추가되어 스케줄된 작업의 단일 실행을 보장합니다.
    • 트랜스코드용 아웃박스 엔터티와 폴링/게시 흐름이 도입되어 비동기 전송이 안정화되었습니다.
  • 개선사항

    • 멀티 노드 환경에서 작업 처리 신뢰성과 재시도/상태 관리가 향상되었습니다.
    • 관련 DB 마이그레이션이 추가되어 아웃박스 및 잠금 테이블이 생성됩니다.

@phonil phonil requested a review from marulog March 18, 2026 18:35
@phonil phonil self-assigned this Mar 18, 2026
@phonil phonil added the feat 새로운 기능 구현 label Mar 18, 2026
@marulog marulog requested a review from Copilot March 18, 2026 18:38
Copy link
Copy Markdown

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

영상 업로드(트랜스코딩 요청) 발행 유실을 줄이기 위해 Outbox 패턴을 도입하고, 다중 서버 환경에서 스케줄러 중복 실행을 방지하기 위해 ShedLock을 추가하는 PR입니다.

Changes:

  • 트랜스코딩 요청을 transcode_outbox 테이블에 적재하고, 폴러가 주기적으로 발행하도록 변경
  • OutboxPoller에 ShedLock 적용 및 shedlock 테이블/설정 추가
  • Contents 업로드 완료 플로우에서 “즉시 MQ 발행”을 제거하고 “outbox 저장”으로 전환

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
modules/infra-db/src/main/resources/db/migration/V12__transcode_outbox.sql transcode_outbox/shedlock 테이블 및 인덱스/FK 추가
modules/domain/src/main/java/com/ott/domain/outbox/repository/TranscodeOutboxRepository.java PENDING outbox 배치 조회용 Spring Data 메서드 추가
modules/domain/src/main/java/com/ott/domain/outbox/domain/TranscodeOutbox.java Outbox 엔티티/상태 전이 로직 추가
modules/domain/src/main/java/com/ott/domain/outbox/domain/OutboxStatus.java Outbox 상태 enum 추가
apps/api-admin/src/main/java/com/ott/api_admin/outbox/writer/OutboxWriter.java outbox 상태 업데이트 헬퍼 추가
apps/api-admin/src/main/java/com/ott/api_admin/outbox/poller/OutboxPoller.java 주기 폴링 + MQ 발행 + ShedLock 적용
apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsWriter.java ingest job 생성 시 outbox 적재 추가
apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java 업로드 완료 시 즉시 발행 제거, outbox 저장으로 전환
apps/api-admin/src/main/java/com/ott/api_admin/config/shedlock/ShedLockConfig.java ShedLock LockProvider 설정 추가
apps/api-admin/build.gradle ShedLock 의존성 추가

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

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +60 to +61
log.warn("Outbox 발행 실패 - outboxId: {}, retryCount: {}/{}, error: {}",
transcodeOutbox.getId(), transcodeOutbox.getRetryCount(), transcodeOutbox.getMaxRetries(), e.getMessage());
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 18, 2026

Walkthrough

아웃박스 패턴을 도입해 업로드 시 트랜스코딩 메시지 발행을 즉시 수행하던 흐름을 변경했습니다. TranscodeOutbox 엔티티·리포지토리·마이그레이션을 추가하고, OutboxPoller와 OutboxWriter를 통해 주기적 폴링 및 발행을 수행하도록 변경했습니다. ShedLock과 스케줄링이 도입되었습니다.

Changes

Cohort / File(s) Summary
빌드 의존성
apps/api-admin/build.gradle
ShedLock 라이브러리 추가: shedlock-spring, shedlock-provider-jdbc-template (v5.10.0)
ShedLock 설정 및 스케줄링 활성화
apps/api-admin/src/main/java/com/ott/api_admin/config/shedlock/ShedLockConfig.java, apps/api-admin/src/main/java/com/ott/api_admin/ApiAdminApplication.java
JdbcTemplateLockProvider 빈 추가(@EnableSchedulerLock(defaultLockAtMostFor="10m")) 및 @EnableScheduling 적용
도메인: 아웃박스 엔티티 및 상태
modules/domain/src/main/java/com/ott/domain/outbox/domain/TranscodeOutbox.java, modules/domain/src/main/java/com/ott/domain/outbox/domain/OutboxStatus.java
TranscodeOutbox JPA 엔티티 추가(상태·재시도 로직 포함) 및 OutboxStatus 열거형 추가(PENDING/PUBLISHED/FAILED)
리포지토리 및 마이그레이션
modules/domain/src/main/java/com/ott/domain/outbox/repository/TranscodeOutboxRepository.java, modules/infra-db/src/main/resources/db/migration/V12__transcode_outbox.sql
TranscodeOutboxRepository 인터페이스 추가 및 DB 마이그레이션(transcode_outbox, shedlock 테이블, 인덱스, FK)
아웃박스 퍼블리싱 컴포넌트
apps/api-admin/src/main/java/com/ott/api_admin/outbox/poller/OutboxPoller.java, apps/api-admin/src/main/java/com/ott/api_admin/outbox/writer/OutboxWriter.java
OutboxPoller: ShedLock 적용 스케줄러(10s)로 PENDING 항목 최대 50개 폴링 후 RabbitMQ 발행; OutboxWriter: 발행/실패 상태 전환 트랜잭션 처리
서비스/라이터 변경: 아웃박스 저장 흐름으로 전환
apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java, apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsWriter.java, apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormService.java, apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormWriter.java
createIngestJob → createIngestJobWithOutbox로 변경하여 즉시 메시지 발행 제거하고 TranscodeOutbox 엔티티 저장으로 전환; 로그 메시지와 호출 경로 업데이트

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Service as Content/ShortForm<br/>Service
    participant Writer as Content/ShortForm<br/>Writer
    participant OutboxRepo as TranscodeOutbox<br/>Repository
    participant Poller as OutboxPoller<br/>(ShedLock)
    participant RabbitPublisher as RabbitTranscode<br/>Publisher
    participant OutboxWriter as OutboxWriter

    Client->>Service: completeOriginUpload()
    Service->>Writer: createIngestJobWithOutbox()
    Writer->>Writer: create IngestJob
    Writer->>OutboxRepo: save TranscodeOutbox (PENDING)
    OutboxRepo-->>Writer: saved
    Writer-->>Service: IngestJobResult
    Service-->>Client: Success

    loop Every 10s (ShedLock)
        Poller->>OutboxRepo: findTop50ByOutboxStatusOrderByCreatedDateAsc(PENDING)
        OutboxRepo-->>Poller: List<TranscodeOutbox>
        Poller->>Poller: toMessage()
        Poller->>RabbitPublisher: publish(TranscodeMessage)
        alt publish success
            RabbitPublisher-->>Poller: ack
            Poller->>OutboxWriter: markAsPublished(id)
            OutboxWriter->>OutboxRepo: load & update status=PUBLISHED
        else publish failure
            RabbitPublisher-->>Poller: error
            Poller->>OutboxWriter: markAsFailed(id, error)
            OutboxWriter->>OutboxRepo: load & update retryCount, maybe status=FAILED
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • marulog
  • arlen02-01
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 트랜스코딩 이벤트 아웃박스 추가라는 주요 변경사항을 명확하게 요약하며, 변경사항의 핵심을 정확히 반영합니다.
Linked Issues check ✅ Passed 연결된 이슈 #183의 요구사항인 '영상 업로드 시 Outbox 패턴 도입'이 완전히 구현되었으며, 아웃박스 테이블, 엔티티, 리포지토리, 폴러, 라이터 등 모든 필요한 컴포넌트가 추가되었습니다.
Out of Scope Changes check ✅ Passed ShedLock 추가 및 스케줄링 활성화는 다중 서버 환경에서 스케줄러 중복 실행 방지라는 명시된 목표를 지원하는 관련 변경사항입니다.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch OT-335-feature/transcoding-outbox-pattern
📝 Coding Plan
  • Generate coding plan for human review comments

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

@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 (2)
apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormService.java (1)

37-37: ⚠️ Potential issue | 🟡 Minor

RabbitTranscodePublisher 주입이 사용되지 않으므로 제거하세요.

Outbox 패턴으로 마이그레이션되면서 이 필드(37번 줄)는 더 이상 사용되지 않습니다. completeShortFormOriginUpload 메서드에서 writer.createIngestJobWithOutbox()만 호출되며, 직접 메시지 발행 로직은 제거되었습니다.

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

In
`@apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormService.java`
at line 37, BackOfficeShortFormService has an unused RabbitTranscodePublisher
field; remove the private final RabbitTranscodePublisher transcodePublisher
declaration and any constructor parameter, assignment, or import related to
RabbitTranscodePublisher, leaving the service to call
writer.createIngestJobWithOutbox() in completeShortFormOriginUpload() only;
ensure no remaining references (field, constructor arg, or import) remain and
update any tests or usages that expect the publisher to be injected.
apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormWriter.java (1)

207-226: ⚠️ Potential issue | 🟠 Major

중복 완료 요청에서 ingestJob/outbox가 이중 생성될 수 있습니다.

existsByMediaId() 선조회는 원자적이지 않아서, 같은 shortFormId 완료 요청이 동시에 들어오면 두 트랜잭션이 둘 다 false를 보고 각각 IngestJobTranscodeOutbox를 만들 수 있습니다. ShedLock는 poller 중복만 막아주므로 여기에는 효력이 없습니다. ingest_job.media_id 같은 DB unique constraint로 막고 중복 키를 ALREADY_INGESTED로 변환하는 쪽이 안전합니다.

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

In
`@apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormWriter.java`
around lines 207 - 226, The pre-check using
ingestJobRepository.existsByMediaId(media.getId()) is racy and can allow
duplicate IngestJob/TranscodeOutbox creation; add a DB-level unique constraint
on ingest_job.media_id and change the save path (IngestJob.builder...
ingestJobRepository.save and subsequent transcodeOutboxRepository.save) to run
in a single transaction and catch the database unique-key exception (e.g.,
DataIntegrityViolationException / DuplicateKeyException) thrown by the IngestJob
save, converting it into a BusinessException(ErrorCode.ALREADY_INGESTED); ensure
the same defensive handling applies if the outbox insert can violate a unique
constraint so duplicates are mapped to ALREADY_INGESTED rather than creating
duplicate records.
🧹 Nitpick comments (2)
apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsWriter.java (1)

159-176: Outbox 생성 로직이 올바르게 구현되었습니다.

IngestJob과 Outbox가 동일 트랜잭션 내에서 저장되어 원자성이 보장됩니다. 로깅에 모든 관련 ID가 포함되어 추적성이 좋습니다.

fileSize 계산이 두 번 수행됩니다(Line 164, 174). 로컬 변수로 추출하면 중복을 줄일 수 있습니다.

♻️ fileSize 계산 중복 제거 제안
+        long fileSizeBytes = (long) contents.getVideoSize() * 1024;
+
         // 2. Outbox 저장
         TranscodeOutbox outbox = TranscodeOutbox.builder()
                 .mediaId(media.getId())
                 .ingestJobId(ingestJob.getId())
                 .originUrl(originObjectKey)
-                .fileSize((long) contents.getVideoSize() * 1024)
+                .fileSize(fileSizeBytes)
                 .mediaType(MediaType.CONTENTS)
                 .build();
         transcodeOutboxRepository.save(outbox);

         log.info("IngestJob + Outbox 생성 - contentsId: {}, mediaId: {}, ingestJobId: {}, outboxId: {}",
                 contentsId, media.getId(), ingestJob.getId(), outbox.getId());

         return new IngestJobResult(
                 media.getId(), ingestJob.getId(),
-                originObjectKey, (long) contents.getVideoSize() * 1024,
+                originObjectKey, fileSizeBytes,
                 MediaType.CONTENTS);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsWriter.java`
around lines 159 - 176, Compute the fileSize once into a local long variable
(e.g., long fileSize = (long) contents.getVideoSize() * 1024) and use that
variable in both the TranscodeOutbox.builder().fileSize(...) call and the
IngestJobResult(...) return so the duplicated expression using
contents.getVideoSize() is removed; update references in TranscodeOutbox, the
log call if needed, and the IngestJobResult to use the new fileSize variable.
apps/api-admin/src/main/java/com/ott/api_admin/config/shedlock/ShedLockConfig.java (1)

10-10: 사용되지 않는 import 제거 필요.

javax.sql.DataSource import가 사용되지 않습니다.

🧹 사용되지 않는 import 제거
-import javax.sql.DataSource;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/config/shedlock/ShedLockConfig.java`
at line 10, Remove the unused import javax.sql.DataSource from the
ShedLockConfig class; locate the import statement near the top of ShedLockConfig
(the line importing javax.sql.DataSource) and delete it or run your IDE's
"organize imports" to eliminate the unused import without changing any other
code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api-admin/build.gradle`:
- Around line 25-27: The ShedLock dependencies currently pinned to
'net.javacrumbs.shedlock:shedlock-spring:5.10.0' and
'net.javacrumbs.shedlock:shedlock-provider-jdbc-template:5.10.0' are outdated;
update those dependency coordinates to the current stable release (e.g., 7.6.0)
in the build file, ensure both artifacts use the same new version, then run the
project's build and integration tests to resolve any API or configuration
changes introduced by the upgrade and adjust ShedLock configuration/code where
compilation or behavioral changes surface (look for usages of ShedLock
annotations/config classes to update).

In
`@apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java`:
- Around line 72-75: The current flow calls
uploadHelper.completeMultipartUpload(...) then
writer.createIngestJobWithOutbox(...), so if createIngestJobWithOutbox throws
the S3 multipart is complete but DB/outbox is missing; make the operation
idempotent or add a recovery path: after completeMultipartUpload(objectKey, ...)
ensure createIngestJobWithOutbox(contentsId, objectKey) is safe to retry by
first checking for an existing IngestJob/outbox record (lookup by objectKey or
contentsId) and returning existing IngestJobResult if present, or implement a
small durable “pending-outbox” record written before/after S3 completion that
can be used by a separate replay endpoint to call createIngestJobWithOutbox
safely; update createIngestJobWithOutbox (and any unique constraints on the
IngestJob/outbox table) to be idempotent so repeated calls do not create
duplicates and will return the created/existing IngestJobResult.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/outbox/poller/OutboxPoller.java`:
- Around line 60-61: The log prints the pre-update retry count because
transcodeOutbox.getRetryCount() is called before markAsFailed() updates it; call
markAsFailed() first and then log the updated value (either by re-reading
transcodeOutbox.getRetryCount() after markAsFailed() or by using the return
value from markAsFailed() if it returns the updated entity), ensuring the
log.warn that currently references transcodeOutbox.getId(),
transcodeOutbox.getRetryCount(), transcodeOutbox.getMaxRetries(), and
e.getMessage() uses the post-markAsFailed() retryCount.
- Around line 49-62: The outbox publish flow in OutboxPoller is not atomic:
rabbitTranscodePublisher.publish(...) may succeed while
outboxWriter.markAsPublished(...) fails, causing duplicate delivery; change the
flow so state update and publish are performed atomically — e.g., add a new
transactional operation in OutboxPoller that (1) obtains a DB lock or starts a
transaction for the TranscodeOutbox record, (2) marks the record as
“publishing”/reserved or updates a published flag in the same transaction, then
(3) calls rabbitTranscodePublisher.publish(...) and on successful publish
commits the transaction (or sets published=true), and on publish failure rolls
back or marks failed via outboxWriter.markAsFailed(...). Use/extend methods like
outboxWriter.markAsPublished, outboxWriter.markAsFailed, or introduce a new
outboxWriter.reserveForPublish/markPublishedTransactional helper and ensure
rabbitTranscodePublisher.publish is used with publisher confirms so publish
success is known before committing.

In
`@modules/domain/src/main/java/com/ott/domain/outbox/repository/TranscodeOutboxRepository.java`:
- Around line 13-14: The current repository query
findTop50ByOutboxStatusOrderByCreatedDateAsc(status) will keep returning old
failed items that remain PENDING (as set by TranscodeOutbox.markFailed),
blocking newer events; change the selection to only return items whose
nextAttemptAt is <= now (or null) so retries respect backoff, e.g. add a
condition on nextAttemptAt (or split into two queries: new PENDING items and
retryable PENDING items with nextAttemptAt <= now) and update the repository
method(s) accordingly so polling does not fetch records that are not yet
eligible for retry.

---

Outside diff comments:
In
`@apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormService.java`:
- Line 37: BackOfficeShortFormService has an unused RabbitTranscodePublisher
field; remove the private final RabbitTranscodePublisher transcodePublisher
declaration and any constructor parameter, assignment, or import related to
RabbitTranscodePublisher, leaving the service to call
writer.createIngestJobWithOutbox() in completeShortFormOriginUpload() only;
ensure no remaining references (field, constructor arg, or import) remain and
update any tests or usages that expect the publisher to be injected.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormWriter.java`:
- Around line 207-226: The pre-check using
ingestJobRepository.existsByMediaId(media.getId()) is racy and can allow
duplicate IngestJob/TranscodeOutbox creation; add a DB-level unique constraint
on ingest_job.media_id and change the save path (IngestJob.builder...
ingestJobRepository.save and subsequent transcodeOutboxRepository.save) to run
in a single transaction and catch the database unique-key exception (e.g.,
DataIntegrityViolationException / DuplicateKeyException) thrown by the IngestJob
save, converting it into a BusinessException(ErrorCode.ALREADY_INGESTED); ensure
the same defensive handling applies if the outbox insert can violate a unique
constraint so duplicates are mapped to ALREADY_INGESTED rather than creating
duplicate records.

---

Nitpick comments:
In
`@apps/api-admin/src/main/java/com/ott/api_admin/config/shedlock/ShedLockConfig.java`:
- Line 10: Remove the unused import javax.sql.DataSource from the ShedLockConfig
class; locate the import statement near the top of ShedLockConfig (the line
importing javax.sql.DataSource) and delete it or run your IDE's "organize
imports" to eliminate the unused import without changing any other code.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsWriter.java`:
- Around line 159-176: Compute the fileSize once into a local long variable
(e.g., long fileSize = (long) contents.getVideoSize() * 1024) and use that
variable in both the TranscodeOutbox.builder().fileSize(...) call and the
IngestJobResult(...) return so the duplicated expression using
contents.getVideoSize() is removed; update references in TranscodeOutbox, the
log call if needed, and the IngestJobResult to use the new fileSize variable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2e576be8-1915-4816-9903-fef688135d4c

📥 Commits

Reviewing files that changed from the base of the PR and between fb8a522 and a325c6b.

📒 Files selected for processing (12)
  • apps/api-admin/build.gradle
  • apps/api-admin/src/main/java/com/ott/api_admin/config/shedlock/ShedLockConfig.java
  • apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java
  • apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsWriter.java
  • apps/api-admin/src/main/java/com/ott/api_admin/outbox/poller/OutboxPoller.java
  • apps/api-admin/src/main/java/com/ott/api_admin/outbox/writer/OutboxWriter.java
  • apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormService.java
  • apps/api-admin/src/main/java/com/ott/api_admin/shortform/service/BackOfficeShortFormWriter.java
  • modules/domain/src/main/java/com/ott/domain/outbox/domain/OutboxStatus.java
  • modules/domain/src/main/java/com/ott/domain/outbox/domain/TranscodeOutbox.java
  • modules/domain/src/main/java/com/ott/domain/outbox/repository/TranscodeOutboxRepository.java
  • modules/infra-db/src/main/resources/db/migration/V12__transcode_outbox.sql

Comment thread apps/api-admin/build.gradle
Comment thread apps/api-admin/src/main/java/com/ott/api_admin/outbox/poller/OutboxPoller.java Outdated
Copy link
Copy Markdown
Collaborator

@marulog marulog left a comment

Choose a reason for hiding this comment

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

수고하셨습니다~

import javax.sql.DataSource;

@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "10m")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@EnableScheduling
이거 안 달아도 작동하나요?

Copy link
Copy Markdown
Contributor Author

@phonil phonil Mar 18, 2026

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.

🧹 Nitpick comments (1)
apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java (1)

34-34: 사용되지 않는 transcodePublisher 필드를 제거하세요.

아웃박스 패턴 도입으로 직접 publish 호출이 제거되었지만, RabbitTranscodePublisher transcodePublisher 필드는 여전히 주입되고 있습니다. 사용되지 않는 의존성이므로 제거해야 합니다.

♻️ 제안된 수정
 private final BackOfficeContentsReader reader;
 private final BackOfficeContentsWriter writer;
 private final UploadHelper uploadHelper;
-private final RabbitTranscodePublisher transcodePublisher;

또한 import 문도 제거:

-import com.ott.api_admin.publish.RabbitTranscodePublisher;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java`
at line 34, Remove the unused RabbitTranscodePublisher dependency: in
BackOfficeContentsService delete the private final RabbitTranscodePublisher
transcodePublisher field and its constructor/injection parameter (if present),
update any constructors or `@Autowired` usages accordingly, and remove the unused
import for RabbitTranscodePublisher so there are no dangling references or
unused imports left.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java`:
- Line 34: Remove the unused RabbitTranscodePublisher dependency: in
BackOfficeContentsService delete the private final RabbitTranscodePublisher
transcodePublisher field and its constructor/injection parameter (if present),
update any constructors or `@Autowired` usages accordingly, and remove the unused
import for RabbitTranscodePublisher so there are no dangling references or
unused imports left.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 33e4f07f-9efd-43f3-858f-78b8c4039a01

📥 Commits

Reviewing files that changed from the base of the PR and between a325c6b and 618690f.

📒 Files selected for processing (4)
  • apps/api-admin/src/main/java/com/ott/api_admin/ApiAdminApplication.java
  • apps/api-admin/src/main/java/com/ott/api_admin/config/shedlock/ShedLockConfig.java
  • apps/api-admin/src/main/java/com/ott/api_admin/content/service/BackOfficeContentsService.java
  • apps/api-admin/src/main/java/com/ott/api_admin/outbox/poller/OutboxPoller.java

@phonil phonil merged commit 2084f75 into develop Mar 18, 2026
1 check passed
@phonil phonil deleted the OT-335-feature/transcoding-outbox-pattern branch April 4, 2026 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 새로운 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[OT-335] [FEAT]: Outbox 패턴 도입

3 participants