84 lines
13 KiB
Markdown
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는 사용자 요청대로 진행하지 않았습니다.
|