Files
HMDesign/docs/org-chart/implementation-report-p7.md
T

189 lines
19 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.
# HMDesign OrgChart P7 구현·검증 보고
RESULT: **PASS — P7 변경 범위.** 전체 접근성·CSS 디자인 의도·운영 배포 승인으로 확대하지 않는다.
TB/LR/Hybrid 독립 모드, 데이터 선택, 선택형 HM Dialog를 구현했다. 최신 dabeng LR 예제 비교에서 추가 기능 수정이 필요한 결함은 발견하지 않았다.
Compact는 **현재 Auto adapter에서 NOT SUPPORTED**이며 요구사항의 허용된 제외 사유를 아래에 명시한다.
## 요청 항목별 결과
| 번호 | 항목 | 결과와 근거 |
|---|---|---|
| 1 | 폴더·브랜치·HEAD | `D:\디자인시스템\HMDesign-OrgChart` / `feature/orgchart-package` / `7614507583927a25a270963a74ff044be0557b9f`. origin `https://gitea.hmac.kr/b25027/HMDesign.git`. 시작·완료 HEAD 동일. |
| 2 | 작업 시간 | 아래 KST 시간 기록 참조. 최초 예상 60–90분. |
| 3 | 전체 합산 20/100/300 | **PASS**. 모든 7회사, 고유 Employee ID 기준 정확히 20/100/300. 가중 분배 후 선택 회사만 필터링하며 재분배하지 않음. |
| 4 | 회사별 20/100/300 | **PASS**. 각 회사 정확히 N명. helper 단위 검사는 모든 회사·규모 조합, 실제 화면은 단일 회사 20/100/300 확인. |
| 5 | 다중 회사 | **PASS**. 한맥기술+삼안 ×100=200명, 전체 7×300=2,100명. 빈 선택은 Core empty view. 전환 전 예상 규모 표시·데이터 적용 버튼 제공. |
| 6 | TB 유지 | **PASS**. 기존 Small fixture의 직원/그룹 위치·치수를 시작 전 dist와 직접 비교해 동일. 일반 TB 관계선 경로 보존. |
| 7 | LR | **PASS**. 실제 dabeng `direction:'l2r'`, 부모 좌측·자식 우측·형제 세로 정렬. 회사마다 독립 tree. 아래 공식 예제 비교 참조. |
| 8 | Hybrid | **PASS**. 실제 `verticalLevel` + 명시적 engine level. Root=1Depth, 시작 Depth 2/3/4. 부모별 지역 세로 배치·재귀 구조 검증. |
| 9 | 초기 Depth | **PASS**. 1/2/3/all, 모든 레이아웃에서 독립. 변경하면 초기 접힘 정책으로 재설정; 이후 사용자 접힘 상태는 유효한 조직 ID에 대해 유지. |
| 10 | 그룹 Hybrid·Compact | 그룹 Hybrid **PASS**, TB의 지정 그룹 자손에만 실제 적용. LR/전체 Hybrid와 조합 거절·Story disabled/자동 해제. Compact **NOT SUPPORTED**, 설명 참조. |
| 11 | 접기·펼치기 | **PASS**. click/Enter/Space, 유효한 하위 상태·형제 상태 유지. 독립 `collapse` 설정 제공. LR 접기·재확장 후 실제 양끝 연결 좌표·재배치 확인. |
| 12 | Zoom/Pan/Fit | **PASS**. 각 독립 설정·실제 pointer Pan·Ctrl-wheel gate·도구 버튼. Fit/100% 복원 및 키보드 focus 노출은 기능 스위치와 독립. |
| 13 | 연결선·Border | **PASS**. 실제 parentId·제목 좌표 및 직원 카드 도착점에 SVG 배치. LR 모든 직원 left 연결/left accent, TB/Hybrid 기존 top/left/right. 다른 면 중립·카드 치수 보존. |
| 14 | 컬러·흰 타이틀 | **PASS**. 7회사 프리셋 파일/배경 동일, 시작 전 `#ffffff` 변경 보존. normal/hover/focus/collapsed/expanded 흰 글자 확인. 삼안·장헌산업 대비 진단은 유지. |
| 15 | HM Dialog | **PASS**. 실제 공개 HM Dialog/Portal·Avatar·Button. 직원 identity, 필드, 단일 팝업, Enter/Space, ESC/닫기·focus trap/복귀, source 변경 시 stale 팝업 정리. 390px 필드/팝업 가로 overflow 없음. |
| 16 | Vanilla 호환 | **PASS**. 기존 Core native dialog 및 callback 계약 유지. React/HM은 Core 의존성이 아님. 동일 공개 helper/DataSource/Core로 직원 기록 공유. |
| 17 | 300/2,100 성능 | **PASS — 이 PC의 측정 시나리오**. 신규 LR/Hybrid 별도 실측·DOM/JS heap 기록. 아래 표 참조. 장시간·타 기기·peak memory는 NOT VERIFIED. |
| 18 | Fixed 영향 | **PASS — 최소 회귀**. 시작 전 dist와 geometry/SVG/text/gradient/border 동일, 새 Auto control 없음, 기존 팝업 open/ESC. 보호 자산 33개·고정형 관련 파일/프리셋/fixture 해시 동일. 전체 Fixed 픽셀 인증은 별도 미검증. |
| 19 | Storybook URL | [Expanded OrgChart](http://127.0.0.1:6056/?path=/story/orgchart--expanded-org-chart). 실제 React Story, 기존 사용자용 4개 메뉴 유지. internal/verification Story는 기존 제외 정책 적용. |
| 20 | 캡처 | 아래 현재 화면·LR·Hybrid·2,100명·Dialog·390px 링크 참조. |
| 21 | 수정 파일 | 아래 27개 authored 파일 목록. 기존 흰색 타이틀 변경과 새 P7 CSS는 같은 파일에 공존. |
| 22 | 변경 범위 검사 | focused unit **25/25**, Core/React typecheck/build, scoped Story typecheck, 실제 React consumer production build, 변경 범위 브라우저, `git diff --check` **PASS**. 초기 실패·수정 검사 provenance는 아래 기록. |
| 23 | 기존 FAIL/미검증 | 과거 기록을 변경하지 않음. Guard 정적 PASS / runtime·CSS intent/final NOT VERIFIED, 기존 제목 대비 진단, 실기기·스크린리더·전체 역사 회귀 등을 아래에 분리. |
| 24 | Git 미진행 | **Stage·Commit·Push·Merge·checkout·pull·reset·rebase·PR 모두 미진행.** staged 파일 0, branch/HEAD 동일. |
## 독립 옵션과 호환 범위
공개 사용 예와 세부 계약은 [expanded-usage.md](expanded-usage.md)에 있다.
`autoLayout.type`은 TB/LR/Hybrid 중 하나이며 다른 기능을 켤 필요가 없다.
| 옵션 | TB | LR | Hybrid | 제한 |
|---|---|---|---|---|
| 접기·펼치기 / Zoom / Pan | 각각 선택 | 각각 선택 | 각각 선택 | 각각 기본 true, 다른 스위치의 필수 사용 없음 |
| 초기 Depth / 회사 선택 | 독립 | 독립 | 독립 | 초기 Depth 변경은 접힘 상태를 초기 정책으로 재설정 |
| React popup core/hm-dialog/none | 독립 | 독립 | 독립 | HM 모드만 HM UI optional peer·호스트 theme 필요; callback은 기본 팝업보다 우선 |
| Hybrid 시작 Depth 2/3/4 | 적용 안 함 | 적용 안 함 | 선택 | 값은 보관하되 TB/LR에서는 적용하지 않음 |
| 지정 그룹 Hybrid | 지원 | 조합 거절 | 조합 거절 | Story는 비호환 모드로 전환할 때 목록을 해제 |
| Compact | 미지원 | 미지원 | 미지원 | 엔진 기능 자체의 미지원이라는 뜻은 아님 |
dabeng 6 Compact는 자식 `.node`를 부모 `.node` 내부에 넣고 140×50 grid 및 별도 compact/loose 토글을 사용한다.
현재 HM article·카드 크기·측정 연결선·그룹 접기 계약과 충돌한다. 기존 카드 디자인을 유지하면서
안전하게 연결할 수 없어 옵션을 제공하지 않았다. 새 엔진이나 레이아웃 라이브러리는 추가하지 않았다.
`visibleLevel` 요구는 Core 초기 접힘 projection으로 제공한다. upstream hidden 자손을 그대로 둘 경우
직원 카드·연결선 측정이 충돌하므로 engine에는 `visibleLevel:999`를 전달하고 실제 보이는 트리를 넘긴다.
## dabeng LR 공식 예제 비교
[사용자 제공 예제](https://dabeng.github.io/OrgChart/left2right.html) 및
[공식 원본](https://github.com/dabeng/OrgChart/blob/master/demo/left2right.html)을 현재 소스와 비교했다.
원본은 `direction:'l2r'`와 `.title/.content`를 사용한다. 설치된 dabeng 6도 동일 옵션이며
차트 회전·50×140 node·title/content 반회전 CSS를 사용한다.
현재 구현은 해당 방향 API·재귀 DOM을 재사용하고, 기존 HM 복합 article의 정방향·치수 유지에 필요한
Auto 전용 flex/측정 SVG adapter를 적용한다. 원본 화면과 픽셀 동일성을 요구하거나 주장하지 않는다.
| 사용자 확인 항목 | 판정 | 증거 |
|---|---|---|
| 1 실제 `l2r` 우선 재사용 | PASS | engine options 단위 검사, 실제 7개 `.orgchart.l2r`, 공식 원본/설치 소스 비교 |
| 2 최상위 왼쪽·하위 오른쪽 | PASS | 모든 parentId 대상 child-right 실측 |
| 3 형제 세로 정렬 | PASS | 모든 같은-parent 형제의 y 범위 검사 |
| 4 3Depth 이상 관계선 | PASS | 5Depth fixture, parentId 및 실제 heading endpoint 검사 |
| 5 LR 카드 Border 일치 | PASS | 모든 카드 left 방향·실제 도착점 <1px·한 면 accent 검사 |
| 6 접기 후 갱신 | PASS | 닫기/재확장 시 자손 수·겹침·부모/자식 선 양끝 재측정 |
| 7 전환 잔상 | PASS | TB→Hybrid→LR에서 tree 7 / l2r 7 / SVG 7 / 관계선 70 / 부모 있는 node 70 / vertical list 0 |
| 8 독립 회사 Root·겹침 | PASS | 7회사 300/2,100명 전체, 카드/그룹 겹침 없음, 회사 선택 독립 |
| 9 사진·직위·이름 정방향 | PASS | 모든 관련 element transform=none, 사진 36×36, 100% 캡처 확인 |
| 10 Zoom/Pan/Fit·팝업 | PASS | 기존 LR 통과 증거 재사용 + 독립 스위치/실제 HM Dialog 검증 |
이번 예제 비교 이후 제품 코드에 LR 추가 수정은 하지 않았다. 미확인한 정방향·접기 양끝·잔상만 추가 검사했다.
## 실행 검증과 초기 실패 처리
기존 P5/P6 전체 suite는 재실행하지 않았다. 새로운 helper/policy와 직접 영향받는 경로만 확인했다.
단위 검사 25개는 data example 11 + auto policy 7 + 기존 expanded layout 4 + company 3이며,
중간 수정 이후에는 영향받은 policy 검사만 갱신하고 나머지 유효한 결과를 재사용했다.
| 검사 | 결과 | 근거 |
|---|---|---|
| Core/React typecheck·build | PASS | 공개 패키지별 명령 실행. 마지막 Core build는 변경된 선언 주석까지 dist에 반영. |
| scoped Story typecheck | PASS | P7 Story만 포함한 tsconfig, 최종 그룹 이름 변경 후 확인. |
| 실제 React production consumer | PASS | 공개 패키지·HM theme/CSS·StrictMode bootstrap, production build 및 실제 브라우저. 기존 asset 크기로 chunk size 경고 1종, build 오류 없음. |
| Core 최초 변경 검사 | 84 PASS / 10 FAIL → 수정 확인 PASS | [초기 raw](../../test-results/org-chart-p7/browser-core-initial.json). update 후 Fit, LR 형제 CSS 우선순위, Hybrid engine level/부모별 list를 최소 수정. 실패 경로 및 연결선/2,100명 관련 [31/31 repair](../../test-results/org-chart-p7/browser-repair.json). |
| Story·production React | 50 PASS / timing 검사 2 FAIL → PASS | [초기 raw](../../test-results/org-chart-p7/browser-story-react.json). Radix 종료 animation/presence 전 검사였음. 종료 hidden을 기다리는 [3/3 targeted 확인](../../test-results/org-chart-p7/browser-react-repair.json). 제품 결함으로 재분류하지 않음. |
| 독립 interaction·최종 popup | 79 PASS 후 runner 중단 | [raw](../../test-results/org-chart-p7/browser-options-react-repair.json). 실제 그룹 옵션의 중복 회사 접두사 정리, 남은 옵션/폭/색상 [12 PASS](../../test-results/org-chart-p7/browser-options-tail.json). 최초 메뉴 집계는 internal 3개까지 포함해 실패; 기존 제외 정책 적용한 [2/2 메뉴 검사](../../test-results/org-chart-p7/browser-story-menu.json). |
| LR reference 추가 영향 | 4 PASS 후 잔상 집계 1 FAIL → PASS | [raw](../../test-results/org-chart-p7/browser-lr-reference.json). 빈 parentId Root까지 관계선 수에 포함한 테스트 오류; Root 제외 후 해당 검사만 [2/2 PASS](../../test-results/org-chart-p7/browser-lr-residue.json). 제품 코드 변경 없음. |
| 신규 성능·390px Dialog | 6/6 PASS | [raw](../../test-results/org-chart-p7/browser-performance-dialog-narrow.json). 측정 시간을 새로 확보한 검사이며 전체 suite 반복 아님. |
| 390/768/1280/1440 | PASS | 최종 설정 UI 줄바꿈, document 가로 overflow 없음, stage scrollLeft/Top=0, scrollWidth/clientWidth·scrollHeight/clientHeight 일치, Fit 전체 bounds. 문서 세로 스크롤은 정상. |
| 최소 Fixed 회귀 | PASS | 최초 Core raw의 Fixed geometry/SVG/text/gradient/border, Auto control 부재·native 팝업 open/ESC 및 보호 hash. |
| Guard 1회 | static PASS, issues 0 | [원본](../../test-results/org-chart-p7/guard.json), STORYBOOK/PARTIAL. raw status PASS, runtimeStatus NOT VERIFIED. 아래 CSS 범위 구분 유지. |
| 최종 diff·보호 파일 | PASS | `git diff --check`, [baseline](../../test-results/org-chart-p7/baseline.json), [최종 audit](../../test-results/org-chart-p7/final-state.json). |
Chrome `155.0.8059.39`, 기존 설치 Playwright/Chrome를 사용했으며 패키지 설치/업그레이드 없음.
localhost sandbox `ERR_NETWORK_ACCESS_DENIED` 초기 로그를 보존하고 허용된 로컬 브라우저 실행으로 확인했다.
서로 다른 실행의 PASS 수를 중복 합산해 총 검사 수라고 주장하지 않는다. 모든 성공 실행의 신규 console/page 오류는 0이다.
## 신규 모드 성능
Windows 이 PC, Chrome headless, 1440×1100, full depth·7회사·가상 fixture, 각 1회 관측이다.
Core mount는 `performance.now()`의 `handle.mount()` 시간, ready/interaction은 Playwright 동작과
font 준비·5 animation frame 대기를 포함한 경과 시간이다. 네트워크/브라우저 warm 상태와 GC 영향을 받으며 서로 다른 지표를 동일 benchmark로 비교하지 않는다.
| 데이터·모드 | Core mount | 화면 준비 | 접기 | Zoom | Fit | used JS heap | 내부 DOM |
|---|---:|---:|---:|---:|---:|---:|---:|
| 300 LR | 31.6ms | 442ms | 195ms | 116ms | 116ms | 9,839,068B | 3,306 |
| 300 Hybrid Depth2 | 19.2ms | 300ms | 182ms | 131ms | 118ms | 12,887,564B | 3,152 |
| 300 Hybrid Depth3 | 18.2ms | 325ms | 182ms | 133ms | 117ms | 17,325,639B | 3,194 |
| 300 Hybrid Depth4 | 17.1ms | 321ms | 183ms | 116ms | 118ms | 15,098,350B | 3,243 |
| 2,100 LR | 160.5ms | 미측정 | 미측정 | 미측정 | 전체 Fit PASS | 15,640,127B | 17,706 |
| 2,100 Hybrid Depth3 | LR→Hybrid 전환+준비 917ms | 앞 열 지표 | 미측정 | 미측정 | 전체 Fit PASS | 28,410,298B | 17,594 |
2,100명의 실제 카드 수·고유 ID·겹침 없음·전체 bounds를 따로 확인했다. 전체 Fit은 가독성이 작은 개요 화면이다.
카드 읽기에는 Zoom 또는 초기 표시 Depth가 필요하다. Story에서 2,100명 전환 규모를 적용 전에 표시하고
초기 Depth2로 전환하는 실제 UI도 확인했다. `performance.memory.usedJSHeapSize`는 한 시점의 JS heap이며
DOM native memory·프로세스 전체 메모리·peak·누수/장시간 반복을 증명하지 않는다. 2,100명 interaction latency 전체는 NOT VERIFIED.
## 미검증·기존 진단 보존
- Guard `styleEvidence`: **STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT NOT VERIFIED / FINAL NOT VERIFIED**.
이 실행에 결합 `styleVerification`은 생성하지 않았으며 NOT VERIFIED로 취급한다. Story 정적 graph와
별도 실제 React build/browser 증거를 전체 Core CSS·임의 외부 props/style의 인증으로 합치지 않는다.
- 기존 삼안·장헌산업 흰 타이틀의 일반 텍스트 대비 미달 진단을 유지한다. 요청한 흰색·회사 색은 변경하지 않았다.
P6.1의 Auto 관계선 대비 수정과 과거 FAIL/미검증 기록은 그대로 보존한다.
- 실제 스크린리더 발화·물리 터치·다른 브라우저, 전체 Fixed 픽셀/모든 폭·전체 과거 회귀,
모든 임의 데이터/override/옵션 상태 조합, HM peer 없는 fresh install/bundler, 운영 배포·SSR/hydration은 **NOT VERIFIED**.
실제 API/서버/DB·실제 개인정보는 요청 범위 밖이며 추가하지 않았다.
## 주요 화면
- [최종 설정 화면 1440px](../../test-results/org-chart-p7/story-1440.png), [390px](../../test-results/org-chart-p7/story-390.png)
- [LR 300명·7회사](../../test-results/org-chart-p7/corrected-lr-group.png), [LR 카드 100% 정방향](../../test-results/org-chart-p7/lr-card-upright.png)
- [Hybrid Depth2](../../test-results/org-chart-p7/corrected-hybrid-2.png), [Depth3](../../test-results/org-chart-p7/corrected-hybrid-3.png), [Depth4](../../test-results/org-chart-p7/corrected-hybrid-4.png)
- [HM Dialog LR](../../test-results/org-chart-p7/Final-lr-dialog.png), [HM Dialog 390px](../../test-results/org-chart-p7/hm-dialog-390.png)
- [2,100명 LR](../../test-results/org-chart-p7/2100-lr.png), [2,100명 Hybrid](../../test-results/org-chart-p7/2100-hybrid.png), [Story 초기 Depth2](../../test-results/org-chart-p7/story-2100-depth2.png)
- [보존된 Fixed](../../test-results/org-chart-p7/fixed-1440.png)
Popup full-page 캡처는 고정 overlay가 현재 viewport만 덮는 특성상 문서 바깥 영역과 차이가 보일 수 있다.
실제 popup bounds·overflow·focus는 DOM 실측으로 별도 확인했다.
## Authored 변경 파일
1. `package-lock.json` — optional HM UI peer metadata만 반영, 라이브러리 버전/설치 변경 없음.
2. `packages/org-chart/src/data/examples.ts` — 공통 deterministic 가상 데이터 helper.
3. `packages/org-chart/src/data/examples.test.ts` — 11개 데이터 계약 검사.
4. `packages/org-chart/src/data/index.ts` — 공개 export.
5. `packages/org-chart/src/core/auto-layout-policy.ts` — 모드/Depth/독립 interaction 계약.
6. `packages/org-chart/src/core/auto-layout-policy.test.ts` — 7개 policy 검사.
7. `packages/org-chart/src/core/types.ts` — additive 공개 옵션/setter types.
8. `packages/org-chart/src/core/engine.ts` — 기존 dabeng options 전달.
9. `packages/org-chart/src/core/vendor.d.ts` — 설치 엔진 option typing.
10. `packages/org-chart/src/core/render.ts` — 명시적 level/그룹 hybrid projection.
11. `packages/org-chart/src/core/index.ts` — Auto 상태·setter·전환 Fit/engine lifecycle.
12. `packages/org-chart/src/core/expanded-content.ts` — Auto mode/interaction/방향 표시.
13. `packages/org-chart/src/core/expanded-layout.ts` — Auto 크기 측정·조직 관계선.
14. `packages/org-chart/src/core/expanded-viewport.ts` — 독립 Zoom/Pan gate 및 focus reveal.
15. `packages/org-chart/src/index.ts` — 공개 types export.
16. `packages/org-chart/src/styles/org-chart-expanded.css` — Auto 전용 LR/Hybrid CSS, 기존 흰 타이틀 보존.
17. `packages/org-chart/README.md` — data/API/연결 방향 문서.
18. `packages/org-chart-react/package.json` — optional `@hm-design/ui` peer.
19. `packages/org-chart-react/src/types.ts` — React 옵션 및 popup contract.
20. `packages/org-chart-react/src/OrgChart.tsx` — 기존 Core setter·popup state adapter.
21. `packages/org-chart-react/src/HMEmployeeDialog.tsx` — 실제 HM Dialog와 focus 복귀.
22. `packages/org-chart-react/README.md` — 선택형 HM peer·옵션 사용 안내.
23. `src/org-chart/org-chart-expanded.stories.tsx` — 기존 Expanded Story에 실제 선택 UI.
24. `src/org-chart/org-chart-expanded-story.css` — Expanded 한정 콘텐츠 layout.
25. `examples/org-chart/verify-p7.mjs` — 변경 범위 integration runner.
26. `docs/org-chart/expanded-usage.md` — P7 공개 API·호환 범위.
27. `docs/org-chart/implementation-report-p7.md` — 이 보고서.
`packages/*/dist`, `test-results/org-chart-p7`의 baseline/React consumer/JSON/캡처/tsconfig/audit 등은
기존 ignore 정책의 로컬 산출물이며 Stage하지 않았다. 별도 역사 보고서·승인 SVG·fixture·Theme·UI Component·기타 Story는 수정하지 않았다.
필수 소스·metadata는 함께 검토할 수 있도록 목록에 포함했다. 이번에는 Git 반영 계획이나 자동 Stage를 실행하지 않는다.
## 시간 기록 — Asia/Seoul
- Started At: 2026-10-13 09:07:58 KST
- Completed At: 2026-10-13 09:40:32 KST
- Actual Duration: 32분 34초
- Estimated Duration: 60–90분 (분석 10–15분 / 구현 30–45분 / 통합 검증 20–30분)
- Variance: 예상보다 27분 26초–57분 26초 빨리 완료