Files
s2f/cursor-rules/architecture-and-design.md
T
2026-07-06 22:03:22 +08:00

128 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 架构与设计原则
本规则用于指导架构决策、接口设计、数据库变更和技术选型。
## 核心原则
- 职责分明的模块架构优先于优雅代码,优雅代码优先于功能堆砌。
- 优先评估模块边界、数据流向、状态机、权限边界、错误边界和扩展点。
- 出现复杂度扩散、参数爆炸、数据流回溯、状态同步困难时,应优先建议调整模块关系或架构,而不是继续局部补丁。
- 默认偏好 Functional Programming 和可读的 DSL 化组织方式;除非项目已明确是面向对象架构。
- 新技术、新依赖、新服务引入前,说明理由、收益、成本、风险和替代方案,并等待确认。
- 接口设计优先明确契约:输入、输出、错误结构、状态码、幂等性、权限、兼容性。
## ADR 架构决策记录
- 重大技术决策必须写入 ADR,避免决策只存在于聊天或临时说明中。
- ADR 路径:`pmdocs/adr/YYYY-MM-DD-序号-主题.md`
- ADR 触发条件:
- 前端技术栈、后端技术栈、数据库或运行时选择。
- 认证授权、权限模型、状态管理、路由结构或部署方式选择。
- 重大模块边界调整、数据流调整、状态机调整。
- 引入会影响长期维护成本的新依赖、新服务或基础设施。
- 关键性能、安全、可扩展性方案选择。
- ADR 必须包含:背景、决策选项、最终选择、选择理由、影响后果、风险和回滚思路。
- ADR 只记录重要决策;普通实现细节不要过度记录。
### ADR 模板示例
```markdown
# 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、越权访问等常见问题。
- 遵循最小权限原则。