com um clique
verify-frontend-ui
프론트엔드 UI 컴포넌트 품질 검증 (shadcn/ui + Tailwind 기준). UI 컴포넌트 수정 후 사용.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Menu
프론트엔드 UI 컴포넌트 품질 검증 (shadcn/ui + Tailwind 기준). UI 컴포넌트 수정 후 사용.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Baseado na classificação ocupacional SOC
세션 변경사항을 분석하여 검증 스킬 누락을 탐지합니다. 기존 스킬을 동적으로 탐색하고, 새 스킬을 생성하거나 기존 스킬을 업데이트한 뒤 CLAUDE.md를 관리합니다.
REST API 응답 DTO 일관성 및 에러 코드 표준 검증. API 엔드포인트 추가/수정, DTO 변경, 에러 처리 수정 후 사용. API 계약 변경이 프론트엔드에 영향을 줄 수 있을 때 사용.
Flyway DB 마이그레이션 일관성 검증. 마이그레이션 추가/수정 후 사용.
KB 비동기 인덱싱 파이프라인 검증. 인덱싱 관련 코드 수정 후 사용.
RAG 파이프라인 (답변 작성 + 분석 + 다운로드) 검증. 답변 작성/분석/다운로드 관련 코드 수정 후 사용.
문의 상세 페이지 UI 컴포넌트 검증 (shadcn/ui + Tailwind 기준). 문의 탭(Info/Analysis/Answer/History) 및 업로드 컴포넌트 수정 후 사용.
| name | verify-frontend-ui |
| description | 프론트엔드 UI 컴포넌트 품질 검증 (shadcn/ui + Tailwind 기준). UI 컴포넌트 수정 후 사용. |
.dark 클래스 기반 테마 전환 시 색상 정상 동작 확인frontend/src/components/ui/ 하위 컴포넌트 수정 후frontend/src/app/globals.css CSS 변수 변경 후frontend/tailwind.config.ts 테마 변경 후| File | Purpose |
|---|---|
frontend/src/app/globals.css | HSL CSS 변수 (shadcn + Bio-Rad 시맨틱, light/dark) |
frontend/tailwind.config.ts | Tailwind 테마 (색상 매핑, 키프레임, 폰트) |
frontend/src/lib/utils.ts | cn() 유틸리티 (clsx + tailwind-merge) |
frontend/src/components/ui/Badge.tsx | 상태 뱃지 (cva, variant: info/success/warn/danger/neutral) |
frontend/src/components/ui/button.tsx | shadcn Button (cva, forwardRef, asChild) |
frontend/src/components/ui/card.tsx | shadcn Card (6개 sub-components, forwardRef) |
frontend/src/components/ui/input.tsx | shadcn Input (forwardRef) |
frontend/src/components/ui/skeleton.tsx | shadcn Skeleton (animate-pulse) |
frontend/src/components/ui/DataTable.tsx | 제네릭 테이블 (키보드 내비게이션) |
frontend/src/components/ui/Tabs.tsx | 탭 전환 (ARIA tablist 패턴) |
frontend/src/components/ui/Toast.tsx | 알림 토스트 (cn + variant 매핑) |
frontend/src/components/ui/EmptyState.tsx | 빈 상태 CTA (shadcn Button) |
frontend/src/components/ui/FilterBar.tsx | 필터 검색바 (shadcn Button, role=search) |
frontend/src/components/ui/Pagination.tsx | 페이지 내비게이션 (aria-current) |
frontend/src/components/ui/PdfViewer.tsx | PDF 미리보기 (shadcn Button, SSR 미지원, triggerBlobDownload) |
frontend/src/components/ui/PdfExpandModal.tsx | PDF 확대 모달 (@radix-ui/react-dialog, SSR 미지원, triggerBlobDownload) |
frontend/src/components/ui/sonner.tsx | Sonner Toaster 래퍼 (shadcn toast provider) |
frontend/src/components/ui/PipelineProgressBadge.tsx | 파이프라인 진행 상태 뱃지 (role=list, ARIA, CSS 변수 기반 색상) |
frontend/src/components/ui/index.ts | 배럴 export (PdfViewer 제외) |
frontend/src/components/theme-provider.tsx | next-themes ThemeProvider 래퍼 |
frontend/src/components/theme-toggle.tsx | 다크/라이트 모드 토글 버튼 |
frontend/src/app/layout.tsx | 루트 레이아웃 (sticky footer, header/main/footer 구조) |
frontend/src/components/app-shell-nav.tsx | 상단 네비게이션 (데스크톱 수평 nav + 모바일 햄버거 메뉴) |
frontend/src/app/dashboard/page.tsx | 대시보드 (반응형 통계 그리드) |
파일: frontend/src/components/ui/*.tsx
검사: 하드코딩 hex 색상이나 rgb() 대신 Tailwind 시맨틱 클래스(text-foreground, bg-card, border-border 등)를 사용하는지 확인.
grep -rn 'style={{' frontend/src/components/ui/*.tsx | grep -v 'width\|height\|flex\|opacity' | head -10
PASS: 색상 관련 인라인 스타일 없음 (모두 Tailwind 클래스 사용) FAIL: 하드코딩 색상 인라인 스타일 발견
파일: frontend/src/components/ui/*.tsx
검사: 조건부 클래스 조합에 cn() 유틸리티를 사용하는지 확인.
grep -rn "import.*cn.*utils" frontend/src/components/ui/*.tsx
PASS: cn()을 사용하는 컴포넌트에 import 존재 FAIL: 문자열 템플릿으로 클래스 조합 (tailwind-merge 미적용)
파일: frontend/src/components/ui/*.tsx
검사: 인터랙티브 컴포넌트에 적절한 ARIA 역할이 있는지 확인.
grep -rn "role=" frontend/src/components/ui/*.tsx
필수 매핑:
role="table"role="tablist", role="tab", role="tabpanel"role="alert"role="status"role="search"role="navigation"PASS: 모든 필수 role 존재 FAIL: role 속성 누락
파일: frontend/src/components/ui/*.tsx
검사: 아이콘에 aria-hidden, 버튼에 aria-label, 동적 영역에 aria-live가 있는지 확인.
grep -rn "aria-hidden\|aria-label\|aria-live\|aria-selected\|aria-current" frontend/src/components/ui/*.tsx
필수 패턴:
aria-hidden="true"aria-label="설명"aria-live="assertive" + aria-atomic="true"aria-selected={boolean}aria-current="page"aria-live="polite"PASS: 모든 필수 ARIA 속성 존재 FAIL: 접근성 속성 누락
파일: DataTable.tsx, Tabs.tsx, FilterBar.tsx
검사: 키보드 이벤트 핸들링이 구현되어 있는지 확인.
grep -rn "onKeyDown\|ArrowLeft\|ArrowRight\|Enter\| Space" frontend/src/components/ui/DataTable.tsx frontend/src/components/ui/Tabs.tsx frontend/src/components/ui/FilterBar.tsx
PASS: 모든 키보드 이벤트 핸들러 존재 FAIL: 키보드 내비게이션 누락
예외: Tabs.tsx가 @radix-ui/react-tabs를 사용하는 경우, Radix UI가 빌트인 키보드 내비게이션(ArrowLeft/ArrowRight 탭 전환)을 제공하므로 소스 코드에 명시적 onKeyDown/Arrow 핸들러가 없어도 PASS로 판정. import 문에서 @radix-ui/react-tabs 사용 여부를 확인할 것.
파일: frontend/tailwind.config.ts, frontend/src/app/layout.tsx
검사: darkMode: ["class"] 설정과 ThemeProvider 래핑이 올바른지 확인.
grep -n 'darkMode\|ThemeProvider\|suppressHydrationWarning' frontend/tailwind.config.ts frontend/src/app/layout.tsx
PASS: darkMode: ["class"] + ThemeProvider attribute="class" + suppressHydrationWarning FAIL: 다크 모드 설정 불완전
파일: frontend/src/app/globals.css, frontend/src/app/layout.tsx
검사: body에 min-h-screen flex flex-col이 적용되고, main에 flex-1이 있어 콘텐츠가 짧아도 footer가 뷰포트 하단에 고정되는지 확인.
grep -n 'min-h-screen\|flex-col' frontend/src/app/globals.css
grep -n 'flex-1' frontend/src/app/layout.tsx
PASS: body에 min-h-screen flex flex-col + main에 flex-1 존재
FAIL: sticky footer 레이아웃 클래스 누락 (콘텐츠 짧을 때 footer가 위로 떠오름)
파일: frontend/src/app/globals.css
검사: globals.css가 CSS 변수 + 최소 기반 스타일만 포함하고 컴포넌트 CSS 클래스가 없는지 확인.
wc -l frontend/src/app/globals.css
grep -c '^\.' frontend/src/app/globals.css
PASS: 180줄 이하, 컴포넌트 CSS 클래스 없음 (.dark만 허용) FAIL: 레거시 CSS 클래스 잔존 (.btn, .card, .badge 등)
파일: frontend/src/components/ui/button.tsx, card.tsx, input.tsx
검사: shadcn 표준 패턴(cva, forwardRef, displayName)을 따르는지 확인.
grep -rn "forwardRef\|displayName\|cva\|VariantProps" frontend/src/components/ui/button.tsx frontend/src/components/ui/card.tsx frontend/src/components/ui/input.tsx
PASS: forwardRef + displayName + cva (button) 존재 FAIL: shadcn 패턴 불완전
파일: frontend/src/components/ui/index.ts
검사: PdfViewer와 PdfExpandModal이 배럴 export에서 제외되고 사용처에서 dynamic import + ssr: false 사용.
grep -n "PdfViewer\|PdfExpandModal" frontend/src/components/ui/index.ts
grep -rn "dynamic.*PdfViewer\|dynamic.*PdfExpandModal\|ssr.*false" frontend/src/components/inquiry/*.tsx frontend/src/components/ui/PdfViewer.tsx
PASS: index.ts에 PdfViewer/PdfExpandModal export 없음 + 사용처에서 dynamic + ssr: false FAIL: 배럴 export에 포함 또는 직접 import
파일: frontend/src/components/ui/index.ts
검사: 모든 UI 컴포넌트가 배럴 export에 포함되는지 확인 (PdfViewer 제외).
grep -c "export" frontend/src/components/ui/index.ts
PASS: Badge, DataTable, Pagination, Tabs, Toast, EmptyState, FilterBar, Toaster, Button, Card*, Input, Skeleton 모두 export (PdfViewer, PdfExpandModal 제외) FAIL: 신규 컴포넌트 export 누락 (단, SSR 미지원 컴포넌트는 제외가 정상)
파일: frontend/src/components/app-shell-nav.tsx
검사: md: 이상에서 수평 네비게이션, md: 미만에서 햄버거 버튼 + 슬라이드 오버레이 메뉴가 구현되어 있는지 확인. 메뉴 열기/닫기 상태 관리와 ARIA 속성(aria-expanded, dialog role) 확인.
grep -n "md:hidden\|md:flex\|hamburger\|메뉴 열기\|메뉴 닫기\|isMenuOpen\|aria-expanded\|dialog\|모바일" frontend/src/components/app-shell-nav.tsx
PASS: md:hidden 햄버거 + md:flex 수평 nav + 슬라이드 오버레이 + aria-expanded + dialog role FAIL: 모바일에서 수평 네비게이션 그대로 표시 또는 햄버거 메뉴 없음
파일: frontend/src/app/globals.css
검사: @media (pointer: coarse) 쿼리로 터치 디바이스에서 최소 44px 터치 타겟이 설정되어 있는지 확인.
grep -n "pointer.*coarse\|min-height.*44\|min-width.*44\|touch" frontend/src/app/globals.css
PASS: @media (pointer: coarse) + 44px 최소 터치 타겟 규칙 존재
FAIL: 터치 타겟 규칙 없음
파일: frontend/src/components/ui/DataTable.tsx
검사: 테이블 wrapper에 overflow-x-auto + min-w-[640px] 패턴이 적용되어 모바일에서 수평 스크롤이 가능한지 확인.
grep -n "overflow-x-auto\|min-w-\[640px\]" frontend/src/components/ui/DataTable.tsx
PASS: overflow-x-auto wrapper + min-w-[640px] 테이블 최소 너비
FAIL: overflow-x-auto 없이 모바일에서 테이블 깨짐
파일: frontend/src/components/ui/FilterBar.tsx
검사: 필터 입력의 최소 너비가 모바일에서 min-w-0으로 축소 가능하고, sm: 이상에서 sm:min-w-[160px]로 복원되는지 확인.
grep -n "min-w-0\|sm:min-w" frontend/src/components/ui/FilterBar.tsx
PASS: min-w-0 sm:min-w-[160px] 반응형 패턴
FAIL: min-w-[160px] 고정 (모바일 오버플로우)
| # | 검사 항목 | 결과 | 상세 |
|---|---|---|---|
| 1 | Tailwind 시맨틱 클래스 | PASS/FAIL | 하드코딩 색상 스타일 |
| 2 | cn() 유틸리티 사용 | PASS/FAIL | 미사용 컴포넌트 |
| 3 | ARIA role 속성 | PASS/FAIL | 누락 role |
| 4 | aria-label/hidden/live | PASS/FAIL | 누락 속성 |
| 5 | 키보드 내비게이션 | PASS/FAIL | 미구현 핸들러 |
| 6 | 다크 모드 설정 | PASS/FAIL | 설정 불완전 항목 |
| 7 | Sticky Footer 레이아웃 | PASS/FAIL | body min-h-screen + main flex-1 |
| 8 | globals.css 최소화 | PASS/FAIL | 라인 수, 레거시 클래스 |
| 9 | shadcn 컴포넌트 패턴 | PASS/FAIL | 누락 패턴 |
| 10 | PdfViewer SSR 제한 | PASS/FAIL | import 방식 |
| 11 | 배럴 export 완전성 | PASS/FAIL | 누락 export |
| 12 | 모바일 햄버거 메뉴 | PASS/FAIL | md:hidden 햄버거 + 슬라이드 오버레이 |
| 13 | 터치 타겟 최소 크기 | PASS/FAIL | @media (pointer: coarse) + 44px |
| 14 | DataTable 수평 스크롤 | PASS/FAIL | overflow-x-auto + min-w-[640px] |
| 15 | FilterBar 모바일 최적화 | PASS/FAIL | min-w-0 sm:min-w-[160px] |
다음은 위반이 아닙니다:
style={{ width: \${percentage}%` }}` 등 런타임 계산이 필요한 인라인 스타일은 허용