8.4 KiB
AI 화면 선택·완료 계약
읽는 순서는 AGENTS.md → 아래 해당 기능 행 → 공개 인덱스의 선택 문서와 대표 All Story다. 과거 보고서·verification Story의 기능을 새 요구사항으로 복사하지 않는다.
구현 전 기록
요구사항마다 필수 액션·상태·완료 조건을 기록한다. 요청된 메뉴 이름만 Navigation에 넣는다. 미지정이면 선택 근거를 기록한다. 범위는 STORYBOOK_ONLY | PRODUCTION_UI | BOTH, 신규 화면 Runtime은 React다.
| 요구 기능 | 먼저 선택할 Pattern | Component·소비 책임 |
|---|---|---|
| 목록 검색·필터 | FilterBar, 표가 필요하면 DataTable | 조건 → 검색 → 조회 → 초기화. draft/applied 분리. PageHeader 밖 Card 하나. layout="list-basic" 가운데, 추가 조건은 list-extended 왼쪽. |
| 업무 Dashboard | DashboardLayout·Header·Main·Content | Header 48px, 최소 960px 내부 스크롤. Sidebar 없음. 상태는 Dashboard Status 계약. |
| Form | 별도 공개 Form Pattern 없음 | Label + Input/Textarea/Select/Checkbox를 Card 안에 조합. useId, htmlFor, 오류 메시지, 첫 오류 focus. 중복 Form Component 불필요. |
| 서비스 상단 메뉴 | GNB + GNBMobileMenu | 요청된 경로만 Desktop/Mobile에 동일하게 구성. Sidebar 없음. |
| 계층별 좌측 메뉴 | LNB + LNBMobileHeader/Menu | 공식 독립 LNB 허용. 모바일에도 LNB 모드 유지. |
| 작업 확인 | Dialog 또는 AlertDialog | Title/Description, 취소/진행, Escape와 trigger focus 복귀. 취소·삭제는 Solid. |
| 측면 상세 | Sheet | 방향·안쪽 모서리·키보드 focus는 기존 API. 메뉴 대체로 추가하지 않음. |
| 하단 작업·드래그 | Drawer | desktop 취소→실행, mobile 실행 위·취소 아래. 실기기 drag 별도 검증. |
| 초기/부분 로딩 | LoadingScreen 또는 Skeleton | 기존 콘텐츠 유지 여부를 요구사항으로 결정. |
| 빈 목록·오류 | DataTable emptyMessage / 콘텐츠 HTML / Alert | 임의 Empty Component 불필요. 재시도는 요청된 경우만. |
Pattern → Component → Variant/Prop → Composition 순으로 선택한다. 부적합한 Pattern은 구체적인 API·구조 제약을 기록한다. React composition용 로컬 함수는 허용하지만 HM 위젯과 동일 기능의 중복 구현은 만들지 않는다.
의존성 탐색과 명령 결과
패키지의 공개 API와 설치된 package.json의 exports/types를 먼저 확인한다. 내부 선언이 필요한 경우 rg --files <실제 패키지> -g '*.d.ts'나 Test-Path -LiteralPath로 존재를 확인한 파일만 읽는다. 배포 패키지에 src/features가 있다고 추측하거나 없는 경로를 만들어 복구하지 않는다. CWD와 실제 node_modules 연결 위치를 기록한다.
독립 실험 사본에는 .storybook 설정이나 브라우저 도구가 제공되지 않을 수 있다. 실제 폴더 목록을 먼저 확인하고 검색 root에는 존재하는 경로만 넣는다. 대표 Story 소스는 Component/Pattern 참조에 사용하지만, Storybook 실행을 요청하지 않은 독립 React 생성에서는 .storybook 설정은 선택 참조다. 필수 문서·공개 패키지·bootstrap의 누락은 별도 실패이며, 선택 참조의 부재와 혼용하지 않는다. 도구 목록 검색 무결과는 도구가 다른 환경에도 없다는 증거가 아니다.
rg의 exit 1은 오류 진단이 없는 검색 무결과일 때만 정상 검색 결과다. exit 2, 읽기/접근 오류와 Typecheck/Build의 nonzero exit는 별도 실패다. 복합 명령의 마지막 exit 0이 앞선 읽기·컴파일 실패를 가릴 수 있으므로 검증 명령별 종료 코드와 진단을 보존한다. vite.config.ts를 읽는 명령은 Build 실행이 아니다. 중단 실험의 CLI 완료를 화면 생성 PASS로 기록하지 않는다.
실행기가 개별 명령 결과를 제공하지 않으면 파일 읽기와 각 검색을 별도 호출한다. 복합 명령의 마지막 exit 1만으로 전체 명령을 정상 무결과로 확정하지 않는다. 명령별 결과가 있으면 모든 단계의 원문·exit·stdout/stderr를 확인하고, 앞선 실제 실패를 보존한다.
Theme와 접근성
- bootstrap은
index.css에서 Tailwind와 공개 HM Tailwind 설정,hm-theme.css에서 공개 Theme를 연결한다. 상태 사용 시 공개 Status CSS를 추가한다. Runtime 계약을 적용한다. - 자주 쓰는 변수:
--hm-sem-bg-content,--hm-sem-bg-surface,--hm-sem-fg-primary,--hm-sem-fg-secondary,--hm-sem-stroke-default,--hm-sem-stroke-input-default,--hm-sem-action-primary. 이름을 유추하지 말고 연결된 CSS의 선언을 확인한다. 공개text-primary,text-muted-foreground,bg-cardutility도 사용 가능하다. --hm-sem-text-*,--hm-sem-border-*,--hm-sem-stroke-divider는 선언 확인 없이 쓰지 않는다. 없는 HM token을 임의 fallback 색으로 감추지 않는다. Token 검사를 참고한다.- Component style/className은 기존 Prop·Token 계약을 먼저 사용한다. 동적 Token 후보와 fallback의 선언 여부를 확인하고, 외부 값·Props·동적 문자열은 실제 DOM·상태·브라우저·폭을 연결한 근거를 남긴다. HM Component의 임의 HEX/RGB/HSL·Spacing/Radius override는 Guard STYLE-001 대상이다. 일반 콘텐츠 레이아웃과 승인 여부가 불명확한 override는 CSS Intent 검사에서 구분하며, 미실행 Theme·상태와 사용자 디자인 의도는 NOT VERIFIED다.
- 항목명은 공개 Label과 control ID를 연결한다. SelectTrigger/Combobox도 id 또는 aria-labelledby를 연결한다. 반복 조합은 useId를 사용한다. placeholder는 항목명 대체가 아니다.
- Popup의
aria-haspopup은aria-controls가 가리키는 실제 role과 일치해야 한다. HM Combobox는 dialog를 열고 내부 검색 입력이 listbox를 제어한다. 기존 Component의 연결 속성을 임의로 덮어쓰지 않는다. GNBUser/LNBProfile의 명시적 접근성 이름도 화면에 보이는 이름·설명을 포함한다. - 레이아웃·콘텐츠 HTML 허용. 미지원 native 위젯은 구체적인 이유와 이름 연결을 기록한다. 숨겨진 focus 대상, 존재하지 않는 active panel, disabled/readOnly 값 변경을 확인한다.
- 내부 스크롤 화면의 숨김 absolute live region도 위치 기준이 필요하다. LNB 콘텐츠 연결의 positioned ancestor와 높이 분배를 따르고, 초기·조회·초기화·완료 상태에서 문서와 main의 scrollHeight/clientHeight를 따로 측정한다. 숨김 1px/clip 스타일만으로 외부 스크롤 방지를 보장하지 않는다. 전역 overflow:hidden으로 가리지 않는다.
- 표의 ID처럼 분절되면 의미가 흐려지는 값은 DataTable 식별자 소비 예제를 따른다. 표 내부 가로 스크롤과 실제 전체 ID 식별을 함께 확인하며 Typography/Color를 축소해 해결하지 않는다.
완료와 보고
- 화면 typecheck/build를 수행한다.
- 실제 entry에 Guard를 한 번 실행한다. 외부 앱도 동일 CLI로 검사한다. Production graph에 Story나 전체 저장소를 넣지 않는다. PARTIAL은 변경 파일을 명시한다.
- 실제 빌드 결과를 390/768/1280/1440px에서 확인한다. Dashboard는 내부 스크롤, 나머지는 페이지 가로 넘침 없이 구성한다. utility, Label, 키보드·focus 복귀, 보호 상태, 필수 액션을 확인한다.
staticStatus, 원본status, 브라우저 결과와 결합 결과를 따로 기록한다. source/contract 해시가 일치하는 Runtime 증거만 연결한다. 승인 CSS/native 예외의 미검증은 Runtime PASS로 지우지 않는다.- 실제 렌더된 Component·Pattern, 선택/미사용 이유, Navigation, 액션 범위, 실행한 검사와
NOT VERIFIED를 보고한다. 미요청 CSV·다운로드·API·추가 메뉴는 구현하지 않는다.
신규 화면은 Story로 등록하지 않는다. Storybook Reference 개선은 사용자 요청 범위에서 별도로 수행한다. Guard PASS는 디자인 점수·스크린리더 인증·backend 성공을 의미하지 않는다.