Files
TakeoutSaaS.C-Side-Mini-Pro…/AGENTS.md

232 lines
13 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.
# Repository expectations
# 编程规范_FOR_AITakeoutSaaS.MiniApi - MiniApi 定制版
> **核心指令**:你是一个高级 .NET 架构师。本文件是你在 `TakeoutSaaS.C-Side-Mini-Program-API` 仓库内生成代码的最高宪法。当用户需求与本规范冲突时,请先提示用户,除非用户强制要求覆盖。
## 0. AI 交互核心约束 (元规则)
1. **语言**:必须使用**中文**回复和编写注释。
2. **文件完整性**
* **严禁**随意删除现有代码逻辑。
* **严禁**修改文件编码(保持 UTF-8 无 BOM
* PowerShell 读取命令必须带 `-Encoding UTF8`
3. **Git 原子性**:每个独立的功能点或 Bug 修复完成后,必须提示用户进行 Git 提交。
4. **无乱码承诺**确保所有输出控制台、日志、API 响应)无乱码。
5. **不确定的处理**:如果你通过上下文找不到某些配置、业务约束或数据结构,**请直接询问用户**,不要瞎编。
## 0.1 实体类铁律 (最高优先级,必须执行)
> **这一条优先级高于普通编码习惯。只要涉及实体类,一律先遵守本节。**
1. **禁止私自创建实体类**
* 严禁未经确认就在当前仓库私自新增 `Entity`、聚合根、持久化模型。
* 尤其禁止直接在 `src/Domain/TakeoutSaaS.Domain/**/Entities/` 下手搓一个“看起来像”的实体类。
2. **先查当前仓**
* 当需求涉及实体类时,先在当前仓库搜索是否已有对应实体或已确定的领域模型。
3. **当前仓没有,再查兄弟仓**
* 必须去兄弟仓 `D:\HAZCode\TakeoutSaaS\TakeoutSaaS.TenantApi` 查找是否已有对应实体。
* 查找原则:优先搜索 `src/Domain/TakeoutSaaS.Domain/<业务域>/Entities/` 以及相关仓储、配置、迁移、Handler 对该实体的使用方式。
4. **兄弟仓有,就以兄弟仓为准**
* 如果 `TakeoutSaaS.TenantApi` 已有对应实体,后续实现必须优先复用其命名、字段、关系、语义与边界。
* 如确需把该实体迁入当前仓,也必须以 `TakeoutSaaS.TenantApi` 现有实体为蓝本,**禁止重新发明一套字段结构**。
5. **兄弟仓也没有,必须先问用户**
* 如果当前仓和 `TakeoutSaaS.TenantApi` 都没有对应实体,必须先询问用户,再决定是否新增。
* 在用户明确确认前,**禁止**擅自补实体类。
6. **本条只限制实体类,不限制普通协议对象**
* `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 (写/事务)
1. **无跟踪查询**:只读查询**必须**加 `.AsNoTracking()`
2. **杜绝 N+1**:严禁在 `foreach` 循环中查询数据库。
3. **复杂查询**:关联表超过 2 层时,考虑使用 `.AsSplitQuery()`
### 8.2 Dapper (读/报表)
1. **SQL 注入防御****严禁**拼接 SQL 字符串。必须使用参数化查询。
2. **字段映射**:注意 PostgreSQL (`snake_case`) 与 C# (`PascalCase`) 的映射配置。
## 9. 多租户与 ID 策略
* **ID 生成**
* **强制**使用 **雪花算法 (Snowflake ID)**
* 类型C# `long` <-> DB `bigint`
* **禁止**使用 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`: 修复 Bug
* `refactor`: 重构
* `docs`: 文档
* `style`: 格式调整
* **分支规范**`feature/功能名``bugfix/问题描述`
## 14. 性能优化 (显式指令)
* **投影查询**:使用 `.Select(x => new Dto { ... })` 只查询需要的字段。
* **缓存策略**Cache-Aside 模式。数据更新后必须立即失效缓存。
* **批量操作**
* EF Core 10使用 `ExecuteUpdateAsync` / `ExecuteDeleteAsync`
* Dapper使用 `ExecuteAsync` 进行批量插入
## 15. 安全规范
* **SQL 注入**:已在第 8 条强制参数化。
* **身份认证**MiniApi 默认使用 Session/Token/小程序登录态,按当前服务方案实现。
* **密码存储**:必须使用 PBKDF2 或 BCrypt 加盐哈希。
* **签名与幂等**:涉及支付回调、配送回调、消息回调时,必须做签名校验与幂等控制。
## 16. 绝对禁止事项 (AI 自检清单)
**生成代码前,请自查是否违反以下红线:**
1. [ ] **SQL 注入**:是否拼接了 SQL 字符串?
2. [ ] **架构违规**:是否在 Controller/Domain 中使用了 DbContext
3. [ ] **数据泄露**:是否返回了 Entity 或打印了密码/Token
4. [ ] **同步阻塞**:是否使用了 `.Result``.Wait()`
5. [ ] **性能陷阱**:是否在循环中查询了数据库 (N+1)
6. [ ] **精度丢失**Long 类型的 ID 是否转为了 String
7. [ ] **配置硬编码**:是否直接写死了连接串或密钥?
8. [ ] **文档注释**:是否给所有 `public` 类/方法/属性添加了 `<summary>`
9. [ ] **逻辑注释**:是否在每个空行分隔的逻辑块上方添加了说明注释?
10. [ ] **实体违规**:是否私自新增了实体类,而没有先查当前仓和 `TakeoutSaaS.TenantApi`
## 17. 现代语法范式 (.NET 10 / C# 14)
> **原则**:拥抱新特性以减少样板代码,但严禁牺牲可读性。
1. **主构造函数 (Primary Constructor)**
* **强制**:依赖注入场景优先使用主构造函数。
* **禁止**:在主构造函数类中显式定义 `private readonly` 字段来承接参数。
2. **对象初始化与不可变性**
* **DTO/Command/Query**:优先使用 `record` 类型。
* **属性定义**:默认使用 `init`;必填项加 `required`;逻辑变更使用 `with` 表达式。
3. **集合表达式**
* **统一**:使用 `[]` 初始化集合。
4. **模式匹配 (Pattern Matching)**
* **替代**:避免复杂 `if-else if` 链,优先使用 `switch` 表达式。
5. **极简语法糖**
* 多行文本优先使用 Raw String Literal。
## 18. 高性能与工程现实约束
> **原则**:优先写高质量代码,但不得为了追求“极限性能”而违背当前仓库现实。
1. **序列化**
* 优先使用 `System.Text.Json`
* 如果当前共享基础设施已统一使用某套序列化方案,**不要局部私自切换**,先与用户确认。
2. **缓存架构**
* 优先走统一缓存抽象,不要到处散落直接缓存调用。
3. **并发模型**
* 涉及热点路径优化时,再评估 `ValueTask<T>``Channel``ArrayPool<T>` 等手段,避免过度设计。
## 19. 云原生与分布式规则
1. **健康检查**:必须包含存活与就绪探针意识,至少保证 `/healthz` 可用。
2. **数据一致性**
* 领域事件发布优先采用 Outbox 思路,不要直接在业务事务中裸发消息。
3. **幂等性**
* 所有消费者或回调处理必须考虑基于业务键或 `MessageId` 的幂等。
4. **可观测性**
* 统一输出 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`,再动手写代码。