// 人工为 self-report 的「分组(文件/类)」与「流程」写入一句话摘要, // 写进 CodeFile.summary / Container.summary / Flow.summary,供 UI 展示。 // // 匹配用稳定标识(文件路径 / 类名 / 流程名),不依赖会随代码改动漂移的行号, // 因此重新生成报告后可直接重跑本脚本恢复标注。 // 用法: node scripts/annotate-self-report.mjs import { readFileSync, writeFileSync, copyFileSync } from "node:fs"; import { resolve } from "node:path"; const target = resolve("web/public/self-report.json"); const mirror = resolve("self-report.json"); // 文件分组摘要(key = CodeFile.path) const fileSummaries = { "src/scanner.ts": "递归扫描项目目录,按扩展名收集源文件并识别语言", "src/types.ts": "标准化代码报告的核心类型定义(Schema 真相源)", "src/externals.ts": "聚合函数交互,派生外部系统(数据库 / 服务)清单", "src/flows.ts": "从入口点遍历调用图,自动生成调用链流程", "src/analyzer.ts": "基于 TS 编译器 API 的解析核心:构建函数层级与调用边", "src/cli.ts": "命令行入口:解析参数、运行分析、写出报告 JSON", "src/overview.ts": "从报告推导「概览」确定层数据(接口 / 入口 / 外部系统 / 热点)", "src/overview-cli.ts": "概览推导的命令行运行器,打印可读的项目地图", "web/src/model/report.ts": "前端侧报告类型定义(与 CLI Schema 对齐)", "web/src/model/reportRepository.ts": "报告数据源抽象,HTTP 加载报告 JSON", "web/src/model/graphModel.ts": "将 Flow 转换为与渲染无关的「中性图」结构", "web/src/services/dagreLayout.ts": "用 Dagre 计算图的自动布局坐标", "web/src/model/overview.ts": "前端侧概览推导(与 CLI overview 同构)", "web/src/services/sourceService.ts": "源码绑定:向开发服务器请求真实源码片段", "web/src/services/languageMap.ts": "文件扩展名到语法高亮语言的映射", "web/src/viewmodel/GraphViewModel.ts": "图视图 ViewModel:编排加载 / 选择 / 布局 / 搜索 / 源码", "web/src/view/vmContext.ts": "提供 GraphViewModel 的 React Context", "web/src/view/components/FlowNode.tsx": "自定义流程图节点:显示函数名 / 归属 / 交互徽标", "web/src/view/components/FlowGraph.tsx": "React Flow 画布容器,渲染当前流程图", "web/src/view/components/FlowList.tsx": "左侧流程列表面板", "web/src/view/components/GroupList.tsx": "最左侧分组列表:按类 / 文件过滤流程", "web/src/view/components/NodeDetailPanel.tsx": "右侧节点详情:位置 / 归属 / 交互 / 所在流程", "web/src/view/components/SearchBar.tsx": "顶部搜索栏,检索流程与函数", "web/src/view/components/OverviewPage.tsx": "概览落地页视图", "web/src/view/components/CodePanel.tsx": "底部源码面板:语法高亮显示选中函数实现", "web/src/view/components/FlowBanner.tsx": "画布顶部横幅:显示当前流程名与说明", "web/src/view/App.tsx": "应用主组件:编排头部与各面板布局", "web/src/main.tsx": "前端入口:构建数据源与 ViewModel 并挂载 App", "web/vite.config.ts": "Vite 配置 + 开发期源码服务中间件", }; // 类分组摘要(key = Container.name) const containerSummaries = { HttpReportRepository: "通过 HTTP 从 URL 加载报告 JSON 的仓库实现", GraphViewModel: "图视图 ViewModel:持有全部可观察状态与命令", }; // 流程摘要(key = Flow.name) const flowSummaries = { " (web/src/main.tsx)": "前端启动:构建报告数据源与 ViewModel,挂载 React 应用", "visit (src/analyzer.ts)": "AST 遍历核心:递归访问语法树,登记函数 / 容器并建立调用边", "observer() 回调@24 (web/src/view/components/OverviewPage.tsx)": "渲染概览落地页:项目信息、接口分组、外部系统、热点", "observer() 回调@13 (web/src/view/components/NodeDetailPanel.tsx)": "渲染右侧节点详情:位置、归属、交互、所在流程", "observer() 回调@7 (web/src/view/components/CodePanel.tsx)": "渲染底部源码面板:随选中节点显示语法高亮源码", "observer() 回调@11 (web/src/view/App.tsx)": "渲染应用骨架:头部、搜索、各面板布局", "GraphViewModel.positionedGraph (web/src/viewmodel/GraphViewModel.ts)": "计算当前流程的带坐标中性图(含 Dagre 自动布局)", "observer() 回调@16 (web/src/view/components/FlowGraph.tsx)": "把中性图适配为 React Flow 节点 / 边并渲染画布", "observer() 回调@4 (web/src/view/components/FlowList.tsx)": "渲染流程列表并处理流程选择", "observer() 回调@4 (web/src/view/components/GroupList.tsx)": "渲染分组列表,按类 / 文件过滤流程", "observer() 回调@6 (web/src/view/components/SearchBar.tsx)": "渲染搜索框与结果下拉", "匿名函数@26 (web/src/view/components/SearchBar.tsx)": "搜索输入变更处理回调", "map() 回调@72 (src/flows.ts)": "生成流程步骤时的映射回调", "inProject (src/analyzer.ts)": "判断文件是否属于目标项目,过滤外部依赖", "map() 回调@229 (src/overview.ts)": "概览推导中的流程映射回调", "map() 回调@44 (web/src/model/graphModel.ts)": "将流程步骤映射为图节点", "map() 回调@205 (web/src/model/overview.ts)": "前端概览推导中的映射回调", "GraphViewModel.overview (web/src/viewmodel/GraphViewModel.ts)": "从报告推导概览确定层数据的计算属性", "GraphViewModel.groups (web/src/viewmodel/GraphViewModel.ts)": "派生分组列表的计算属性", "GraphViewModel.visibleFlows (web/src/viewmodel/GraphViewModel.ts)": "按当前分组过滤后的流程列表", "GraphViewModel.selectedFuncOwner (web/src/viewmodel/GraphViewModel.ts)": "计算选中函数的归属(类 / 文件)及其说明", "reaction() 回调@79 (web/src/viewmodel/GraphViewModel.ts)": "监听选中节点变化,自动拉取对应源码", "memo() 回调@40 (web/src/view/components/FlowNode.tsx)": "自定义节点渲染(memo 回调)", "匿名函数@41 (web/src/view/components/SearchBar.tsx)": "搜索结果项点击处理", "observer() 回调@4 (web/src/view/components/FlowBanner.tsx)": "渲染当前流程横幅:流程名与一句话说明", " (src/cli.ts)": "CLI 主流程:解析参数、运行分析、写出报告", " (src/overview-cli.ts)": "概览 CLI 主流程:读取报告并打印项目地图", " (web/vite.config.ts)": "Vite 配置与源码服务中间件初始化", }; const report = JSON.parse(readFileSync(target, "utf-8")); let f = 0; for (const file of report.files) { if (fileSummaries[file.path]) { file.summary = fileSummaries[file.path]; f++; } } let c = 0; for (const cont of report.containers) { if (containerSummaries[cont.name]) { cont.summary = containerSummaries[cont.name]; c++; } } let fl = 0; const unmatched = []; for (const flow of report.flows) { if (flowSummaries[flow.name]) { flow.summary = flowSummaries[flow.name]; flow.provenance = "manual"; fl++; } else { unmatched.push(flow.name); } } writeFileSync(target, JSON.stringify(report, null, 2), "utf-8"); copyFileSync(target, mirror); console.log(`已标注: 文件 ${f}/${report.files.length} · 类 ${c}/${report.containers.length} · 流程 ${fl}/${report.flows.length}`); if (unmatched.length) console.log(`未匹配流程: ${unmatched.join(" | ")}`); console.log(`写入: ${target}\n镜像: ${mirror}`);