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

113 lines
12 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 P9.2 — Full Composition 중앙 정렬 · 회사 선택 통합
RESULT: **PASS — 요청한 P9.2 변경 범위.** 기존 Guard FAIL/NOT VERIFIED 및 사용자 디자인 승인 상태는 별도로 유지한다.
## 작업 기준·시간
- 범위: `STORYBOOK_ONLY`, 기존 실제 React Storybook 수정.
- 작업 폴더: `D:\디자인시스템\HMDesign-OrgChart`
- 브랜치: `feature/orgchart-package`
- 시작/완료 HEAD: `7614507583927a25a270963a74ff044be0557b9f`
- origin: `https://gitea.hmac.kr/b25027/HMDesign.git`. 원격 조회·Fetch·Pull 없음.
- Started At: 2026-10-13 10:53:44 KST
- Completed At: 2026-10-13 11:06:16 KST
- Actual Duration: 12분 32초
- Estimated Duration: 최초 35~50분 — 구조 확인 8분 / 수정 15~20분 / 검증·캡처·보고 12~22분.
- Variance: 예상보다 22분 28초~37분 28초 짧음.
## Full Composition 원인·수정
P9.1은 6개 조직 카드의 시각적 합집합 중심을 전체 Stage 중심으로 취급했다. 가용 폭도 부모의 border-box 폭으로 구해 Border/Padding이 있을 때 실제 콘텐츠 영역과 달라졌다. 따라서 1920·1440px에서 Stage가 약 16.12px 오른쪽으로 이동했고, 비대칭 여백에서 약 51.44px 오차와 실제 콘텐츠 밖 배치가 발생했다.
실제 사용자에게 보이는 회색 배경 `section.hm-orgchart-story-full[aria-label="Full Composition"]`을 Content Wrapper로 사용한다. 경로는 StoryPage → StorySection의 `.sb-page-section-body` → 이 section → React OrgChart host/Shadow DOM → Core Scale Wrapper `.hm-orgchart-composition` → `.hm-orgchart-stage[data-workdesk-artwork]`다.
Wrapper의 BoundingRect에서 왼쪽 Border·Padding을 더하고 오른쪽 Border·Padding을 빼 콘텐츠 가용 영역을 계산한다. 그 중심과 변환된 전체 Stage BoundingRect 중심의 차이를 실측해 전체 Stage 하나에 CSS translate를 적용한다. 임의 고정 이동값·조직별 좌표 수정이 없으며 Core transform/width-height fit과 원본 1920×914.5px을 유지한다. P9.1의 카드 중심에 맞춘 추가 scale 보정은 제거했다.
| 화면 폭 | Wrapper Left | Wrapper Right | Wrapper Center X | Stage Left | Stage Right | Stage Center X | 수정 전 오차 | 수정 후 오차 |
|---|---:|---:|---:|---:|---:|---:|---:|---:|
| 1920px | 360.000 | 1560.000 | 960.000 | 360.000000 | 1560.000000 | 960.000000 | +16.117645 | 0.000000 |
| 1440px | 120.000 | 1320.000 | 720.000 | 121.967201 | 1318.032753 | 719.999977 | +16.117462 | -0.000023 |
| 390px | 16.000 | 374.000 | 195.000 | 16.000000 | 374.000000 | 195.000000 | +4.808695 | 0.000000 |
canonical 화면에서 Wrapper 중심이 Viewport 중심과 우연히 일치한다. 기준이 Viewport가 아님은 비대칭 조건에서 확인했다: 1440px Viewport 중심720, 실제 콘텐츠 중심680, Stage 중심680. Padding만 재분배하면 콘텐츠/Stage 중심714로 같이 이동한다. 1010/390px 동일 mount resize에서도 오차 최대0.000016px이다.
- Full Composition 브라우저 **43/43 PASS**, canonical3개+비대칭 Border/Padding+동일 폭 Padding 재분배+1010/390 resize7조건.
- 152개 내부 요소의 DOM·정규화 상대 좌표·computed style 및 이미지139개의 SHA-256을 수정 전과 비교해 일치.
- 카드43개·조직6개·연결경로5개·대표자·허브·협업 화살표·우측통계·좌측파견/휴직·하단관계사·배경/장식 유지.
- 실제 rendered Stage와 모든 측정 콘텐츠가 부모 콘텐츠 영역에 포함됨. 잘림·카드/통계의 부적절한 충돌0건, 문서/사용 가능한 내부 스크롤바0건.
- 기존 Core `overflow:hidden`은 변경하지 않았다. transform 전 자연1920×915 layout 때문에 Scale Wrapper raw scrollWidth/scrollHeight가 client 크기보다 큰 기존 값은 보존된다. 이를 raw overflow0으로 보고하지 않으며, 실제 변환 후 Stage/콘텐츠 포함 검사로 잘림이 없음을 별도로 증명했다.
- 정렬 후12프레임 Stage style mutation0, observer 반복 루프 없음.
- [수정 전 측정](../../test-results/org-chart-p9-2/before-composition.json), [수정 후 원본](../../test-results/org-chart-p9-2/browser-composition.json).
## Expanded 회사 선택
외부에 펼쳐진 회사 체크박스7개와 전체 회사/선택 해제 버튼을 제거하고, 기존 FilterBar 데이터 범위·직원 수 사이에 회사 선택 드롭다운1개를 배치했다. 공개 MultiSelect export가 없고 Select는 단일값 API이므로 실제 HM `Popover + Checkbox + Label + Button + Separator`를 렌더링한다. 기존 library 의존성을 사용하며 추가 설치 없음.
실제 P5-0 preset ID/이름 `hanmac/한맥기술, saman/삼안, jangheon-industry/장헌산업, jangheon/장헌, ptc/피티씨, halla/한라산업개발, baron/바론컨설턴트`를 그대로 사용한다.
| 선택 상태 | 닫힘 요약 | 전체 선택 상태 | 실제 결과 |
|---|---|---|---|
| 7개 | 전체 회사 (7개) | checked | 전체 회사 Root/기존 합산20명 |
| 1개 | 한맥기술 또는 실제 선택회사명 | mixed | 해당 회사만 표시 |
| 2개 | 2개 회사 선택 | mixed | 한맥기술+삼안 반영 |
| 0개 | 회사를 선택하세요 | unchecked | 빈 forest·0명·오류 없음 |
- 전체 선택·해제·단일·복수·개별 제외·부분 선택에서 전체 선택을 확인했다. 닫고 다시 열어도 상태 유지.
- 회사 선택은 draft/applied의 companyIds에 즉시 반영한다. 데이터 범위·직원 수의 기존 draft→데이터 적용 정책은 보존한다. 미적용 범위/인원수를 바꾼 뒤 회사만 체크해도 적용된 범위/인원수는 그대로다.
- 회사별100명: 한맥기술100명 → 삼안 추가 즉시200명. 회사별20/300명도 단일회사 실제 확인.
- 전체 합산20/100/300명: 기존 P7 weighted partition 후 선택회사만 필터하는 계약 유지, 선택회사에 재분배하지 않음. 데이터 helper/직원JSON/Core 계약 source hash 동일.
- TB/LR/Hybrid 대표모드에서 선택된6개 회사/직원 및 제외된회사 반영 확인. 흰 제목·연결 방향별 Border, 그룹 접기/Space 펼치기, HM 직원 Dialog identity/ESC/카드focus복귀, 실제 Zoom·pointer Pan·Fit PASS.
- Enter로 열기, Tab으로 전체/회사checkbox 접근, Space 조작, ESC/trigger 클릭/외부 클릭 닫기, ESC trigger focus복귀 PASS. 접근성 이름 및 aria-checked true/mixed/false 제공, 기존 HM focus 스타일 사용.
- 실제 public Popover Portal 사용. 1920/1440/768/390px에서 표시 및 요청한 닫힘/열림/전체/부분선택 캡처. 1920/768/390px 모든8개checkbox의 panel 포함·viewport 포함·가로overflow없음 확인.
- Expanded 최초 원본44PASS/1FAIL 중 FAIL은 검증 코드가 존재하지 않는 `.hm-orgchart-empty` 안내요소를 찾은 문제였다. 기존 Core empty 계약은 자식이 없는 forest이므로 probe만 수정하고 실패한 항목만 재실행2/2PASS. 앱 코드는 변경하지 않았으며 성공한 테스트를 재실행하지 않았다. **최종45개 항목PASS**. 원본 실패기록은 보존하고 [종합/provenance](../../test-results/org-chart-p9-2/verification-summary.json)에 해소 근거를 연결했다.
- [최초 원본](../../test-results/org-chart-p9-2/browser-expanded.json), [empty항목 보정](../../test-results/org-chart-p9-2/browser-expanded-empty.json).
## 기술 검증·보존
| 항목 | 결과 |
|---|---|
| 변경 Story/helper Typecheck | PASS — `node node_modules/typescript/bin/tsc -p test-results/org-chart-p9-2/story-tsconfig.json` |
| Storybook production build | PASS — `npm.cmd exec -- storybook build -o storybook-static --disable-telemetry`. 기존500kB chunk 경고/plugin timing 진단 유지, 오류없음 |
| 신규 console/pageerror | 두 변경 및 보정/변수근거 실행 모두0건 |
| 기존 공개메뉴·StoryID | Overview / Department Colors / Full Composition / Expanded OrgChart4개 동일. OrgChart root/Patterns 다음 메뉴설정 hash 동일, 기존P8 manager증거 재사용 |
| Fixed/Auto CSS 격리 | Core/React 패키지와 공통CSS hash 동일. 신규StoryCSS는 설정컨트롤/Portal만 대상으로 하며 Shadow 내부 Fixed/Auto 카드·레이아웃을 변경하지 않음 |
| Overview·Department Colors | JSX/스타일/helper/CSF hash 동일. P9.1 간소화 결과 보존 |
| 코드리뷰·변경범위 | 독립 read-only 리뷰 finding0. 소스3개만 수정, baseline 나머지 파일 SHA-256 동일 |
| diff/공백 | `git diff --check` PASS 및 신규 authored파일 whitespace 확인 |
Core/React 데이터 생성·레이아웃 알고리즘·Theme·카드SVG·회사색은 수정하지 않았다. 기존 P7~P9.1 PASS를 동일 소스 근거로 재사용하며 전체2100명 성능·과거전체suite·전체Guard는 반복하지 않았다.
## Guard·미검증
이번 PARTIAL/STORYBOOK Guard 원본은 **status/staticStatus/runtimeStatus NOT VERIFIED**, 신규FAIL0. 원본 issue2개:
- `TOKEN-001 NOT VERIFIED`: StoryCSS의 `--radix-popover-content-available-height`. HM 공개 Popover/Radix가 런타임에 선언하는 위치변수이므로 연결consumerTheme 정적 선언만으로 확인되지 않는다. 실제 변수값과 maxHeight 일치를 [추가 런타임 근거](../../test-results/org-chart-p9-2/browser-expanded-token.json)로 확인했다. 원본 미검증을 덮어쓰지 않았다.
- `TOKEN-002 NOT VERIFIED`: 기존 StoryPage 동적class site. 소스불변.
styleEvidence는 **STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT NOT VERIFIED / FINAL NOT VERIFIED**, 결합styleVerification은 생성하지 않았으며 NOT VERIFIED다. 실제 computed/상호작용PASS는 사용자 디자인의도 승인으로 확대하지 않는다.
기존 P9 Guard의 status/staticStatus **FAIL**, runtime **NOT VERIFIED**, TOKEN-00110FAIL/TOKEN-00210NOT VERIFIED 및 패키지CSS SCOPE-0012NOT VERIFIED 원본/보고서/hash를 그대로 보존한다. 이번 PARTIAL 검사가 이전 전체범위 결과를 대체하지 않는다. 삼안·장헌산업 흰 제목 대비 잔여진단, Compact NOT SUPPORTED도 유지한다.
사용자 최종 디자인 승인·다른브라우저/실기기/스크린리더·모든옵션조합·SSR/배포는 NOT VERIFIED. 요청범위 완료 후 사용자 검토 대기하며 P10은 시작하지 않았다.
## 변경파일
| 파일 | P9.2 변경 |
|---|---|
| src/org-chart/center-composition-preview.ts | 실제부모 content-box 기준 전체Stage 중앙정렬 |
| src/org-chart/org-chart-expanded.stories.tsx | HM 회사선택Popover·전체/부분/미선택·즉시회사반영 |
| src/org-chart/org-chart-expanded-story.css | trigger/요약/Portal 콘텐츠레이아웃 |
| examples/org-chart/verify-p9-2-composition.mjs | 중앙정렬 수정전후·포함·내부보존·scroll/resize검증 |
| examples/org-chart/verify-p9-2.mjs | 회사선택·데이터·키보드·레이아웃·Portal 검증 |
| docs/org-chart/implementation-report-p9-2.md | 이 보고서 |
test-results/org-chart-p9-2 및 storybook-static은 생성검증산출물이다. [시작baseline](../../test-results/org-chart-p9-2/baseline.json), [최종audit](../../test-results/org-chart-p9-2/final-state.json), [typecheck log](../../test-results/org-chart-p9-2/typecheck.log), [build log](../../test-results/org-chart-p9-2/build.log), [Guard원본](../../test-results/org-chart-p9-2/guard.json).
**Stage·Commit·Push·Merge·main checkout·PR·Pull·Reset·Rebase·Force Push 모두 미진행.** 시작과완료branch/HEAD 동일, staged파일0. 기존미커밋P7~P9.1변경 보존.
## 실제 Storybook·캡처
- [Full Composition](http://127.0.0.1:6062/?path=/story/orgchart--full-composition): [1920px](../../test-results/org-chart-p9-2/after-full-composition-1920.png), [1440px](../../test-results/org-chart-p9-2/after-full-composition-1440.png), [390px](../../test-results/org-chart-p9-2/after-full-composition-390.png).
- [Expanded OrgChart](http://127.0.0.1:6062/?path=/story/orgchart--expanded-org-chart): [닫힘](../../test-results/org-chart-p9-2/expanded-closed.png), [열림](../../test-results/org-chart-p9-2/expanded-open-all.png), [전체선택](../../test-results/org-chart-p9-2/expanded-all-selected.png), [부분선택](../../test-results/org-chart-p9-2/expanded-open-partial.png), [2회사100명씩](../../test-results/org-chart-p9-2/expanded-closed-partial.png), [390px열림](../../test-results/org-chart-p9-2/expanded-open-390.png).
- [수정전회사UI](../../test-results/org-chart-p9-2/before-expanded-1440.png). 수정전FullComposition은 같은폴더before-full-composition-1920/1440/390.png에 보존.