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

140 lines
14 KiB
Markdown

# OrgChart P11 — 외부 CSS 테마 및 Guard 결과
RESULT: **PASS** (아래 명시된 구현·검증 범위)
| 구분 | 결과 |
|---|---|
| 외부 CSS 테마 실제 적용 | **PASS** — React / Vanilla / 순수 HTTP Core 소비자 |
| 기존 TOKEN-001 5건 Guard 실제 재검사 | **PASS** — 원본 `status PASS`, `staticStatus PASS`, FAIL **5 → 0**, issues 0 |
| 다른 공용 Guard 검사 결과 보존 | **PASS** — UI/CENTER/Foundation/Pattern의 기존 67개 이슈 동일, FAIL 0 유지 |
| 기본 디자인 보존 | **PASS** — 6개 기본 화면의 변경 전후 PNG SHA-256 동일 |
Guard의 자체 `runtimeStatus NOT VERIFIED`는 그대로 보존했다. 정적 Guard PASS를 브라우저 결과로 덮어쓰지 않았다. 외부 테마 브라우저 검증과 원본 Guard 판정은 각각 보고한다. 전체 제품·전체 접근성·모든 브라우저의 PASS를 뜻하지 않는다.
## 작업 기준 및 Git
- 폴더: `D:\디자인시스템\HMDesign-OrgChart-Recovered`
- 브랜치: `feature/orgchart-package`
- 시작/완료 HEAD: `dcfa4e0895eecc97ce516cbf3d4424bbaadfddeb`
- origin: `https://gitea.hmac.kr/b25027/HMDesign.git`
- Git 작성자 설정: `b25027 <shkim4@samaneng.com>`
- 시작 Working Tree: clean. 완료 Working Tree: 아래 P11 변경만 unstaged. Staged 파일 0.
- 이번 첨부 요청의 경로·Feature 브랜치·Commit/Push 보류 지시를 적용했다. Stage·Commit·Push·Merge·운영 서버·Docker·Registry Publish 미진행.
- 범위: 기존 OrgChart Core의 컬러 구현 및 소비 검증. 공개 API·데이터 계약·엔진·회사 프리셋·기존 4개 공개 Story 소스·HM UI Theme를 변경하지 않았다. 신규 업무 화면/Navigation/FilterBar를 추가하는 작업이 아니다.
## 구현과 CSS 변수
회사색과 Fixed 6개 부서색의 JS inline 주입을 제거하고 `data-company-id`, `data-group-variant`에 따른 CSS 계산으로 옮겼다. `color-presets.css`에 실제 사용 범위의 `current-card-background`, `current-card-color`, `current-department-color`, `current-border`, `current-gradient`와 compatibility alias 기본 선언을 추가했다. Auto의 `expanded-primary`, `expanded-card-primary`, 기존 secondary alias도 CSS로 계산한다.
외부 공개 입력은 조상 CSS가 Shadow DOM을 통과해 상속되도록 내부에 고정 기본 선언하지 않는다. 내부 `resolved-*`/`current-*`가 해당 공개 입력과 기존 색상 fallback을 해석한다. 외부 테마를 JS inline 기본색으로 막지 않는다.
주요 추가/연결 입력은 다음과 같다. 전체 이름·기본 정책·회사/부서 ID 목록은 [사용 가이드](org-chart-usage-guide.md#p11-외부-css-테마-2026-10-13)에 있다. 접두사는 모두 `--hm-orgchart-`다.
| 영역 | 입력 |
|---|---|
| 회사 | 기존 `company-{id}` 경로를 공개 입력으로 연결, 7개 기본색 유지 |
| 그룹 | `group-title-background`, `group-title-color`, `group-border` |
| 카드 | `card-background`, `card-color`, `card-position-color`, `card-border`, `card-accent` |
| 역할 | `leader-card-background`, `top-leader-card-background` (Auto) |
| 상태/Focus | `card-hover-background`, `card-focus-color` |
| 연결선 | 기존 `expanded-line-color`를 상속 입력으로 전환, `fixed-line-color` 추가 |
| 파견/휴직 | `status-*`, `dispatched-*`, `on-leave-*`의 제목·카드 gradient/Border/글자 입력 |
| Core 팝업 | `dialog-background`, `dialog-color`, `dialog-border`, `dialog-close-color`, `dialog-close-hover-background`, `dialog-focus-color` |
| 기존 공통 | `bg-surface`, `bg-content`, `fg-primary`, `stroke-default` 등 재사용 |
| Fixed | 기존 `{department}-gradient/border/department-color/card-background/card-color` 입력 유지 |
상태 요약 카드의 고정 gradient/Border를 변수로 바꾸고 기존 `!important`를 제거했다. 미지정 Hover는 원래 카드/상태 gradient를 유지한다. SVG/PNG 자산을 수정하거나 Cell Border Only를 재적용하지 않았다.
## 외부 파일 연결 및 실제 결과
- [external-theme.css](../../examples/org-chart-react/external-theme.css): 기본 공개 CSS를 먼저 import하고 `:host`의 컬러 입력을 뒤에 선언한다. Vite에서는 `?url`로 import해 기존 `stylesheetUrls.core`에 전달한다.
- 일반 HTTP Vanilla에서는 기본 `style.css`를 상대/절대 HTTP 경로로 import하는 같은 파일을 사용한다. 검증 fixture는 공개 Core ESM만 로드했으며 React 또는 node_modules 요청 0건이었다.
- [host-theme.css](../../examples/org-chart-react/host-theme.css): 호스트 HTML에 연결하는 변수 전용 예제. 호스트 class 적용/제거만으로 회사색·배경이 변경/복원됐다.
- [external-group-theme.css](../../examples/org-chart-react/external-group-theme.css): 회사색과 별도로 공통 제목 배경을 바꾸는 CSS 파일. 실제 `rgb(97, 62, 139)` 적용 확인.
- Shadow 파일의 `:host` 선언이 조상 상속보다 우선한다. 호스트 selector는 Shadow 내부 카드에 접근하지 못하므로 내부 selector 수정은 `stylesheetUrls.core`에 포함한다. 기본 CSS 전체를 포함하지 않은 변수 전용 파일로 core URL을 대체하면 안 된다.
| 확인 대상 | 실제 적용 결과 |
|---|---|
| 한맥 / 삼안 | 제목·소속 카드 강조선이 `#2457a7` / `#385ca8`로 변경 |
| 나머지 5개 회사 | 각각 개별 CSS 색상 변경. 7개 승인 기본색도 브라우저 확인 |
| 그룹 | 제목 글자 `#fff4d6`, 공통 배경 별도 파일 override 확인 |
| 직원·대표자·그룹장 | Auto 배경 `#f4f8ff` / `#d2e3ff` / `#e3eeff`, Border `#527aa9` |
| Hover / Focus | 실제 pointer Hover `#c1d8f8`, 키보드 Focus `#7650a5` |
| Auto 연결선 | 직원 SVG 경로 및 조직 pseudo 연결선 `#249a79` |
| Fixed 연결선 | 실제 overlay path `#297ab0`. 이미지 화살표 내부 색은 그대로 |
| 조직도 배경 | Auto canvas `#edf4ff`, Fixed readOnly 내용 `#dce8f8` |
| 파견·휴직 | 서로 다른 녹색/보라색 gradient·Border, Fixed 및 Auto 상태 카드 확인 |
| Core 팝업 | 배경 `#eef2ff`, 글자 `#283568`, Border `#6879ba`, 실제 닫기 Hover/Focus 확인 |
| 런타임 복원 | mount 상태에서 호스트 class 제거 시 기본 색상·크기 즉시 복원 |
React HM Dialog는 Shadow 밖의 별도 HM Theme/Portal 계약을 계속 따른다. `dialog-*`는 Core 팝업에만 적용된다. `@hm-design/ui/theme` 연계 및 Portal 주의사항을 사용 가이드에 추가했으며 HM Dialog 구현 자체는 바꾸지 않았다.
## 기본 디자인 및 Fixed 한계
React/Vanilla 각각 Auto Chart Only, Fixed readOnly Full Composition, Fixed Interactive를 변경 전 Core/Wrapper dist로 캡처했다. 변경 후 빌드에서 모든 카드·제목·캔버스·팝업의 주요 computed 색상/Border/크기를 비교했다. 화면 6개의 PNG SHA-256이 정확히 동일했다([이미지 비교 결과](../../test-results/org-chart-p11/default-image-comparison.json)).
기존 공개 Story 4개(Full Composition, Expanded OrgChart, Department Colors, Overview)를 실제 브라우저에서 열었다. 4/4 렌더 확인, 오류 0, Department Colors의 서로 다른 기본 gradient 6개 유지. Story 소스·ID·등록은 변경하지 않았다. Story 화면은 현재 렌더 확인이며 변경 전 Story 전체의 픽셀 비교를 수행한 것은 아니다.
Fixed의 CSS 제목·상태 카드·Focus·배경·실제 SVG overlay path는 변경할 수 있다. `cards/*.svg` 카드 이미지, 회사 로고 PNG, Workdesk `Group.svg`, `bg_sky.png`, `bg_main.png`, `Frame2@3x.png`, `1-8-4x-1@2x.png`, `team-arrow-*.png` 내부 색상은 CSS 변수로 바꿀 수 없다. 대표자/부서 SVG의 불투명 영역은 카드 CSS 배경을 바꿔도 유지된다. 자산 전면 재작성·필터 착색 없음.
## Guard 5건 해결과 공용 영향
기존 분석기에서 다음 명령으로 TOKEN-001 5건을 먼저 재현했다. [원본 재현 JSON](../../test-results/org-chart-p11/guard-before.json)은 보존한다.
```powershell
node scripts/ai-generation-guard.mjs --target . --scope PARTIAL --profile STORYBOOK --files packages/org-chart/src/core/department-colors.ts,packages/org-chart/src/core/style-presets.ts,packages/org-chart/src/core/expanded-content.ts --json
```
| 기존 FAIL | 해결 |
|---|---|
| Department Colors의 `current-gradient`, `current-card-background` (2건) | 실제 `data-group-variant` 범위의 CSS 기본 선언 및 공개 CSS 연결 |
| Style presets의 `resolved-bg-surface` (1건) | 기존 공개 design-tokens.css 선언 정상 수집 |
| Style presets의 `current-border`, `current-gradient` (2건) | 실제 범위 기본 선언. JS 색상/alias 주입 제거 |
CSS 선언만으로는 `?url`로 연결된 공개 CSS를 기존 분석기가 볼 수 없어 5건을 해결할 수 없었다. 필요한 분석기 변경은 `guard-theme-analysis.mjs`의 **공개 OrgChart CSS 두 import 형태와 상대 CSS import 선언 수집**으로 한정했다. 임의 CSS URL 전체를 적용 스타일로 인정하지 않고, setProperty 정의 자동 승인·예외 목록·규칙 비활성화를 하지 않았다. 미선언 HM 토큰은 fallback이 있어도 FAIL이다.
동일 명령의 [최종 JSON](../../test-results/org-chart-p11/guard-final.json): `status PASS`, `staticStatus PASS`, `issues []`, FAIL 0. 원본 CSS phases는 STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT PASS / FINAL NOT VERIFIED다. 실제 테마 적용은 별도 브라우저 결과로 확인했다. Guard에 그 Runtime 증거를 결합하여 원본 결과를 변경하지 않았다.
기존 Guard 94/94 및 신규 공개 CSS 회귀 5/5 PASS. 이전 분석기를 임시 복사해 UI/CENTER/Foundation/Pattern의 실제 현재 소스를 검사한 뒤 수정 분석기와 비교했다. 기존 67개 이슈·status·staticStatus가 동일했다([비교 JSON](../../test-results/org-chart-p11/guard-other-comparison.json)). 해당 다른 범위의 원본 status는 NOT VERIFIED, FAIL 0이며 이를 PASS로 올리지 않았다. 비교용 임시 분석기 파일은 제거했다.
P11 React 소비 fixture는 `--result p11.html`도 별도 실행했다([소비 Guard](../../test-results/org-chart-p11/guard-consumer.json)). 기존 공용 Guard는 OrgChart를 HM UI 화면 재사용 계약 대상으로 모델링하지 않아 `staticStatus NOT APPLICABLE`, 원본 NOT VERIFIED다. 이를 기존 5건의 PASS와 혼동하지 않는다. 패키지 CSS 구현 자체는 해당 소비 graph 밖의 범위이며 빌드·타입·실제 브라우저로 검증했다.
## 기술 검증
| 검사 | 결과 / 증거 |
|---|---|
| 최종 빌드 React/Vanilla 테마·기본값·동작·4개 폭 | **104/104 PASS**, 콘솔/page 오류 0 — [browser-result.json](../../test-results/org-chart-p11/browser-result.json) |
| 순수 HTTP Vanilla Core | **8/8 PASS**, 오류 0. 외부 CSS @import, 팝업, 공개 zoomTo/panBy/fitToView/destroy — [standalone 결과](../../test-results/org-chart-p11/standalone-vanilla-result.json) |
| 기존 공개 Story | **4/4 PASS**, 오류 0 — [Storybook 결과](../../test-results/org-chart-p11/storybook-result.json) |
| 회사 프리셋·Expanded company/layout 관련 테스트 | **17/17 PASS** (bundled Node 24.19.0 사용) |
| 공용 Guard 회귀 | **94/94 PASS** — [로그](../../test-results/org-chart-p11/guard-tests.txt) |
| 신규 Guard/CSS 기본값 회귀 | **5/5 PASS** — [로그](../../test-results/org-chart-p11/guard-orgchart-tests.txt) |
| Core / React Typecheck | PASS. P11 TSX fixture 별도 Typecheck도 PASS |
| Core / React Wrapper / 소비 예제 Build | PASS. 외부 CSS URL이 실제 배포 assets에 산출됨 |
| 390/768/1280/1440px | Auto canvas 폭 일치, 문서 가로 overflow 없음. Fixed 문서 overflow 없음 |
| 상호작용 | 직접 Wheel, Pan, 접기/펼치기, Enter 팝업, Escape 닫기/Focus 복귀, Hover/Focus, Drag & Drop ON/OFF 속성 확인 |
| git diff --check | PASS, Staged 파일 0, HEAD 유지 |
빌드의 기존 `:host-context(.dark)` minifier 경고와 큰 bundle 경고는 남아 있다. 최초 시스템 Node 20에서 기존 unit runner의 `node:fs globSync` import가 실패해, 해당 runner는 제공된 Node 24로 실행하여 관련 17개를 통과했다. 의존성/패키지 버전 업그레이드 없음.
NOT VERIFIED: Firefox/Safari/Edge, screen reader 음성, 물리 터치, 실제 Drag & Drop 데이터 이동 전체 회귀, `/hm-dialog` 별도 Theme를 변경한 새 브라우저 비교, 기존 Story 4개 전체의 변경 전 픽셀 비교, 전체 제품 테스트·배포. Fixed 이미지 내부 색상 테마화는 이번 범위에서 지원하지 않는다. 기본 렌더·팝업의 픽셀/computed 비교와 실제 테마 결과의 검사 범위는 위 증거로 한정한다.
## 변경 파일
- Core: `packages/org-chart/src/core/style-presets.ts`, `expanded-content.ts`, `department-colors.ts`
- CSS: `packages/org-chart/src/styles/color-presets.css`(신규), `org-chart.css`, `employee-card.css`, `employee-info-dialog.css`, `org-chart-content.css`, `org-chart-expanded.css`, `org-chart-readonly.css`, `summary-sections.css`
- CSS packaging: `packages/org-chart/build.mjs`
- Guard: `scripts/guard-theme-analysis.mjs`, `scripts/guard-orgchart-theme.test.mjs`(신규)
- 소비/검증: `examples/org-chart-react/p11.html`, `p11.tsx`, `external-theme.css`, `external-group-theme.css`, `host-theme.css`, `verify-p11.mjs`, `verify-p11-stories.mjs`(모두 신규), `vite.config.ts`
- 순수 Vanilla 검증: `examples/org-chart/verify-p11-standalone.mjs`(신규)
- 문서: `docs/org-chart/org-chart-usage-guide.md`, `docs/guidelines/ai-generation-guard.md`, 이 보고서
- ignored 산출물: Core/Wrapper/소비 dist, `test-results/org-chart-p11/*`. Stage하지 않았다.
## 시간 (Asia/Seoul)
- Started At: 2026-10-13 21:43:34 KST
- Completed At: 2026-10-13 22:20:11 KST
- Actual Duration: 36분 37초
- Estimated Duration: 최초 약 60분 (분석 10 / 구현·가이드 25 / 검증 25)
- Variance: 예상보다 23분 23초 단축