5.9 KiB
5.9 KiB
架构与设计原则
本规则用于指导架构决策、接口设计、数据库变更和技术选型。
核心原则
- 职责分明的模块架构优先于优雅代码,优雅代码优先于功能堆砌。
- 优先评估模块边界、数据流向、状态机、权限边界、错误边界和扩展点。
- 出现复杂度扩散、参数爆炸、数据流回溯、状态同步困难时,应优先建议调整模块关系或架构,而不是继续局部补丁。
- 默认偏好 Functional Programming 和可读的 DSL 化组织方式;除非项目已明确是面向对象架构。
- 新技术、新依赖、新服务引入前,说明理由、收益、成本、风险和替代方案,并等待确认。
- 接口设计优先明确契约:输入、输出、错误结构、状态码、幂等性、权限、兼容性。
ADR 架构决策记录
- 重大技术决策必须写入 ADR,避免决策只存在于聊天或临时说明中。
- ADR 路径:
pmdocs/adr/YYYY-MM-DD-序号-主题.md。 - ADR 触发条件:
- 前端技术栈、后端技术栈、数据库或运行时选择。
- 认证授权、权限模型、状态管理、路由结构或部署方式选择。
- 重大模块边界调整、数据流调整、状态机调整。
- 引入会影响长期维护成本的新依赖、新服务或基础设施。
- 关键性能、安全、可扩展性方案选择。
- ADR 必须包含:背景、决策选项、最终选择、选择理由、影响后果、风险和回滚思路。
- ADR 只记录重要决策;普通实现细节不要过度记录。
ADR 模板示例
# ADR-001:选择 xxx
## 背景
为什么需要决策
## 选项
- A:优点 / 缺点
- B:优点 / 缺点
## 决策
选择哪个方案
## 后果
带来的收益、成本、风险
API 变更约束
- API 变更必须明确:请求结构、响应结构、错误码、权限要求、幂等性、兼容性和废弃策略。
- API 变更必须同步到
pmdocs/1-prd-XXX.md、pmdocs/2-task-XXX.md或对应变更文档;如果项目已有 OpenAPI / GraphQL Schema / RPC IDL,也必须同步。 - 涉及权限码的 API 变更,必须同步权限码表、后端校验、前端权限门禁和测试用例。
- 破坏性 API 变更必须进入需求变更流程,并在 7 维度影响评估表中明确处理动作和状态。
API 变更检查清单
- 请求结构(字段、类型、必填、默认值)
- 响应结构(字段、类型、状态码、错误码)
- 权限要求(角色、权限码、访问边界)
- 幂等性(POST / PUT / DELETE 是否幂等)
- 兼容性(新增字段 / 废弃字段 / 破坏性变更)
- 文档同步(PRD / 任务 / OpenAPI / GraphQL Schema)
- 测试覆盖(单元测试 / 集成测试 / 权限测试)
数据库变更约束
- 数据库变更必须明确:表、字段、索引、约束、迁移脚本、回滚脚本、seed 是否调整、历史数据兼容策略。
- 数据库变更必须评估查询性能、索引影响、默认值、空值、唯一约束和线上数据迁移风险。
- 涉及权限码的 DB 变更,必须同步权限码表、后端校验、前端权限门禁和测试用例。
- 破坏性 DB 变更必须进入需求变更流程,并在 7 维度影响评估表中明确处理动作和状态。
实体唯一代码规范
- 业务主体实体(用户、组织、部门、商品、订单、项目)和配置数据(角色、字典项、模板)必须有唯一业务代码。
- 唯一代码格式:
{前缀}_{业务含义}或{模块}_{编号},例如:- 用户:
USER_admin001、USER_john_doe - 商品:
PROD_SKU12345 - 订单:
ORDER_20260705001 - 权限:
PERM_USER_CREATE
- 用户:
- 唯一代码约束:
- 必须有唯一索引
- 一旦创建不可修改
- 优先可读性,而非简洁性
- 其他表引用时,优先使用唯一业务代码作为外键,而不是自增 ID。
- 好处:数据可读、跨系统可追溯、数据库导入导出友好、便于调试。
- 权衡:查询性能可能略低于整数 ID,必须在唯一代码字段上建立索引。
- 不需要唯一代码的场景:纯关联表、日志、审计、历史记录、一次性临时数据、只在父实体内部使用的子表。
数据库变更检查清单
- 表、字段、索引、约束变化
- 迁移脚本(migration)
- 回滚脚本(rollback)
- seed 数据是否调整
- 历史数据兼容策略(默认值 / 数据填充 / 迁移脚本)
- 查询性能影响(索引 / 全表扫描 / 锁表风险)
- 空值、唯一约束、外键约束影响
- 线上数据迁移风险(停机 / 灰度 / 双写)
- 测试覆盖(单元测试 / 集成测试 / 迁移测试)
代码质量
- 遵循项目既有代码风格。
- 保持单一职责、高内聚、低耦合。
- 避免重复代码,避免过度抽象。
- 命名必须语义清晰。
- 注释只解释代码无法自解释的意图、约束和权衡,不写表面行为注释。
错误处理
- 不忽略错误。
- 用户可见错误要友好,内部错误要可诊断。
- 对关键边界做输入校验、权限校验和异常处理。
- 错误处理路径应有测试覆盖。
测试与验证
- 功能代码和测试代码尽量同步完成。
- 公共函数、核心业务规则、权限判断、错误处理和边界条件应有测试。
- 测试优先使用 Arrange-Act-Assert 或 Given-When-Then。
- 使用 Mock / Stub 隔离外部依赖。
- 测试应快速稳定,避免不必要的 sleep 或长等待。
- 完成实质性编辑后,检查 linter 或诊断;若引入错误,应修复。
安全
- 不在代码、规则、提交信息或文档中硬编码密钥、令牌、密码。
- 敏感信息应使用环境变量、密钥管理器或用户指定的安全存储方式。
- 验证所有用户输入,防止注入、XSS、越权访问等常见问题。
- 遵循最小权限原则。