mcpField
S
structural-review

structural-review

github.com/shipshitdev测试与质量3855 次安装2 天前更新
代码仓库

关于 structural-review

structural-review 是用于评估代码结构、可维护性和开发体验的报告型技能。它着重提出明确、可执行的简化建议,不重复正确性和安全审查。

主要功能

  1. 01审查结构、可维护性和开发体验
  2. 02指出过大的文件和薄弱抽象
  3. 03检查规范层次与类型位置
  4. 04识别分支问题和非原子变更
  5. 05按严重程度排列可执行发现

适用场景

  1. 01检查拉取请求中的结构退化
  2. 02找出可删除的抽象或分支
  3. 03合并变更前检查可维护性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/shipshitdev/skills --skill structural-review

安装后在 Claude Code 中输入/structural-review确认已加载。

附带文件plugin.json

详细介绍

结构审查

一套观点鲜明的结构与可维护性审查准则。仅报告问题——此技能只会给出发现,不会修改文件或创建 PR。

核心原则

每条结构性发现都必须回答:“作者具体应该删除、合并或重命名什么——以及哪个具体文件/行是规范的落点?” 含糊的吹毛求疵(“这里可以更整洁”)只会制造噪声。只报告确信度高且可执行的问题。

本准则明确补充 /code-review。不要重复标记其中已涵盖的正确性 bug 或仓库指令文件违规问题。只负责与之正交的结构、可维护性和开发体验(DevEx)维度。判断变更是否让模块更深或更浅时,使用 codebase-design 术语(模块、接口、深度、接缝)。

首要审查问题

在逐项查找问题之前,先问这些问题:

  1. 这个 PR 让代码库变小了还是变大了? 如果变大了:每个新抽象是否物有所值,还是只是盲目增加了复杂性?
  2. 决策逻辑在哪里? 它是在规范层(服务端操作、领域服务、钩子)中,还是散落在渲染树和事件处理器里?
  3. 读者能否独立理解这个模块? 还是必须跨 4 个以上文件追踪状态/逻辑才能理解?
  4. 每个新类型是否放在了合适的位置? 是否用裸 unknown 和 as X 类型断言掩盖了未来的故障?接口是否被直接内联,而不是放在应该存放它们的 *.types.ts 中?
  5. PR 是否让技术栈比修改前更整洁? Tailwind v3 残留、npm 调用、shadcn 项目中的原生 HTML、Next.js 16 应用中的 middleware.ts——这些都是退步,不是风格问题。

评审维度

1. 文件大小——约 1,000 行规则

文件超过约 1,000 行时,原则上应阻止合并。这不是硬性的数值规定,但强烈表明该模块承担了过多职责。

以下情况应标记:

  • 此 PR 修改的任何文件现在超过 1,000 行。
  • PR 本身增加了足够多的行数,使原本接近阈值的文件超过了限制。

首选修复方案: 在 PR 合并前拆分为同目录下的多个部分——*.service.ts、*.queries.ts、*.types.ts、*.hooks.ts。不要等到合并之后。

表述示例:“文件现在有 1 180 行。在发布前将查询层拆分到 *.queries.ts 中——1 000 行规则正是为这类 PR 设立的。”

严重级别: 阻止合并。

2. 抽象必须物有所值

每个新函数、钩子、类或文件都必须证明其存在的必要性。薄封装、恒等辅助函数和透传式重新导出一律不符合这一要求。

以下情况应标记:

  • 新辅助函数只是单行改名,或只是调用其他函数,没有增加任何不变量。
  • 新文件只是从另一个文件重新导出符号,没有做任何转换。
  • 钩子只封装了一个 useState,没有相关逻辑。
  • 接口只定义了一次,且只在调用处使用一次——将其内联。

首选修复方案: 删除这个抽象;在调用处内联真正的符号。Bun + TS 路径别名让原始符号很容易引用。

表述示例:“这个辅助函数只是对 formatDate 的恒等封装——将它内联并删除该文件。纯属多此一举。”

严重级别: 请求修改。

3. 意大利面式分支

在现有流程中临时添加分支,是干净的代码库变得难以维护的主要原因。

以下情况应标记:

  • 同一个 if (isAdmin) / if (featureFlag) / if (isPremium) 分支出现在此 PR 修改的 2 个或更多文件中。
  • 在一个已有 3 条或更多条件路径的渲染函数中新增分支。
  • 功能标志分支散布在组件渲染路径中,而不是在单一决策点统一处理。

首选解决方案: 将所有分支合并到一个统一的决策点——客户端状态使用 hook,变更操作使用 server action 或领域服务。这样,组件中的分支就可以消失。

措辞:“渲染树中散布着 3 个 if (isAdmin) 分支。将决策合并到一个 hook 或 server action 中,这样组件中的分支就可以消失。”

严重程度: 要求修改。

4. 规范的分层纪律

在此技术栈中,逻辑应归属于特定层。违反分层模型是结构性缺陷,而非偏好问题。

分层映射:

  • 变更操作 → server action 或领域服务。不要放在原始 <form onSubmit> 中,也不要放在 useEffect 中。
  • 派生的客户端状态 → hook。不要在 JSX 中内联重新计算。
  • 交互元素 → shadcn/ui 基元或 packages/ui 组件。不要使用原始 <button>、<input>、<dialog>。
  • 路由中间件 → proxy.ts。不要使用 middleware.ts(Next.js 16)。

以下情况应标记:

  • 项目中已有 server action,但变更操作直接绑定到了 DOM 事件处理器。
  • 本可写成 hook 的计算逻辑被内联在 JSX 中,并在 2 个或更多组件中重复。
  • 某个文件已经从 packages/ui 或 shadcn 导入内容,却又出现原始 HTML 元素。
  • 自定义辅助函数重复实现了代码库中已有的规范工具——应复用现有辅助函数,而不是添加一个近似重复项。

措辞:“某个组件已经从 packages/ui 导入了 Button,却还使用 <button onClick={...}>——请替换它;在此代码库中使用原始 HTML 是一种退步。”

严重程度: 要求修改;在使用 shadcn/packages/ui 的项目中,若元素是原始交互元素,则为阻断级。

5. 类型结构纪律

此项涵盖结构位置和形状问题——不包括 any 的存在,因为这由 /code-review 检查流程负责。

违规情况(全部标记):

  • 没有相邻类型守卫的裸 unknown——这相当于将 any 延后处理,在结构上等同于未明确类型形状。
  • 使用 as X 断言,却没有注释说明类型系统为何无法推断出更窄的类型。
  • 在组件或服务文件中内联定义接口——应放在同目录的 *.types.ts 或 packages/types 中。

首选解决方案: 在 *.types.ts 中定义类型形状。在 unknown 进入系统的边界处添加类型守卫。

措辞:“没有类型守卫的裸 unknown 等同于延后处理的 any。请在 *.types.ts 中定义类型形状,或在此处添加守卫。”

严重程度: 没有守卫的裸 unknown → 阻断级。内联接口 → 要求修改。没有注释的 as X → 轻微。

6. 非原子变更操作

依次执行、且每次都会写入数据库的 await 调用,是与正确性密切相关的结构性缺陷。写入之间发生崩溃会使系统处于只完成部分写入的状态。

以下情况应标记:

  • 同一个函数中出现 2 个或更多 await db.update() / await db.insert() 调用,且没有用事务包裹。
  • 某个函数先执行写入,再调用外部服务,然后执行第二次写入,却没有补偿/回滚路径。

首选解决方案: 使用数据库事务包裹,或将其建模为单次原子写入。如果外部调用无法放在事务中,则添加明确的补偿逻辑。

措辞:“这两次 await db.update() 调用不是原子的。两次调用之间发生故障会使该行处于无效状态——请用事务包裹,或将其建模为单次原子写入。”

严重程度: 阻断级。

7. 顺序编排异味

连续编排 5 个或更多步骤,且没有中间抽象的函数,会成为未来的维护隐患。它们难以测试、复用,也难以独立理解。

以下情况应标记:

  • 新函数中有 5 个或更多连续的 await 调用,且没有中间的具名步骤或辅助函数。
  • 路由处理器或服务器操作在内联代码中完成读取、转换、验证、写入和通知。
  • 两项互不相关的工作(两个无关的读取或获取操作)没有理由却被串行等待——如果并行执行也能简化流程,就应并行执行。

首选解决方案: 提取具名阶段。每个阶段都可以单独测试。编排函数则成为一份清晰易读的意图列表。

严重程度: 要求修改。

8. 技术栈整洁度(严重回归)

这不是风格建议,而是 PR 引入、必须在合并前修复的回归。

问题规则表述
创建或保留了 middleware.tsNext.js 16 将入口点重命名为 proxy.ts;旧名称会被静默忽略“这是 middleware.ts。请重命名为 proxy.ts——Next.js 16 已重命名入口点。”
添加了 tailwind.config.ts 或 tailwind.config.jsv4 使用基于 CSS 的配置(在 CSS 中使用 @theme);JS 配置属于 v3“此 PR 创建了 tailwind.config.ts——这是 v3 的做法。请删除该文件,并按 v4 的要求将主题令牌移入 CSS 的 @theme 块。”
添加了 @apply 指令或 bg-opacity-* 类这是 v3 的写法;必须迁移到 v4 的斜杠语法指出确切行号和 v4 中的对应写法。
在脚本、CI YAML 或文档中使用 npm run、npx、yarn add 或 pnpm execBun 是唯一的包管理器;请替换为 bun run / bunx / bun add“下面两行的 npx prisma migrate 必须改为 bunx prisma migrate。”

严重程度: 全部为阻止合并。

9. 设计纯粹性——相同行为,更简洁的结构

最关键的结构性问题不是“这样对吗?”,而是“能否用显著更少的结构表达相同行为?”在可避免的复杂性之上实现了正确行为,意味着错过了简化机会,而错过的简化会不断累积。

以下情况应标记:

  • 新状态机、配置对象或分支树表达的决策,其实用一个派生值或默认值就能实现。
  • 添加了特殊情况,而将其并入通用路径(采用合理的默认值或提前返回)就能彻底删除该分支。
  • 重构只是重新排列代码,却没有减少读者必须同时掌握的活动部件数量。

首选解决方案: 重新构想状态模型。将特殊情况合并到默认逻辑中。删除和合并胜过润色——应通过“代码柔道”彻底消除复杂性类别,而非仅仅整理它。

表述: “这个三态标志可以简化为一个派生布尔值——行为不变,还能整个删掉一个分支。应重新构想,而非润色。”

严重程度: 要求修改(如果更简单的形式还能消除正确性隐患,则阻止合并)。

10. 直接性与魔法

优先采用显而易见的机制,而非巧妙的机制。过度通用的抽象、隐藏的假设,以及掩盖控制流的间接层,带来的阅读成本往往高于编写时节省的成本。

以下情况应标记:

  • 引入通用或参数化机制,却只有一个具体调用方(“投机式泛化”)。
  • 行为依赖隐藏假设——隐式排序、全局变量、命名约定、反射或元编程——而读者无法从调用位置看出这些假设。
  • 使用间接层(动态分派、事件间接调用、深层配置)代替直接调用,却没有值得采用这种做法的不变量。

首选解决方案: 对唯一实际调用方内联为直接写法。在边界处明确说明假设,或者移除魔法。

表述: “只有一个处理器却使用通用注册表——删除它,直接调用处理器。等第二个调用方真正出现时,再添加抽象。”

严重程度: 要求修改。

忽略项

  • 未根植于结构性缺陷的风格偏好(缩进、命名上的细微差异)。
  • 正确性缺陷和测试覆盖缺口——这些应在 /code-review 中处理。
  • 安全问题——这些应在 /security-audit 中处理。
  • 正确性审查框架已涵盖的仓库指令文件规则违规。
  • 文档缺口(内联文档、README 更新)——除非明确要求,否则不处理。
  • 覆盖率百分比下限——仅指出新增关键路径缺少测试的问题,不要求达到特定数字。

输出格式

按严重程度排序列出发现:

## Structural Review

### Blockers (must fix before merge)
[File-size violations, non-atomic mutations, stack regressions (middleware.ts, tailwind config, npm/yarn usage), bare unknown without guard, design-purity simplifications that also remove a correctness footgun]

### Request Changes (significant structural debt)
[Abstraction-earns-keep failures, canonical-layer violations, spaghetti branching, sequential orchestration smells, inline interfaces, missed design-purity simplifications, speculative generality / magic indirection]

### Minor (low-debt, flag for awareness)
[as X casts without comments, small layer suggestions with obvious inlines]

### Approved Axes
[Axes with no findings — confirm clean]

每项发现都包括:

  • 文件 + 行号范围(准确,不得近似)。
  • 一句话说明结构性缺陷。
  • 一句话说明具体的修复方法。
  • 一条审查者措辞(使用上面的示例,或根据具体代码调整)。

批准标准

阻止和要求修改的标准已包含在上面的各个维度中。如有歧义,默认要求修改——承担歧义成本的是作者,而不是代码库。

评论

支持 Markdown