Skip to content

[refactor] 웹뷰 필터칩-라우트 config 기반으로 통합#1536

Merged
seongwon030 merged 5 commits into
develop-fefrom
refactor/#1535-webview-filter-config-driven-routes-MOA-843
May 13, 2026
Merged

[refactor] 웹뷰 필터칩-라우트 config 기반으로 통합#1536
seongwon030 merged 5 commits into
develop-fefrom
refactor/#1535-webview-filter-config-driven-routes-MOA-843

Conversation

@seongwon030
Copy link
Copy Markdown
Member

@seongwon030 seongwon030 commented May 12, 2026

#️⃣연관된 이슈

ex) #1536

📝작업 내용

배경

기존에는 웹뷰 필터탭의 label·path 정보가 두 곳에 중복 관리되고 있었습니다.

  • Filter.tsx — 탭 UI 렌더링용 options 배열
  • webviewRoutes.tsx — 라우트 등록용 배열

필터탭을 추가하거나 수정할 때 두 파일을 각각 찾아서 동기화해야 했고,
누락 시 UI에는 탭이 보이지만 라우트가 없거나(혹은 그 반대) 그 반대 상황이 발생할 수 있었습니다.

변경 사항

src/routes/webviewFilterConfig.ts를 단일 진실 공급원으로 도입해 label·path를 한 곳에서 관리합니다.

  export const WEBVIEW_FILTER_CONFIG = [
    { label: '동아리', path: '/webview/main' },
    { label: '홍보', path: '/webview/promotions' },
    { label: '대동제', path: '/webview/festival-busking'
  },
  ] as const;
  • Filter.tsx: 기존 하드코딩 배열 제거 → WEBVIEW_FILTER_CONFIG import로 대체
  • webviewRoutes.tsx: WEBVIEW_FILTER_CONFIG를 순회해 라우트를 자동 생성, 컴포넌트 연결은 PAGE_MAP에서 담당

새 필터탭 추가 방법 (AS-IS → TO-BE)

AS-IS: Filter.tsx + webviewRoutes.tsx 두 파일에 각각 항목 추가

TO-BE:

  1. webviewFilterConfig.ts — { label, path } 항목 추가
  2. webviewRoutes.tsx의 PAGE_MAP — 해당 path에 컴포넌트 연결

탭 순서·라벨 변경은 webviewFilterConfig.ts 한 곳만 수정하면 UI와 라우트에 동시 반영됩니다.

중점적으로 리뷰받고 싶은 부분(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

논의하고 싶은 부분(선택)

논의하고 싶은 부분이 있다면 작성해주세요.

🫡 참고사항

Summary by CodeRabbit

릴리스 노트

  • Documentation

    • 필터 컴포넌트의 알림 표시 규칙 및 동작 설명서 업데이트
  • Refactor

    • 웹뷰 필터 설정을 단일 구성 소스로 통합하여 유지보수성 개선
    • 필터 옵션 및 라우팅 정의가 한 곳에서 관리되도록 개선

Review Change Stack

WEBVIEW_FILTER_CONFIG 단일 소스에서 label·path·component를 관리,
webviewRoutes와 Filter가 같은 config를 참조하도록 변경
@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
moadong Ready Ready Preview, Comment May 13, 2026 1:52am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Warning

Rate limit exceeded

@seongwon030 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 57 minutes and 23 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 44448489-8559-41c9-afcf-061a99a50123

📥 Commits

Reviewing files that changed from the base of the PR and between b181e5d and 70b0943.

📒 Files selected for processing (2)
  • frontend/src/pages/FestivalPage/BuskingPage/BuskingPage.styles.ts
  • frontend/src/pages/FestivalPage/BuskingPage/BuskingPage.tsx

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid regex pattern for base branch. Received: "**" at "reviews.auto_review.base_branches[0]"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

안내

이 PR은 웹뷰 필터 옵션과 라우트 정의를 단일 설정 소스(WEBVIEW_FILTER_CONFIG)로 통합하고, BuskingPage의 레이아웃 구조를 최적화합니다. Filter 컴포넌트와 라우트 생성 로직이 중앙 설정을 동적으로 사용하도록 리팩토링되어 중복을 제거합니다.

변경 사항

웹뷰 필터 설정 중앙화

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.

👉 Get started


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 and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 12, 2026

🎨 UI 변경사항을 확인해주세요

변경된 스토리를 Chromatic에서 확인해주세요.

구분 링크
🔍 변경사항 리뷰 https://www.chromatic.com/build?appId=67904e61c16daa99a63b44a7&number=324
📖 Storybook https://67904e61c16daa99a63b44a7-mpalrvkqzy.chromatic.com/

2개 스토리 변경 · 전체 57개 스토리 · 22개 컴포넌트

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 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

📥 Commits

Reviewing files that changed from the base of the PR and between f13b9a1 and 5123ef4.

📒 Files selected for processing (4)
  • frontend/docs/features/main/filter.md
  • frontend/src/components/common/Filter/Filter.tsx
  • frontend/src/routes/webviewFilterConfig.tsx
  • frontend/src/routes/webviewRoutes.tsx

webviewFilterConfig에서 page component 제거 후 .ts로 변경,
PAGE_MAP을 webviewRoutes에서 관리하여 순환 참조 해소
Copy link
Copy Markdown
Collaborator

@suhyun113 suhyun113 left a comment

Choose a reason for hiding this comment

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

수고하셨어여! 빠른 수정 좋슴다

WEBVIEW_FILTER_CONFIG이 필터탭 UI와 라우트의 단일 진실 공급원임을 명시,
새 필터탭 추가 시 수정할 파일 2곳(webviewFilterConfig.ts, webviewRoutes.tsx) 안내
@seongwon030 seongwon030 merged commit f56b278 into develop-fe May 13, 2026
5 checks passed
@seongwon030 seongwon030 deleted the refactor/#1535-webview-filter-config-driven-routes-MOA-843 branch May 13, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants