import fs from 'node:fs/promises'; const companies = [ ['hanmac', '한맥기술', '회장'], ['saman', '삼안', '사업총괄'], ['jangheon-industry', '장헌산업', '본부장'], ['jangheon', '장헌', '대표이사'], ['ptc', '피티씨', '총괄책임자'], ['halla', '한라산업개발', '사장'], ['baron', '바론컨설턴트', null], ]; for (const [size, count, companyCount, depth] of [['small', 20, 3, 2], ['medium', 100, 5, 3], ['large', 300, 7, 4]]) { const organizations = [], employees = [], affiliations = []; const addEmployee = (org, position, name) => { const id = `virtual-${String(employees.length + 1).padStart(3, '0')}`; employees.push({ id, organizationId: org.id, affiliationId: org.companyId, name: name ?? (employees.length === 5 ? '홍길동' : `가상직원 ${String(employees.length + 1).padStart(3, '0')}`), position, jobTitle: null, profileImage: null, workStatus: 'active' }); return id; }; for (const [index, [companyId, companyName, position]] of companies.slice(0, companyCount).entries()) { affiliations.push({ id: companyId, name: companyName }); const org = (suffix, parentId, name, type, order) => { const node = { id: `${companyId}-${suffix}`, companyId, parentId, name, type, leaderId: null, displayOrder: order }; organizations.push(node); return node; }; const root = org('root', null, `${companyName} · 가상 조직`, 'root', index); if (position) root.leaderId = addEmployee(root, position, `가상책임자 ${index + 1}`); for (let branch = 0; branch < 2; branch++) { const division = org(`division-${branch}`, root.id, `가상 ${branch ? '지원' : '사업'}본부`, 'division', branch); if (count > 20) division.leaderId = addEmployee(division, '본부장'); const office = org(`office-${branch}`, division.id, `가상 ${branch + 1}실`, 'office', 0); if (depth >= 3) { const cell = org(`cell-${branch}`, office.id, `가상 ${branch + 1}셀`, 'cell', 0); if (depth >= 4) { org(`team-${branch}`, cell.id, `가상 ${branch + 1}팀`, 'team', 0); if (branch === 0) org('team-sibling', cell.id, '가상 협력팀', 'team', 1); } } if (count > 20 && branch === 0) org('office-sibling', division.id, '가상 계획실', 'office', 1); } } // Unequal groups: deterministic weighted membership; no random or live data. const pool = organizations.filter(org => org.parentId !== null); const weighted = pool.flatMap((org, index) => Array.from({ length: 1 + index % 4 }, () => org)); let cursor = 0; while (employees.length < count) { const org = weighted[cursor++ % weighted.length]; addEmployee(org, ['사원', '선임', '책임', '수석'][cursor % 4]); } const data = { schemaVersion: '0.1-draft', organizations, employees, affiliations, relations: [], presentation: { title: '확장형 조직도 · 가상 데이터', description: '실제 직원 정보가 아닌 고정된 테스트 데이터입니다.', hubText: null, groups: { showEmployees: true, showSummary: false, showDispatched: false, showOnLeave: false, showAffiliations: false }, organizationOrder: [] }, metadata: { asOfDate: '2026-10-12', dataVersion: `p5-23-${size}-${count}`, updateNote: '가상 데이터 · 운영 정보 아님' } }; await fs.writeFile(new URL(`./data-expanded-${size}.json`, import.meta.url), JSON.stringify(data, null, 2) + '\n'); }