Files
HMDesign/docs/org-chart/react-integration-report-v0.1.md
T

84 lines
13 KiB
Markdown

# HMDesign OrgChart v0.1 React Wrapper · Storybook 통합 검증
RESULT: **PASS** — 이번 요청의 React 통합 MVP 완료 조건 13개를 충족했습니다. 아래 NOT VERIFIED는 별도 한계로 보존하며 모든 기능·디자인·배포 환경의 검증 완료를 뜻하지 않습니다.
## 구현 결과
1. 작업 경로 `D:\디자인시스템\HMDesign-OrgChart`, 브랜치 `feature/orgchart-package`. 사용자 첨부 요청의 별도 작업/Git 지시를 적용했습니다. 운영 `D:\디자인시스템\HMDesign` 및 `main`은 수정하지 않았습니다.
2. 작업 전/후 HEAD, Local main, 공식 원격 main/Feature 모두 `d18e3c33801e165e17b6d971e2f6198eed483c3c`. 공식 origin은 `https://gitea.hmac.kr/b25027/HMDesign.git`입니다. 시작/완료 시 원격을 읽기 전용으로 확인했습니다.
3. 신규 `packages/org-chart-react`, `@hm-design/org-chart-react@0.1.0`. Core `@hm-design/org-chart@0.1.0` dependency, React `^19.0.0` peer. React DOM은 Wrapper가 사용하지 않아 별도 dependency/peer를 추가하지 않았으며 소비 앱이 제공합니다. 설치 package/lock과 React/DOM `19.3.0`, Storybook `10.6.1`, 엔진 `6.0.0` 일치를 확인했습니다.
4. Runtime Export는 `OrgChart`. Type Export는 `OrgChartProps` 및 Core 공개 타입의 type-only re-export입니다. Props는 공개 `OrgChartOptions`에서 container/onStateChange를 제외하여 재사용합니다. 필수 `dataSource`, `stylesheetUrls`; 선택 `aggregationPolicy`, `className`, `style`, `onStateChange`, `onLifecycleError`. 제목·직원·Zoom 등 임의 Props는 추가하지 않았습니다.
5. 생명주기는 Core 생성 → 구독 → mount, Source identity 교체 → reload, cleanup → 구독 해제·destroy입니다. 최초 추가 Reload가 없고 Callback 변경만으로 재생성하지 않습니다. Core가 변경 setter를 제공하지 않는 Policy identity/CSS URL 값 변경은 정리 후 재생성합니다. 같은 URL 문자열의 새 객체는 재생성하지 않습니다. Source/Policy 내부 mutation은 변경 알림으로 취급하지 않습니다.
6. committed Callback, 소유권, Source 갱신을 순서대로 layout effect에 연결했습니다. commit과 passive cleanup 사이의 오래된 요청 Callback 가능 구간을 닫습니다. generation/operation 검사는 이전 인스턴스 Promise의 늦은 rejection을 차단하며 Core revision/AbortSignal이 오래된 데이터 응답을 차단합니다. Wrapper 안에 DOM 엔진·Validation·Summary·노드 UI·엔진 정리 로직을 복제하지 않았습니다.
7. ESM과 선언을 자체 최소 build.mjs로 생성하며 React, JSX runtime, Core를 external로 유지합니다. 산출물의 client boundary를 보존했습니다. 기존 공통 build 스크립트는 수정하지 않았습니다. 최종 Wrapper ESM 약 3.09 kB/gzip 0.92 kB입니다.
8. 기존 HM Theme/폰트를 호스트에서 제공하고 공개 engine.css/style.css의 실제 URL을 Shadow DOM에 주입합니다. Storybook의 기존 preview CSS/decorator를 그대로 사용하며 별도 소비자는 공개 Theme entry를 사용합니다. Production의 해시 Asset URL과 폰트 로드를 실제 확인했습니다. 새 Theme·브랜드 팔레트나 reset을 만들지 않았습니다.
9. `src/org-chart/org-chart.stories.tsx`, 분류 `OrgChart/Content`. 기존 glob에 포함되므로 `.storybook/main.ts`/preview 변경이 없습니다. 기존 Component/Pattern Story를 바꾸지 않았습니다. 모든 Story는 공개 Wrapper와 Strict Mode를 사용합니다.
10. 필수 Story 8개: Basic Organization, Organization Hierarchy, Employee Cards, Organization Summary, JSON Data Update, Loading / Empty / Error, Responsive Container, Multiple Instances. 기존 HTML v1/v2 JSON을 직접 import하며 추가 시나리오는 파생 가상 데이터 및 같은 Source Interface만 사용합니다. 주변 조작은 공개 HM Button을 실제 렌더링합니다.
11. Navigation·Header·Dashboard·CSV·추가 업무 메뉴·API는 없습니다. FilterBar/DataTable은 검색·필터·정렬·선택 요구가 없어 사용하지 않습니다. 노드/상태/집계는 Framework-independent Core의 승인된 책임이며 React HM 위젯으로 복제하지 않습니다.
12. 실제 empty 화면을 구현한 것으로 표시하지 않습니다. 직원 0명은 Ready, 조직 0개는 Error입니다. Zoom/Pan은 비활성 상태로 유지합니다. hubText/showDispatched/showOnLeave 등 기존 reserved 영역, 복잡한 relation overlay도 추가 구현하지 않았습니다.
## 최종 통합 검증
- **PASS** Wrapper Typecheck: `npm run typecheck:org-chart-react`. 최종 생명주기 수정 후 다시 확인했습니다.
- **PASS** 루트 앱·Storybook TypeScript graph: `tsc -p tsconfig.app.json --noEmit`. 별도 React 소비자도 strict Bundler 타입 검사를 통과했습니다.
- **PASS** Wrapper Package Build: ESM/선언/client boundary/external 확인. Storybook prebuild의 기존 workspace 빌드도 Core/UI/Center Graphic을 포함해 성공했습니다.
- **PASS** 실제 npm tarball Public Export 및 선언: 추출된 Core/Wrapper에서 DOM 없는 ESM import, strict NodeNext consumer, 필수 Source와 미지원 Zoom/container 타입 경계 확인. React/compiler는 현재 검증 환경에서 제공합니다. 새 PC의 fresh dependency install 결과로 해석하지 않습니다.
- **PASS** Storybook Production Build: 최종 Wrapper/Story/CSS 상태의 `storybook build` 성공. 큰 기존 chunk 및 plugin timing 경고가 있으나 build 실패는 없습니다.
- **PASS** Storybook 실제 브라우저: Production의 8개 Story와 개발 6025의 실제 Wrapper 노드 실행. JSON v2 갱신, Unmount/Mount, Source 오류·복구, 직원/조직 0개, 취소를 무시하는 늦은 응답, A 갱신/제거 시 B identity·데이터·Callback 유지 확인.
- **PASS** 독립 React Consumer: `examples/org-chart-react`의 공개 package import·Vite Production Build·실제 Chrome 실행, 초기 mount/Source 교체/최신 Callback/Unmount. Storybook 성공을 소비자 성공으로 대신하지 않았습니다.
- **PASS** 개발 React Strict Mode: setup → cleanup → setup에서 두 번의 Source load와 최종 Ready 1회, 활성 Core host 1개. Production은 replay 없이 초기 load/Ready 각 1회임을 별도로 확인했습니다. 두 Source load는 Strict Mode의 의도된 setup 반복이며 Wrapper의 초기 이중 Reload가 아닙니다.
- **PASS** 생명주기: Callback/className 변경 시 같은 Core·추가 load 없음; Source 교체 시 같은 Core reload; Policy/CSS URL 변경 시 새 Core; 같은 CSS URL 값은 유지. 실패한 구성의 lifecycle callback, 정상 오류→Ready 복구, 늦은 응답·Unmount 후 Callback 차단, 5회 반복 mount/unmount의 DOM/관찰자 기준 유지, 최종 Core DOM/관찰자 0 확인.
- **PASS** HTML/React 공통 데이터: v1 조직 3개·직원 4명·직접 Root/A/B 1/2/1, v2 조직 3개·직원 5명·직접 1/1/3. DOM의 organization ID/parentId·employee ID·노드 텍스트·Heading·Summary를 비교하여 일치했습니다.
- **PASS** Theme CSS: HTML/React의 전경·surface·radius·폰트 computed 일치, 기존 Theme 변수 상속, 두 CSS link의 실제 stylesheet 로드, scoped Theme 변경 시 다른 인스턴스 유지, Engine selector의 light DOM 오염 없음.
- **PASS** 반응형: 실제 390/768/1280/1440px에서 소비자 및 Basic/Employee/Responsive Story의 document overflow·노드 겹침·텍스트 폭·null 사진 fallback 확인. scrollWidth/clientWidth 및 scrollHeight/clientHeight 측정을 저장했습니다. 390px은 원래 노드 크기와 내부 가로 스크롤을 유지합니다. 실제 scrollLeft 이동도 확인했습니다. 소비자 Grid item min-width와 Story Grid track을 수정하여 문서 overflow를 제거했습니다.
- **PASS** 키보드: Enter/Space 접기·펼치기 및 데이터 교체로 기존 focus가 제거될 때 안정된 Core viewport로 복귀. 접기 애니메이션이 끝나기 전 재입력은 기존 Core가 거부하므로 검사도 실제 transition 완료를 기다립니다.
- **PASS** 기존 Vanilla: 기존 HTTP HTML의 v1→v2 비교 및 `file://` classic의 Ready 4명→Update 5명 smoke. 변경 없는 기존 22개 데이터 테스트/69개 전체 브라우저 검사는 반복하지 않았습니다.
- **PASS** Chrome `155.0.8059.39`: 통합 검사 **70/70**, 추가 경계 검사 **9/9**, console/pageerror **0**. 대표 390px 긴 텍스트·Responsive 및 1440px 소비자 캡처도 육안 확인했습니다.
- **PASS** 보존: 시작 파일 **614/614 SHA-256 일치**, 기존 Core/HTML/7개 설계 문서/이전 구현 보고/UI/Center Graphic/Theme/Story/공유 build 설정 보존. `git diff --check` 통과. 운영 main Working Tree는 시작·완료 시 깨끗합니다. Staged diff는 비어 있으며 Stage/Commit/Push/Merge가 없습니다.
## Guard와 미검증
- Storybook과 독립 소비자에 범위별 PARTIAL Guard를 실행했습니다. 최종 원본 status/staticStatus는 **NOT VERIFIED**, FAIL 0입니다. Storybook의 동적 width, 소비자의 동적 className 및 실제 브라우저 증명 요구를 그대로 유지합니다.
- 원본 CSS styleEvidence는 **STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT NOT VERIFIED / FINAL NOT VERIFIED**입니다. 별도 브라우저 computed·컨테이너 검사 PASS는 기록한 요소/상태/폭의 증거이며 Guard 원본이나 디자인 의도 승인을 덮어쓰지 않습니다. Guard 결합 판정은 수행하지 않았습니다.
- 최초 소비자 Guard의 target 상대경로 입력이 맞지 않아 checkedFiles=[] 진단이 발생했습니다. 원본 `guard-consumer-initial.json`을 보존하고 상대경로/entry를 교정한 실제 graph 검사를 별도로 저장했습니다. Story CSS 수정 후 CSS-only PARTIAL은 NOT APPLICABLE이어서 최종 Story graph 검사를 별도로 저장했습니다. 빈 검사 결과를 PASS로 계산하지 않았습니다.
- **NOT VERIFIED** 완전한 Heap/GC 회수, 전체 스크린리더·SSR/hydration, 모든 브라우저/모바일 touch, 매우 큰 데이터 성능·깊이, Workdesk 원본과의 시각적 일치, Theme 미연결 스타일, 실제 API/auth, fresh npm registry 설치 및 임의 배포 base/CSP/origin입니다.
- Scope 한계: 공개 Props의 arbitrary className/style 및 모든 외부 데이터·Theme 조합은 전수 검사하지 않았습니다. readOnly/disabled 입력 필드는 없는 콘텐츠 패키지이며 전체 업무 화면 접근성 검증으로 해석하지 않습니다.
- 기술적 리스크: 기존 Core의 엔진 6.0.0 내부 init observer hook 의존은 유지됩니다. 엔진 upgrade 시 정리 계약 재검토가 필요합니다. Policy identity 변경은 재생성되므로 immutable/memoized Props를 권장합니다. Core 갱신 시 expansion/scroll state 보존은 추가하지 않았습니다.
- 도구 이슈: 로컬 npm symlink EPERM 및 sandbox Chrome loopback 차단은 허용된 실행 권한으로 재시도해 해결했습니다. 최초 sandbox Storybook의 사용자 설정/registry 쓰기 경고도 접근 가능한 개발 서버 재실행 후 사라졌습니다. 운영 6024 서버를 중단하지 않았습니다.
## 파일과 증거
이번 변경(기존 작업 위에 추가):
- 수정 `package.json`: 기존 OrgChart scripts 유지, Wrapper build/typecheck·소비자 build/dev/browser scripts, Core/Wrapper root dependency 연결.
- 수정 `package-lock.json`: root Core/Wrapper dependency, Wrapper workspace link·manifest. 해당 추가를 제거하고 원래 CRLF로 재직렬화한 SHA가 시작 lockfile SHA와 일치하므로 기존 dependency graph/버전은 보존했습니다. npm 재직렬화로 line ending은 LF입니다.
- 신규 `packages/org-chart-react/{package.json,build.mjs,tsconfig.json,tsconfig.build.json,README.md,src/OrgChart.tsx,src/types.ts,src/index.ts}`.
- 신규 `src/org-chart/{org-chart.stories.tsx,org-chart-stories.css}`.
- 신규 `examples/org-chart-react/{index.html,index.css,app.tsx,vite.config.ts,README.md,verify.mjs,verify-package.mjs,verify-boundaries.mjs}`.
- 신규 이 보고서. 시작 시 기존 package/lock의 Core 관련 diff와 untracked docs/examples/Core는 이번 신규 변경과 구별하여 보존했습니다.
검증 생성물(Git ignored):
- `test-results/org-chart-react/report.json`: 70개 검사, HTML/React snapshots, four-width 측정과 PNG.
- `test-results/org-chart-react/boundaries.json`: 추가 9개 경계 검사.
- `test-results/org-chart-react/tarball-consumer/report.json`: public archive/declaration 검사.
- `test-results/org-chart-react/preservation.json`, `baseline.json`, `baseline-lock-reconstructed.json`: 시작/완료 보존 근거.
- `test-results/org-chart-react/guard-storybook-final.json`, `guard-consumer.json`: 최종 원본 Guard. 초기/부분 진단도 별도 보존.
- `test-results/org-chart-react/storybook-build.log`: 최종 Production Build 로그.
확인용 개발 URL:
- Storybook `http://127.0.0.1:6025/?path=/story/orgchart-content--basic-organization`.
- 독립 React 소비자 `http://127.0.0.1:6026/`.
- 기존 운영 Storybook `6024`, 원래 PID `19932` 유지.
## 시간 기록 (Asia/Seoul)
- Started At: 2026-10-12 10:24:24 KST
- Completed At: 2026-10-12 10:42:39 KST
- Actual Duration: 18분 15초
- Estimated Duration: 최초 2~3시간
- Variance: 예상 하한 2시간 대비 101분 45초 단축; 예상 상한 3시간 대비 161분 45초 단축
예상 시간은 참고값입니다. 기존 Core/설치 환경과 병렬 구현을 재사용해 실제 시간이 줄었으며 미검증을 PASS로 대체하지 않았습니다. Commit·Push·Merge는 사용자 요청대로 진행하지 않았습니다.