커밋 그래프

7 커밋

작성자 SHA1 메시지 날짜
c51873ab85 fix(frontend): a11y/호환성 — backdrop-filter webkit prefix + Button/Input/Select 접근 이름
axe/forms/backdrop 에러 3종 모두 해결:

1) CSS: backdrop-filter Safari 호환성
   - design-system CSS에 -webkit-backdrop-filter 추가
   - trk-pulse 애니메이션을 outline-color → opacity로 변경
     (composite만 트리거, paint/layout 없음 → 더 나은 성능)

2) 아이콘 전용 <button> aria-label 추가 (9곳):
   - MainLayout 알림 버튼 → '알림'
   - UserRoleAssignDialog 닫기 → '닫기'
   - AIAssistant/MLOpsPage 전송 → '전송'
   - ChinaFishing 좌/우 네비 → '이전'/'다음'
   - 공통 컴포넌트 (PrintButton/ExcelExport/SaveButton) type=button 누락 보정

3) <input>/<textarea> 접근 이름 27곳 추가:
   - 로그인 폼, ParentReview/LabelSession/ParentExclusion 폼 (10)
   - NoticeManagement 제목/내용/시작일/종료일 (4)
   - SystemConfig/DataHub/PermissionsPanel 검색·역할 입력 (5)
   - VesselDetail 조회 시작/종료/MMSI (3)
   - GearIdentification InputField에 label prop 추가
   - AIAssistant/MLOpsPage 질의 input/textarea
   - MainLayout 페이지 내 검색
   - 공통 placeholder → aria-label 자동 복제 (3)

Button 컴포넌트에는 접근성 정책 JSDoc 명시 (타입 강제는 API 복잡도 대비
이득 낮아 문서 가이드 + 코드 리뷰로 대응).

검증:
- 실제 위반 지표: inaccessible button 0, inaccessible input 0, textarea 0
- tsc , eslint , vite build 
- dist CSS에 -webkit-backdrop-filter 확인됨
2026-04-08 13:04:23 +09:00
9dfa8f5422 fix(frontend): Select 접근성 — aria-label 필수 + 네이티브 <select> 보완
이슈: "Select element must have an accessible name" — 스크린 리더가 용도를
인지할 수 없어 WCAG 2.1 Level A 위반.

수정:
- Select 공통 컴포넌트 타입을 union으로 강제
  - aria-label | aria-labelledby | title 중 하나는 TypeScript 컴파일 타임에 필수
  - 누락 시 tsc 단계에서 즉시 실패 → 회귀 방지
- 네이티브 <select> 5곳 aria-label 추가:
  - admin/SystemConfig: 대분류 필터
  - detection/RealVesselAnalysis: 해역 필터
  - detection/RealGearGroups: 그룹 유형 필터
  - detection/ChinaFishing: 관심영역 선택
  - detection/GearIdentification: SelectField에 label prop 추가
- 쇼케이스 FormSection Select 샘플에 aria-label 추가

이제 모든 Select 사용처가 접근 이름을 가지며,
향후 신규 Select 사용 시 tsc가 누락을 차단함.
2026-04-08 12:50:51 +09:00
52749638ef refactor(frontend): 쇼케이스 SSOT 구조 — 카탈로그 레지스트리 + variant 메타
Phase A: 쇼케이스의 카탈로그/variant 정보를 중앙 상수로 끌어올림

- shared/constants/catalogRegistry.ts 신규
  - 19+ 카탈로그의 id/showcaseId/titleKo/titleEn/description/source/items를
    단일 레지스트리로 통합 관리
  - 새 카탈로그 추가 = 레지스트리에 1줄 추가로 쇼케이스 자동 노출
  - CATALOG_REGISTRY + getCatalogById()
- lib/theme/variantMeta.ts 신규
  - BADGE_INTENT_META: 8 intent의 titleKo/titleEn/description
  - BUTTON_VARIANT_META: 5 variant의 titleKo/titleEn/description
  - BADGE_INTENT_ORDER/SIZE_ORDER, BUTTON_VARIANT_ORDER/SIZE_ORDER
- 쇼케이스 섹션 리팩토링 — 하드코딩 제거
  - CatalogSection: CATALOG_REGISTRY 자동 열거 (CATALOGS 배열 삭제)
  - BadgeSection: BADGE_INTENT_META에서 의미 가이드 + titleKo 참조
  - ButtonSection: BUTTON_VARIANT_META에서 의미 가이드 + titleKo 참조

효과:
- 카탈로그의 라벨/색상/intent 변경 시 쇼케이스와 실 페이지 동시 반영
- Badge/Button의 variant 의미가 variantMeta 한 곳에서 관리됨
- 쇼케이스 섹션에 분산돼 있던 하드코딩 제거 (INTENT_USAGE, VARIANT_USAGE 등)

다음 단계: 실 페이지를 PageContainer/PageHeader/Button/Input으로 마이그레이션
2026-04-08 11:42:43 +09:00
4170824f15 feat(frontend): 쇼케이스 테마 전환 단축키 A 추가 2026-04-08 11:31:16 +09:00
d7f8db88ee fix(frontend): Badge 다크 팔레트를 translucent로 통일 + 쇼케이스 한/영 병기
- badgeVariants 다크 팔레트를 classes 기반 4종 카탈로그와 동일 패턴으로 통일
  - 이전: dark:bg-X-400 dark:text-slate-900 dark:border-X-600 (솔리드)
  - 이후: dark:bg-X-500/20 dark:text-X-400 dark:border-X-500/30 (translucent)
  - 라이트 팔레트는 그대로 유지 (이미 통일되어 있음)
- CatalogSection: 각 카탈로그 항목을 [code / 한글 배지 / 영문 배지] 3열 행으로 렌더
  - 한글/영문 라벨 두 버전을 한눈에 비교 검토 가능
  - 추적 ID Trk는 행 전체를 감싸서 호버/복사 동작
2026-04-08 11:28:02 +09:00
f589cb0f94 fix(frontend): 카탈로그 배지 테마 분리 + 단속 조치 가독성 수정
변경:
- badgeVariants 8 intent 모두 라이트/다크 팔레트 분리
  - 다크: 밝은 솔리드 배경(-400) + slate-900 글자 + 강한 보더(-600)
  - 라이트: 파스텔 배경(-100) + 진한 글자(-900) + 소프트 보더(-300)
  - base에서 text-on-bright 제거 (intent별로 관리)
- classes 기반 카탈로그 4종에 dark: 변형 추가로 라이트 모드 대응:
  - eventStatuses: bg-red-100 text-red-800 dark:bg-red-500/20 dark:text-red-400
  - enforcementResults: 동일 패턴 (red/purple/yellow/green)
  - patrolStatuses: border 포함 (7 상태)
  - enforcementActions: classes 필드 신규 추가 (기존에 없어서 fallback grey로 떨어져
    라이트 모드에서 글자 안 보이던 원인)
- CatalogSection fallback classes도 dark: 변형 추가 (안전장치)
- enforcementActions에 getEnforcementActionClasses() 헬퍼 신규

빌드 검증:
- tsc , vite build 
- CSS 확인: .dark\:bg-red-400:is(.dark *) 컴파일 정상
2026-04-08 11:23:38 +09:00
e0b51efc54 feat(frontend): 디자인 시스템 쇼케이스 페이지 + 신규 공통 컴포넌트
쇼케이스 (/design-system.html):
- 별도 Vite entry (System Flow 패턴 재사용, 메인 SPA 분리)
- 10개 섹션: Intro / Token / Typography / Badge / Button / Form /
  Card / Layout / Catalog (19+) / Guide
- 추적 ID 체계 (TRK-CATEGORY-SLUG):
  - hover 시 툴팁 + "ID 복사 모드"에서 클릭 시 클립보드 복사
  - URL hash 딥링크 (#trk=TRK-BADGE-critical-sm) 스크롤+하이라이트
  - 산출문서/논의에서 특정 변형 정확히 참조 가능
- Dark/Light 테마 토글로 양쪽 시각 검증

신규 공통 컴포넌트:
- Button (@shared/components/ui/button.tsx)
  - 5 variant × 3 size = 15 변형
  - primary/secondary/ghost/outline/destructive × sm/md/lg
- Input / Select / Textarea / Checkbox / Radio
  - Input · Select 공통 inputVariants 공유 (sm/md/lg × default/error/success)
- PageContainer / PageHeader / Section (shared/components/layout/)
  - PageContainer: size sm/md/lg + fullBleed (지도/풀화면 예외)
  - PageHeader: title + description + icon + demo 배지 + actions 슬롯
  - Section: Card + CardHeader + CardTitle + CardContent 단축

variants.ts 확장:
- buttonVariants / inputVariants / pageContainerVariants CVA 정의
- Button/Input/Select는 variants.ts에서 import하여 fast-refresh 경고 회피

빌드 검증 완료:
- TypeScript 타입 체크 통과
- ESLint 통과 (경고 0)
- vite build: designSystem-*.js 54KB (메인 SPA와 분리)

이 쇼케이스가 확정된 후 실제 40+ 페이지 마이그레이션 진행 예정.
2026-04-08 11:09:36 +09:00