# OrgChart 선택형 UI 의존성 및 최소 설치 검증 RESULT: **PASS — 이번 최소 설치·선택형 Adapter 개선 범위.** 기존 P10 전체 판정 PARTIAL과 기존 Guard FAIL 10건은 유지한다. 전체 회귀·디자인 승인 결과로 확장하지 않는다. ## 1. 실제 실패 원인 원본 외부 로그: `D:\디자인시스템\조직도 테스트\evidence\consumer-build-without-ui.log`. 기준 Feature/HEAD: `feature/orgchart-package`, `5acaf8a29596317133e54e8ad437ee00beba1cf0`. 기본 React Entry → `OrgChart.tsx` → `lazy(() => import('./HMEmployeeDialog.js'))` → Dialog 청크 → `@hm-design/ui` 순으로 연결됐다. UI가 없는 소비자도 Vite 8.3.0이 dynamic import 청크를 Production Build에서 해석했다. optional peer stub에는 named export가 없어 다음 오류를 포함한 **12건의 MISSING_EXPORT**로 실패했다. ```text [MISSING_EXPORT] "Avatar" is not exported by "__vite-optional-peer-dep:@hm-design/ui:@hm-design/org-chart-react". node_modules/@hm-design/org-chart-react/dist/HMEmployeeDialog-gdk9Uddu.js:3:10 ``` React.lazy는 실행 시 로딩을 늦추지만 소비자의 빌드 의존성 그래프에서 해당 Import를 제거하지 않는다. 원인을 확인한 후에만 Entry를 분리했다. ## 2. 의존성·Import·공개 API - Core dependencies는 기존 `orgchart: 6.0.0` 그대로다. React/HM UI dependency, peer, Import를 추가하지 않았다. - Wrapper dependencies는 `@hm-design/org-chart: 0.1.0` 그대로다. `react: ^19.0.0` peer 및 `@hm-design/ui: 0.1.0` optional peer 선언도 그대로다. 신규 런타임 라이브러리·lockfile 변경이 없다. - 기본 `@hm-design/org-chart-react`는 UI-independent 공유 Wrapper만 Import한다. runtime JS와 `.d.ts`의 전이 그래프에 UI Import/참조가 없다. - 신규 공개 `@hm-design/org-chart-react/hm-dialog`는 같은 Props의 `OrgChart`와 `HMEmployeeDialog`를 제공한다. 이 Entry만 HM UI 공개 API를 Import한다. package exports의 JS/타입 경로와 실제 tarball 산출물이 일치한다. - 기존 `OrgChart`, 기존 Props, Core type-only re-export, `'core' | 'hm-dialog' | 'none'` 값을 유지했다. `'adapter'`, `employeePopupAdapter`, `OrgChartEmployeeSelection`, `OrgChartEmployeePopupProps`는 추가 API다. - 기본값은 항상 Core다. HM UI 설치, HM Entry Import 또는 Adapter 전달만으로 팝업을 전환하지 않는다. `employeePopup` 설정으로 사용자가 명시적으로 선택한다. - 기본 Entry에서 `'hm-dialog'`/`'adapter'`를 선택하고 Adapter를 제공하지 않으면 Core 팝업으로 유지하며 `onLifecycleError`에 구성 오류를 전달한다. `onEmployeeClick`은 기존대로 우선한다. - HM Adapter의 직원 필드·Avatar·Dialog·닫기·Escape·focus 복귀 구현은 유지했다. 타입 계약만 공용 UI-independent 타입으로 이동했다. - Auto에서 팝업 소유권 전환은 기존 `setEmployeeClickHandler`를 사용한다. Core 인스턴스와 데이터는 재생성·변경하지 않는다. Fixed의 기존 Core 팝업 정책은 유지하며, 다른 UI는 기존 `onEmployeeClick`으로 연결할 수 있다. - Department Colors와 Overview의 별도 페이지 Export를 추가하지 않았다. AI 실험 페이지를 이관하지 않았다. **기존 HM 소비자의 설치/API 전환은 Import 한 줄이 필요하다.** 기존 기본 Entry와 `employeePopup="hm-dialog"`만 사용한 코드는 다음 Entry를 선택하거나 `HMEmployeeDialog`를 명시적으로 주입해야 한다. 자동 HM 로딩은 더 이상 제공하지 않는다. ```tsx import { OrgChart } from '@hm-design/org-chart-react/hm-dialog'; ; ``` 다른 디자인 시스템은 기본 Entry에서 `employeePopup="adapter" employeePopupAdapter={MyPopup}`를 사용한다. Adapter는 `{ selection, onClose }`를 받으며 직원/context 원본을 수정하지 않고 접근성·닫기·focus 복귀를 소유한다. Core와 조직도 JSON을 수정하지 않는다. ## 3. CSS·자산·설치 경계 Core의 공개 `engine.css`와 `style.css` 실제 배포 URL을 기존 `stylesheetUrls`로 Shadow DOM에 연결했다. Core CSS는 기존 빌드가 source-relative CSS를 inline한 자체 산출물이며 HM Theme/CSS를 Import하지 않는다. React Wrapper에는 자동 CSS Import나 새로운 자산 참조가 없다. HM Entry도 Theme를 자동 Import하지 않고 호스트의 실제 HM Theme/Tailwind 연결을 사용한다. A/B에서는 HM Theme나 Tailwind를 설치하지 않았다. A에는 React도 없다. C는 선택 HM UI와 해당 peer/Theme를 소비 프로젝트에서 제공했다. 일반 콘텐츠 CSS나 Fixed/Expanded 디자인을 수정하지 않았다. ## 4. 실제 외부 프로젝트 A/B/C 세 프로젝트는 저장소 및 상위 `node_modules` 밖의 새 임시 폴더에 만들었다. 소비자 소스에는 저장소 내부 Import/alias/symlink가 없다. `npm pack` 실제 `.tgz`를 dependency로 설치했고 `npm ls --all --json`으로 설치 그래프를 기록했다. 프로젝트 절대경로는 [projects.json](../../test-results/org-chart-minimal-install/projects.json)에 보존했다. - **A Core + Vanilla: PASS.** React·Wrapper·HM UI가 없는 실제 설치. strict Typecheck, Production Build, Fixed/Auto 렌더링 및 native Core 팝업·Enter·Escape·닫기·focus 복귀 PASS. - **B Core + React Wrapper: PASS.** React/React DOM 19.3.0, HM UI·HM Theme·Tailwind 없음. 기본 선언 strict Typecheck, Production Build, Fixed/Auto 렌더링·Core 팝업 PASS. 다른 디자인 시스템의 팝업 Adapter 주입·callback 우선권·Adapter 미제공 시 Core 유지도 PASS. - **C Core + React Wrapper + HM UI: PASS.** React 19.3.0, HM UI optional peer·Theme 연결. strict Typecheck 및 Production Build PASS. 기본 Entry와 HM Entry 모두 명시적 HM 선택 이전에는 Core를 유지한다. 기존 HM Dialog의 직원 정보·Enter·Escape·닫기·focus 복귀, HM→Core 전환 시 동일 Core 인스턴스 유지 PASS. [외부 브라우저 검사](../../test-results/org-chart-minimal-install/browser.json): **17개 그룹 PASS**, 브라우저 Chromium 155.0.8059.39, 콘솔 오류·브라우저 예외·HTTP 실패 0. StrictMode의 최종 host 1개와 입력 데이터 byte 보존도 검사했다. 이것은 전체 회귀 테스트 건수가 아니다. [기본 Entry 전이 그래프](../../test-results/org-chart-minimal-install/default-entry-graph.json): `index.js`, 공유 Wrapper JS, `index.d.ts`, `OrgChart.d.ts`, `types.d.ts`에 HM UI 참조가 없음 PASS. B의 `skipLibCheck: false` 타입 검사가 HM UI 없이 통과했다. 실제 로그: [A 빌드](../../test-results/org-chart-minimal-install/build-A.log), [B 빌드](../../test-results/org-chart-minimal-install/build-B.log), [C 빌드](../../test-results/org-chart-minimal-install/build-C.log), [최종 외부 실행](../../test-results/org-chart-minimal-install/verification-online.log). 첫 offline 설치 시도는 샌드박스 npm 캐시에 TypeScript가 없어 ENOTCACHED로 중단됐다. 네트워크 설치로 해결했고 패키지 FAIL로 계산하지 않았다. 반복 검증은 실패한 환경·미완료 검사만 보완했다. ## 5. 기존 Storybook·최소 통합 검증 - `npm pack`: Core/UI/Wrapper의 prepack Build와 선언 생성 PASS. 공개 Entry가 실제 tarball에 포함됨 PASS. - `tsc -p tsconfig.app.json --noEmit`: 기존 앱·Storybook TypeScript graph PASS. - Storybook 10.6.1 Production Build: PASS. 기존 전체 회귀 suite는 실행하지 않았다. - [Storybook 브라우저](../../test-results/org-chart-minimal-install/storybook-browser.json): Expanded의 기본 HM 팝업, Escape/focus 복귀, 기존 Select를 통한 Core 팝업 전환 및 Core 모달 focus PASS. Full Composition Fixed의 렌더링·Core 팝업·Escape PASS. 콘솔 오류·브라우저 예외 0. - 외부 HM Dialog 캡처와 Storybook Expanded 캡처를 직접 확인했다. 레이아웃·직원 정보·닫기 버튼이 정상 표시됐다. 디자인 최종 승인을 의미하지 않는다. - [Git/산출물 보존](../../test-results/org-chart-minimal-install/preservation.json): Core/UI/Center Graphic/Theme/기존 데이터/정책/P10 보호 파일의 tracked 수정 0. Expanded Story는 Import 한 줄만 변경했다. 최종 Wrapper tarball은 README의 잔여 lazy 설명만 보완하여 `--ignore-scripts`로 다시 pack했고, 모든 JS·`.d.ts`가 실제 설치·검증된 B/C와 byte 동일함을 확인했다. 정상 Build를 반복하지 않았다. 빌드 경고는 기존 `:host-context` CSS minify 경고, vendor `use client` bundling 경고 및 큰 chunk 경고다. 빌드 실패는 없다. 이 작업에서는 관련 디자인·엔진 최적화 범위를 확대하지 않았다. ## 6. Guard와 NOT VERIFIED 기존 [P10.1 Guard](../../test-results/org-chart-p10-1/guard.json)의 FAIL 10건은 Core Token 참조에 대한 기존 기록이며 해당 파일을 수정하지 않았다. 원본 보고서를 보존했다. 전체 Guard를 반복하거나 전체 판정을 PASS로 바꾸지 않았다. 이번 변경만 한 번 검사한 [PARTIAL Guard](../../test-results/org-chart-minimal-install/guard-partial.json)는 **FAIL 0 / NOT VERIFIED 5**다. 원본 `status`와 `staticStatus`는 NOT VERIFIED, `runtimeStatus`도 NOT VERIFIED로 그대로 둔다. - SCOPE-001 3건: 패키지 구현이 Guard의 증명된 Storybook graph 범위 밖임. 별도 npm pack·외부 build·브라우저 증거를 연결하며 원본 상태를 덮어쓰지 않는다. - TOKEN-001: 기존 Expanded CSS의 Radix runtime 제공 변수. - TOKEN-002: 기존 StoryPage의 동적 className. - CSS styleEvidence: STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT NOT VERIFIED / FINAL NOT VERIFIED. 기존 CSS를 수정하지 않았으며 기술적 팝업 성공을 CSS 디자인 승인으로 사용하지 않았다. SSR/hydration, 다른 React major·bundler·OS, 전체 스크린리더, 실제 touch, 장기 메모리/성능, 390/768/1280px의 재검증, 전체 회귀 및 디자인·배포 승인은 **NOT VERIFIED / 이번 범위에서 미실행**이다. 이번 브라우저 검증은 1440px 핵심 팝업 동작에 한정했다. 기존 유효한 검사 결과는 과거 증거로 보존한다. ## 7. 변경 파일과 사용 가이드 반영 기존 수정 파일: - `packages/org-chart-react/package.json`: 선택 HM Entry Export 추가. dependency 선언 유지. - `packages/org-chart-react/build.mjs`: UI-independent/HM Entry를 함께 빌드. - `packages/org-chart-react/src/OrgChart.tsx`: UI Import 제거, 명시 Adapter 주입·Core fallback. - `packages/org-chart-react/src/types.ts`: UI-independent popup Adapter 계약 및 추가 Props. - `packages/org-chart-react/src/index.ts`: 공용 Adapter 타입 Export. - `packages/org-chart-react/src/HMEmployeeDialog.tsx`: 팝업 타입을 공용 계약으로 변경. - `src/org-chart/org-chart-expanded.stories.tsx`: HM 선택 Entry로 Import 한 줄 변경. - `packages/org-chart-react/README.md`: 최소 설치·HM Import 전환·커스텀 Adapter·빌드 경계 안내. - `docs/org-chart/expanded-usage.md`: HM 선택 Entry·Adapter 사용법 보완. 신규 파일: - `packages/org-chart-react/src/hm-dialog.tsx`: 선택 HM Adapter Entry. - `scripts/verify-orgchart-minimal-install.mjs`: 외부 실제 설치·타입·빌드·팝업 검증. - `scripts/verify-orgchart-hm-story.mjs`: 기존 변경 Story/Fixed 핵심 팝업 검증. - 이 보고서. 병렬 사용 가이드 담당자가 반영할 내용: 최소 설치에서 UI/Theme 제외, 기존 HM 소비자의 `/hm-dialog` Import 전환, `employeePopupAdapter` 및 `'adapter'` 계약, package 설치만으로 전환하지 않는 정책, Fixed의 기존 Core/`onEmployeeClick` 정책. Chart Only·UsageGuide Worktree 파일은 수정하지 않았다. 같은 파일의 동시 변경을 발견하지 않아 현재 Feature에서 최소 수정했다. ## 8. Git 및 시간 공식 origin: `https://gitea.hmac.kr/b25027/HMDesign.git`. Local/Remote Feature HEAD: `5acaf8a29596317133e54e8ad437ee00beba1cf0`. 읽기 전용 확인한 Remote main: `c45d63a03b84eaac43f01bd400a16488a80e4229`. main을 checkout·수정·Merge하지 않았다. Stage 0. **Commit·Push·main Merge 미진행.** 이 작업의 수정은 현재 Feature Working Tree에 남긴다. 기존 P10.1과 병렬 정책·사용 가이드 작업을 보존한다. - Started At: 2026-10-13 15:17:35 KST - Completed At: 2026-10-13 15:32:28 KST - Actual Duration: 14분 53초 - Estimated Duration: 약 35–50분 - Variance: 예상보다 20분 7초–35분 7초 짧음 검증 재현: 저장소의 일반 개발 의존성이 준비된 상태에서 `ORGCHART_PLAYWRIGHT_MODULE`을 기존 Playwright entry로 설정하고 `node scripts/verify-orgchart-minimal-install.mjs`를 실행한다. 기존 Chrome의 다른 설치 경로는 `ORGCHART_CHROME`으로 지정한다. 각 실행은 새 외부 임시 소비자를 만들고 기존 폴더를 삭제하지 않는다. Storybook 빌드 후 `node scripts/verify-orgchart-hm-story.mjs`로 선택된 기존 Story만 검사한다. 생성물은 `test-results/org-chart-minimal-install`에 보존하며 Stage하지 않았다.