Skip to content

[REFACTOR] MIDI 이벤트 저장 방식 수정#23

Open
on1yoneprivate wants to merge 12 commits into
developfrom
refactor/#21-embed-midi-data
Open

[REFACTOR] MIDI 이벤트 저장 방식 수정#23
on1yoneprivate wants to merge 12 commits into
developfrom
refactor/#21-embed-midi-data

Conversation

@on1yoneprivate

@on1yoneprivate on1yoneprivate commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

📍 개요

MIDI 이벤트 저장 구조를 Playing 엔티티의 JSONB 기반 저장 방식으로 변경

⛓️‍💥 관련 이슈


🛠️ 작업 내용

  • 기존 MidiEvent 엔티티 제거
  • MIDI 이벤트 저장용 MidiEventData 객체 구현
  • Playing 엔티티에 midiData JSONB 필드 추가
  • MIDI 이벤트 데이터를 Playing 엔티티에 종속하여 저장하도록 구조 변경
  • MIDI 이벤트 전체 목록 저장 및 timestamp 기준 정렬 로직 구현
  • MIDI 이벤트 입력값 및 목록 검증 로직 추가
  • MIDI 이벤트 관련 예외 코드 추가
  • Playing 엔티티의 불필요한 메트로놈 설정 필드 제거 (메트로놈은 항상 작동)

🔥 리뷰 요청 사항

리뷰어가 중점적으로 확인해주었으면 하는 내용을 작성해주세요.

  • MIDI 이벤트 전체 목록 저장 및 timestamp 기준 정렬 방식이 적절한지

✅ 체크리스트

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

📎 참고 사항

  • 연주 완료 후 [분석하기] 버튼 클릭 시 MIDI 데이터 전체를 저장합니다.
  • MIDI 데이터의 1초 단위 실시간 저장 방식은 MVP 이후 개발할 예정입니다.

Summary by CodeRabbit

  • 새 기능
    • 연주 기록에 MIDI 이벤트 데이터를 저장하고(동일 타임스탬프 내 순서 포함) 완료된 연주에서 조회할 수 있습니다.
  • 버그 수정
    • MIDI 이벤트가 비어 있거나 목록에 유효하지 않은 값이 포함된 경우, 명확한 오류를 안내합니다(타입/음/세기/타임스탬프/순서 검증 및 길이 기준으로 정리 포함).
  • 변경 사항
    • 자유 연주 및 반주 트랙 생성 시 메트로놈 설정 옵션이 제거되었습니다.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

MIDI 이벤트를 Playing 내부 JSONB 목록으로 저장하도록 확장하고, 동일 타임스탬프 내 순서를 나타내는 sequence 필드와 검증을 추가했다. 완료 처리에서는 이벤트 검증·필터링·정렬 후 재생 상태와 종료 정보를 갱신한다.

Changes

MIDI JSON 저장 및 완료 처리

Layer / File(s) Summary
MIDI 이벤트 계약
src/main/java/com/mr/domain/playing/entity/MidiEventData.java
MidiEventDatasequence JSON 필드와 팩토리 인자를 추가하고, null 및 음수 여부를 검증한다. 기존 MIDI 값과 타임스탬프 검증도 유지된다.
Playing 저장 모델 및 생성 계약
src/main/java/com/mr/domain/playing/entity/Playing.java
midiData를 JSONB와 빈 목록으로 초기화하고 metronomeEnabled 필드를 제거했다. @VersionUser·BackingTrack 연관관계를 추가했으며 생성 메서드 시그니처를 변경했다.
MIDI 완료 처리 및 오류 계약
src/main/java/com/mr/domain/playing/entity/Playing.java, src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java
completeWithMidiData가 입력값, 최대 개수, 중복 (timestampMs, sequence), 허용 시간 범위를 검증하고 이벤트를 정렬·저장한다. endedAt, durationSec, status를 갱신하며, 빈 목록과 잘못된 이벤트 오류 상태를 추가했다.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MidiEventData
  participant Playing
  participant JSONB
  Client->>MidiEventData: sequence 포함 MIDI 이벤트 생성
  MidiEventData-->>Client: 검증된 이벤트 반환
  Client->>Playing: completeWithMidiData(events)
  Playing->>Playing: 검증, 시간 필터링, 정렬
  Playing->>JSONB: midiData 저장
  Playing-->>Client: 완료 상태 및 MIDI 데이터 반환
Loading

Possibly related PRs

  • Musereview/BE#15: Playing의 생성 계약, 오류 코드 및 MIDI 도메인 구조와 직접 연결된다.
  • Musereview/BE#24: 변경된 createBackingTrack(...)이 받는 BackingTrack 타입과 직접 연결된다.

Poem

순서표를 단 MIDI 음표가
Playing 안에 모여들고
시간 따라 가지런히 흐르네
끝난 연주는 JSONB에 잠들고
작은 음표도 검증을 통과하네 🎵

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning version 추가와 User/BackingTrack 관계 재모델링은 MIDI 저장 리팩터 요구사항 밖의 변경으로 보입니다. MIDI 저장과 직접 관련 없는 엔티티 구조 변경은 별도 PR로 분리하거나, 현재 PR에 필요한 이유를 명확히 적어 주세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive JSON 저장과 검증 로직은 보이지만, MidiEvent 엔티티/Repository 제거와 테스트 수정은 제공된 요약만으로 확인되지 않습니다. MidiEvent 엔티티·Repository 삭제와 관련 테스트 변경이 실제로 반영됐는지 diff 요약을 추가로 제공해 주세요.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 MIDI 이벤트 저장 방식 변경이라는 핵심 변경을 짧고 명확하게 요약합니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/#21-embed-midi-data

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.

@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)
src/main/java/com/mr/domain/playing/entity/Playing.java (1)

164-172: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

대용량 MIDI 이벤트 데이터에 대한 제한(Limit) 검증을 고려해 보세요.

단일 연주(Playing) 전체를 한 번에 저장하는 구조라면 MIDI 이벤트가 매우 방대해질 수 있습니다. 이럴 경우 JSONB 컬럼을 메모리에서 직렬화/역직렬화하는 과정에서 애플리케이션의 메모리를 과도하게 점유하거나 OOM(Out of Memory)이 발생할 수 있습니다.

시스템 안정성을 위해 한 번에 저장할 수 있는 최대 이벤트 개수(예: 10,000개 등)를 제한하는 검증 로직을 추가해 보는 것은 어떨까요? 데이터가 폭주해도 끄떡없는 튼튼한 서버를 위해 고려해 볼 만한 훌륭한 방어 로직입니다! 💪

🛡️ 리미트 검증 추가 예시
    private static void validateMidiData(List<MidiEventData> midiData) {
        if (midiData == null || midiData.isEmpty()) {
            throw new GeneralException(PlayingErrorStatus.EMPTY_MIDI_EVENTS);
        }
+       
+       // TODO: MVP 이후 최대 허용 개수 초과 시 예외 처리 로직 추가 고려
+       // if (midiData.size() > MAX_MIDI_EVENTS) {
+       //     throw new GeneralException(PlayingErrorStatus.TOO_MANY_MIDI_EVENTS);
+       // }

        if (midiData.stream().anyMatch(Objects::isNull)) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/mr/domain/playing/entity/Playing.java` around lines 164 -
172, Update validateMidiData in Playing to reject MIDI event lists exceeding the
system’s defined maximum event count, using the existing validation
exception/status pattern. Preserve the current empty-list and null-event checks,
and reference an established limit constant or add a single named constant for
the maximum rather than embedding an unexplained literal.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/mr/domain/playing/entity/MidiEventData.java`:
- Around line 36-43: Update MidiEventData.create to be the Jackson
deserialization creator by adding `@JsonCreator` and explicit `@JsonProperty`
annotations for type, pitch, velocity, and timestampMs, ensuring JSON mapping
uses the existing validation path instead of the protected no-arg constructor.

---

Nitpick comments:
In `@src/main/java/com/mr/domain/playing/entity/Playing.java`:
- Around line 164-172: Update validateMidiData in Playing to reject MIDI event
lists exceeding the system’s defined maximum event count, using the existing
validation exception/status pattern. Preserve the current empty-list and
null-event checks, and reference an established limit constant or add a single
named constant for the maximum rather than embedding an unexplained literal.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8b1de69a-37de-4172-ac52-dcd7f33cfd7f

📥 Commits

Reviewing files that changed from the base of the PR and between 444519b and af1a11b.

📒 Files selected for processing (3)
  • src/main/java/com/mr/domain/playing/entity/MidiEventData.java
  • src/main/java/com/mr/domain/playing/entity/Playing.java
  • src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java

Comment thread src/main/java/com/mr/domain/playing/entity/MidiEventData.java Outdated

@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/domain/playing/entity/Playing.java Outdated
Comment thread src/main/java/com/mr/domain/playing/entity/Playing.java Outdated
Comment thread src/main/java/com/mr/domain/playing/entity/Playing.java
Comment thread src/main/java/com/mr/domain/playing/entity/Playing.java
Comment thread src/main/java/com/mr/domain/playing/entity/Playing.java
Comment thread src/main/java/com/mr/domain/playing/entity/Playing.java
Comment thread src/main/java/com/mr/domain/playing/entity/Playing.java Outdated
Comment on lines +27 to +28
validatePitch(pitch);
validateVelocity(velocity);

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.

MidiType을 지금 NOTE_ON, NOTE_OFF만 갖고 있는데 저희 MIDI 데이터를 요 정도만 받아도 되는 건지 궁금해요! (이건 PM님과 논의할 사안인 것 같지만....) 현재는 모든 타입에 pitch와 velocity를 필수로 검증하고 있어, 추후 페달이나 Control Change 이벤트까지 저장한다면 타입별 검증 또는 이벤트 모델 분리가 필요할 것 같아요!!

Comment thread src/main/java/com/mr/domain/playing/entity/MidiEventData.java
Comment thread src/main/java/com/mr/domain/playing/entity/MidiEventData.java
public void saveMidiData(List<MidiEventData> midiData) {
validateMidiData(midiData);

this.midiData = new ArrayList<>(midiData);

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.

midi 데이터를 저장할 때, 컬렉션 래퍼 참조가 끊기는 것을 방지하기 위해 this.midiData.clear(); 후 addAll() 방식으로 기존 컬렉션 객체를 유지하면서 갱신하는 방식은 어떤가요? 저도 비슷한 걸 찾아보다가 의견 어쭙습니다!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

현재 midiData는 JSON 컬럼에 매핑된 컬렉션이라 Hibernate 영속 컬렉션 래퍼를 유지해야 하는 상황은 아니라고 판단해서 기존 코드대로 ArrayList를 생성해 교체하는 방식을 유지하려고 합니다!
혹시 다른 의견 있으시면 말씀해 주세요

@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 (2)
src/main/java/com/mr/domain/playing/entity/Playing.java (2)

46-54: 🗄️ Data Integrity & Integration | 🔵 Trivial

신규 NOT NULL 컬럼(version, midi_data) 백필 전략 확인 필요.

기존 playing 테이블에 데이터가 있는 상태에서 nullable = falseversion, midi_data 컬럼을 추가하는 마이그레이션이라면, 기존 로우에 기본값(version=0, midi_data='[]')을 백필하는 스크립트가 함께 있는지 확인이 필요합니다. 마이그레이션 파일이 이번 리뷰 범위에 없어서 코드만으로는 확인이 어려운데요, 누락 시 배포 시점에 제약 조건 위반으로 실패할 수 있습니다.

Also applies to: 91-93

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/mr/domain/playing/entity/Playing.java` around lines 46 -
54, Update the migration that adds the Playing entity’s non-null version and
midi_data columns to backfill existing playing rows with version=0 and
midi_data='[]' before enforcing NOT NULL constraints. Ensure the migration is
safe for already-populated tables and applies to both columns.

174-201: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

validateMidiData 이중 호출 — 후반부 호출은 사실상 "필터 후 빈 리스트" 체크만 유효합니다.

sortedMidiData는 이미 null-free임이 보장된 원본에서 필터링만 한 결과라서, 재호출된 validateMidiData(sortedMidiData)의 null-check/size-limit 검증은 항상 통과하는 중복 연산입니다(최대 10만 건 순회가 한 번 더 발생). 의도(필터링으로 전부 제거된 경우 방어)는 좋지만, 전용 체크로 좁히면 가독성과 성능 모두 이득이에요.

♻️ 제안
-        List<MidiEventData> sortedMidiData = midiData.stream()
-                .filter(event -> event.getTimestampMs() <= allowedTimestampMs)
-                .sorted(Comparator.comparingLong(MidiEventData::getTimestampMs))
-                .toList();
-
-        validateMidiData(sortedMidiData);
+        List<MidiEventData> sortedMidiData = midiData.stream()
+                .filter(event -> event.getTimestampMs() <= allowedTimestampMs)
+                .sorted(Comparator.comparingLong(MidiEventData::getTimestampMs))
+                .toList();
+
+        if (sortedMidiData.isEmpty()) {
+            throw new GeneralException(PlayingErrorStatus.EMPTY_MIDI_EVENTS);
+        }

Also applies to: 213-225

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/mr/domain/playing/entity/Playing.java` around lines 174 -
201, In completeWithMidiData, replace the second
validateMidiData(sortedMidiData) call with a focused check for the filtered
result being empty, preserving the intended guard when all events exceed
allowedTimestampMs. Keep the initial validateMidiData(midiData) validation and
the subsequent sorting and completion logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/mr/domain/playing/entity/Playing.java`:
- Around line 184-191: Update the MIDI event filtering flow in Playing so events
with timestamps above allowedTimestampMs are counted and the number of dropped
events is logged at WARN or INFO level. Preserve the existing timestamp boundary
and sorting behavior for retained events.

---

Nitpick comments:
In `@src/main/java/com/mr/domain/playing/entity/Playing.java`:
- Around line 46-54: Update the migration that adds the Playing entity’s
non-null version and midi_data columns to backfill existing playing rows with
version=0 and midi_data='[]' before enforcing NOT NULL constraints. Ensure the
migration is safe for already-populated tables and applies to both columns.
- Around line 174-201: In completeWithMidiData, replace the second
validateMidiData(sortedMidiData) call with a focused check for the filtered
result being empty, preserving the intended guard when all events exceed
allowedTimestampMs. Keep the initial validateMidiData(midiData) validation and
the subsequent sorting and completion logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 872403ff-2719-4a40-8b54-ff7543cad22e

📥 Commits

Reviewing files that changed from the base of the PR and between 8b3808b and 119a6df.

📒 Files selected for processing (2)
  • src/main/java/com/mr/domain/playing/entity/Playing.java
  • src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java

Comment on lines +184 to +191
// 실제 연주 허용 시간 = min(실제 연주 시간, 10분) + 오차 범위(500ms)
long allowedTimestampMs = Math.min(savedDurationMs + MIDI_TIMESTAMP_TOLERANCE_MS,
MAX_DURATION_MS);

List<MidiEventData> sortedMidiData = midiData.stream()
.filter(event -> event.getTimestampMs() <= allowedTimestampMs)
.sorted(Comparator.comparingLong(MidiEventData::getTimestampMs))
.toList();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

허용 시간 범위를 벗어난 MIDI 이벤트가 조용히 삭제됩니다.

allowedTimestampMs를 초과하는 이벤트를 아무 로그 없이 필터링해서 버리고 있어요. 악의적/오차 있는 타임스탬프를 방어하는 목적 자체는 타당하지만, 클라이언트 타이머 버그로 다수 이벤트가 매번 조용히 잘려나가는 상황을 운영 중에 알아채기 어렵습니다. 최소한 드롭된 이벤트 수를 로그(WARN/INFO)로 남기면 추후 분석 결과 품질 이슈를 추적하기 훨씬 쉬워질 거예요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/mr/domain/playing/entity/Playing.java` around lines 184 -
191, Update the MIDI event filtering flow in Playing so events with timestamps
above allowedTimestampMs are counted and the number of dropped events is logged
at WARN or INFO level. Preserve the existing timestamp boundary and sorting
behavior for retained events.

Comment thread src/main/java/com/mr/domain/playing/entity/Playing.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/playing/entity/Playing.java Outdated

@p1001q p1001q 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.

답변 주신 부분 이해 됐습니다!!
저랑 저의 클로드가 봤을 땐 문제가 없어보입니다... 타지에서 고생 많으셨어용
은우님이 마지막으로 수정사항 보시고 머지해주심 될 거 같습니다!

@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.

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/mr/domain/playing/entity/Playing.java (1)

98-100: 🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

대용량 midiData 조회 경로를 분리해 주세요.

Playing 엔티티에 JSONB midiData 필드가 기본 속성으로 매핑되어 있어, 목록/상세 조회마다 필요하지 않은 대용량 MIDI 이벤트를 함께 읽고 역직렬화할 수 있습니다. MIDI 분석 전용 조회·프로젝션 또는 별도 저장 구조로 분리하고; Hibernate bytecode enhancement를 통해 기본 필드도 lazy fetch로 처리하려면 Spring Boot bytecode enhancement 설정이 실제로 적용되는지 추가 검증이 필요합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/mr/domain/playing/entity/Playing.java` around lines 98 -
100, Playing 엔티티의 기본 midiData 매핑으로 목록·상세 조회 시 대용량 JSONB가 함께 로드되지 않도록 조회 경로를
분리하세요. MIDI 분석에 필요한 전용 조회·프로젝션 또는 별도 저장 구조를 도입하고, midiData를 lazy fetch에 의존한다면
Hibernate bytecode enhancement 설정이 실제 적용되는지도 검증하세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/main/java/com/mr/domain/playing/entity/Playing.java`:
- Around line 98-100: Playing 엔티티의 기본 midiData 매핑으로 목록·상세 조회 시 대용량 JSONB가 함께
로드되지 않도록 조회 경로를 분리하세요. MIDI 분석에 필요한 전용 조회·프로젝션 또는 별도 저장 구조를 도입하고, midiData를 lazy
fetch에 의존한다면 Hibernate bytecode enhancement 설정이 실제 적용되는지도 검증하세요.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0449f6a9-80ea-463c-9a3f-f77112cea6f8

📥 Commits

Reviewing files that changed from the base of the PR and between 126ebe5 and 615fc67.

📒 Files selected for processing (1)
  • src/main/java/com/mr/domain/playing/entity/Playing.java

@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.

수고하셨습니다!

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.

♻️ Refactor - MIDI 이벤트 저장 방식 수정

4 participants