Files
HMDesign/docs/guidelines/consistency-audit-2026-10-06.md
T

94 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HMDesignSystem 전체 정합성 감사 — 2026-10-06
> HISTORICAL_RECORD: 2026-10-06 감사 시점의 저장소 상태·실측·보류 판단을 보존한다. 이후 상태 정책과 구현을 이 기록으로 대체하지 않는다. 현재 Component/Pattern 상태는 각 [Component 문서](../components/)/[Pattern 문서](../patterns/), Runtime 적용은 [Runtime Theme](runtime-theme.md), Designer 사용은 [Theme 가이드](designer-theme-guide.md)를 따른다.
현재 Production 코드와 실제 Storybook을 1차 기준으로 새로 대조했다. 문서/CLAUDE.md는 비교 대상이며 과거 작업 보고서의 검증 수치를 이번 결과로 재사용하지 않았다. 수정 전 분류를 먼저 보고한 뒤 명백한 불일치만 수정했다.
## 범위와 현재 구조
- `packages/ui`: private source export 패키지. Component, 7개 Pattern, CSS Theme와 `@hm-design/ui/theme` Runtime API를 소유한다.
- `packages/center-graphic`: UI와 서로 의존하지 않는 private source export 패키지. 통합 Storybook에서 별도 그룹으로 제공한다.
- 루트 `src`, `.storybook`: Demo와 Component/Pattern/Theme/CENTER Story. UI 44개 그룹, Pattern 6개 그룹(Page Header는 Dashboard에서 조합), 전체 56개 Story 파일을 확인했다.
- 대조 문서: Component 45개(Field 소비 가이드 포함), Pattern 7개, 기존 guideline 9개 및 CLAUDE.md/README.md. 현재 API·상태·Token·Story 경로를 비교하고 날짜가 있는 과거 검증 기록은 이력으로 읽었다.
- 현재 루트에 `.git`이 없다. Git diff/커밋 검증 대신 수정 전 확보한 파일과 로컬 변경 기록을 사용했다. 과거 기준 화면 snapshot과 보고서/CSV를 재생성하지 않았다.
Theme 흐름은 `primitives.css` → `default.css`의 Semantic/Theme palette 및 shadcn adapter → Component Mapping → CSS selector/utility → 실제 UI다. `theme.css`가 Default를 먼저 import한다. Component Mapping은 `:root, [data-hm-theme]`에서 다시 계산된다.
Runtime 계약은 `contract.ts`의 73개 입력이며 `runtime.ts`가 unknown 입력 전체를 검증한다. 색상은 6자리 불투명 HEX, input/container radius는 2–12px 정수, gradient는 세트 전체 또는 미지정이다. Partial/empty, atomic invalid fallback, 교체/cleanup, host inline value/priority 복원을 지원한다. Global 아래 명시적 Scoped Theme는 독립 HM Default + 자기 override이며 미지정 값이 Global override를 이어받지 않는다. 네트워크 Loader와 운영 Publish는 아직 없다.
## MATCHED — 유지한 구현
- **Active / Focus 분리**: Checkbox/Radio/Switch/Slider/Progress/Calendar selected·range edge는 Active, 일반 focus border/ring은 Focus를 사용한다. Runtime에서 Primary `#6837a8`, Active `#007f73`, Focus `#c75b00`을 분리해 기존 자동 검증을 새로 실행했고 실제 Checkbox/Calendar 채움과 Focus shadow 검사를 통과했다. Default에서는 Active/일반 Focus 모두 `#266651`이나 서로 alias하지 않는다.
- **Calendar / Date Picker**: selected와 range edge는 Active, hover/range middle은 Accent 45%, today는 Subtle Surface다. Global External에서 실제 Date Picker를 열면 body Portal의 selected day가 `rgb(0,127,115)`이고, 10/16 선택 후 닫히며 트리거로 Focus가 복귀했다. Wrapper Scoped popup의 제한은 아래 FOLLOW_UP이다.
- **Badge / Pagination**: Default Badge와 Pagination Current는 Primary Green(Default `#123328`). Global External에서는 둘 다 Primary purple로 바뀌고 Active teal과 구분된다. 실제 Pagination 일반 링크 hover는 Accent yellow 45%, Current는 Primary를 유지했다.
- **Table / Data Table**: row hover/selected는 공통 Accent 45%. Global Table에서 실제 hover/selected를 같은 `color(srgb 1 0.827451 0.427451 / 0.45)`로 확인했다. Data Table에서 행 선택 후 선택 면은 Default Accent 45%, Checkbox는 전환 종료 후 `rgb(38,102,81)`(Active), Current 페이지는 `rgb(18,51,40)`(Primary), 선택 요약은 `1개 선택됨 · 전체 47개`였다. Header 팔레트 장식은 별도 정책이다.
- **LNB 3Depth**: 기존 LNBGroup 중첩/Collapsible 조합을 유지한다. 3Depth 행 48px, padding-start 88px, weight 500/current 700, connector 40%와 current 배경·상위 노랑을 코드 및 실제 DOM으로 대조했다. Enter/Space 접기·펼치기와 소비자가 제어하는 중첩 open 상태가 유지된다.
- **Brand / Mobile / Scroll**: GNB+LNB는 GNBBrand 1개와 LNBBrand 0개. Standalone은 desktop LNBBrand, mobile Local bar의 서비스명으로 대체한다. 1023px에서는 GNB 56px/LNB hidden, 1024px에서는 GNB 70px/LNB 표시, 문서 폭은 viewport와 같다. 높이 700에서 LNB nav는 y=98→610, client 512/scroll 526; 실제 scrollTop=14에도 Profile y=610, GNB y=0을 유지했다. nav RTL/내용 LTR로 scrollbar를 시작 쪽에 배치한다. Standalone Mobile Sheet의 지역 3Depth 메뉴, Escape 닫힘과 `서비스 메뉴` 트리거 Focus 복귀를 확인했다.
- **Dashboard composition**: header/sidebar/children slot과 main scroll 소유권, desktop GNB/LNB 접점 및 mobile 전환이 현재 문서와 일치한다. KPI/Filter Bar/Data Table은 공개 primitive/pattern 조합이다. GNB+LNB 조립은 이미 구현되어 있다.
- **Dialog Wide Table**: 390px viewport에서 Dialog 358px, 문서 scrollWidth 390px, Table container client 308px/scrollWidth 1600px/overflow-x auto. 가로 스크롤은 내부 Table container가 소유한다. Header 13/20, Cell 14/20, padding 14/12를 유지하고 Escape 후 `넓은 표` 트리거 Focus 복귀를 확인했다.
- **Filter Bar Search Input**: 기본 padding-start 36px, focus 상태 35.5px 보정으로 아이콘 뒤 텍스트 시작점을 유지한다. 실제 검색 입력/조건 수/지우기와 좁은 화면 overflow를 확인했다. Input 구현/CSS는 수정하지 않았다.
- **Storybook**: favicon override는 실제 Manager DOM에서 icon link 1개, href `data:,`로 확인했다. 최종 빌드 index는 254개 Story/56개 그룹이며 UI 44개와 Pattern 6개 그룹은 각각 대표 Story 하나다. Theme 4개 Story는 verification으로 기본 숨김. 새 Progress NonDefaultMax도 숨김 verification이며 대표 Story에 같은 specimen이 있다.
## DOC_FIX — 수정 완료
- Component/Pattern의 오래된 Story 경로를 현재 category/title로 갱신했다. Page Header는 별도 Story 없이 `Patterns/Layout/Dashboard Layout`에서 사용한다.
- Primitive 직접 참조 설명을 현재 Semantic/Theme palette 연결에 맞췄다. Input/Textarea/Radio의 Destructive, Table/Subtle, Slider/Progress track, Tabs/Separator/Scroll Area, GNB/LNB/Loading Screen을 대조했다.
- Button의 로컬 HEX 잔존 설명, Select indicator 리터럴 설명, Select/Menu/Command의 full Accent 설명을 실제 palette/Accent 45% 연결로 고쳤다. Toggle on/full Accent와 Select selected/45%의 차이를 명시했다.
- Runtime API 미구현/Preview 전용, root 아래 Production 경로, toolbar 전환, 초기 5개 Component 상태를 현재 workspaces/API/Story 구조로 정정했다. Library build/registry/Loader/Publish 목표 절차와 현재 구현을 구분했다.
- CLAUDE.md의 Portal container API 설명을 실제 HM popup API 제한으로 바로잡았다. general Focus 설명에 기존 Slider/GNB/LNB 예외를 명시했다.
- Data Table의 With Filter Bar를 두 번째 대표 Story라고 한 설명을 숨김 verification으로 정정했다. Filter Bar 문서의 연동 대상도 Data Table로 유지했다.
- 과거 검증 절의 당시 색상·측정·실패/미확인 기록은 현재 결과로 덮지 않았다. Progress의 이전 max 제한에는 이번 수정 기록을 추가했다.
## CODE_FIX — 수정 완료
**Progress의 max 비율 계산 한 곳**을 수정했다(`packages/ui/src/components/ui/progress.tsx`). 이전에는 value를 백분율로 간주하므로 max=200/value=50에서 ARIA는 50/200인데 채움은 50%였다. 이제 유효 value/max 비율로 25% 채우며 Radix 기본 max/유효 범위 및 값 없음 상태를 따른다. 디자인/CSS/공개 API는 유지했다.
`src/components/progress.stories.tsx`에 max=200의 0/50/200/값 없음 specimen과 ARIA/Indicator 회귀 검증을 추가했다. 실제 DOM은 각각 transform -100%/-75%/0%/-100%, ARIA 0/50/200/valuenow 없음으로 일치했다. 기존 max=100 대표 상태와 interactive specimen도 유지했다.
Production 수정은 위 파일 1개, Story 수정은 Progress 파일 1개다. 기존 문서는 58개 파일에 경로/Token/현재 상태를 정정했으며 Component·Pattern 구현을 재작성하지 않았다.
## STALE — 현재 설명에서 정리
- 초기 5개 Component/Medium Preview만 구현된 상태.
- Storybook toolbar Default/Draft 전환과 Runtime API 공개 여부를 미래 결정으로 적은 설명.
- Dashboard가 다음 작업이거나 GNB+LNB 조립 자체가 아직 없는 상태.
- Alert Dialog 미구현, Dialog 이후 구조 안정화 대기, Select의 근거 없는 동시 작업 추측.
날짜가 있는 이전 작업 보고서, CSV, ui-viz 비교표는 폐기하지 않았다. 현재 구현 증거로 재사용하지 않고 당시 이력으로 구분했다.
## AMBIGUOUS — 이번에 변경하지 않음
- Slider Primary 20% halo, desktop GNB/LNB inverse outline(current는 Primary)까지 일반 Focus Semantic으로 통합할지. 현재 component 문서와 Runtime 문서는 예외를 명시하지만 일반 Focus 표현을 한 가지로 확대하면 디자인 결정이 필요하다. 일반 Focus의 Light 2 자체도 가이드에 시험 적용값으로 남아 있다.
- GNB+LNB gradient 이음새/콘텐츠 모서리의 최종 시각 승인. 조립과 Brand ownership은 구현/확정되었고, 이 부분은 Dashboard/GNB 문서에서 확정 대기로 남아 있다.
- 선택 경로 전체 connector 강조와 모바일 LNB의 14px 지역 메뉴/상위 current 표현 등 기존 미확정 Layout 항목. 현재 문서에 없는 최종 정책을 추정해 바꾸지 않았다.
## FOLLOW_UP — 별도 작업
- HM SelectContent/PopoverContent/DatePicker의 wrapper Scoped Theme 전달 API. 현재 body Portal은 Global Theme를 따르며 자동 Scoped 전달을 제공하지 않는다.
- Date Picker/Combobox를 undefined로 비우는 controlled reset 제약(현재 문서대로 key remount 사용). 새 API/상태 모델 작업으로 분리한다.
- FilterBarSearch에 disabled/readOnly를 전달할 때 별도 지우기 버튼의 활성 정책. 현재 input props는 Input에 전달되고 clear callback은 독립적으로 실행된다. 이번에 새 상태 계약을 만들지 않았다.
- Center Graphic/Facility의 7개 노출 Story는 서로 다른 시설물 export를 묶은 그룹이다. UI와 같은 단일 집계 대표 Story로 정리할지 검수 구조를 별도로 결정한다. 기존 CENTER 구현은 이번에 변경하지 않았다.
- 문서 예시를 자동 탐색해 생기는 CSS warning, Storybook chunk size와 docgen callback 성능 안내. 빌드 실패는 아니며 source 탐색/번들 최적화는 별도 범위다.
- Library 산출물/Registry, 네트워크 Loader, Theme Publish 운영은 아직 미구현이다.
## 최종 통합 검증
- `npm run typecheck`: PASS / exit 0. 루트와 두 workspace 포함.
- `npm run build`: PASS / exit 0. CSS 예시 warning 1개 유지.
- `npm run build-storybook`: PASS / exit 0. CSS 예시 warning, 500kB chunk 안내 및 PLUGIN_TIMINGS 성능 안내가 출력되었다.
- 현재 실제 Storybook Runtime 자동 검증: **PASS — 136 checks; 63 rendered parts**. Default parity, 73개 공개 입력, 의미 독립성, partial/empty/invalid, switching/cleanup, Global/Scoped, geometry를 새로 실행했다.
- CSS 변수 의존성/현재 문서 Token·Story 경로/73개 계약표를 정적으로 대조했다. Loading spinner index는 TSX inline style로 선언되며 LNB collapsed-width는 문서에서 명시적으로 없는 변수다.
- 최종 빌드 index에서 대표/verification 태그와 신규 NonDefaultMax 포함을 확인했다. 전체 254개 Story의 모든 play/interaction을 실행했다는 의미는 아니다. 실제 동작 검수는 위 핵심 대상에 집중했으며 다른 브라우저/실기기는 미검증이다.
로그/변경 기록: `_local/consistency-typecheck.log`, `consistency-build.log`, `consistency-storybook-build.log`, `consistency-audit-data.json`, `consistency-audit-diff.txt`. 로컬 비교용 파일은 `_local/consistency-audit-before/`에 확보 시점 기준으로 보관했다. Page Header 경로 및 Loading Screen Token의 단일 문구 수동 수정은 위 수정 범위에 별도로 기록했다.
화면 증거: `_local/consistency-progress.png`, `_local/consistency-progress-final.png`(실제 Manager에서 대표 Story 하나와 max=200), `_local/consistency-dialog-mobile.png`. Runtime 검증의 PASS 수치는 현재 브라우저의 result output에서 직접 읽었다.
## 작업 시간 (KST)
- Started At: 2026-10-06 15:03:01
- Estimated Duration: 40–60분(분석 20–30 / 최소 수정 10–15 / 통합 검증 10–15)
- Completed At: 2026-10-06 15:25:46
- Actual Duration: 22분 45초
- Variance: 예상보다 17분 15초–37분 15초 단축