[refactor] 웹뷰 필터칩-라우트 config 기반으로 통합#1536
Conversation
WEBVIEW_FILTER_CONFIG 단일 소스에서 label·path·component를 관리, webviewRoutes와 Filter가 같은 config를 참조하도록 변경
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, 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 the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
Warning
|
| Layer / File(s) | 요약 |
|---|---|
WEBVIEW_FILTER_CONFIG 계약 정의 frontend/src/routes/webviewFilterConfig.ts |
label과 path를 포함하는 필터 항목을 as const 배열로 정의하고, WebviewFilterPath 타입을 추출하여 경로 문자열 리터럴을 타입 안전하게 관리합니다. |
웹뷰 라우트 동적 생성 frontend/src/routes/webviewRoutes.tsx |
WEBVIEW_FILTER_CONFIG를 매핑하여 /webview 자식 라우트를 동적으로 생성합니다. PAGE_MAP을 통해 필터 경로를 페이지 컴포넌트에 연결하고, 각 라우트를 ContentErrorBoundary로 감싸며, 기존 하드코딩된 route 정의를 제거합니다. |
Filter 컴포넌트 업데이트 frontend/src/components/common/Filter/Filter.tsx |
로컬 WEBVIEW_FILTER_OPTIONS 상수를 제거하고, WEBVIEW_FILTER_CONFIG를 import하여 웹뷰 경로의 필터 옵션으로 사용합니다. |
필터 및 라우팅 문서화 frontend/docs/features/main/filter.md, frontend/docs/claude/features.md |
WEBVIEW_FILTER_CONFIG를 필터 UI 및 라우트 등록의 단일 진실 공급원으로 설명하고, NotificationDot 세션 스토리지 동작, 새 필터 추가 시 수정 위치, 자동 반영 범위를 명시합니다. |
BuskingPage 레이아웃 최적화
| Layer / File(s) | 요약 |
|---|---|
BuskingPage 스타일 및 레이아웃 재구성 frontend/src/pages/FestivalPage/BuskingPage/BuskingPage.styles.ts, frontend/src/pages/FestivalPage/BuskingPage/BuskingPage.tsx |
Container 스타일에 min-height: 100vh를 추가하여 최소 뷰포트 높이를 보장하고, motion.div 스와이프 핸들러를 Styled.Container를 감싸도록 이동하여 내비게이션과 콘텐츠를 포함하는 통합 래퍼 구조로 변경합니다. |
🎯 검토 소요 시간
🎯 2 (단순) | ⏱️ ~12분
관련 가능성 있는 PR
- Moadong/moadong#1534: festival-busking 자식 라우트 정의 변경사항이 겹쳐 있습니다.
- Moadong/moadong#1506: 웹뷰 필터 플럼빙 관련 코드(Filter.tsx, webviewRoutes.tsx)에서 직접적인 연관이 있습니다.
- Moadong/moadong#1528: BuskingPage 레이아웃 및 CSS 구조 변경이 유사합니다.
제안 라벨
🔨 Refactor, 💻 FE
제안 검토자
- suhyun113
- lepitaaar
- oesnuj
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | PR 제목이 주요 변경사항인 웹뷰 필터칩-라우트 설정의 통합을 명확하게 설명하고 있으며, 전체 changeset의 핵심을 정확히 반영하고 있습니다. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
| Linked Issues check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
refactor/#1535-webview-filter-config-driven-routes-MOA-843
Tip
💬 Introducing Slack Agent: The best way for teams to turn conversations into code.
Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
- Generate code and open pull requests
- Plan features and break down work
- Investigate incidents and troubleshoot customer tickets together
- Automate recurring tasks and respond to alerts with triggers
- Summarize progress and report instantly
Built for teams:
- Shared memory across your entire org—no repeating context
- Per-thread sandboxes to safely plan and execute work
- Governance built-in—scoped access, auditability, and budget controls
One agent for your entire SDLC. Right inside Slack.
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 @coderabbitai help to get the list of available commands and usage tips.
🎨 UI 변경사항을 확인해주세요
2개 스토리 변경 · 전체 57개 스토리 · 22개 컴포넌트 |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
frontend/src/routes/webviewFilterConfig.tsx (2)
6-10: ⚡ Quick win인터페이스를 export하여 타입 안전성을 향상시키세요.
WebviewFilterItem인터페이스가 현재 로컬로만 정의되어 있지만,Filter.tsx에서filterOptions의 타입을 명시적으로 지정하려면 이 타입에 접근할 수 있어야 합니다. 인터페이스를 export하면 다른 파일에서도 재사용할 수 있어 타입 일관성이 보장됩니다.♻️ 제안하는 수정
-interface WebviewFilterItem { +export interface WebviewFilterItem { label: string; path: string; component: ComponentType; }🤖 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 `@frontend/src/routes/webviewFilterConfig.tsx` around lines 6 - 10, Export the WebviewFilterItem interface so other modules can import and reuse it; update the declaration of WebviewFilterItem to be exported (export interface WebviewFilterItem { ... }) and then import and apply that type where needed (e.g., in Filter.tsx for filterOptions) to ensure type safety and consistency across files.
12-20: ⚡ Quick win
as const단언을 추가하여 타입 추론을 개선하세요.현재 배열은 가변(
WebviewFilterItem[])으로 추론되지만, 이 config는 런타임에 변경되지 않는 상수입니다.as const단언을 추가하면 TypeScript가 각 항목의 리터럴 타입을 보존하여 더 정확한 타입 체킹이 가능합니다.♻️ 제안하는 수정
-export const WEBVIEW_FILTER_CONFIG: WebviewFilterItem[] = [ +export const WEBVIEW_FILTER_CONFIG = [ { label: '동아리', path: '/webview/main', component: WebviewMainPage }, { label: '홍보', path: '/webview/promotions', component: PromotionListPage }, { label: '대동제', path: '/webview/festival-busking', component: BuskingPage, }, -]; +] as const satisfies readonly WebviewFilterItem[];참고: React 19는
satisfies키워드를 지원합니다.🤖 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 `@frontend/src/routes/webviewFilterConfig.tsx` around lines 12 - 20, The WEBVIEW_FILTER_CONFIG constant is currently typed as a mutable WebviewFilterItem[] which loses literal types; make it readonly by appending an `as const` assertion to the array expression so TypeScript preserves literal string values and tuple-like types for each entry (references: WEBVIEW_FILTER_CONFIG, WebviewFilterItem, components WebviewMainPage, PromotionListPage, BuskingPage). Optionally, if you prefer a type-checked shape and your toolchain supports it, use the `satisfies` operator instead of a plain type annotation to retain literal types while ensuring conformance to WebviewFilterItem.frontend/src/routes/webviewRoutes.tsx (1)
13-20: ⚡ Quick win경로 문자열 조작 로직을 더 견고하게 개선하세요.
현재
path.replace('/webview/', '')는 첫 번째 일치 항목만 교체하며, 경로가/webview/로 시작하지 않는 경우 예상치 못한 결과가 발생할 수 있습니다.정규식을 사용하거나 명시적으로 prefix를 제거하는 방식이 더 안전합니다.
♻️ 제안하는 수정
방법 1: 정규식 사용 (권장)
- ...WEBVIEW_FILTER_CONFIG.map(({ path, component: Page }) => ({ - path: path.replace('/webview/', ''), + ...WEBVIEW_FILTER_CONFIG.map(({ path: fullPath, component: Page }) => ({ + path: fullPath.replace(/^\/webview\//, ''), element: ( <ContentErrorBoundary> <Page /> </ContentErrorBoundary> ), })),방법 2: slice 사용
+const WEBVIEW_PREFIX = '/webview/'; + ...WEBVIEW_FILTER_CONFIG.map(({ path: fullPath, component: Page }) => ({ - path: fullPath.replace('/webview/', ''), + path: fullPath.startsWith(WEBVIEW_PREFIX) + ? fullPath.slice(WEBVIEW_PREFIX.length) + : fullPath, element: (🤖 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 `@frontend/src/routes/webviewRoutes.tsx` around lines 13 - 20, The path trimming is brittle because path.replace('/webview/', '') only removes the first match and can mis-handle strings that don't start with that prefix; update the mapping over WEBVIEW_FILTER_CONFIG so the transformed path is computed robustly (e.g. use a regex anchored to the start like /^\/webview\// or check path.startsWith('/webview/') and slice off the prefix) when building the object for each entry ({ path, component: Page }) so the element routing uses the correct cleaned path.
🤖 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 `@frontend/src/routes/webviewFilterConfig.tsx`:
- Around line 6-10: Export the WebviewFilterItem interface so other modules can
import and reuse it; update the declaration of WebviewFilterItem to be exported
(export interface WebviewFilterItem { ... }) and then import and apply that type
where needed (e.g., in Filter.tsx for filterOptions) to ensure type safety and
consistency across files.
- Around line 12-20: The WEBVIEW_FILTER_CONFIG constant is currently typed as a
mutable WebviewFilterItem[] which loses literal types; make it readonly by
appending an `as const` assertion to the array expression so TypeScript
preserves literal string values and tuple-like types for each entry (references:
WEBVIEW_FILTER_CONFIG, WebviewFilterItem, components WebviewMainPage,
PromotionListPage, BuskingPage). Optionally, if you prefer a type-checked shape
and your toolchain supports it, use the `satisfies` operator instead of a plain
type annotation to retain literal types while ensuring conformance to
WebviewFilterItem.
In `@frontend/src/routes/webviewRoutes.tsx`:
- Around line 13-20: The path trimming is brittle because
path.replace('/webview/', '') only removes the first match and can mis-handle
strings that don't start with that prefix; update the mapping over
WEBVIEW_FILTER_CONFIG so the transformed path is computed robustly (e.g. use a
regex anchored to the start like /^\/webview\// or check
path.startsWith('/webview/') and slice off the prefix) when building the object
for each entry ({ path, component: Page }) so the element routing uses the
correct cleaned path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 185ddce4-bb5f-4830-b2db-71eac127bc36
📒 Files selected for processing (4)
frontend/docs/features/main/filter.mdfrontend/src/components/common/Filter/Filter.tsxfrontend/src/routes/webviewFilterConfig.tsxfrontend/src/routes/webviewRoutes.tsx
webviewFilterConfig에서 page component 제거 후 .ts로 변경, PAGE_MAP을 webviewRoutes에서 관리하여 순환 참조 해소
WEBVIEW_FILTER_CONFIG이 필터탭 UI와 라우트의 단일 진실 공급원임을 명시, 새 필터탭 추가 시 수정할 파일 2곳(webviewFilterConfig.ts, webviewRoutes.tsx) 안내
…riven-routes-MOA-843
#️⃣연관된 이슈
📝작업 내용
배경
기존에는 웹뷰 필터탭의 label·path 정보가 두 곳에 중복 관리되고 있었습니다.
필터탭을 추가하거나 수정할 때 두 파일을 각각 찾아서 동기화해야 했고,
누락 시 UI에는 탭이 보이지만 라우트가 없거나(혹은 그 반대) 그 반대 상황이 발생할 수 있었습니다.
변경 사항
src/routes/webviewFilterConfig.ts를 단일 진실 공급원으로 도입해 label·path를 한 곳에서 관리합니다.새 필터탭 추가 방법 (AS-IS → TO-BE)
AS-IS: Filter.tsx + webviewRoutes.tsx 두 파일에 각각 항목 추가
TO-BE:
탭 순서·라벨 변경은 webviewFilterConfig.ts 한 곳만 수정하면 UI와 라우트에 동시 반영됩니다.
중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
릴리스 노트
Documentation
Refactor