Skip to content

[FIX] 학습 모범 연주 S3 재생 오류 수정 - #227

Merged
p1001q merged 8 commits into
developfrom
fix/#168-learning-example-s3-cleanup
Aug 13, 2026
Merged

[FIX] 학습 모범 연주 S3 재생 오류 수정#227
p1001q merged 8 commits into
developfrom
fix/#168-learning-example-s3-cleanup

Conversation

@p1001q

@p1001q p1001q commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

📍 개요

비공개 S3에 저장된 학습 모범 연주 MP3의 원본 URL을 API가 그대로 반환하여 브라우저에서 403 AccessDenied가 발생하던 문제를 수정합니다.
DB에는 S3 Object Key만 저장하고, 단계별 학습 상세 조회 시 10분 동안 유효한 Presigned GET URL을 발급하도록 정리했습니다.

⛓️‍💥 관련 이슈


🛠️ 작업 내용

반영한 작업

구분 반영 내용
재생 오류 수정 LearningService가 모범 연주 Object Key로 Presigned GET URL을 발급하여 응답하도록 변경
저장 기준 정리 PlayingExample.audioFileUrlaudioObjectKey로 변경하고 DB 컬럼도 audio_object_key로 전환
데이터 마이그레이션 Flyway V9에서 기존 S3 URL을 playing_example/... Object Key로 변환하고, 잘못된 값은 배포 중 즉시 감지하도록 검증 추가
S3 공용 콘텐츠 지원 소유자 없는 공용 학습 콘텐츠용 다운로드 경로를 추가하고 PLAYING_EXAMPLE 파일 유형을 정의
보안 회귀 방지 RECORDING, BACKING_TRACK처럼 사용자 소유권 검증이 필요한 파일은 공용 다운로드 경로로 우회할 수 없도록 차단
응답/명세 정리 DTO가 저장값을 URL로 오인하지 않고 서비스가 생성한 URL을 받도록 변경하고 Swagger에 10분 유효 Presigned URL임을 명시
주석 정리 동작을 그대로 번역하는 주석은 제거하고, 소유권 경계·검증 의도처럼 코드만으로 드러나지 않는 이유만 남김

이번 PR에서 의도적으로 유지·제외한 작업

항목 결정 이유
학습 진행률 단일 조회 API 삭제 유지 현재 FE StepLearningPlayPage에서 실제 호출 중이므로 죽은 코드로 단정할 수 없음. FE 호출 전환과 함께 별도 리팩토링 필요
FE 코드 수정 제외 이번 오류는 BE가 재생 가능한 Presigned URL을 내려주는 것으로 해결되며, FE 계약 변경은 필요하지 않음
정적 ERD 원본(sql/png/xlsx) 수동 동기화 제외 런타임 DB 변경은 Flyway V9에 포함했지만, 정적 설계 자료 대조·갱신은 사용자 확인 후 별도 작업으로 분리
기존 학습·진행률 로직 변경 제외 긴급한 MP3 재생 오류와 S3 저장 경계만 보수적으로 수정하고, 무관한 비즈니스 로직은 건드리지 않음

🔥 리뷰 요청 사항

  • Flyway V9이 운영 DB의 기존 audio_file_url 값을 안전하게 Object Key로 변환하는지 확인 부탁드립니다.
  • S3FileType.ownerScoped로 사용자 소유 파일과 공용 학습 콘텐츠의 다운로드 경계를 나눈 방식이 적절한지 확인 부탁드립니다.
  • 공용 다운로드 메서드에서 소유권이 필요한 파일 유형을 fail-fast로 차단하는 조건을 중점적으로 봐주세요.
  • 학습 상세 조회 시에만 Presigned URL을 생성하고 DTO에는 최종 응답값만 전달하는 책임 분리가 적절한지 확인 부탁드립니다.

✅ 체크리스트

  • 코드 컨벤션을 준수했습니다.
  • 불필요한 코드 및 import를 제거했습니다.
  • 예외 처리를 적용했습니다.
  • 테스트를 완료했습니다.
  • 관련 Issue를 연결했습니다.

검증 결과

  • AWS 콘솔에서 playing_example/triads_step1.mp3 등 실제 객체 존재 및 직접 열기 재생 확인
  • 로컬 단계별 학습 상세 API가 Presigned URL을 반환하는 것 확인
  • 발급 URL의 Range 요청이 206 Partial Content, audio/mp3, ID3 헤더를 반환하는 것 확인
  • PostgreSQL에서 Flyway V9의 URL 변환, 기존 Object Key 유지, 쿼리스트링 제거, 잘못된 prefix 차단 확인
  • 전체 448개 테스트 성공 및 clean build 통과
  • git diff --check 통과

📎 참고 사항

  • S3 버킷의 퍼블릭 액세스 차단은 그대로 유지합니다.
  • 운영 반영 시 애플리케이션 IAM 자격 증명에 대상 객체의 GetObject 권한이 있어야 합니다.
  • Flyway V9 검증에서 잘못된 기존 데이터가 발견되면 조용히 잘못 변환하지 않고 마이그레이션을 중단하도록 했습니다.
  • Draft PR로 먼저 올려 최신 develop 기준 CI와 리뷰를 확인한 뒤 Ready 상태로 전환합니다.

쉽게 비유하면

비공개 S3는 잠긴 음원 창고입니다. 기존 API는 사용자에게 창고 주소와 선반 위치만 알려주고 열쇠는 주지 않은 셈이라, 파일이 실제로 있어도 입구에서 AccessDenied가 발생했습니다.

이번 수정은 DB에 **선반 번호(Object Key)**만 기록하고, 사용자가 재생을 요청할 때 서버가 **10분짜리 임시 출입증(Presigned URL)**을 발급하는 방식입니다. 창고 전체를 공개하지 않으면서도 해당 음원만 안전하게 들을 수 있습니다. Flyway V9은 장부에 적힌 예전 전체 주소를 선반 번호로 바꾸는 장부 정리 작업이고, 이상한 주소가 나오면 잘못 배송하지 않도록 작업을 멈춥니다.

진행률 단일 조회 API는 다른 조회 응답과 역할이 겹쳐 보여도, 현재 프론트 화면에 아직 연결된 사용 중인 구형 인터폰과 같습니다. 새 인터폰이 같은 내용을 알려준다고 해서 먼저 선을 뽑으면 현재 화면이 고장 날 수 있으므로, 이번에는 유지하고 FE 전환과 함께 별도로 정리하기로 했습니다.

정적 ERD 문서는 건물 도면에 해당합니다. 이번 PR에는 실제 배관을 바꾸는 Flyway V9까지 포함했지만, 도면 원본의 수동 대조·수정은 별도 확인 작업으로 남겼습니다.

Summary by CodeRabbit

  • 새로운 기능

    • 학습 단계 상세 조회 시 모범 연주 음원의 안전한 Presigned GET URL을 제공합니다.
    • 음원이 없는 모범 연주에는 오디오 URL을 제공하지 않습니다.
  • 개선 사항

    • 음원 정보가 안전한 저장소 객체 기준으로 관리됩니다.
    • 음원 경로와 파일 유형에 대한 검증이 강화되었습니다.
    • 기존 음원 데이터가 새로운 형식으로 자동 변환됩니다.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e1752a0b-3cfc-4609-8d0e-2d00e59170f7

📥 Commits

Reviewing files that changed from the base of the PR and between 02c78a5 and 02690d5.

📒 Files selected for processing (4)
  • src/main/java/com/mr/domain/learning/dto/res/LearningStepDetailResponseDTO.java
  • src/main/java/com/mr/global/file/s3/service/S3FileService.java
  • src/main/resources/db/migration/V9__migrate_playing_example_audio_file_url_to_object_key.sql
  • src/test/java/com/mr/global/file/s3/service/S3FileServiceTest.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/resources/db/migration/V9__migrate_playing_example_audio_file_url_to_object_key.sql
  • src/main/java/com/mr/domain/learning/dto/res/LearningStepDetailResponseDTO.java

📝 Walkthrough

Walkthrough

학습 모범 연주의 저장값을 S3 Object Key로 변경합니다. 공용 콘텐츠용 Presigned GET URL 발급과 Object Key 검증을 추가합니다. 학습 단계 상세 API는 생성된 URL을 반환하며, 마이그레이션과 테스트를 갱신합니다.

Changes

학습 모범 연주 Presigned URL 전환

Layer / File(s) Summary
PlayingExample 저장 구조와 데이터 마이그레이션
src/main/java/com/mr/domain/learning/entity/PlayingExample.java, src/main/resources/db/migration/V9__migrate_playing_example_audio_file_url_to_object_key.sql
audioFileUrl 필드를 audioObjectKey로 변경합니다. 기존 URL에서 Object Key를 추출하고 형식을 검증합니다.
공용 S3 Object Key 검증과 Presigned URL 발급
src/main/java/com/mr/global/file/s3/enums/S3FileType.java, src/main/java/com/mr/global/file/s3/service/S3FileService.java, src/main/java/com/mr/global/file/s3/service/S3ObjectKeyGenerator.java, src/test/java/com/mr/global/file/s3/service/*
PLAYING_EXAMPLE 유형을 추가합니다. 공용 Object Key의 prefix를 검증하고 Presigned GET URL을 발급합니다. 사용자 소유 경로에서 공용 콘텐츠와 소유자 전용 유형을 거부합니다.
학습 단계 상세 응답 통합
src/main/java/com/mr/domain/learning/service/LearningService.java, src/main/java/com/mr/domain/learning/dto/res/LearningStepDetailResponseDTO.java, src/main/java/com/mr/domain/learning/controller/LearningController.java, src/test/java/com/mr/domain/learning/service/LearningServiceTest.java
학습 단계 상세 조회가 모범 연주 Object Key로 URL을 생성합니다. 생성된 URL을 modelPerformance.audioUrl에 전달합니다. 모범 연주가 없으면 URL을 생성하지 않고 null을 반환합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Mergeability Score: ⚪ Minimal · up to 02690

The PR changes private learning audio delivery to use presigned URLs and updates stored object-key handling; no actionable merge-blocking risk remains based on the supplied evidence.

Possibly related PRs

  • Musereview/BE#188: 다른 오디오 도메인에 Object Key 저장과 Presigned GET URL 방식을 적용했습니다.
  • Musereview/BE#159: S3FileService의 Presigned GET URL 발급 흐름을 추가했습니다.
  • Musereview/BE#166: 녹음 파일에 동일한 S3 Object Key 전환 패턴을 적용했습니다.

Poem

Object Key에 담긴 연주,
Presigned URL이 문을 열고,
잠긴 버킷 너머로
단계 상세에 음악이 흐릅니다. 🎵

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning S3 Object Key 전환과 Presigned URL 발급은 충족했지만, 진행률 회귀 검증과 ERD·DB 매핑 문서 동기화 요구사항은 충족되지 않았습니다. 진행률 API의 기존 응답·동작 회귀 테스트를 추가하고, playing_example Object Key 기준의 ERD·DB 매핑 문서를 동기화하세요.
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 (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 학습 모범 연주의 S3 재생 오류 수정이라는 PR의 핵심 변경을 정확하고 간결하게 설명합니다.
Out of Scope Changes check ✅ Passed 변경 사항은 모범 연주 S3 URL 전환, Object Key 마이그레이션, 공용 콘텐츠 검증 및 관련 테스트 범위에 포함됩니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/#168-learning-example-s3-cleanup

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.

@p1001q p1001q self-assigned this Aug 12, 2026
@p1001q
p1001q marked this pull request as ready for review August 12, 2026 12:30
@p1001q
p1001q requested a review from on1yoneprivate August 12, 2026 12:30

@ownue ownue left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

확인 부탁드립니땅

Comment thread src/main/java/com/mr/global/file/s3/service/S3FileService.java

@rkdehdrbs7885-oss rkdehdrbs7885-oss left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

수고하셨습니다!

Comment thread src/main/java/com/mr/domain/learning/dto/res/LearningStepDetailResponseDTO.java Outdated

@on1yoneprivate on1yoneprivate left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

사소한 코멘트라서 편한 대로 유지/수정하면 될 듯!! 수고하셨습니다~~

@p1001q
p1001q merged commit 274de8e into develop Aug 13, 2026
2 checks passed
@kimyw1018
kimyw1018 deleted the fix/#168-learning-example-s3-cleanup branch August 14, 2026 00:35
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.

🐛 BugFix & ♻️ Refactor - 학습 모범 연주 S3 재생 오류 수정 및 Learning 도메인 정리

4 participants