--- name: code-flow-viz description: 用于梳理和可视化代码流程,生成清晰的 ASCII 流程图、数据流图和表格分析。适用于已有代码的梳理、新功能设计的说明、以及技术文档的编写。 --- # 代码流程可视化规范 本 Skill 提供一套可复用的模板和方法,用于梳理代码流程、生成可视化文档。 > **核心原则**:用文字和 ASCII 图表讲清楚"数据从哪来、经过哪些层、最后到哪去"。 ## When to use 在以下场景使用本 Skill: - 用户询问"某个功能是怎么工作的" - 新增功能需要设计数据流 - 重构前需要梳理现有逻辑 - 编写技术文档或架构说明 - 代码评审时需要可视化调用链 ## 核心模板 ### 1. 完整流程图(多场景对比) 适用于:梳理一个功能的多种使用场景(如手动 vs 自动、成功 vs 失败) ``` ┌─────────────────────────────────────────────────────────────────────┐ │ 功能名称(如:限额管理全生命周期) │ └─────────────────────────────────────────────────────────────────────┘ ═══════════════════════════════════════════════════════════════════════ 场景 1:场景名称(如:自动查询限额状态) ═══════════════════════════════════════════════════════════════════════ 用户命令 │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ uv run python -m src.cli.xxx ... │ └────────────────┬────────────────────────────────────────────────┘ │ ▼ ┌────────────────┐ │ CLI 层 │ 调用 Flow 函数 │ _do_xxx() │ ────────────────────┐ └────────────────┘ │ ▼ ┌──────────────────────────┐ │ Flow 层 │ │ xxx_flow() │ └───────┬──────────────────┘ │ ▼ ┌─────────────────────────────┐ │ Data 层 │ │ XxxRepo / XxxClient │ └────────┬─────────────────────┘ │ ▼ ┌────────────────────────────┐ │ 外部系统 / 数据库 │ │ (SQLite / API / etc) │ └──────────┬─────────────────┘ │ 返回数据 ▼ ┌──────────────────────────────────┐ │ 数据处理(解析/转换) │ └─────────────┬────────────────────┘ │ ▼ ┌──────────────────────┐ │ 返回值数据类 │ ← 说明为什么保留/简化 │ (Result / Item / ...)│ └──────────┬───────────┘ │ ▼ ┌──────────────────────┐ │ CLI 层格式化输出 │ └──────────────────────┘ │ ▼ ╔══════════════════════════════════════════════════╗ ║ 终端输出示例 ║ ║ (用框线包围,突出最终用户看到的效果) ║ ╚══════════════════════════════════════════════════╝ ═══════════════════════════════════════════════════════════════════════ 场景 2:另一个场景 ═══════════════════════════════════════════════════════════════════════ (重复上述结构,突出差异点) ``` ### 2. 数据库表结构说明 适用于:解释某个功能涉及的数据库表 ```sql CREATE TABLE table_name ( id INTEGER PRIMARY KEY AUTOINCREMENT, -- ← 说明主键作用 field1 TEXT NOT NULL, -- 说明字段含义 field2 TEXT, -- NULL 的业务含义 ... ); -- 索引(说明为什么需要这个索引) CREATE INDEX idx_xxx ON table_name(field1, field2); ``` **示例数据表**: | id | field1 | field2 | field3 | 说明 | |----|--------|--------|--------|------| | **42** | value1 | value2 | value3 | 解释这条记录的业务含义 | | **43** | ... | ... | ... | ... | **典型查询**: ```sql -- 场景说明:什么时候需要这样查? SELECT * FROM table_name WHERE condition1 = ? AND (condition2 IS NULL OR condition2 >= ?); ``` ### 3. 分层调用链图(简化版) 适用于:快速说明函数调用关系 ``` CLI 层 (_do_xxx) │ └─> Flow 层 (xxx_flow) │ ├─> Data/Repo (xxx_repo.get) │ │ │ └─> SQLite (SELECT ...) │ └─> Data/Client (xxx_client.fetch) │ └─> 外部 API (HTTP GET ...) ``` ### 4. 数据类设计分析表 适用于:评估中间数据类是否必要 | 类名 | 字段数 | 用途 | 判定 | 理由 | |------|--------|------|------|------| | `XxxResult` | 6 | 多字段聚合 + CLI 展示 | ✅ 保留 | 满足"最小必要原则" | | `XxxWrapper` | 1 | 单字段包装 | ❌ 删除 | 过度包装,直接返回原始类型 | | `XxxItem` | 3 | 列表明细项 | ✅ 保留 | 有业务语义 | **对比示例**: ```python # ❌ 过度包装 @dataclass class XxxResult: field: SomeType # 只有一个字段 def xxx_flow() -> XxxResult: return XxxResult(field=value) # ✅ 简化后 def xxx_flow() -> SomeType: # 直接返回 return value ``` ### 5. 业务关键点标注 适用于:突出业务规则和设计决策 ``` ┌─────────────────────────────────────────────────────────────┐ │ 业务关键点 │ ├──────────────────────┬──────────────────────────────────────┤ │ 为什么这样设计? │ 具体决策 │ ├──────────────────────┼──────────────────────────────────────┤ │ • 数据精度 │ 金额用 Decimal,2 位小数 │ │ • 幂等性 │ 按 (fund_code, date) 唯一约束 │ │ • 可追溯性 │ record_id 作为全局唯一标识 │ └──────────────────────┴──────────────────────────────────────┘ ``` ## 使用方法 ### Step 1: 确定分析目标 回答以下问题: 1. 用户想了解**哪个功能**的流程? 2. 这个功能有**几种场景**?(成功/失败、手动/自动等) 3. 涉及**哪些层次**?(CLI → Flow → Data → DB/API) 4. **关键数据类**有哪些?为什么设计成这样? ### Step 2: 选择合适的模板 - **多场景对比** → 模板 1(完整流程图) - **单一流程** → 模板 3(分层调用链) - **数据库设计** → 模板 2(表结构 + 示例数据) - **数据类评估** → 模板 4(分析表) ### Step 3: 填充内容 **原则**: - 用 ASCII 图表代替长篇文字 - 用箭头(`│ ▼ ┐ ┘ └ ├ ─`)串联数据流 - 用框线(`┌ ┐ └ ┘ │ ─`)分隔层次 - 用双线框(`╔ ╗ ╚ ╝ ║ ═`)突出用户可见部分 - 在关键节点加注释(`← 说明`) **符号使用规范**: | 符号 | 用途 | 示例 | |------|------|------| | `│ ▼` | 垂直流向 | 数据从上到下 | | `→ ←` | 水平说明 | `record_id: int ← 数据库主键` | | `┌ ┐ └ ┘` | 单线框 | 包围代码块、命令 | | `╔ ╗ ╚ ╝` | 双线框 | 突出终端输出、重要结果 | | `═══` | 分隔线 | 分隔不同场景 | ### Step 4: 添加对比分析 **Before vs After**(重构场景): ```python # Before(问题版本) ...代码... # 问题: # - 过度包装 # - 字段冗余 # - 增加认知负担 # After(改进版本) ...代码... # 改进: # - 直接返回有意义类型 # - 减少中间层 # - 降低维护成本 ``` ## 实际案例 ### 案例 1:限额管理流程(完整版) (见上面的模板 1 示例,展开 4 个场景的完整流程) ### 案例 2:数据类评估(fund_restriction 模块) | 函数 | 之前返回 | 现在返回 | 判定 | 原因 | |------|---------|---------|------|------| | `add_restriction` | `AddRestrictionResult`(6字段) | **保留** | ✅ | CLI 需要展示所有字段 | | `end_restriction` | `EndRestrictionResult`(4字段) | `bool` | ❌ | 只需要成功/失败 | | `check_trading_status` | `CheckStatusResult`(2字段) | `ParsedRestriction \| None` | ❌ | 只是简单包装 | ## 输出清单(Checklist) 生成流程可视化文档时,确保包含: - [ ] 顶层概述(功能目标、涉及模块) - [ ] 场景枚举(成功/失败、手动/自动等) - [ ] 分层流程图(CLI → Flow → Data → 外部) - [ ] 数据库表结构(如果涉及) - [ ] 示例数据和查询(帮助理解) - [ ] 关键数据类说明(为什么保留/简化) - [ ] 设计原因(为什么这样做?) - [ ] 未来扩展点(TODO 或预留接口) ## 反模式(不要这样做) ❌ **纯文字描述流程** ``` 首先调用 CLI 层的 _do_xxx 函数,然后 _do_xxx 会调用 Flow 层的 xxx_flow 函数, xxx_flow 再调用 Data 层的 xxx_repo.get 方法... ``` ✅ **用 ASCII 图表** ``` CLI (_do_xxx) → Flow (xxx_flow) → Data (xxx_repo.get) → SQLite ``` --- ❌ **表格没有重点** | 字段 | 类型 | |------|------| | id | int | | name | str | ✅ **突出业务含义** | 字段 | 类型 | 说明 | 业务约束 | |------|------|------|----------| | id | int | 主键 | 自动生成,全局唯一 | | name | str | 基金名称 | 非空,用于展示 | --- ❌ **SQL 没有场景说明** ```sql SELECT * FROM table WHERE id = ?; ``` ✅ **带业务场景** ```sql -- 场景:用户查询某条限制记录详情 SELECT * FROM fund_restrictions WHERE id = ?; -- 场景:DCA 分析时检查某日是否被限额 SELECT * FROM fund_restrictions WHERE fund_code = ? AND start_date <= ? AND (end_date IS NULL OR end_date >= ?); ``` ## 与其他 Skill 的协作 - **code-style**:输出代码示例时遵循编码规范 - **architecture**:流程图需符合分层架构约束 - **dev-workflow**:梳理流程前先读取相关代码和文档 ## 总结 本 Skill 的核心价值: 1. **可复用的模板**:减少从零开始的时间 2. **统一的视觉风格**:ASCII 图 + 表格 + 框线 3. **业务视角**:不只是代码流程,更关注"为什么" 4. **对比分析**:重构前后、多场景对比 5. **清单检查**:确保不遗漏关键信息 **使用频率**:每次需要解释"某个功能怎么工作"时都可以用。