mcpField
C
codebase-architecture

codebase-architecture

github.com/mblode开发169463 次安装2 天前更新
代码仓库

关于 codebase-architecture

codebase-architecture 是用于设计 TypeScript 代码库结构并降低变更成本的技能。它涵盖新代码库架构简报、现有代码的针对性改进,以及防止既定结构逐渐失效的约束机制。

主要功能

  1. 01为新代码库设计架构简报
  2. 02排序并迁移现有代码改进
  3. 03定义模块与接口边界
  4. 04添加 lint、类型和 CI 约束
  5. 05改善 Agent 在仓库中的导航

适用场景

  1. 01为新的 TypeScript 应用或服务选择结构
  2. 02减少概念分散和边界泄漏
  3. 03在 CI 中强制执行既定模块边界
  4. 04帮助 Agent 在仓库中找到规范模式

安装

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

$npx skills add https://github.com/mblode/agent-skills --skill codebase-architecture

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
evals.json
evaluation-scenarios.md
references/
agent-runtime.md
api-design.md
brief-conventions.md
contagion-markers.md
deepening-existing.md
distributed-correctness.md
domain-language.md
enforcement-ladder.md
guardrail-tooling.md
stack-defaults.md
verification-tiers.md
vocabulary.md
wayfinding.md

详细介绍

代码库架构

确定 TypeScript 代码库的结构,在变更成本变得高昂时加以改进,并确保结构保持稳定。目标是打造一个读者能在脑中把握全貌的代码库:界面少,每项工作都有一种规范做法,行为也出现在你最先会去查找的地方。

  • 是: 文件夹结构、模块接口、请求上下文和中间件管道、前后端边界;架构简报;领域语言和决策记录;融入领域知识的深化;护栏工具、CI 门禁和 Agent 导航指引。
  • 不是: 搭建新仓库(Next.js turborepo 用 scaffold-nextjs,TypeScript CLI 用 scaffold-cli)、多租户领域/隔离/路由(multi-tenant-architecture)、AGENTS.md 本身的内容(agents-md)、单个功能的计划(planning)、限定于 diff 的清理(tidy)、对本地 diff 进行结构审查(tidy),或产品自身的 verify CLI、doctor 命令和功能图(app-verification,请按名称调用)。

目录

  • 模式
  • 参考资料
  • Design 模式(新代码库)
  • Deepen 模式(现有代码库)
  • Harden 模式(确保结构持久)
  • 验证循环
  • 输出模板
  • 注意事项
  • 相关技能

模式

根据问题而不是产物来选择模式,并说明你选择了哪一种。

模式适用情况输出
Design开始构建新的应用、服务或界面,尚未确定结构架构简报
Deepen代码可以正常工作,但变更成本高昂:概念分散、边界泄漏、同一个想法有三种叫法排序后的改进机会,然后迁移一个切片
Harden结构已经确定,却总在退化,或者 Agent 在此仓库中总是做错事接入检查、标记和操作指南

模式可以组合,同时运行多个模式也很正常。 Design 以 Harden 收尾,因为没有检查的契约只是建议。Deepen 也以 Harden 收尾,这样新边界就不会再次退化。若结构已经正确,只缺少执行机制,则单独运行 Harden 即可;在 Agent 参与工作的仓库中,这种情况最常见。

两个模式看起来同样合适时,优先选择 Deepen。 “Agent 总在用旧模式”听起来像是 Harden 的问题,但如果原因是一个概念同时存在于两个地方,那么隔离只会冻结重复内容:Deepen 会删除重复内容,而 Harden 会守住底线,直到改动落地。只有旧内容确实必须保留时,才适合单独运行 Harden。

无法修改仓库时(没有检出代码、请求为只读,或用户提出的是问题而非修改),各模式的输出会退化为计划:简报、排序后的改进机会,或列出名称及等级的检查项。请说明哪些检查尚未得到验证,因为它们都还未接入。

尽可能简单,但不要过度简化。 每种模式都会做减法:Design 减少界面,Deepen 精简概念,Harden 消除双路径和休眠配置。但底线不能削减:信任边界处的验证、防止数据丢失的错误处理、安全性、无障碍性、任何已部署内容的可观测性,以及明确提出的要求。简化若触及其中任何一项,就是缺陷。若有意在某个角落做了取舍,请标明其上限和升级路径,不要让后续读者猜测它是否已经完成。

复制以下内容以跟踪进度,并删除未运行模式对应的行:

Codebase architecture progress:
- [ ] Modes chosen and stated (Design / Deepen / Harden)
- [ ] Design: assumptions stated, repo shape, every contract names its check, brief written
- [ ] Deepen: git hot spots, glossary, ranked opportunities with paths, one slice migrated
- [ ] Harden: existing checks surveyed, checks picked by failure, each landed green and proven to bite
- [ ] Validation loop run for the modes used; evidence recorded, N/A items named

参考资料

仅在条件适用时加载。

参考资料模式阅读时机
references/vocabulary.md全部在任何输出中为模块、接口、接缝或适配器命名之前;该文档定义了删除测试
references/stack-defaults.md设计选择库、工具或部署目标时
references/api-design.md设计、深入设计端点、模块接口、请求上下文、错误格式或转发凭证时
references/distributed-correctness.md设计、深入工作可证实地涉及外部系统、Webhook、重试、审计跟踪或资金时。在深入模式下,可以搜索确认;在设计模式下,这属于需求问题,因此应先确认再加载,不要根据产品领域推断
references/brief-conventions.md设计编写 brief 中的约定、测试、质量标准或发布与回滚部分时
references/deepening-existing.md深入运行深入流程时:机会模式、设计两次、排序、衡量面向 Agent 的变更、输出模板
references/domain-language.md深入编写或修复词汇表、解决命名分歧、记录决策时
references/enforcement-ladder.md加固为已有违规的代码库添加任何检查时
references/guardrail-tooling.md加固选择并接入实际检查项时:死代码、重复代码、循环依赖、模块和包边界、文件大小、陈旧度门槛
references/wayfinding.md加固Agent 找不到所需内容,或总是重复推导相同路径时
references/contagion-markers.md加固代码库包含遗留代码、生成代码、双路径或有意简化的代码时
references/verification-tiers.md加固定义 Agent 应运行哪些命令及其运行时机时
references/agent-runtime.md加固配置编辑后钩子、权限允许列表,或配置由 Agent 无人值守地起草修复或分流警报的任务时

设计模式(新代码库)

在做以下任何事情之前,先确认每个界面是否都确有存在的必要。可以作为现有交付内容中的一个文件夹的模块、服务、应用或入口点,是成本最低的架构决策,也是唯一能始终保持低成本的决策。你接受的每个界面都会消耗界面范围预算(brief-conventions.md)中的关系成本:将其纳入简报前,先明确其负责人、测试、可观测性和删除路径。

  1. 先明确约束:产品范围、团队规模、合规性/安全性、预期规模、部署目标、必需的集成,以及质量标准。一句话的需求不会提供这些信息,因此请按常见情况假设,在简报第一部分列明所有假设,并邀请对方纠正。只有当错误的猜测会重构简报,而非仅仅扩展简报时,才直接提问;实际需要确认的通常只有多租户和 API 是否公开。
  2. 选择代码仓库结构:
    • apps/ 用于可部署的界面(api、web、admin)。
    • packages/ 用于共享库(shared、ui、icons、auth、proto)。
  3. 定义后端模块接口,并为每项注明如何强制执行(导入边界 lint 或类型检查):
    • handler:仅负责传输。
    • service:业务编排。
    • dao:仅负责数据库访问;只有 DAO 可以导入 db 包,每张表由一个模块负责,其服务是唯一的写入方。查询规则见 references/api-design.md 中的“Data Access”。
    • mapper:DB/proto/领域模型之间的转换。
    • constants 和 types:模块本地契约。
  4. 定义请求上下文和中间件:
    • 在由 AsyncLocalStorage 支持的 RequestContext 中携带 tenantId、userId 和 traceId,并在每个入口点(RPC、HTTP、作业、CLI)初始化,通过 getContext() 读取。在线程间传递 ctx 参数会让每个函数签名不断膨胀,而以后新增字段也会影响每个调用点。实现见 references/api-design.md。
    • 注册每个 RPC 方法时,必须明确指定认证策略;没有指定策略的方法应导致注册失败,而不是默认开放。
    • 将认证、日志记录、错误处理和上下文放在共享中间件中,而非各个处理器的代码中。
  5. 定义前端边界(默认使用 Next.js App Router):
    • app/ 仅存放路由文件(page、layout、loading、error、route)。领域代码放在 src/modules/<name>/ 中,并通过其根文件暴露;仅供单个路由使用的 UI 放在页面旁边的 _components/ 文件夹中。页面逻辑变得复杂时,应将其移到模块中,而不是放到 app/ 下的同级文件中。
    • 默认使用 Server Components;在交互叶节点上添加 "use client"。客户端包装器需要服务器渲染内容时,将内容作为 children 传入。
    • 服务端状态使用 TanStack 或 Connect Query;客户端状态使用组件状态;只有适合跨领域客户端状态、且不适合前两者的情况才使用 MobX。每份数据都应有一个所有者:将服务端数据镜像到 useState,或通过 useEffect 同步两个存储,都是数据归属不明确的信号。
    • proxy.ts(Next 16 对 middleware.ts 的命名)负责重定向、重写和标头。授权在每个路由处理器和 Server Function 内部决定,因为被 matcher 排除的路径会跳过 proxy,而 Server Function 会向其页面的路由发起请求。
  6. 测试和发布:
    • 单元测试不依赖 DB;集成测试/E2E 测试并行运行,并使用动态生成的 ID,确保各次运行不会在测试夹具上冲突。
    • 以小型、完整、可逆的垂直切片发布,并为每项变更制定回滚计划。
    • 只有在可靠性、错误路径、可观测性和面向用户的状态都得到覆盖后,一个切片才算完成;把这些推迟到润色阶段,往往就意味着它们永远不会交付。
  7. 简报中的每项契约都应注明能检测其违规情况的 lint 规则、类型检查或测试,然后继续进入 Harden 模式,将这些检查接入流程。

深化模式(现有代码库)

目标:基于领域知识深化,而非重写。加载 references/deepening-existing.md,了解分析方法、机会模式和输出模板。

  1. 梳理领域语言和决策。 如果存在 CONTEXT.md、docs/adr/ 或本地等效文件,请先阅读,然后阅读代码,了解团队如何命名实体、操作和上下文。记录偏差(一种概念,三种名称;或一个名称,三种概念)。格式和 ADR 规则见 references/domain-language.md。
  2. 根据变更落点限定扫描范围。 深化对持续变更的代码最有价值,因此先通过 git log --oneline 查看足够长时间范围的历史记录,并重点关注反复出现的文件。未限定范围的扫描容易偏向推测性的清理。
  3. 寻找深化机会。 留意贫血概念、浅层模块、泄漏的边界、命名偏差、重复概念、原始类型痴迷、逻辑错置,以及被迫越过公共接口的测试。逐一记录具体的文件路径,不要只写模糊的问题描述。每个候选项都先检查能否删除:没有活跃调用方的概念、分支从不执行的标志,或只有一种实现的层。删除就是深化,而且是唯一不会让代码库更难阅读的做法。
  4. 按杠杆效应排序。 优先选择通过删除测试、能明确限定未来变更范围、变更频率低、满足当前需求且有可行测试接缝的机会。设计目标接口之前,先给候选项排序;舍弃推测性的清理。对排名最高的候选项,先设计两种接口,再择一采用。
  5. 先迁移一个纵向切片。 在推广通用化之前,先通过一个切片端到端验证杠杆效应最高的改动。
  6. 通过 lint、类型或测试检查强制执行新的边界,防止其退化,然后逐个模块推广。继续进入 Harden 模式,完成强制执行环节和 check-bites 测试。

强化模式(让规则落实)

分为两部分:防护措施阻止错误内容进入,寻路方式让正确内容容易找到。之所以两者都不可或缺,是因为 Agent 是通过 grep 找到内容,而不是阅读文档,所以警告必须出现在它们找到的位置,规则也必须通过退出码来落实,而不能只是一句可能被人记住的话。

优先采用最强的机制:结构,然后是 lint 和 CI,再然后是说明文档,最后才是人工审查;每条审查意见、事故或重复出现的错误,都意味着缺少一项检查(references/enforcement-ladder.md)。

步骤 1 至 3 始终执行。只有满足相应条件时才执行步骤 4 至 6;如果请求只要求添加一项检查,到步骤 3 即可。每次请求都执行全部六步会加载大部分内容包,这是此模式最容易出现的问题。

  1. 盘点现有内容。 检查包脚本、CI 步骤、钩子配置、lint 配置、说明文件和文档索引。找出三类内容:在本地运行但不会阻止合并的检查、在 CI 中运行但无法使流程失败的检查(verification-tiers.md 中的 “Commands that lie”),以及无人调用的休眠配置。接入第一类,修复第二类,删除第三类(references/contagion-markers.md)。
  2. 根据检查所防止的故障来选择检查项,切勿根据工具的人气来选。类别和工具见 references/guardrail-tooling.md。挑出此代码库实际出现的两三类故障;一次性安装全套工具,会迫使所有故障都采用最弱的执行等级。
  3. 安装每项检查: 针对现存违规选择一个执行等级(references/enforcement-ladder.md),以通过检查的状态交付,然后验证检查确实有效(运行检查,故意制造错误,确认它会失败并显示指出修复方法的消息,然后撤销更改)。将其接入提交前钩子和 CI。
  4. 寻路方式按 references/wayfinding.md 执行:命名与就近放置、添加新 X 的操作指南文件、标注可信度的文档索引,以及唯一的规范说明文件。
  5. 传播标记按 references/contagion-markers.md 执行:任何 Agent 不得复制或编辑的内容,都要在代码所在位置添加可通过 grep 搜索的标记,并注明应改用什么内容。
  6. 运行时体验: 按 references/verification-tiers.md 设置验证等级;按 references/agent-runtime.md 设置会话钩子、权限允许列表、无人值守修复任务和警报分流;在执行顺序的第 4 级进行审查门禁。

验证循环

运行与你所采用模式相匹配的项目,并在输出中记录结果。每项都需要证据;“看起来一致”不算通过。若因尚未安装任何内容或仓库不可写而暂时无法执行某项,请记录为 N/A 并说明原因。悄悄跳过检查,正是导致未经强制执行的约定带着“已验证”的外表发布的原因。

  1. 一致性(Design、Deepen):所有服务中的命名、模块接口和中间件规则表述一致。证据:矛盾扫描结果为零。
  2. 可强制执行性(全部):每项约定都注明对应的 lint 规则、类型检查或测试。证据:每项约定都有强制执行说明;对于实际已安装的检查,还需先通过,再通过故意引入违规使其失败,最后回退后再次通过。
  3. 可运维性(Design):针对每个可部署的表面,说明健康检查、回滚路径和可观测性,以便发现缓慢或卡住的情况(按路由统计 p95/p99 延迟;按任务类型统计队列深度和最早任务的等待时长)。缓慢、可重试或依赖第三方的工作应作为持久化任务运行,其状态存储在应用现有数据库的一行记录中,而不是新建队列或存储;直接调用模块,只有当调用方既不应等待消费者,也不应了解消费者时才使用事件(references/distributed-correctness.md)。每个自动化任务都必须有无需部署即可启用的紧急停止开关;每项功能都必须说明依赖项不可用时是故障开放还是故障关闭。证据:发布部分逐项列出这些内容;模块之间若使用事件或队列,必须说明为何不能直接调用。
  4. 质量门禁(代码有变更时):仓库的 lint、类型检查和定向测试(pnpm lint、pnpm check-types、pnpm --filter <pkg> test 或等效命令)。证据:引用通过检查的输出。
  5. CI 与本地一致(Harden):CI 步骤调用开发者运行的同一总控命令,或明确说明差异是有意为之。
  6. 没有悬空指针,冷启动时流程可行(Harden):通过 grep 证明文档索引和指令文件中列出的所有路径都存在;此外,由一个全新上下文中的 Agent 端到端遵循一份“添加新 X”的操作指南,且无需进一步指导。
  7. 整体简洁性(全部):结果应让读者需要记住的内容更少,而不是更多。证据:列出文件、表面和导出名称的净变化,说明并补偿每项增加所替代的内容;此外,对于新增的每个层、端口或间接层,都要指出使其落地的第二个调用方或实现。若架构审查只带来增加,即使其他各项都通过,也视为未通过此检查。

失败时:修正简述、约定或连线,然后重新运行验证循环。

输出模板

Design 模式生成此简述。Deepen 模式的机会排序模板见 references/deepening-existing.md。Harden 模式的输出是连线本身及验证循环的证据,而非文档。

# Architecture brief

## Context and constraints
## Repo shape
## Backend module interfaces
## Request context and middleware policy
## Frontend boundaries
## Testing strategy
## Quality bar and surface-area budget
## Rollout and rollback plan
## Open risks and follow-ups

简述的篇幅应与决策数量相匹配,而不是与模板相匹配。 项目不涉及的标题应直接删除,而不是勉强填写:没有前端的单租户内部服务,不必提供“前端边界”一节。每节应说明决策及其背后的约束,而不是复述参考资料中的约定。为了凑足九节而填充内容,会占用评审注意力,而这些注意力本应留给那两个存在争议的决策。

注意事项

Harden 模式的注意事项列于每个步骤加载的参考文档中(guardrail-tooling.md、enforcement-ladder.md、contagion-markers.md、verification-tiers.md、wayfinding.md)。

  • 对于人数少于 5 人的团队,微服务会带来部署流水线、契约版本管理,以及每个服务各自的值班工作面。应从模块化单体仓库开始;等团队或规模压力证明边界确有必要时再拆分。
  • 单体仓库根目录 package.json 中的应用级依赖会被静默提升,因此应用可能在本地构建成功,却在单独部署时失败。每个应用都应管理自己的依赖。
  • 如果没有导入边界规则,handler/service/dao 契约会在第一个截止日期到来时失效。编写契约的当天就添加规则(dao 不得导入 handler)。
  • 在页面或布局级别使用 "use client" 会将整个子树转换为客户端渲染,从而失去流式传输和直接访问服务端数据的能力。应将它推到叶节点。
  • 在有 3 个或更多应用需要代码之前就将其提取到 packages/,只会徒然耦合发布周期。例外是两个界面已共享的契约(生成的类型、RPC 架构、品牌化 ID):它们是两者之间的接口,在有两个应用时就应放入一个包中。
  • 在没有 outbox(或 CDC)的情况下,同时写入数据库和队列或 webhook,只要一边提交而另一边失败,就会丢失或凭空产生通知。参见 references/distributed-correctness.md。
  • 通过构造强制执行、但可被外部强行改变的不变量(无符号类型、硬性 CHECK),会在外部强行改变状态时崩溃或截断值。应将其表示出来,在事后检测,并明确恢复。
  • 若仅依赖 proxy.ts 作为授权层:被 matcher 排除的路径会跳过它,而 Server Functions 会向其页面的路由发起 POST,因此 matcher 的变更会悄然移除覆盖范围。应在处理程序或 Server Function 本身检查授权。
  • 不按 git log 热点范围筛选,就对整个代码库进行深入扫描,会让清单充满无人触及的模块,而其中每一项从定义上说都是推测。

相关技能

  • agents-md:AGENTS.md / CLAUDE.md 文件本身。此技能负责该文件所指向的检查和文档树;可由 linter 强制执行的规则应在这里作为退出码实现,而不是写在那里作为说明文字。
  • tidy:评审和限定于差异范围的清理工作,Harden 的防护规则可使其保持小规模。
  • planning:针对单个功能的计划;Design 模式生成的架构概要会作为输入。
  • scaffold-nextjs、scaffold-cli:创建随后由此技能进行结构设计的仓库。
  • multi-tenant-architecture:租户识别、隔离和路由;此技能提供其下层的模块布局。
  • dx-audit:包向外提供的开发者界面;此处的 api-design.md 仅涵盖契约形态。
  • app-verification:构建和维护仓库自行运行的 verify CLI、doctor 命令和功能映射;此技能的 Harden 模式会接入 CI 检查,确保该工具的脚本和固件通过。请按名称调用。
  • 仅供维护:evals/evals.json 和 evals/evaluation-scenarios.md 保存此技能变更的回归场景;在用户任务期间,两者都不会加载。

评论

支持 Markdown