


修改类型安全的 Web 框架,并把数据库代码分成三层
修改由多个包组成的类型安全 Web 框架时使用。它在固定的开发环境里工作,先快速检查再完整测试,让公共模块保持精简,把数据库访问分层,并且绝不强制推送。
要使用这个AI规则
## 进入仓库固定的开发环境,并找到负责改动的包
通过仓库声明的环境管理器进入开发环境,不要依赖全局安装的工具。
### 环境设置
- 从仓库根目录开始,并激活经过批准的开发 shell。
- 如果环境提供缓存执行路径,请使用它来加快重复命令的执行。
- 确认编译器、包管理器、数据库工具和文档工具均来自版本固定的环境。
- 使用相关包或文档配置所声明的运行时版本。
- 仅在本地诊断需要时启用调试日志,不要将调试模式视为生产环境的默认设置。
### 工作上下文
在多包仓库中,运行命令前应先确定哪个包负责该项变更。查明其源目录、测试入口点、生成的工件、公共模块和本地说明,不要假定每个包都采用相同的工作流程。
## 先用类型检查快速确认,再运行全部测试
迭代期间使用最快且可靠的反馈循环,然后执行交接所需的、更广泛的权威验证。
### 聚焦迭代
- 如果完整构建环境的成本很高,应优先使用交互式编译器、类型检查器或模块加载器来快速获得类型反馈。
- 在早期迭代期间,只加载发生变更的模块或聚焦测试的入口点。
- 读取标准输入的交互式工具必须收到命令和明确的退出路径;否则,它们可能会无限期等待。
- 如果交互式会话支持重新加载,请在编辑后复用该会话,而不要反复重新构建整个环境。
### 测试注册
- 将新测试添加到包的规范测试聚合器或发现配置中。
- 确认聚焦测试确实通过该入口点运行。
- 当变更准备就绪,或共享行为、构建配置或包边界受到影响时,运行完整的仓库验证。
- 不要把聚焦编译检查说成完整测试套件已经通过的证据。
### 开发服务器
只能从经过批准的环境和正确的工作目录启动本地服务。当开发服务器依赖宿主应用程序或父目录时,应在调用其入口点之前明确建立该上下文。
## 让每个包各管一件事,只公开最少的模块
更改代码前先梳理职责,尤其是在一个仓库中同时包含运行时、开发工具、模板、迁移、同步、应用程序编程接口、测试和可选集成时。
### 职责图
- 将服务器启动和中间件与框架配置分开。
- 确保路由和统一资源定位符生成具有类型安全性,并与请求处理隔离。
- 按职责分离模型、验证、身份验证、后台工作、存储、邮件和实时更新。
- 如果架构将代码生成、模式设计和开发服务器行为定义为工具,请将它们放在核心运行时包之外。
- 将可选集成和服务器端组件视为独立的包,不要让它们的依赖项渗入核心。
### 公共接口
只公开使用方所需的最小稳定模块接口。将原始语句、内部组合、辅助前置代码和实现模块保持为私有,使它们可以在不破坏调用方的情况下演进。为公共模块和函数添加项目标准的 API 文档。
### 语言惯例
对于纯值、上下文参数、字段访问、模板、类型级路由和模型类型,应遵循代码库已有的惯用写法。相比会增加不一致性的等效形式,应优先采用项目已经使用的惯例。
## 值一律用占位符,不拼进查询语句,只对外提供会话层
将数据库访问组织为语句层、事务层和会话层,并明确编码、原子性和连接的所有权。
### 语句层
- 将原始参数化查询与其输入编码器和结果解码器放在一起。
- 对每个运行时值使用占位符,而不要把值插入查询文本。
- 明确编码可空性和数据库类型。
- 选择与预期基数相符的解码器:可选的单行、必需的单行或多行。
- 将语句缓存决策与语句定义放在一起。
### 事务层
- 将语句组合为需要原子性的业务操作。
- 当分支规则、存在性检查和创建决策必须观察一个一致状态时,应将它们保留在事务内部。
- 明确表达幂等结果,使调用方可以区分已有记录和新创建的记录。
- 仅当操作确实彼此独立并能保留预期的事务语义时,才使用独立组合或选择性组合。
### 会话层
- 将会话层作为公共数据库接口提供。
- 让会话负责连接执行和事务边界,同时隐藏原始语句和内部事务。
- 对多语句操作使用显式事务,对单个独立查询直接执行语句。
## 按每个数据库操作选择隔离级别和返回类型
使隔离级别、基数和结果类型与操作语义相匹配,而不要在所有地方套用同一种模式。
### 隔离选项
- 对正确性依赖串行化的关键操作使用强写事务。
- 对并发性重要且可以接受较弱隔离的查询,使用适当的读隔离级别。
- 记录所有正确性依赖特定隔离模式的操作。
### 结果惯例
- 使用可选值表示零行或一行的结果。
- 使用项目的标准序列类型表示多行结果。
- 对小型内部多列结果,如果命名包装器无法增加有用边界,则使用元组。
- 当更新或删除可能不影响任何行时,返回明确的成功指示符。
- 对幂等操作,同时返回是否执行了工作以及最终的值。
### 编解码器组合
当编码器库组合嵌套的二元组时,应有意识地适配扁平输入元组,并将映射放在语句旁边。组合解码器时应保留列顺序、可空性和行基数。对于可能在不被察觉的情况下将值映射到错误字段的不匹配,应添加聚焦测试。
## 只在用到的包里添加依赖项,绝不强制推送
确保变更保持兼容、便于审查且可以恢复。
### 代码与依赖项
- 当项目偏好的语言形式能提高贡献者理解代码的清晰度时,应使用这些形式。
- 使用仓库的标准文档系统记录公共接口。
- 遵守代码库已启用的语言扩展,没有具体需要时不要引入新的扩展。
- 只将依赖项添加到使用它的包。
- 声明与所支持生态系统相适应的兼容性下限和上限。
- 将实验性依赖项视为明确的风险,并将它们隔离在狭窄接口之后。
### Git 安全
- 绝不进行 force-push,包括 force-with-lease。
- 如果远程分支已有推进,应获取更新,并在更新后的历史之上进行变基或合并,解决冲突、验证,然后正常推送。
- 不要通过重写共享历史来掩盖被拒绝的推送。
- 不要在提交中包含无关的生成文件、锁文件变更和本地性能设置。
## 本地覆盖设置不进提交,文档按发布流程上线
在开发中使用本地性能和依赖项覆盖,同时防止它们渗入共享源代码管理。
### 本地性能覆盖
- 如果项目支持,可以为本地迭代临时启用快速构建标志。
- 不要提交仅限本地的性能变更。
- 交接前应检查实际差异,不要只依赖可能隐藏修改的索引标志。
### 本地依赖项开发
同时开发框架和使用该框架的应用程序时:
1. 将本地框架检出放在特意选定的开发位置。
2. 通过受支持的覆盖机制,将应用程序依赖项指向该本地路径。
3. 激活所需环境并刷新依赖项状态。
4. 使用本地框架测试应用程序。
5. 准备共享变更之前,移除覆盖或有意记录该覆盖。
### 文档与发布
- 从文档指定的环境在本地预览文档。
- 如果已发布文档是单独维护的,应通过经过批准的仓库工作流程更新其框架或文档依赖项。
- 只提交该更新所需的锁文件或源代码变更。
- 只能通过指定的发布流程部署文档或基础设施,并保持依赖项更新、已提交状态和部署之间所需的顺序。
- 当框架发布需要同步下游文档时,应将该步骤列入发布检查清单,而不要依赖记忆。
