[Refactor/#153] 멤버 선택 바텀시트 리팩토링 - #154
Conversation
|
Warning Review limit reached
Next review available in: 50 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough인덱스 기반 멤버 선택을 Member 객체 기반으로 변경하여 계약, ViewModel 상태 로직, Screen 호출을 갱신하고 기존 core designsystem 바텀시트 구현을 제거했습니다. ChangesMember 객체 기반 선택 처리로 전환
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Screen as ProductPartyListScreen
participant ViewModel as ProductPartyListViewModel
participant State as ProductPartyListUiState
Screen->>ViewModel: OnMemberSelect(member: Member)
ViewModel->>ViewModel: onBottomSheetMemberChanged(member)
ViewModel->>State: bottomSheetSelectedMembers 토글 업데이트
Screen->>ViewModel: 멤버 필터 갱신
ViewModel->>State: 선택 멤버 기준 displayMembers 갱신
Screen->>ViewModel: 멤버 선택 저장
ViewModel->>State: selectedMembers 갱신
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListScreen.kt (1)
149-149: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
LazyColumnitems에key파라미터 추가를 권장합니다.
items(productPartyListInfo.partySummaries)에key파라미터가 누락되어 있습니다. 리스트 아이템이 추가/삭제/재정렬될 때 Compose가 각 아이템을 식별하지 못하면 불필요한 리컴포지션이 발생할 수 있습니다.파티 목록은 필터링/정렬로 인해 순서가 바뀔 수 있으므로,
partyId를 key로 사용하는 것이 좋습니다.♻️ key 파라미터 추가 예시
-items(productPartyListInfo.partySummaries) { party -> +items( + items = productPartyListInfo.partySummaries, + key = { it.partyId } +) { party -> PartyCard(코딩 가이드라인에 따르면,
LazyColumn등 리스트에서key파라미터 누락 여부를 확인하여 불필요한 리컴포지션을 방지하도록 권장하고 있습니다.🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListScreen.kt` at line 149, The LazyColumn items call in ProductPartyListScreen is missing a stable key, so update the items(productPartyListInfo.partySummaries) { party -> ... } invocation to include a key parameter that uses the party's stable identifier (e.g., items(productPartyListInfo.partySummaries, key = { it.partyId }) { party -> ... }) to prevent unnecessary recompositions when the list is filtered, sorted, or items are added/removed.Source: Coding guidelines
🧹 Nitpick comments (4)
app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt (2)
153-156: ⚡ Quick win멤버 토글 로직의 성능을 개선할 수 있습니다.
member in selectedMembers체크가 List에서 O(n) 시간이 소요됩니다. 멤버가 많아질수록 성능 저하가 발생할 수 있습니다.Line 23에서
bottomSheetSelectedMembers를Set<Member>로 변경하면 이 체크가 O(1)이 되어 성능이 개선됩니다.현재는 List의
+/-연산자를 사용하여 불변성을 잘 유지하고 있습니다만, Set을 사용해도 동일한 연산자로 불변성을 유지할 수 있습니다.♻️ Set 사용 시 코드 변경 (참고)
private fun onBottomSheetMemberChanged(member: Member) { val selectedMembers = uiState.value.bottomSheetSelectedMembers - val newSelectedMembers = if (member in selectedMembers) selectedMembers - member else selectedMembers + member + val newSelectedMembers = if (member in selectedMembers) selectedMembers - member else selectedMembers + member updateState { copy(bottomSheetSelectedMembers = newSelectedMembers, isMemberBottomSheetToucehd = true) } }Set도
+/-연산자를 지원하므로 로직 변경 없이 타입만 바꾸면 됩니다.🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt` around lines 153 - 156, Change the type of bottomSheetSelectedMembers from List<Member> to Set<Member> in the UI state/data class so membership checks become O(1); no logic changes are required in onBottomSheetMemberChanged (which uses "member in bottomSheetSelectedMembers" and "+"/"-" to produce newSelectedMembers and calls updateState { copy(bottomSheetSelectedMembers = newSelectedMembers, isMemberBottomSheetToucehd = true) }) because Set also supports + and - and preserves immutability.
146-146: ⚡ Quick win멤버 필터링 성능을 개선할 수 있습니다.
displayMembers.filter { it in bottomSheetSelectedMembers }는bottomSheetSelectedMembers가List일 경우 각 요소마다 O(n) 탐색이 발생하여 전체 O(n²) 복잡도를 가집니다.두 가지 개선 방안이 있습니다:
bottomSheetSelectedMembers를Set으로 변경 (Line 23 참고)- 임시로 Set으로 변환하여 필터링
멤버 수가 적다면 큰 문제는 아니지만, 확장성을 고려하면 개선하는 것이 좋습니다.
♻️ 성능 개선 방안
방안 1: State를 Set으로 변경한 경우 (권장)
-val newSelectedMembers = uiState.value.displayMembers.filter { it in uiState.value.bottomSheetSelectedMembers } +val newSelectedMembers = uiState.value.displayMembers.filter { it in uiState.value.bottomSheetSelectedMembers }변경 없이 자동으로 O(n) 성능 확보됩니다.
방안 2: List를 유지해야 하는 경우
-val newSelectedMembers = uiState.value.displayMembers.filter { it in uiState.value.bottomSheetSelectedMembers } +val selectedSet = uiState.value.bottomSheetSelectedMembers.toSet() +val newSelectedMembers = uiState.value.displayMembers.filter { it in selectedSet }🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt` at line 146, The current filtering in ProductPartyListViewModel (val newSelectedMembers = uiState.value.displayMembers.filter { it in uiState.value.bottomSheetSelectedMembers }) is O(n²) when bottomSheetSelectedMembers is a List; fix by making bottomSheetSelectedMembers a Set in state (see the state declaration around line 23) so the membership test is O(1), or if you must keep it as a List, convert it once to a Set before filtering (e.g., val selectedSet = uiState.value.bottomSheetSelectedMembers.toSet(); val newSelectedMembers = uiState.value.displayMembers.filter { it in selectedSet }) to ensure O(n) overall.app/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt (2)
23-23: ⚡ Quick win선택 멤버 저장에
Set<Member>를 고려해보세요.
bottomSheetSelectedMembers를List<Member>로 선언하셨는데, 멤버 선택은 중복이 불필요하고 순서가 중요하지 않은 경우가 많습니다.Set<Member>를 사용하면 다음과 같은 이점이 있습니다:
- 중복 방지가 자동으로 보장됩니다
- ViewModel에서
member in selectedMembers체크 시 List는 O(n)이지만 Set은 O(1)입니다 (Line 155에서 성능 개선)- 의도가 명확해집니다 (선택된 멤버의 집합)
다만 UI에서 선택 순서를 표시해야 한다면 List가 적절할 수 있으니, 요구사항을 확인해주세요.
♻️ Set으로 변경 시 제안 diff
- val bottomSheetSelectedMembers: List<Member> = emptyList(), + val bottomSheetSelectedMembers: Set<Member> = emptySet(),이 경우 ViewModel의 Line 142, 155도 함께 수정이 필요합니다.
🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt` at line 23, Change bottomSheetSelectedMembers from List<Member> to Set<Member> (e.g., val bottomSheetSelectedMembers: Set<Member> = emptySet()) to prevent duplicates and make membership checks O(1); then update the ViewModel usages that manipulate or query this collection (places that add/remove members and checks like "member in selectedMembers") to use Set semantics (use toMutableSet() when mutating, add/remove on the mutable set, and assign back as an immutable Set) and ensure any UI code that depends on ordering is adjusted or retained as a separate ordered list if needed.
13-25: ⚡ Quick winCompose 안정성을 위해
@Immutable어노테이션 추가를 고려해주세요.
ProductPartyListUiState가List<Member>등 복잡한 타입을 포함하고 있습니다. Compose 컴파일러가 이 클래스의 안정성을 추론하지 못하면 불필요한 리컴포지션이 발생할 수 있습니다.
Member와ProductPartyList가 모두 불변 타입이라면@Immutable어노테이션을 추가하여 Compose에게 안정성을 명시적으로 알려주는 것이 좋습니다.♻️ 안정성 어노테이션 추가 예시
+import androidx.compose.runtime.Immutable + +@Immutable data class ProductPartyListUiState( val productPartyListInfo: ApiState<ProductPartyList> = ApiState.Loading,단,
Member와ProductPartyList도 모두 불변이어야 합니다. 그렇지 않다면@Stable사용을 고려해주세요.코딩 가이드라인에 따르면, List나 일반 클래스를 State로 사용할 때 불필요한 리컴포지션을 막기 위해
@Immutable이나@Stable어노테이션 사용을 권장합니다.🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt` around lines 13 - 25, Add a Compose stability annotation to the ProductPartyListUiState data class: if Member and ProductPartyList are immutable, annotate ProductPartyListUiState with `@Immutable`; if those types are not fully immutable, annotate with `@Stable` instead. Verify and, if necessary, make Member and ProductPartyList immutable (or adjust their annotations) so the chosen annotation on ProductPartyListUiState is correct, then import androidx.compose.runtime.Immutable or Stable and apply it above the ProductPartyListUiState declaration.Source: Coding guidelines
🤖 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
`@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListScreen.kt`:
- Line 149: The LazyColumn items call in ProductPartyListScreen is missing a
stable key, so update the items(productPartyListInfo.partySummaries) { party ->
... } invocation to include a key parameter that uses the party's stable
identifier (e.g., items(productPartyListInfo.partySummaries, key = { it.partyId
}) { party -> ... }) to prevent unnecessary recompositions when the list is
filtered, sorted, or items are added/removed.
---
Nitpick comments:
In
`@app/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt`:
- Line 23: Change bottomSheetSelectedMembers from List<Member> to Set<Member>
(e.g., val bottomSheetSelectedMembers: Set<Member> = emptySet()) to prevent
duplicates and make membership checks O(1); then update the ViewModel usages
that manipulate or query this collection (places that add/remove members and
checks like "member in selectedMembers") to use Set semantics (use
toMutableSet() when mutating, add/remove on the mutable set, and assign back as
an immutable Set) and ensure any UI code that depends on ordering is adjusted or
retained as a separate ordered list if needed.
- Around line 13-25: Add a Compose stability annotation to the
ProductPartyListUiState data class: if Member and ProductPartyList are
immutable, annotate ProductPartyListUiState with `@Immutable`; if those types are
not fully immutable, annotate with `@Stable` instead. Verify and, if necessary,
make Member and ProductPartyList immutable (or adjust their annotations) so the
chosen annotation on ProductPartyListUiState is correct, then import
androidx.compose.runtime.Immutable or Stable and apply it above the
ProductPartyListUiState declaration.
In
`@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt`:
- Around line 153-156: Change the type of bottomSheetSelectedMembers from
List<Member> to Set<Member> in the UI state/data class so membership checks
become O(1); no logic changes are required in onBottomSheetMemberChanged (which
uses "member in bottomSheetSelectedMembers" and "+"/"-" to produce
newSelectedMembers and calls updateState { copy(bottomSheetSelectedMembers =
newSelectedMembers, isMemberBottomSheetToucehd = true) }) because Set also
supports + and - and preserves immutability.
- Line 146: The current filtering in ProductPartyListViewModel (val
newSelectedMembers = uiState.value.displayMembers.filter { it in
uiState.value.bottomSheetSelectedMembers }) is O(n²) when
bottomSheetSelectedMembers is a List; fix by making bottomSheetSelectedMembers a
Set in state (see the state declaration around line 23) so the membership test
is O(1), or if you must keep it as a List, convert it once to a Set before
filtering (e.g., val selectedSet =
uiState.value.bottomSheetSelectedMembers.toSet(); val newSelectedMembers =
uiState.value.displayMembers.filter { it in selectedSet }) to ensure O(n)
overall.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 853cffab-feae-4594-9723-24820e07cb0e
📒 Files selected for processing (4)
app/src/main/java/com/poti/android/core/designsystem/component/bottomsheet/MemberSelectBottomSheet.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListScreen.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt
💤 Files with no reviewable changes (1)
- app/src/main/java/com/poti/android/core/designsystem/component/bottomsheet/MemberSelectBottomSheet.kt
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt (2)
153-156: ⚡ Quick win멤버십 체크 성능 개선을 권장해요.
List에 대해in연산자를 사용하면 O(n) 선형 탐색이 발생합니다.toSet()으로 변환하여 O(1) 조회를 하는 것이 더 효율적이에요.♻️ 제안하는 개선 방법
private fun onBottomSheetMemberChanged(member: Member) { val selectedMembers = uiState.value.bottomSheetSelectedMembers - val newSelectedMembers = if (member in selectedMembers) selectedMembers - member else selectedMembers + member + val selectedMembersSet = selectedMembers.toSet() + val newSelectedMembers = if (member in selectedMembersSet) { + selectedMembers - member + } else { + selectedMembers + member + } updateState { copy(bottomSheetSelectedMembers = newSelectedMembers, isMemberBottomSheetToucehd = true) } }🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt` around lines 153 - 156, The membership check in onBottomSheetMemberChanged currently uses "member in selectedMembers" on a List (uiState.value.bottomSheetSelectedMembers) causing O(n) checks; change the implementation to perform the containment test on a Set (e.g., val selectedSet = selectedMembers.toMutableSet()), then add or remove the member on that set and convert back to the List type expected by uiState (e.g., newSelectedMembers = selectedSet.toList()) before calling updateState { copy(bottomSheetSelectedMembers = newSelectedMembers, isMemberBottomSheetToucehd = true) }; alternatively, if bottomSheetSelectedMembers can be changed to a Set at the state level, update the state type and use constant-time contains/add/remove on that Set in onBottomSheetMemberChanged.
146-146: ⚡ Quick win멤버십 체크 성능 개선을 권장해요.
List에 대해in연산자를 사용하면 O(n) 선형 탐색이 발생합니다. 멤버 리스트가 일반적으로 작긴 하지만,toSet()으로 변환하여 O(1) 조회를 하는 것이 Kotlin 모범 사례예요.♻️ 제안하는 개선 방법
private fun saveSelectedMember() { - val newSelectedMembers = uiState.value.displayMembers.filter { it in uiState.value.bottomSheetSelectedMembers } + val selectedMembersSet = uiState.value.bottomSheetSelectedMembers.toSet() + val newSelectedMembers = uiState.value.displayMembers.filter { it in selectedMembersSet } updateState { copy(selectedMembers = newSelectedMembers) }🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt` at line 146, The filter uses "in" against a List causing O(n^2) behavior when checking membership; convert the membership collection to a Set first and use that for O(1) lookups. For example, in the ProductPartyListViewModel where newSelectedMembers is computed, build a Set from uiState.value.bottomSheetSelectedMembers (e.g., val selectedSet = uiState.value.bottomSheetSelectedMembers.toSet()) and then use uiState.value.displayMembers.filter { it in selectedSet } so membership checks are O(1).
🤖 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.
Nitpick comments:
In
`@app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt`:
- Around line 153-156: The membership check in onBottomSheetMemberChanged
currently uses "member in selectedMembers" on a List
(uiState.value.bottomSheetSelectedMembers) causing O(n) checks; change the
implementation to perform the containment test on a Set (e.g., val selectedSet =
selectedMembers.toMutableSet()), then add or remove the member on that set and
convert back to the List type expected by uiState (e.g., newSelectedMembers =
selectedSet.toList()) before calling updateState {
copy(bottomSheetSelectedMembers = newSelectedMembers, isMemberBottomSheetToucehd
= true) }; alternatively, if bottomSheetSelectedMembers can be changed to a Set
at the state level, update the state type and use constant-time
contains/add/remove on that Set in onBottomSheetMemberChanged.
- Line 146: The filter uses "in" against a List causing O(n^2) behavior when
checking membership; convert the membership collection to a Set first and use
that for O(1) lookups. For example, in the ProductPartyListViewModel where
newSelectedMembers is computed, build a Set from
uiState.value.bottomSheetSelectedMembers (e.g., val selectedSet =
uiState.value.bottomSheetSelectedMembers.toSet()) and then use
uiState.value.displayMembers.filter { it in selectedSet } so membership checks
are O(1).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: bf196957-560f-4669-b8f8-17f9cb039ca8
📒 Files selected for processing (4)
app/src/main/java/com/poti/android/core/designsystem/component/bottomsheet/MemberSelectBottomSheet.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListScreen.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt
💤 Files with no reviewable changes (1)
- app/src/main/java/com/poti/android/core/designsystem/component/bottomsheet/MemberSelectBottomSheet.kt
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt (1)
26-26: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winCompose 상태의 컬렉션 안정성을 보장해 주세요.
이번 변경으로
UiState에 일반List<Member>가 추가되었습니다. Compose에서List는 불안정 타입으로 판단될 수 있어, 바텀시트 선택 상태가 변경될 때 관련 UI에 불필요한 리컴포지션이 발생할 수 있습니다. 프로젝트에서 지원한다면ImmutableList<Member>와persistentListOf()를 사용하거나,Member및 컬렉션의 불변성을 보장하는 안정적인 래퍼를 적용해 주세요.As per path instructions, List나 일반 클래스를 State로 사용할 때는 불필요한 리컴포지션을 막기 위해
@Immutable또는@Stable사용을 검토해야 합니다.🤖 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 `@app/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt` at line 26, Update the UiState property bottomSheetSelectedMembers to use an immutable collection type such as ImmutableList<Member>, initialized with persistentListOf(). If project support prevents that, apply an appropriate `@Immutable` or `@Stable` wrapper that guarantees Member and collection immutability, while preserving the existing empty-list default and state behavior.Source: Path instructions
🤖 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.
Nitpick comments:
In
`@app/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt`:
- Line 26: Update the UiState property bottomSheetSelectedMembers to use an
immutable collection type such as ImmutableList<Member>, initialized with
persistentListOf(). If project support prevents that, apply an appropriate
`@Immutable` or `@Stable` wrapper that guarantees Member and collection
immutability, while preserving the existing empty-list default and state
behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 48559e9c-c052-42f4-9df7-5d249f8e62ab
📒 Files selected for processing (3)
app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListScreen.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.ktapp/src/main/java/com/poti/android/presentation/party/product/partylist/model/Contracts.kt
🚧 Files skipped from review as they are similar to previous changes (2)
- app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListScreen.kt
- app/src/main/java/com/poti/android/presentation/party/product/partylist/ProductPartyListViewModel.kt
|
✅ Ktlint check passed. Run: https://github.com/team-poti/POTI-ANDROID/actions/runs/29725470375 |
Related issue 🛠️
Work Description ✏️
core의MemberSelectBottomSheet제거party.component.MemberSelectBottomSheet사용Member객체 자체를 관리해List<Member>로 저장Screenshot 📸
Uncompleted Tasks 😅
To Reviewers 📢
Summary by CodeRabbit
Member목록 기반으로 전환되어 초기화·동기화·저장 흐름이 업데이트되었습니다.