fix(chat): wire spot actions to backend#8
Conversation
- enrich chat rooms with spot participants, schedule, votes, and files - call spot vote APIs and sync room/message state - enforce owner/supporter action gates from backend user identity - block placeholder file registration until a real file URL contract exists - keep map-selected feed creation location changes with regression coverage
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Your plan currently allows 1 review/hour. Refill in 24 minutes and 29 seconds. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more review capacity refills, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 Walkthrough워크스루이 PR은 스팟 팀 채팅의 투표, 파일, 일정 관리를 백엔드 API 중심으로 전환하면서 소유자 권한 검증을 강화하고, 포스트 위치 선택에 수동 좌표 입력 기능을 추가합니다. 주요 변경은 비동기 상태 관리, 권한 기반 UI 제어, 그리고 타입 구조 정리입니다. 변경사항스팟 채팅 권한 및 백엔드 동기화
포스트 위치 선택 기능 개선
예상 코드 리뷰 노력🎯 4 (Complex) | ⏱️ ~50 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/features/post/ui/post-form/MapLocationPicker.test.tsx (1)
78-96: ⚡ Quick win입력 검증 실패 경로 테스트도 추가해 주세요.
빈 문자열/범위 초과 입력에서
onChange가 호출되지 않고 오류 메시지가 노출되는 케이스를 함께 검증하면 회귀 방지에 효과적입니다.테스트 추가 예시
+it('shows an error and does not call onChange for invalid manual coordinates', () => { + const handleChange = vi.fn(); + render(<MapLocationPicker value={null} onChange={handleChange} />); + + fireEvent.change(screen.getByLabelText('선택할 위치의 위도'), { + target: { value: '' }, + }); + fireEvent.change(screen.getByLabelText('선택할 위치의 경도'), { + target: { value: '200' }, + }); + fireEvent.click(screen.getByRole('button', { name: '좌표로 선택' })); + + expect(handleChange).not.toHaveBeenCalled(); + expect( + screen.getByText('위도는 -90~90, 경도는 -180~180 사이 숫자로 입력해주세요.'), + ).toBeTruthy(); +});🤖 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/features/post/ui/post-form/MapLocationPicker.test.tsx` around lines 78 - 96, Add tests for the MapLocationPicker component to cover input validation failure paths: using the existing test pattern with MapLocationPicker and the handleChange mock, add cases where latitude or longitude inputs are empty strings and where values are out of range (e.g., lat beyond ±90 or lng beyond ±180), trigger the selection button (the '좌표로 선택' button via getByRole) and assert that onChange (handleChange) is NOT called and that the component shows the appropriate validation error message (use screen.getByText / getByLabelText to verify the displayed error). Reference the existing MapLocationPicker test file and mimic the fireEvent.change + fireEvent.click flow used in the successful case to validate these failure scenarios.src/features/chat/client/MainChatPageClient.tsx (1)
292-294: 💤 Low value선택적 제안: 권한 판정 헬퍼를 모델 레이어로 이동
isOwnedSpotRoom헬퍼가 이 파일 내에서 여러 곳(Line 306, 826, 830)에 사용되고 있고,isSupporterForSpot는 모델 레이어(model/mock)에서 임포트되고 있습니다. 권한 판정 로직의 일관성과 재사용성을 위해isOwnedSpotRoom도 모델 레이어로 옮기는 것을 고려해 보세요.현재 동작에는 문제가 없으나, 향후 다른 컴포넌트에서도 소유자 권한 체크가 필요할 경우 중복 구현을 방지할 수 있습니다.
🤖 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/features/chat/client/MainChatPageClient.tsx` around lines 292 - 294, Extract the isOwnedSpotRoom helper from MainChatPageClient into the model layer (same place as isSupporterForSpot, e.g., model/mock): move the function implementation into that module, export it, then replace the local definition in MainChatPageClient with an import of the new exported isOwnedSpotRoom and update all call sites (the usages inside MainChatPageClient and any other modules) to use the imported function; ensure TypeScript types (SpotChatRoom) are imported or exported as needed and run type checks to confirm no breakages.src/features/chat/ui/ChatDetail.tsx (1)
1000-1093: 💤 Low value"새로 만들기" 섹션 빈 상태 가능성
OFFER 타입 스팟에서 비소유자(non-author)인 경우,
canManageOwnerActions와canCreateReverseOffer모두 false가 되어 "새로 만들기" 제목만 표시되고 항목이 없는 상태가 됩니다. 해당 케이스에서 섹션 자체를 숨기거나 안내 메시지를 추가하는 것이 UX에 도움될 수 있습니다.💡 빈 상태 처리 예시
+const hasCreationItems = canManageOwnerActions || canCreateReverseOffer; <section className="flex flex-col gap-2"> + {hasCreationItems ? ( + <> <p className="text-[11px] font-semibold tracking-[0.14em] text-muted-foreground uppercase"> 새로 만들기 </p> <div className="grid grid-cols-2 gap-2"> {/* ... existing items ... */} </div> + </> + ) : null} </section>🤖 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/features/chat/ui/ChatDetail.tsx` around lines 1000 - 1093, The "새로 만들기" section can render empty when both canManageOwnerActions and canCreateReverseOffer are false; update the component to check the combined items array (derived from canManageOwnerActions and canCreateReverseOffer) before rendering: if the array is empty, either do not render the entire <section> block or render a small empty-state hint (e.g., "사용 가능한 항목이 없습니다") in place of the grid; keep existing handlers (openCreation, setShortcutPickerOpen) untouched and reference the same keys (step) and props when rendering items.src/features/chat/ui/ChatCreationPanel.tsx (1)
234-243: ⚡ Quick win
createTeamVote실패 시 에러 피드백 누락
ScheduleCreatePanel은isSaving/saveError상태로 에러를 처리하지만,VoteCreatePanel은createTeamVote실패 시 에러를 catch하지 않아 사용자에게 피드백이 없습니다. 일관성 있는 UX를 위해 동일한 패턴 적용을 권장합니다.🔧 에러 처리 추가 제안
+ const [isCreating, setIsCreating] = useState(false); + const [createError, setCreateError] = useState<string | null>(null); async function handleSubmit() { - if (!canSubmit) return; + if (!canSubmit || isCreating) return; + + setIsCreating(true); + setCreateError(null); + setSelectedContextId(room.id); - const createdRoom = await createTeamVote( - question.trim(), - options.filter((o) => o.trim()), - multiSelect, - ); - if (createdRoom) onClose(); + try { + const createdRoom = await createTeamVote( + question.trim(), + options.filter((o) => o.trim()), + multiSelect, + ); + if (createdRoom) onClose(); + } catch { + setCreateError('투표 생성에 실패했어요. 잠시 후 다시 시도해주세요.'); + } finally { + setIsCreating(false); + } }🤖 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/features/chat/ui/ChatCreationPanel.tsx` around lines 234 - 243, The handleSubmit function should mirror ScheduleCreatePanel's save pattern: set an "isSaving" flag before calling createTeamVote and clear it afterward, and catch errors to set a "saveError" state so the UI can show feedback. Update handleSubmit to call setIsSaving(true) at start, await createTeamVote(question.trim(), options.filter(o => o.trim()), multiSelect) inside try, call onClose() only on success, and in catch setSaveError(err) (and ensure setIsSaving(false) in finally); reference the existing handleSubmit, createTeamVote, setSelectedContextId, onClose, question, options and multiSelect symbols when making the change.
🤖 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/features/post/ui/post-form/MapLocationPicker.tsx`:
- Around line 59-75: handleManualSelect currently converts manualLat/manualLng
to numbers which treats empty strings as 0; first check that manualLat and
manualLng are non-empty (e.g., trim and verify not '') before Number conversion,
setManualError with the same message and return if either is empty, then proceed
to parse and validate numeric ranges; update the logic inside handleManualSelect
to validate emptiness first, then Number.isFinite and range checks, referencing
manualLat, manualLng, handleManualSelect, and setManualError.
---
Nitpick comments:
In `@src/features/chat/client/MainChatPageClient.tsx`:
- Around line 292-294: Extract the isOwnedSpotRoom helper from
MainChatPageClient into the model layer (same place as isSupporterForSpot, e.g.,
model/mock): move the function implementation into that module, export it, then
replace the local definition in MainChatPageClient with an import of the new
exported isOwnedSpotRoom and update all call sites (the usages inside
MainChatPageClient and any other modules) to use the imported function; ensure
TypeScript types (SpotChatRoom) are imported or exported as needed and run type
checks to confirm no breakages.
In `@src/features/chat/ui/ChatCreationPanel.tsx`:
- Around line 234-243: The handleSubmit function should mirror
ScheduleCreatePanel's save pattern: set an "isSaving" flag before calling
createTeamVote and clear it afterward, and catch errors to set a "saveError"
state so the UI can show feedback. Update handleSubmit to call setIsSaving(true)
at start, await createTeamVote(question.trim(), options.filter(o => o.trim()),
multiSelect) inside try, call onClose() only on success, and in catch
setSaveError(err) (and ensure setIsSaving(false) in finally); reference the
existing handleSubmit, createTeamVote, setSelectedContextId, onClose, question,
options and multiSelect symbols when making the change.
In `@src/features/chat/ui/ChatDetail.tsx`:
- Around line 1000-1093: The "새로 만들기" section can render empty when both
canManageOwnerActions and canCreateReverseOffer are false; update the component
to check the combined items array (derived from canManageOwnerActions and
canCreateReverseOffer) before rendering: if the array is empty, either do not
render the entire <section> block or render a small empty-state hint (e.g., "사용
가능한 항목이 없습니다") in place of the grid; keep existing handlers (openCreation,
setShortcutPickerOpen) untouched and reference the same keys (step) and props
when rendering items.
In `@src/features/post/ui/post-form/MapLocationPicker.test.tsx`:
- Around line 78-96: Add tests for the MapLocationPicker component to cover
input validation failure paths: using the existing test pattern with
MapLocationPicker and the handleChange mock, add cases where latitude or
longitude inputs are empty strings and where values are out of range (e.g., lat
beyond ±90 or lng beyond ±180), trigger the selection button (the '좌표로 선택'
button via getByRole) and assert that onChange (handleChange) is NOT called and
that the component shows the appropriate validation error message (use
screen.getByText / getByLabelText to verify the displayed error). Reference the
existing MapLocationPicker test file and mimic the fireEvent.change +
fireEvent.click flow used in the successful case to validate these failure
scenarios.
🪄 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
Run ID: e14841a5-b417-48c8-b336-2376b4e299ef
📒 Files selected for processing (12)
src/features/chat/client/MainChatPageClient.tsxsrc/features/chat/model/mock.tssrc/features/chat/model/use-main-chat-store.test.tssrc/features/chat/model/use-main-chat-store.tssrc/features/chat/ui/ChatBottomNav.tsxsrc/features/chat/ui/ChatCreationPanel.tsxsrc/features/chat/ui/ChatDetail.tsxsrc/features/post/model/types.tssrc/features/post/model/use-post-base-form.tssrc/features/post/ui/post-form/MapLocationPicker.test.tsxsrc/features/post/ui/post-form/MapLocationPicker.tsxsrc/features/post/ui/post-form/PostBaseInfoSection.tsx
|
Deployment failed with the following error: |
Summary
Checks
Summary by CodeRabbit
릴리스 노트
새로운 기능
버그 수정
개선