docs(ai): add packaged AI guides for Web, SW and OrgChart
- Shared entry point docs/ai/AI_GUIDE.md (type selection Web / SW / OrgChart / mixed, steps 1-7, package style separation, report format, examples A-D) and AGENTS_SNIPPET.md, copied into every package ai/ folder - New ai/ docs for @hm-design/ui and @hm-design/org-chart (+ org-chart-react pointer): AI_USAGE, COMPONENT_CATALOG, DESIGN_RULES, COMPOSITION_PATTERNS - SW ai/ linked to the shared guide; catalog lists every Props type explicitly - "ai" added to package files of ui, org-chart, org-chart-react - scripts/ai-docs.mjs: sync:ai-docs / check:ai-docs (copies, files, catalog <-> exports, links) - Maintenance guide and verification record under docs/ai
This commit is contained in:
1 parent
e8409eff44
commit
fb74cd756f
34 files changed
+2396
-6
No files matched your search
@@ -0,0 +1,109 @@
|
||||
# OrgChart 공개 API 카탈로그
|
||||
|
||||
기준: `@hm-design/org-chart` 0.1.0(`src/index.ts` → `dist/index.d.ts`)과 `@hm-design/org-chart-react` 0.1.0(`.`, `./hm-dialog`). **이 문서에 없는 이름은 공개 API가 아닙니다.** 저장소의 `npm run check:ai-docs`가 이 문서와 실제 Export의 일치를 검사합니다.
|
||||
|
||||
- 런타임 helper(`JsonOrgChartDataSource` 등)는 항상 Core에서 import합니다. React 패키지는 Core 타입을 type-only로 다시 export합니다.
|
||||
- 옵션은 생성 시점에 고정되는 것이 많습니다. 아래 "변경 방법"을 확인하고, React에서는 객체 Props를 `useMemo`로 고정합니다.
|
||||
|
||||
## 1. React — `@hm-design/org-chart-react`
|
||||
|
||||
| Export | 내용 |
|
||||
|---|---|
|
||||
| `OrgChart` | 유일한 기본 runtime export. React가 전용 container를 소유하고 Core handle의 mount·subscribe·destroy를 관리. Props는 아래 표 |
|
||||
| 타입 `OrgChartProps`, `OrgChartEmployeeSelection`, `OrgChartEmployeePopupProps` | `OrgChartEmployeePopupProps = { selection: { employee, context } \| null; onClose }` |
|
||||
| `/hm-dialog`의 `OrgChart`, `HMEmployeeDialog` | 같은 Props. 직원 팝업을 Web `Dialog`로(`employeePopup="hm-dialog"` 명시). `@hm-design/ui` 0.1.0 peer와 Web CSS 진입점 필요. `HMEmployeeDialog`는 이 Entry에서만 export |
|
||||
|
||||
`OrgChartProps` = Core `OrgChartOptions`에서 `container`·`onStateChange`를 뺀 것 + 아래 React 전용 Props.
|
||||
|
||||
| Prop | 값 | 변경 시 |
|
||||
|---|---|---|
|
||||
| `dataSource` (필수) | `OrgChartDataSource` (`new JsonOrgChartDataSource(data)`) | 새 객체 → 같은 handle `reload` (useMemo로 고정) |
|
||||
| `stylesheetUrls` (필수) | `{ engine: string; core: string }` CSS URL | 문자열 값이 바뀌면 재생성 |
|
||||
| `layoutMode` | `'fixed'`(기본) · `'auto'` | 재생성 |
|
||||
| `displayMode` | `'interactive'`(기본) · `'readOnly'` | 재생성 |
|
||||
| `presentationMode` | `'default'`(기본) · `'chart-only'` — **Auto 전용**, Fixed와 쓰면 `TypeError` | — |
|
||||
| `initialView` | `'center'` · `'fit'` (chart-only 기본 `fit`) | — |
|
||||
| `wheelZoom` | `'modifier'`(Ctrl/⌘ + 휠) · `'direct'` (chart-only 기본 `direct`) | — |
|
||||
| `companyId` | Auto 기본 회사 프리셋(기본 `hanmac`) | 재생성 |
|
||||
| `selectedCompanyIds` | `undefined` = 전체, `[]` = 없음 (Auto) | 같은 handle에서 선택 변경 |
|
||||
| `autoLayout` | `{ type?: 'tb' \| 'lr' \| 'hybrid'; hybridStartDepth?: 2 \| 3 \| 4; initialVisibleDepth?: 1 \| 2 \| 3 \| 'all'; hybridOrganizationIds?: string[] }` | 같은 handle |
|
||||
| `interactions` | `{ collapse?, zoom?, pan? }` 모두 기본 true (Auto) | 같은 handle |
|
||||
| `dragDropEnabled` | 기본 `false`. true면 Auto 직원·그룹 이동(포인터, `Alt+M` → 방향키 → Enter) | 같은 handle |
|
||||
| `companyTopNodes` | `{ [companyId]: { employeeId?, title?, name?, profileImage?, organizationName?, display?: 'card' \| 'titleOnly' \| 'hidden' } }` (표시만 변경) | 재생성 |
|
||||
| `employeeConnections` | `{ [organizationId]: 'top' \| 'left' \| 'right' }` 직원 연결선 방향 | 재생성 |
|
||||
| `zoom` | `{ min?, max?, step? }` (기본 5–300%) | 재생성 |
|
||||
| `organizationLinks` | `{ [organizationId]: url }` 1Depth 제목만 링크. HTTP(S)·상대 URL | 재생성 |
|
||||
| `employeePopup` | `'core'`(기본) · `'hm-dialog'` · `'adapter'` · `'none'` (Auto. Fixed는 항상 Core 팝업) | 같은 handle |
|
||||
| `employeePopupAdapter` | `ComponentType<OrgChartEmployeePopupProps>` (`employeePopup="adapter"`와 함께) | — |
|
||||
| `onEmployeeClick(employee, context)` | 호스트 소유 정보 UI. 지정하면 기본 팝업 대신 호출(최우선) | — |
|
||||
| `onMove(result)` | Auto 이동 결과(`moved` 성공/거절). 서버 저장 없음 | — |
|
||||
| `aggregationPolicy` | `ApprovedAggregationPolicy` (업무 집계 정책) | 재생성 |
|
||||
| `onStateChange(state)` | `loading` → `ready`(summary 포함) / `error`(issues) | — |
|
||||
| `onLifecycleError(error)` | 생성·mount·reload·cleanup의 예기치 않은 오류 | — |
|
||||
| `className`, `style` | 바깥 container에만 적용. 캔버스 높이는 container 높이(미지정 시 최소 320px) | — |
|
||||
|
||||
없는 것: `ref`/imperative handle, `children`, `data`, `title`, `chartOnly`, `showToolbar`. React에서 `fitToView` 등을 직접 호출하는 공개 경로는 없습니다(Chart Only의 `initialView="fit"`이 초기 Fit 담당).
|
||||
|
||||
## 2. Core — `@hm-design/org-chart`
|
||||
|
||||
### 2.1 렌더링
|
||||
|
||||
| Export | 내용 |
|
||||
|---|---|
|
||||
| `createOrgChart(options)` → `OrgChartHandle` | 전체 조직도. 옵션 = §1 표의 Core 항목 + `container?: HTMLElement`, `onStateChange?`. DOM 없이 생성 가능, `mount`에서 연결된 HTMLElement 필요 |
|
||||
| `createOrgChartTree(options)` | 계층만 렌더링(독립 Tree). Chart Only를 대신하지 않음 |
|
||||
| `createPositionSummary`, `createAffiliationSummary`, `createStatusSummary` (옵션 타입 `OrgChartSummaryComponentOptions`) | 직위별·관계사별·근무 상태별 요약 독립 모듈 |
|
||||
|
||||
`OrgChartHandle`:
|
||||
|
||||
| 메서드 | 내용 |
|
||||
|---|---|
|
||||
| `mount(container?)`, `update(input)`, `reload(source?)`, `destroy()` | 수명주기. `destroy`는 최종·idempotent — 다시 쓰려면 새 handle |
|
||||
| `subscribe(listener)` → unsubscribe, `getState()` | 상태 구독 |
|
||||
| `setSelectedCompanies(ids?)`, `getSelectedCompanies()` | Auto 회사 선택 |
|
||||
| `setAutoLayout(options)`, `getAutoLayout()` | Auto 배치 변경(접기 상태 유지) |
|
||||
| `setInteractions(options)`, `getInteractions()` | Auto 접기·Zoom·Pan on/off |
|
||||
| `setEmployeeClickHandler(handler?)` | Auto 팝업 소유자 변경 |
|
||||
| `setDragDropEnabled(enabled)`, `getDragDropEnabled()`, `move(request)`, `getData()` | Auto 이동 편집(브라우저 메모리만) |
|
||||
| `zoomTo(scale)`, `panBy(x, y)`, `fitToView()`, `getViewportState()` | 보기 조작 |
|
||||
|
||||
### 2.2 데이터 계약·검증
|
||||
|
||||
| Export | 내용 |
|
||||
|---|---|
|
||||
| 타입 `OrgChartDataset` | `{ schemaVersion: '0.1-draft'; organizations; employees; affiliations; relations?; presentation?; metadata: { asOfDate; dataVersion; schemaVersion?; updatedAt?; updateNote? } }` (`SCHEMA_VERSION` 상수) |
|
||||
| 타입 `Organization` | `{ id; companyId?; parentId: string \| null; name; type: OrganizationType; leaderId: string \| null; displayOrder: number }` |
|
||||
| 타입 `Employee` | `{ id; organizationId; affiliationId; name; position; jobTitle: string \| null; profileImage: string \| null; workStatus: WorkStatus }` |
|
||||
| 타입 `OrganizationType`, `WorkStatus`, `Affiliation`, `ID` | `'root' \| 'division' \| 'office' \| 'div' \| 'cell' \| 'team'` / `'active' \| 'dispatched' \| 'onLeave'` / `{ id; name }` / `string` |
|
||||
| 타입 `OrganizationRelation`, `RelationType`, `PresentationConfig`, `Metadata` | 관계(`cooperation` · `support`, 검증만 하고 그리지 않음), 표시 설정, 메타데이터 |
|
||||
| `validateOrgChartDataset(input)` → `ValidationResult` | `{ valid: true, data }`(깊게 freeze) 또는 `{ valid: false, issues: ValidationIssue[] }`. 알 수 없는 필드·중복 ID·참조 오류·순환·안전하지 않은 URL 등 거절. `organizations: []`는 오류, `employees: []`는 유효 |
|
||||
| `isSafeImageUrl(url)` | 이미지 URL 안전성 검사 |
|
||||
| `normalizeOrgChartDataset(data)` → `NormalizedOrgChartDataset` (`OrganizationTreeNode`) | 트리 정규화 |
|
||||
| `calculateSummary(data, policy?)` → `OrgChartSummary` (`SummaryCounts`, `AggregationResult`) | `raw` = 원본 고유 직원 집계(업무 승인 인원 아님). 정책 없으면 `aggregation.status='unavailable'` |
|
||||
| 타입 `ApprovedAggregationPolicy`, `AggregationPolicy` | `{ policyVersion; includedStatuses; activeStatuses; includeLeaders; membershipMode }` |
|
||||
| `snapshotOrgChartDataset(data)` | 불변 snapshot |
|
||||
| `JsonOrgChartDataSource(input, options?)` (`JsonOrgChartDataSourceOptions` = `{ fetch? }`) | inline dataset 또는 HTTP(S)/상대 URL. 생성 시 inline 입력 고정 |
|
||||
| `OrgChartSourceError` (`OrgChartSourceErrorCode` = `SOURCE_LOAD` · `SOURCE_PARSE` · `SOURCE_ABORT` · `SOURCE_URL` · `SOURCE_SNAPSHOT`) | Source 오류 |
|
||||
| 타입 `OrgChartDataSource`, `ValidationIssue`, `ValidationResult` | 사용자 정의 Source는 `load(options?: { signal?: AbortSignal }): Promise<unknown>` 구현 |
|
||||
|
||||
### 2.3 회사 컬러·예시·이동
|
||||
|
||||
| Export | 내용 |
|
||||
|---|---|
|
||||
| `companyColorPresets`, `getCompanyColorPreset(id)` / 타입 `CompanyId`, `CompanyColorPreset` | 7개 회사 `{ companyId, companyName, primary, secondary }`. 등록 setter 없음 |
|
||||
| `createOrgChartExampleDataset(template, selection)` / 타입 `OrgChartExampleScope`, `OrgChartExampleEmployeeCount`, `OrgChartExampleSelection` | 기존 large fixture template에서 `employeeCount: 20 \| 100 \| 300`, `scope: 'total' \| 'per-company'`, `companyIds?` 예시 생성 |
|
||||
| `createOrgChartMoveValidator`, `validateOrgChartMove`, `applyOrgChartMove` / 타입 `OrgChartMoveRequest`, `OrgChartMoveFailureCode`, `OrgChartMoveFailure`, `OrgChartMoveValidation`, `OrgChartMoveResult` | 순수 이동 검증·적용(`{ kind: 'employee' \| 'organization', sourceId, targetOrganizationId }`) |
|
||||
|
||||
### 2.4 옵션·상태 타입
|
||||
|
||||
`OrgChartOptions`, `OrgChartHandle`, `OrgChartState`, `OrgChartDisplayMode`, `OrgChartLayoutMode`, `OrgChartPresentationMode`, `OrgChartInitialView`, `OrgChartWheelZoom`, `OrgChartAutoLayoutType`, `OrgChartAutoLayoutOptions`, `OrgChartInteractionOptions`, `OrgChartConnectionDirection`, `OrgChartTopNode`, `OrgChartViewportState`, `OrgChartOrganizationLinks`, `OrgChartEmployeeClickContext`(`{ organization, affiliation, trigger, originalEvent }`).
|
||||
|
||||
## 3. 상태·오류
|
||||
|
||||
- `OrgChartState.status`: `loading` → `ready`(`dataVersion`, `summary`, `aggregation`) 또는 `error`(`issues: { code, path, message }[]`). 타입에 `empty`·`idle`·`destroyed`가 있으나 지원되는 Empty UI 증거는 아닙니다.
|
||||
- Auto는 회사 프리셋·회사 경계·상단 직원 설정을 추가 검사합니다(`COMPANY_PRESET`, `COMPANY_HIERARCHY`, `TOP_NODE_CONFIG`, `TOP_NODE_REFERENCE`). Validator 통과만으로 Auto 표시가 보장되지 않습니다.
|
||||
- 데이터·Source·스타일 오류 = `state.error`, 예기치 않은 생성·수명주기 오류 = React `onLifecycleError`.
|
||||
|
||||
## 4. 지원하지 않는 것
|
||||
|
||||
자연어 → 데이터 자동 생성 UI, CSV/XLSX 직접 import, 서버 저장·외부 API·이미지/PDF export, 임의 회사 프리셋 등록, 카드 교체, Compact 모드, 공개 collapse setter, React imperative ref, Fixed Chart Only, Fixed의 휠 Zoom/Pan, SSR/hydration(검증 범위 밖).
|
||||
Reference in new issue
Block a user