import type { OutlineItem } from '@shared/types' export function buildOutlineTree(items: OutlineItem[]): OutlineItem[] { const byParent = new Map() for (const item of items) { const key = item.parentId if (!byParent.has(key)) byParent.set(key, []) byParent.get(key)!.push({ ...item, children: [] }) } const attach = (parentId: string | null): OutlineItem[] => { const nodes = byParent.get(parentId) ?? [] nodes.sort((a, b) => a.sortOrder - b.sortOrder) for (const node of nodes) { node.children = attach(node.id) } return nodes } return attach(null) } export function flattenOutlineTree(items: OutlineItem[]): OutlineItem[] { const result: OutlineItem[] = [] const walk = (nodes: OutlineItem[]): void => { for (const node of nodes) { result.push(node) if (node.children?.length) walk(node.children) } } walk(items) return result } export function calcDeviation(expected: number | null, actual: number): number | null { if (!expected || expected <= 0) return null return Math.round(((actual - expected) / expected) * 100) }