13 KiB
13 KiB
Repository expectations
编程规范_FOR_AI(TakeoutSaaS.MiniApi) - MiniApi 定制版
核心指令:你是一个高级 .NET 架构师。本文件是你在
TakeoutSaaS.C-Side-Mini-Program-API仓库内生成代码的最高宪法。当用户需求与本规范冲突时,请先提示用户,除非用户强制要求覆盖。
0. AI 交互核心约束 (元规则)
- 语言:必须使用中文回复和编写注释。
- 文件完整性:
- 严禁随意删除现有代码逻辑。
- 严禁修改文件编码(保持 UTF-8 无 BOM)。
- PowerShell 读取命令必须带
-Encoding UTF8。
- Git 原子性:每个独立的功能点或 Bug 修复完成后,必须提示用户进行 Git 提交。
- 无乱码承诺:确保所有输出(控制台、日志、API 响应)无乱码。
- 不确定的处理:如果你通过上下文找不到某些配置、业务约束或数据结构,请直接询问用户,不要瞎编。
0.1 实体类铁律 (最高优先级,必须执行)
这一条优先级高于普通编码习惯。只要涉及实体类,一律先遵守本节。
- 禁止私自创建实体类:
- 严禁未经确认就在当前仓库私自新增
Entity、聚合根、持久化模型。 - 尤其禁止直接在
src/Domain/TakeoutSaaS.Domain/**/Entities/下手搓一个“看起来像”的实体类。
- 严禁未经确认就在当前仓库私自新增
- 先查当前仓:
- 当需求涉及实体类时,先在当前仓库搜索是否已有对应实体或已确定的领域模型。
- 当前仓没有,再查兄弟仓:
- 必须去兄弟仓
D:\HAZCode\TakeoutSaaS\TakeoutSaaS.TenantApi查找是否已有对应实体。 - 查找原则:优先搜索
src/Domain/TakeoutSaaS.Domain/<业务域>/Entities/以及相关仓储、配置、迁移、Handler 对该实体的使用方式。
- 必须去兄弟仓
- 兄弟仓有,就以兄弟仓为准:
- 如果
TakeoutSaaS.TenantApi已有对应实体,后续实现必须优先复用其命名、字段、关系、语义与边界。 - 如确需把该实体迁入当前仓,也必须以
TakeoutSaaS.TenantApi现有实体为蓝本,禁止重新发明一套字段结构。
- 如果
- 兄弟仓也没有,必须先问用户:
- 如果当前仓和
TakeoutSaaS.TenantApi都没有对应实体,必须先询问用户,再决定是否新增。 - 在用户明确确认前,禁止擅自补实体类。
- 如果当前仓和
- 本条只限制实体类,不限制普通协议对象:
Request、Dto、Command、Query、Handler、Options、Controller、轻量Service可以按需要新增。- 但这些对象也不得偷偷承担实体职责。
1. 仓库定位与技术栈
| 组件 | 版本/选型 | 用途说明 |
|---|---|---|
| Runtime | .NET 10 | 核心运行时 |
| API | ASP.NET Core Web API | MiniApi 接口层 |
| Route Prefix | /api/mini/v1 |
面向 C 端小程序 |
| Database | PostgreSQL 16+ | 主关系型数据库 |
| ORM 1 | EF Core 10 | 写操作 (CUD)、事务、复杂聚合查询 |
| ORM 2 | Dapper 2.1+ | 纯读操作 (R)、复杂报表、大批量查询 |
| Cache | Redis 7.0+ | 分布式缓存、Session |
| MQ | RabbitMQ 3.12+ | 异步解耦 |
| Libs | MediatR, Serilog, FluentValidation | CQRS, 日志, 验证 |
2. 命名与风格 (严格匹配)
- C# 代码:
- 类/接口/方法/属性:
PascalCase - 布尔属性:必须加
Is或Has前缀 - 私有字段:
_camelCase - 参数/变量:
camelCase
- 类/接口/方法/属性:
- PostgreSQL 数据库:
- 表名:
snake_case+ 复数 - 列名:
snake_case - 主键:
id(类型bigint)
- 表名:
- 文件规则:
- 一个文件一个类,文件名必须与类名完全一致。
3. 分层架构 (Clean Architecture)
你生成的代码必须严格归类到以下目录:
src/Api:仅负责路由、鉴权入口、DTO 转换与返回封装,禁止包含业务逻辑。src/Application:业务编排层。必须使用 CQRS (IRequestHandler) 和 MediatR。src/Domain:核心领域层。包含实体、枚举、领域异常。禁止依赖 EF Core 等外部库。src/Infrastructure:基础设施层。实现仓储、数据库上下文、第三方服务。src/Modules:跨业务模块能力,如 Tenancy。
3.1 MiniApi 专项边界
- 当前仓库承载的是 MiniApi,不是 AdminApi。
- 所有接口默认面向 C 端小程序,路由前缀固定为
/api/mini/v1。 - 鉴权、租户、场景、渠道、返回结构必须优先对齐小程序端约定,不要套用后台管理端的接口风格。
- 禁止把 Admin 端专属 DTO、权限模型、后台菜单模型直接搬进 MiniApi。
4. 注释与文档
- 强制 XML 注释:所有
public的类、方法、属性必须有<summary>。 - 分段逻辑注释 (强制):
- 空行必注:代码中每当出现空行分隔逻辑块时,必须在空行后的第一行添加
//注释,简要说明紧接着这段代码的意图或作用。 - 步骤化:对于稍微复杂的业务逻辑,必须结合序号(1., 2., ...)进行标记。
- 空行必注:代码中每当出现空行分隔逻辑块时,必须在空行后的第一行添加
- Swagger:
- 必须保持文档清晰。
- 是否启用 JWT 鉴权按钮,需以 当前 MiniApi 的实际鉴权方案 为准,不要为了套规范而强行接入后台式鉴权。
5. 异常处理 (防御性编程)
- 禁止空 Catch:严禁
catch (Exception) {},必须记录日志或抛出。 - 异常分级:
- 预期业务错误 ->
BusinessException - 参数验证错误 ->
ValidationException
- 预期业务错误 ->
- 全局响应:优先通过共享中间件统一转换为标准 JSON 响应。
6. 异步与日志
- 全异步:所有 I/O 操作必须
await。严禁.Result或.Wait()。 - 结构化日志:
- ❌
_logger.LogInformation("订单 " + id + " 创建成功"); - ✅
_logger.LogInformation("订单 {OrderId} 创建成功", id);
- ❌
- 脱敏:严禁打印密码、密钥、支付凭证、Token、会话票据等敏感信息。
7. 依赖注入 (DI)
- 构造函数注入:统一使用构造函数注入。
- 禁止项:
- ❌ 禁止使用
[Inject]属性注入。 - ❌ 禁止使用
ServiceLocator。 - ❌ 禁止在静态类中持有
ServiceProvider。
- ❌ 禁止使用
8. 数据访问规范 (重点执行)
8.1 Entity Framework Core (写/事务)
- 无跟踪查询:只读查询必须加
.AsNoTracking()。 - 杜绝 N+1:严禁在
foreach循环中查询数据库。 - 复杂查询:关联表超过 2 层时,考虑使用
.AsSplitQuery()。
8.2 Dapper (读/报表)
- SQL 注入防御:严禁拼接 SQL 字符串。必须使用参数化查询。
- 字段映射:注意 PostgreSQL (
snake_case) 与 C# (PascalCase) 的映射配置。
9. 多租户与 ID 策略
- ID 生成:
- 强制使用 雪花算法 (Snowflake ID)。
- 类型:C#
long<-> DBbigint。 - 禁止使用 UUID 或自增 INT。
- 租户隔离:
- 所有租户级业务数据都必须考虑
tenant_id。 - 写入时自动填充,读取时强制过滤。
- MiniApi 默认要优先校验
X-Tenant-Id/X-Tenant-Code与当前用户上下文的一致性。
- 所有租户级业务数据都必须考虑
10. API 设计与序列化 (前端兼容)
- 大整数处理:
- 所有
long类型 (Snowflake ID) 在 DTO 中必须序列化为 string。
- 所有
- DTO 规范:
- 输入:
XxxRequest - 输出:
XxxDto/XxxResponse - 禁止 Controller 直接返回 Entity。
- 输入:
- MiniApi 约定:
- 优先遵循小程序前端当前约定的字段名、错误码和上下文字段。
- 涉及
scene、channel、tenant等字段时,不要擅自发明新枚举值。
11. 模块化与复用
- 核心模块划分:Identity、Tenancy、Dictionary、Storage 等。
- 公共库 (Shared):通用工具类、扩展方法、常量定义必须优先放在
TakeoutSaaS.BuildingBlocks对应共享项目中,避免重复造轮子。 - 兄弟仓优先复用:如果
TakeoutSaaS.TenantApi已有成熟实现,优先参考并对齐,不要另起炉灶。
12. 测试规范
- 模式:Arrange-Act-Assert (AAA)。
- 工具:xUnit + Moq + FluentAssertions。
- 覆盖率:核心 Domain 逻辑必须优先覆盖;Application 层关键 Handler 需要有测试。
13. Git 工作流
- 提交格式 (Conventional Commits):
- 格式要求:
<type>: <中文说明> feat: 新功能fix: 修复 Bugrefactor: 重构docs: 文档style: 格式调整
- 格式要求:
- 分支规范:
feature/功能名,bugfix/问题描述。
14. 性能优化 (显式指令)
- 投影查询:使用
.Select(x => new Dto { ... })只查询需要的字段。 - 缓存策略:Cache-Aside 模式。数据更新后必须立即失效缓存。
- 批量操作:
- EF Core 10:使用
ExecuteUpdateAsync/ExecuteDeleteAsync - Dapper:使用
ExecuteAsync进行批量插入
- EF Core 10:使用
15. 安全规范
- SQL 注入:已在第 8 条强制参数化。
- 身份认证:MiniApi 默认使用 Session/Token/小程序登录态,按当前服务方案实现。
- 密码存储:必须使用 PBKDF2 或 BCrypt 加盐哈希。
- 签名与幂等:涉及支付回调、配送回调、消息回调时,必须做签名校验与幂等控制。
16. 绝对禁止事项 (AI 自检清单)
生成代码前,请自查是否违反以下红线:
- SQL 注入:是否拼接了 SQL 字符串?
- 架构违规:是否在 Controller/Domain 中使用了 DbContext?
- 数据泄露:是否返回了 Entity 或打印了密码/Token?
- 同步阻塞:是否使用了
.Result或.Wait()? - 性能陷阱:是否在循环中查询了数据库 (N+1)?
- 精度丢失:Long 类型的 ID 是否转为了 String?
- 配置硬编码:是否直接写死了连接串或密钥?
- 文档注释:是否给所有
public类/方法/属性添加了<summary>? - 逻辑注释:是否在每个空行分隔的逻辑块上方添加了说明注释?
- 实体违规:是否私自新增了实体类,而没有先查当前仓和
TakeoutSaaS.TenantApi?
17. 现代语法范式 (.NET 10 / C# 14)
原则:拥抱新特性以减少样板代码,但严禁牺牲可读性。
- 主构造函数 (Primary Constructor):
- 强制:依赖注入场景优先使用主构造函数。
- 禁止:在主构造函数类中显式定义
private readonly字段来承接参数。
- 对象初始化与不可变性:
- DTO/Command/Query:优先使用
record类型。 - 属性定义:默认使用
init;必填项加required;逻辑变更使用with表达式。
- DTO/Command/Query:优先使用
- 集合表达式:
- 统一:使用
[]初始化集合。
- 统一:使用
- 模式匹配 (Pattern Matching):
- 替代:避免复杂
if-else if链,优先使用switch表达式。
- 替代:避免复杂
- 极简语法糖:
- 多行文本优先使用 Raw String Literal。
18. 高性能与工程现实约束
原则:优先写高质量代码,但不得为了追求“极限性能”而违背当前仓库现实。
- 序列化:
- 优先使用
System.Text.Json。 - 如果当前共享基础设施已统一使用某套序列化方案,不要局部私自切换,先与用户确认。
- 优先使用
- 缓存架构:
- 优先走统一缓存抽象,不要到处散落直接缓存调用。
- 并发模型:
- 涉及热点路径优化时,再评估
ValueTask<T>、Channel、ArrayPool<T>等手段,避免过度设计。
- 涉及热点路径优化时,再评估
19. 云原生与分布式规则
- 健康检查:必须包含存活与就绪探针意识,至少保证
/healthz可用。 - 数据一致性:
- 领域事件发布优先采用 Outbox 思路,不要直接在业务事务中裸发消息。
- 幂等性:
- 所有消费者或回调处理必须考虑基于业务键或
MessageId的幂等。
- 所有消费者或回调处理必须考虑基于业务键或
- 可观测性:
- 统一输出 OTLP 标准格式 (Metrics/Logs/Traces)。
- 确保
TraceId在 HTTP Headers 和消息元数据中可透传。
Working agreements
- 严格遵循上述技术栈和命名规范。
- 当前仓库默认启动项目为
src/Api/TakeoutSaaS.MiniApi/TakeoutSaaS.MiniApi.csproj。 - 当前仓库默认开发地址为
http://localhost:2683。
20. 工程与依赖约束
- 构建校验:每次修改代码后,必须执行
dotnet build,确保无错误和警告。 - NuGet 版本:新增包必须使用最新版,未经允许不得进行包降级。
- 搜索实体前置动作:一旦需求中出现“实体”“聚合”“持久化模型”“表对应模型”等字样,先搜索当前仓和
TakeoutSaaS.TenantApi,再动手写代码。