diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..7323ba8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,143 @@ +# 项目协作与开发规范 + +## 1. 文档关系 + +本文件是当前项目的协作入口,供开发者和 coding agent 在动手前阅读。 + +- 可复用迁移规范统一位于 `docs/import/reusable/`。 +- 通用可复用规范位于 `docs/import/reusable/general-development-guidelines.md`。 +- 前端细则参考 `docs/import/reusable/frontend-development-guidelines.md`。 +- 后端细则参考 `docs/import/reusable/backend-development-guidelines.md`。 +- 后端基础结构、ID、审计字段、分页和 Mapper 规范参考 `docs/import/reusable/backend-base-structure-pagination-guidelines.md`。 +- Java 代码规范参考 `docs/import/reusable/alibaba-java-coding-guidelines-summary.md`。 +- SuperAgent 与 AgentBus 可移植集成经验参考 `docs/import/reusable/integrations/superagent-agentbus-portable-integration-guide.md`。 +- 当前项目专属后端规范位于 `docs/project/backend-development-guidelines.md`。 +- 当前项目专属前端规范位于 `docs/project/frontend-development-guidelines.md`。 +- 当前项目 SuperAgent 与 AgentBus 接入记录位于 `docs/project/integrations/superagent-agentbus-project-integration-guide.md`。 + +如本文件、`docs/project` 与 `docs/import/reusable` 中的通用规范冲突,以本文件和 `docs/project` 的当前项目补充为准。 + +## 2. 工作方式 + +- 先确认目标、边界和验收标准,再写代码。 +- 大改动前先说明目标、范围和预计修改的文件。 +- 每次只做一个明确 checkpoint,不顺手扩展无关功能。 +- 不修改与当前任务无关的用户变更。 +- 不回滚用户自己的改动,除非用户明确要求。 +- 遇到不确定的技术栈、目录、接口契约或数据模型,先确认再继续。 +- 新项目初始化或技术栈升级前,必须检查前端、后端、构建工具、测试工具和运行时版本兼容性。 +- 输出分层结构、目录树、数据模型、字段映射或接口示例时,必须补充中文说明,不能只依赖英文命名表达业务含义。 + +## 3. 分支与提交 + +- `master` 保持稳定。 +- `develop` 用于集成。 +- `feature/*` 用于具体开发。 +- 当前主要开发分支为 `feature/huangting`。 +- commit message 使用中文,清楚说明本次业务或技术变更。 +- 提交前检查工作区,避免误提交本地文件、Secret、构建产物或真实业务数据。 + +## 4. 项目结构 + +本项目是前后端都有的全栈项目,目录应保持职责清晰: + +- `client/`:前端应用。 +- `server/`:后端服务。 +- `docs/`:项目文档、设计文档、导入规范和决策记录。 +- `docs/import/reusable/`:从其他项目迁移来的可复用规范和参考资料,后续新项目可整目录复制。 +- `docs/project/`:当前项目专属业务规则、架构边界和外部系统约束,不作为整包复用资料。 + +前端、后端、文档和接口契约应分目录管理。不要把后端 Secret、外部系统调用或数据库逻辑放入前端。 + +## 5. 低耦合与可维护性 + +项目各功能模块必须保持低耦合、高内聚和高可维护性。新增功能时,应先明确模块边界、输入输出、依赖方向和验收标准,再开始实现。 + +落地要求: + +- 每个模块只负责一个清晰业务能力,避免把多个业务概念揉进同一个类、组件或服务。 +- 依赖方向必须单向清晰:通用平台能力不能反向依赖具体业务流程。 +- 跨模块调用优先通过 Service、Port、API 契约或事件完成,不直接访问对方 Mapper、Entity 或内部实现。 +- 外部系统能力必须通过 `integrations` Adapter 隔离,业务层只依赖稳定端口。 +- DTO、Entity、Domain、Response、外部系统 DTO 不混用。 +- 公共代码只有在出现真实重复和稳定语义后再抽取,禁止为了“看起来通用”提前做大而全工具类。 +- 单个文件、类、方法或组件过大时,应优先按业务职责拆分。 +- 修改一个功能时,不应迫使无关模块跟着改;如果频繁连锁修改,说明边界需要重新设计。 +- 测试应覆盖模块公开行为和关键边界,避免只测试内部实现细节。 + +## 6. 前后端边界 + +- 前端只负责展示、交互、人工确认、调试入口和调用本项目后端。 +- 前端不得直接调用 OHIP、SuperAgent、AgentBus、数据库或任何持有 Secret 的外部系统。 +- 后端负责数据库、Secret、外部系统适配、业务规则、审计和安全脱敏。 +- 接口字段使用稳定代码,不使用中文或英文显示文案做业务判断。 +- 接口变更前先确认字段映射、前后端影响和测试范围。 + +## 7. 后端架构边界 + +后端应优先按以下边界组织: + +- `platform`:部门中立能力,例如消息、证据、AI 调用审计、系统调试、通用任务基础能力。 +- `workflows`:部门业务流程,当前优先考虑 `reservation`。 +- `integrations`:外部系统适配器,例如 SuperAgent、AgentBus、OHIP。 + +平台核心不得依赖部门专有字段;外部系统 DTO、领域模型和 API Response 必须分离。 + +后端 Java 代码默认参考 Alibaba Java Coding Guidelines,并遵守本项目后端开发规范。生成或修改 Java 代码时,应优先保证: + +- 命名、分层、DTO / Entity / Domain / Response 边界清晰。 +- 分层结构、包结构、数据模型和字段映射必须配中文注释或中文说明,说明每层职责、依赖方向和关键字段含义。 +- 不写魔法值,稳定业务代码使用常量或枚举。 +- 集合、空值、字符串、时间、金额和 `BigDecimal` 使用安全写法。 +- 异常不吞掉,日志有上下文但不输出 Secret 或个人敏感信息。 +- 写操作考虑幂等、并发版本、事务边界、审计和失败恢复。 +- 复杂业务规则、外部字段映射、脱敏和幂等逻辑必须有必要中文注释。 + +## 8. AgentBus 与 SuperAgent 边界 + +- AgentBus 是消息入口适配器,不是 AI Provider。 +- SuperAgent 是外部 AI / Agent 能力提供方,不是业务事实来源。 +- AgentBus 实时链路只落 SourceMessage Inbox,不直接生成 Case、Task、Operation、Receipt 或客户回复。 +- SuperAgent 返回内容只能作为建议、证据或审计结果,不能直接改变最终业务状态。 +- 所有业务写操作必须经过规则校验、权限控制、幂等控制和人工确认。 + +## 9. 安全规范 + +- Secret 只放环境变量、本地 `.env` 或部署平台 Secret。 +- 仓库只提交无真实值的 `.env.example`。 +- 禁止提交真实酒店凭证、客户数据、Token、Cookie、API Key、数据库密码或支付信息。 +- 日志、错误响应和测试夹具不得暴露 Token、Secret、原始邮件正文、附件 URL 或个人敏感信息。 +- `.DS_Store`、构建产物、依赖目录、IDE 临时文件和本地样本目录应忽略。 + +## 10. 测试与验证 + +- 修改后运行对应模块已有检查命令。 +- 如果检查命令尚未配置或因环境问题无法运行,必须明确说明原因。 +- 不假装测试通过。 +- 优先做小的可验证闭环,再逐步扩展业务能力。 + +## 11. Agent 协作规则 + +Coding agent 开始任务前应先读取: + +1. `AGENTS.md` +2. `README.md`,如果存在 +3. `docs/` 中与当前任务相关的文档 +4. 当前代码结构和最近 Git 状态 + +改文件前要说明计划;完成后要说明改了什么、如何验证、还有哪些风险或未完成项。 + +## 12. 当前第一个 checkpoint + +第一个建议 checkpoint: + +`checkpoint-001-project-skeleton-health` + +验收标准: + +- 有清晰的根目录协作规范和项目说明。 +- 后端最小服务可以启动。 +- 前端最小应用可以启动。 +- 后端提供 `GET /api/health`。 +- 前端可以调用后端健康检查并展示状态。 +- 前后端都有明确的启动、测试和构建命令。 diff --git a/docs/import/README.md b/docs/import/README.md new file mode 100644 index 0000000..fab1548 --- /dev/null +++ b/docs/import/README.md @@ -0,0 +1,9 @@ +# 导入资料目录 + +本目录用于保存从其他项目沉淀或导入的参考资料。 + +## 目录约定 + +- `reusable/`:可复制到后续新项目的通用开发规范、技术边界和可迁移经验。 + +只适用于当前项目的业务规则、架构决策和外部系统约束,应放在 `docs/project/`,避免混入 `reusable/`。 diff --git a/docs/import/reusable/README.md b/docs/import/reusable/README.md new file mode 100644 index 0000000..aec351f --- /dev/null +++ b/docs/import/reusable/README.md @@ -0,0 +1,27 @@ +# 可复用迁移规范索引 + +## 1. 文档定位 + +本目录保存可复制到后续新项目的通用开发规范和技术边界文档。 + +新项目初始化时,可以复制整个 `docs/import/reusable/` 目录,再根据项目实际情况调整根目录 `AGENTS.md` 的引用路径和项目补充规则。不需要的 `integrations/` 文档可以删除。 + +## 2. 文档清单 + +- `general-development-guidelines.md`:通用开发协作规范。 +- `frontend-development-guidelines.md`:通用前端开发规范,不包含具体业务项目规则。 +- `backend-development-guidelines.md`:通用后端开发规范,不包含具体业务项目规则。 +- `backend-base-structure-pagination-guidelines.md`:后端基础结构、ID、审计字段、分页和 Mapper 规范。 +- `alibaba-java-coding-guidelines-summary.md`:Alibaba Java Coding Guidelines 摘要。 +- `integrations/superagent-agentbus-portable-integration-guide.md`:SuperAgent 与 AgentBus 可移植对接指南,只有需要类似集成时才复制。 + +## 3. 使用方式 + +复制到新项目后,建议先确认: + +- 新项目是否仍使用 `client/` 和 `server/` 目录。 +- 后端是否仍使用 Java、Spring Boot、MyBatis-Plus 和 MySQL。 +- 前端是否仍使用 Vue、TypeScript、Vite 和 PrimeVue。 +- 是否需要 SuperAgent、AgentBus 或其他外部系统接入。 +- 根目录 `AGENTS.md` 是否已经引用本目录下的规范。 +- 当前项目专属业务规则是否已经放在项目自己的文档目录,而不是混入本目录。 diff --git a/docs/import/reusable/alibaba-java-coding-guidelines-summary.md b/docs/import/reusable/alibaba-java-coding-guidelines-summary.md new file mode 100644 index 0000000..440d41b --- /dev/null +++ b/docs/import/reusable/alibaba-java-coding-guidelines-summary.md @@ -0,0 +1,97 @@ +# Alibaba Java Coding Guidelines 摘要 + +## 1. 文档定位 + +本文记录后端 Java 代码生成和人工开发时需要默认遵守的 Alibaba Java Coding Guidelines 摘要。 + +本文是可跨项目复用的工程规范,不替代项目自身的后端分层、业务边界、安全规范和接口契约要求。实际编码时优先级为: + +1. 当前项目 `AGENTS.md` +2. 当前项目后端开发规范 +3. 本文 Java 代码规范摘要 +4. Spring Boot / Java 社区通用习惯 + +## 2. 命名规范 + +- 类名使用 `UpperCamelCase`。 +- 方法名、参数名、局部变量名和成员变量名使用 `lowerCamelCase`。 +- 常量使用 `UPPER_SNAKE_CASE`。 +- 包名全小写,避免下划线、大写和无意义缩写。 +- 抽象类建议使用 `Abstract` 或 `Base` 开头。 +- 异常类以 `Exception` 结尾。 +- 测试类以 `Test` 结尾。 +- 不使用拼音、无意义缩写或随意缩写。 + +## 3. 代码格式 + +- `if`、`for`、`while` 即使只有一行也必须使用 `{}`。 +- 复杂表达式应拆分为有业务含义的局部变量或私有方法。 +- 避免过深嵌套,优先使用提前返回、拆分方法或明确的业务分支。 +- 不写魔法值,业务代码、状态码、固定字符串和数字阈值应抽为常量或枚举。 +- 单个类、方法和代码块应保持职责聚焦,避免把多个业务概念揉在一起。 + +## 4. 对象与类型 + +- DTO、Entity、领域对象、VO / Response 和外部系统 DTO 必须分离。 +- `equals` 和 `hashCode` 需要成对重写。 +- `BigDecimal` 数值比较优先使用 `compareTo`,避免用 `equals` 判断数值相等。 +- 金额、汇率和数量等精确值不使用浮点类型表达。 +- Boolean 字段命名要避免和序列化框架产生歧义。 +- 工具类应禁止实例化。 + +## 5. 集合与空值 + +- 集合初始化时,能预估容量就指定容量。 +- 遍历 `Map` 时优先使用 `entrySet`。 +- 不在增强 `for` 循环中直接删除集合元素。 +- 注意 `Arrays.asList` 返回的列表不支持普通结构修改。 +- 注意 `subList` 与原集合存在关联关系。 +- 方法返回集合时优先返回空集合,不返回 `null`。 +- 对外部输入、第三方返回和可空字段做明确空值处理。 + +## 6. 并发规范 + +- 不随意直接创建线程。 +- 线程池参数必须明确,包括核心线程数、最大线程数、队列、拒绝策略和线程名。 +- 共享变量必须考虑线程安全和可见性。 +- 锁粒度要小,避免死锁和长事务持锁。 +- `ThreadLocal` 使用后必须清理。 + +## 7. 异常与日志 + +- 不吞异常。 +- 不使用异常控制正常业务流程。 +- 捕获异常后要么完成明确处理,要么转换为受控异常继续抛出。 +- 日志必须有足够上下文,便于定位问题。 +- 日志不得输出 Authorization、Cookie、Token、Secret、密码、原始客户消息、附件 URL 或个人敏感信息。 +- 不使用 `System.out.println` 输出业务日志。 +- 日志级别要准确,只有真正错误才使用 `error`。 + +## 8. 数据库与事务 + +- 表名、字段名、索引名应表达清楚业务含义。 +- 不使用 `field1`、`ext1`、`remark1` 等模糊字段承载正式业务语义。 +- 写操作必须考虑幂等、并发版本、事务边界、审计和失败恢复。 +- SQL 不做无条件全表更新或删除。 +- 时间、金额、状态和外部业务标识应使用结构化字段表达。 +- 已发布数据库 migration 不直接修改,修正通过新增 migration 完成。 + +## 9. 安全规范 + +- Secret 不进入代码、前端、日志、测试夹具或提交历史。 +- 用户输入、外部系统响应和文件路径必须做边界校验。 +- 错误响应不得暴露内部堆栈、SQL、Token、Secret、客户隐私或完整原始消息。 +- 测试数据使用合成数据,不使用真实客户、真实组织、真实租户或真实支付信息。 + +## 10. 注释规范 + +- 注释说明业务含义、边界和原因,不复述类名、方法名或字段名。 +- 复杂流程、幂等键、并发控制、事务边界、错误转换、外部系统字段映射和安全脱敏逻辑必须写必要中文注释。 +- 不用 `TODO` 代替真实说明。 +- 修改旧代码时,触达复杂逻辑应顺手补齐必要注释。 + +## 11. 项目落地建议 + +- IDEA 插件可以辅助发现问题,但不要作为唯一检查手段。 +- 后续项目建立 Maven 构建后,建议通过 PMD、Checkstyle、Spotless 或同类工具固化可自动检查的规则。 +- coding agent 生成 Java 代码时,应先满足项目分层和业务边界,再满足本文命名、异常、日志、集合、并发、数据库和安全细节。 diff --git a/docs/import/reusable/backend-base-structure-pagination-guidelines.md b/docs/import/reusable/backend-base-structure-pagination-guidelines.md new file mode 100644 index 0000000..62ef196 --- /dev/null +++ b/docs/import/reusable/backend-base-structure-pagination-guidelines.md @@ -0,0 +1,481 @@ +# 后端基础结构与分页规范 + +## 1. 文档定位 + +本文记录后端基础分层、通用实体、ID 策略、分页、Mapper、Service 和 Controller 的开发习惯。 + +本文适用于 Java + Spring Boot + MyBatis-Plus 项目。具体业务项目可以在此基础上补充自己的包名、模块边界、认证方式和接口响应格式。 + +## 2. 分层结构 + +后端业务代码按以下结构组织: + +```text +server/src/main/java// +├── platform/ +│ ├── common/ +│ │ ├── domain/ +│ │ ├── mapper/ +│ │ ├── page/ +│ │ ├── response/ +│ │ └── security/ +│ ├── message/ +│ ├── ai/ +│ └── system/ +├── workflows/ +│ └── / +└── integrations/ +``` + +每个业务对象建议按以下文件拆分: + +```text +/ +├── domain/ +│ └── Xxx.java +├── mapper/ +│ └── XxxMapper.java +├── service/ +│ ├── XxxService.java +│ └── impl/XxxServiceImpl.java +├── api/ +│ └── XxxController.java +├── dto/ +│ ├── XxxCreateRequest.java +│ ├── XxxUpdateRequest.java +│ └── XxxQueryRequest.java +└── vo/ + └── XxxResponse.java +``` + +规则: + +- `platform` 放通用能力。 +- `workflows` 放业务流程。 +- `integrations` 放外部系统适配器。 +- 平台层不得依赖具体业务流程。 +- 业务层不得直接依赖外部系统 DTO。 +- Controller 不直接访问 Mapper。 +- 前端不直接调用外部系统。 + +## 3. 低耦合与可维护性 + +后端模块必须保持低耦合、高内聚和高可维护性。设计新功能时,应先确认模块归属、依赖方向和公开契约,再创建类和接口。 + +落地要求: + +- 一个业务模块只表达一个清晰业务能力,避免在同一个 Service 中混入多个业务流程。 +- `platform` 只能提供部门中立能力,不依赖 `workflows`。 +- `workflows` 可以依赖 `platform`,但不同业务流程之间不得随意互相调用内部实现。 +- `integrations` 只保存外部系统适配器和外部 DTO,不让外部 DTO 进入领域模型。 +- 跨模块调用通过 Service、Port、API 契约或事件完成,不直接访问对方 Mapper、Entity 或私有工具类。 +- Controller 只调用本模块或明确授权的应用服务,不跨层访问 Mapper 或 Adapter。 +- Mapper 只负责本聚合或本表的数据访问,不承载跨业务编排。 +- 公共能力先放在业务模块内,出现真实重复和稳定语义后再提升到 `platform`。 +- 不为少量相似代码提前抽象大而全的 `CommonService`、`CommonUtil` 或通用模型。 +- 当修改一个模块会牵动多个无关模块时,应优先检查依赖方向和接口边界。 +- 测试优先覆盖模块公开行为、跨模块契约和关键业务边界。 + +## 4. ID 策略 + +### 4.1 内部主键 + +默认使用数据库内部主键: + +```text +数据库类型:BIGINT +Java 类型:Long +生成方式:MyBatis-Plus IdType.ASSIGN_ID +算法类型:Snowflake 风格 64 位 ID +常见长度:18 到 19 位数字 +``` + +推荐实体写法: + +```java +@TableId(type = IdType.ASSIGN_ID) +private Long id; +``` + +规则: + +- 内部主键用于数据库主键、关联关系和内部查询。 +- 不依赖数据库自增。 +- 不使用 UUID 作为默认数据库主键。 +- 不把业务含义塞进主键。 +- 不根据主键大小判断业务时间顺序,除非明确验证过生成器语义。 + +### 4.2 API 与前端 ID + +后端返回给前端的 ID 必须按字符串处理。 + +原因:JavaScript `number` 安全整数上限是 `9007199254740991`,Snowflake 这类 18 到 19 位 ID 可能丢精度。 + +规则: + +- API JSON 中 ID 建议返回字符串。 +- TypeScript 中 ID 类型使用 `string`。 +- 前端不使用 `number` 保存后端 Long ID。 +- 前端不对 ID 做数学运算。 + +示例: + +```json +{ + "id": "1890123456789012345" +} +``` + +### 4.3 公开 ID + +如果需要不可枚举、适合公开传播的 ID,不要替代内部主键,另加字段: + +```text +publicId +externalId +businessKey +``` + +可选方案: + +- ULID:`VARCHAR(26)` +- UUID:`VARCHAR(36)` +- 业务编号:按业务规则生成 + +规则: + +- 内部主键负责关联。 +- 公开 ID 负责对外展示、分享、回调或跨系统引用。 +- 是否需要公开 ID 由具体业务决定,不默认添加。 + +## 5. BaseEntity 规范 + +推荐统一基础实体: + +```java +public abstract class BaseEntity { + + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + private LocalDateTime createdAt; + + private LocalDateTime updatedAt; + + private String createdBy; + + private String updatedBy; +} +``` + +规则: + +- `id` 使用 `Long` + `ASSIGN_ID`。 +- 数据库字段使用 `BIGINT`。 +- `createdAt` / `updatedAt` 由后端自动填充。 +- `createdBy` / `updatedBy` 由后端当前用户上下文自动填充。 +- 前端不得传入审计字段。 +- 业务代码不得散落手动填写审计字段。 +- 不把查询参数、分页参数、`params` Map 放进 `BaseEntity`。 +- Request 对象不继承 `BaseEntity`。 + +## 6. createdBy / updatedBy 来源 + +`createdBy` / `updatedBy` 来自后端当前用户上下文,不来自前端请求体。 + +建议定义统一接口: + +```java +public interface CurrentUserProvider { + + String getCurrentUserId(); +} +``` + +初期没有登录系统时,可以返回: + +```text +system +local-dev +``` + +未来接入登录后,可以从以下来源获取: + +- Spring Security `SecurityContext` +- JWT subject +- Session 用户 +- 网关注入的用户 Header +- 内部系统任务身份 + +推荐通过 MyBatis-Plus `MetaObjectHandler` 自动填充: + +```text +insert 时填充: +- createdAt +- updatedAt +- createdBy +- updatedBy + +update 时填充: +- updatedAt +- updatedBy +``` + +字段类型建议: + +```text +createdBy: VARCHAR +updatedBy: VARCHAR +``` + +原因:操作者可能是内部用户、系统任务、外部集成、本地开发身份或未来 IAM subject,不一定永远是数据库用户表的 Long ID。 + +如果后续有稳定用户表,可以额外添加: + +```text +createdByUserId BIGINT +updatedByUserId BIGINT +``` + +但不建议第一阶段默认添加。 + +## 7. Domain / Entity 规范 + +`Domain` 或 `Entity` 对应数据库表结构,只表达持久化字段和基础业务含义。 + +规则: + +- 可以继承统一 `BaseEntity`。 +- 不直接作为 Controller 入参。 +- 不直接作为 API 响应返回给前端。 +- 不混入外部系统 DTO 字段。 +- 金额使用 `BigDecimal`。 +- 时间使用 `LocalDateTime` 或明确时区语义的类型。 +- 状态字段使用稳定英文代码或枚举,不使用中文展示文案。 +- 字段注释说明业务含义,不只复述字段名。 + +## 8. Request / QueryRequest 规范 + +请求对象用于接收前端入参。 + +建议拆分: + +```text +XxxCreateRequest +XxxUpdateRequest +XxxQueryRequest +``` + +规则: + +- 不使用一个大而全的 `Bo` 承载所有场景。 +- 创建、更新、查询参数分开。 +- 使用 Bean Validation 做基础校验。 +- 查询对象可以包含分页、排序、时间范围等条件。 +- Request 不继承 `BaseEntity`。 +- Request 不包含 `createdBy`、`updatedBy`、`createdAt`、`updatedAt`。 +- 不把前端展示文案作为业务参数。 + +## 9. Response / VO 规范 + +响应对象用于返回给前端。 + +规则: + +- 不直接返回 Entity。 +- 不暴露内部字段、Secret、外部系统原始响应或敏感数据。 +- 字段名稳定。 +- 前端不能依赖中文或英文文案判断业务。 +- Long ID 返回给前端时按字符串处理。 +- 时间统一按 API 规范格式化。 +- 列表接口使用统一分页响应。 + +## 10. Mapper 规范 + +Mapper 基于 MyBatis-Plus。 + +建议提供统一基础接口: + +```java +public interface BaseMapperPlus extends BaseMapper { + + V selectVoById(Serializable id); + + List selectVoList(Wrapper wrapper); + + PageResult selectVoPage(PageQuery pageQuery, Wrapper wrapper); +} +``` + +规则: + +- Mapper 只负责数据库访问。 +- 复杂业务判断不放在 Mapper。 +- 优先使用 MyBatis-Plus Wrapper。 +- 手写 SQL 必须使用 `#{}` 参数绑定。 +- 禁止使用 `${}` 拼接业务参数。 +- 手写 SQL 要避免返回过宽字段。 +- Mapper 不直接依赖 Controller Request。 +- Mapper 不调用外部系统。 + +## 11. Service 规范 + +Service 分接口和实现: + +```text +XxxService +XxxServiceImpl +``` + +职责: + +- 编排业务流程。 +- 管理事务边界。 +- 调用 Mapper、Repository 或外部端口。 +- 做业务校验、幂等、并发版本、审计和失败恢复。 +- 完成 Entity 与 Response 的转换。 + +规则: + +- Controller 不直接调用 Mapper。 +- Service 不返回数据库 Entity 给 Controller。 +- Service 不吞异常。 +- 失败要转换为受控业务异常。 +- 日志只记录必要上下文,不输出敏感信息。 +- 不在 Service 中硬编码中文展示文案作为业务判断。 +- 外部系统调用通过端口或 Adapter 隔离。 + +## 12. Controller 规范 + +Controller 只做 HTTP 入口。 + +职责: + +- 路由定义。 +- 参数校验。 +- 权限入口。 +- 调用 Service。 +- 返回统一响应结构。 + +规则: + +- Controller 不直接访问 Mapper。 +- Controller 不直接调用外部系统 Adapter。 +- 方法名必须和业务语义一致。 +- 不在 Controller 写复杂业务逻辑。 +- 不返回 Entity。 +- 不暴露内部异常栈。 +- 不接收或信任前端传入的审计字段。 + +## 13. 分页规范 + +统一分页请求对象: + +```java +public class PageQuery { + + private Integer pageNum = 1; + + private Integer pageSize = 20; + + private String orderBy; + + private String orderDirection; +} +``` + +规则: + +- `pageNum` 从 1 开始。 +- `pageSize` 默认 20。 +- `pageSize` 必须有最大值限制,例如 100。 +- 不允许默认 `Integer.MAX_VALUE` 查询全部。 +- 排序字段必须做白名单映射。 +- 不能直接拼接前端字段进 SQL。 +- `orderDirection` 只允许 `asc` 或 `desc`。 + +统一分页响应: + +```java +public class PageResult { + + private List items; + + private long total; + + private int pageNum; + + private int pageSize; +} +``` + +推荐 JSON: + +```json +{ + "items": [], + "total": 0, + "pageNum": 1, + "pageSize": 20 +} +``` + +不建议使用 `rows/total` 这种偏表格组件的命名,除非前端组件强依赖。 + +## 14. 统一响应规范 + +可以使用统一响应包装,例如: + +```java +public class ApiResponse { + + private String code; + + private String message; + + private T data; +} +``` + +规则: + +- `code` 使用稳定英文代码。 +- `message` 只用于展示,不用于前端业务判断。 +- 错误响应不返回 Secret、Token、SQL、内部堆栈或个人敏感信息。 +- 业务错误、参数错误、系统错误要有清晰边界。 +- 前端业务判断依赖 `code` 和结构化字段,不依赖 `message`。 + +## 15. 从旧项目借鉴但不照搬 + +可以借鉴: + +- `Domain / Mapper / Service / Controller` 分层。 +- `BO / VO` 分离思想。 +- `BaseMapperPlus` 减少 Entity 到 VO 转换重复代码的思想。 +- `PageQuery + 分页结果` 的统一封装。 +- `BaseEntity` 统一审计字段的思想。 + +不照搬: + +- Mapper 中使用 `${}` 拼 SQL。 +- catch 后空处理。 +- 默认 `pageSize = Integer.MAX_VALUE`。 +- 在日志里打印完整业务对象。 +- Controller 方法名和业务语义不一致。 +- 创建、更新、查询共用一个大 `Bo`。 +- Request 继承包含持久化审计字段的 `BaseEntity`。 +- 业务代码手动散落填写 `createdBy` / `updatedBy`。 +- 前端按 number 处理后端 Long ID。 + +## 16. 与 Alibaba Java Coding Guidelines 的关系 + +本规范默认遵守 Alibaba Java Coding Guidelines,尤其是: + +- 命名清晰。 +- 不写魔法值。 +- 异常不吞掉。 +- 日志不泄露敏感信息。 +- 集合、空值、字符串、时间、金额和 `BigDecimal` 使用安全写法。 +- 复杂流程、幂等、事务、外部字段映射和脱敏逻辑写必要中文注释。 + +项目自身业务边界优先级高于通用 Java 风格规范。 diff --git a/docs/import/reusable/backend-development-guidelines.md b/docs/import/reusable/backend-development-guidelines.md new file mode 100644 index 0000000..fe2ef7f --- /dev/null +++ b/docs/import/reusable/backend-development-guidelines.md @@ -0,0 +1,179 @@ +# 通用后端开发规范 + +## 1. 文档定位 + +本文记录可跨项目复用的后端开发约定,适用于以服务端 API、数据库、外部系统适配和业务规则为核心的后端项目。 + +复制到新项目后,应根据实际技术栈、目录结构、启动命令、接口契约和业务约束做项目级补充。当前项目的业务专属规则不应写入本文。 + +## 2. 技术栈原则 + +具体版本以项目内构建文件为准,例如 `server/pom.xml`、`build.gradle` 或其他构建配置。 + +通用要求: + +- 升级 Java、Spring Boot、ORM、OpenAPI、数据库迁移工具或核心框架前,必须先做兼容性验证。 +- 项目应提供可重复执行的本地启动、测试和构建命令。 +- 后端依赖应按职责引入,避免为了少量功能引入过重框架。 +- 外部 SDK、Provider Client 和生成代码应隔离在适配层,不进入领域模型。 +- 新项目必须明确语言版本、语法版本、框架版本、ORM / Mapper、数据库迁移工具、OpenAPI 工具和测试框架之间的兼容关系。 +- 构建文件应显式声明编译目标版本,避免本地、CI 和生产运行时不一致。 +- Spring Boot 主版本与 ORM、OpenAPI、测试、插件 starter 必须匹配;例如 Spring Boot 3 项目应使用支持 Boot 3 的 starter。 +- 引入 ORM 增强框架或 starter 后,不应再重复引入同生态的原生 starter,避免自动配置和依赖版本冲突。 + +## 3. 后端分层与模块边界 + +推荐按业务能力和技术边界组织模块,而不是把所有代码堆在一个公共包里。 + +常见边界: + +```text +server/src/main/java/ +├── common +├── config +├── modules +│ └── +│ ├── controller +│ ├── service +│ ├── service/impl +│ ├── domain +│ ├── mapper +│ └── repository +├── integrations +└── support +``` + +目录树、包结构、分层图和模块边界说明必须配中文注释或中文说明,不能只给英文目录名。建议在目录树后补充说明表,说明每一层的职责、依赖方向、可以调用什么、禁止调用什么。 + +职责规则: + +- 一个业务模块只负责一个清晰业务能力。 +- 通用能力不能反向依赖具体业务模块。 +- 跨模块调用优先通过 Service、Port、API 契约或事件完成。 +- 禁止直接访问其他模块的 Mapper、Entity 或内部实现。 +- 外部系统通过 `integrations` 或 Adapter 隔离,业务层只依赖稳定端口。 +- 外部 DTO、数据库 Entity、领域对象和 API Response 必须分离。 +- 公共代码只有在出现真实重复和稳定语义后再抽取。 + +## 4. Controller / Service / Repository 规则 + +- Controller 只处理 HTTP 契约、参数校验、权限入口和响应映射。 +- Controller 不直接访问 Mapper,不直接调用外部适配器。 +- Service 负责业务编排、事务边界、领域对象、Repository 和外部端口调用。 +- Domain 对象表达稳定业务语义,不引入 HTTP、JSON、ORM 或外部 Provider 细节。 +- Repository 是领域侧持久化接口。 +- Mapper / Entity / SQL 属于持久化细节,不应向上泄漏到 API 层。 +- 外部调用通过 Port / Adapter 隔离,业务层不依赖厂商 SDK 或厂商 DTO。 + +## 5. 数据建模规则 + +- 内部主键、外部业务标识、第三方系统 ID 和展示编号必须分开建模。 +- API 返回给前端的长整型 ID 建议使用字符串,避免 JavaScript 精度问题。 +- 状态使用稳定代码,展示文案只用于显示。 +- 不把中文或英文显示文本当作接口契约或业务判断依据。 +- 金额使用 `BigDecimal`,并明确币种、精度和舍入规则。 +- 日期、时间、时区必须结构化保存,不只保存展示字符串。 +- JSON 字段只用于扩展元数据,不替代需要查询、约束或索引的正式列。 +- 写操作应考虑幂等、并发版本、审计字段和失败恢复。 + +更多后端基础结构、ID、审计字段、分页和 Mapper 规范见 `backend-base-structure-pagination-guidelines.md`。 + +## 6. 数据库与 Migration 规范 + +- 新建表和改表必须通过 migration 管理。 +- 已发布 migration 禁止直接修改。 +- 修正注释、索引或约束必须新增 migration。 +- 表、字段、索引和约束命名应清晰表达业务含义。 +- 业务表建议包含创建时间、更新时间、创建人、更新人、逻辑删除和版本字段。 +- 需要查询、排序、唯一性或关联的字段必须有明确索引策略。 +- 测试数据、真实业务数据和本地样本不得直接提交到仓库。 + +## 7. API 设计规范 + +- API 契约应有唯一来源,例如 OpenAPI、后端生成文档或共享契约文件。 +- 接口字段使用稳定字段名和稳定业务代码。 +- 前端业务判断不得依赖展示文案。 +- 错误响应应使用统一结构,不回显 Secret、Token、原始报文或个人敏感信息。 +- 写接口必须考虑幂等、并发版本、审计和失败恢复。 +- 外部写操作结果不明确时,禁止盲目重试。 +- 调试接口必须默认关闭,并使用独立访问控制。 + +## 8. 安全与日志 + +Secret 只能通过环境变量、本地 `.env` 或部署平台 Secret 注入。仓库只提交无真实值的 `.env.example`。 + +禁止提交: + +- API Key、Token、Cookie、数据库密码和私钥。 +- 真实客户数据、生产数据、支付信息和个人敏感信息。 +- 外部系统真实凭证、真实请求报文和真实响应报文。 + +日志要求: + +- 日志必须有足够上下文,方便定位问题。 +- 禁止输出 Secret、Token、Cookie、身份证件、支付卡、原始敏感正文和附件 URL。 +- 捕获异常后不能静默吞掉,应保留错误上下文并转换为合适的业务错误。 + +## 9. 配置规范 + +- 本地、测试、生产配置应分环境管理。 +- Secret 与非敏感配置应分开。 +- 后端 Secret 不得暴露给前端公开环境变量。 +- 生产环境推荐使用部署平台 Secret、密钥管理系统或容器 Secret。 +- 配置项应有清晰命名、默认值策略和缺失时的失败方式。 + +## 10. 后端代码注释规范 + +后端 Java 代码应提供必要且准确的中文注释: + +- 架构文档、设计文档、目录结构、数据模型、字段映射和接口示例必须优先使用中文说明业务含义。 +- 领域对象、应用服务、外部适配器、Controller、配置属性和复杂参数对象应说明业务含义、边界或调用约束。 +- 复杂流程、幂等键、并发控制、事务边界、错误转换、外部字段映射和安全脱敏逻辑必须说明原因。 +- 注释不得只复述类名、方法名或字段名。 +- 不得用“TODO 待完善”替代真实说明。 +- 修改旧代码时,应补齐触达代码的必要中文注释。 + +Java 代码风格默认参考 `alibaba-java-coding-guidelines-summary.md`。 + +## 11. 测试与检查命令 + +后端项目应至少提供: + +```bash +cd server +./mvnw test +./mvnw verify +``` + +如果项目不是 Maven,应在项目级文档中替换为实际命令。 + +聚焦开发时可先运行相关测试: + +```bash +cd server +./mvnw -Dtest=SomeFocusedTest test +``` + +如果命令尚未配置或因环境问题无法运行,必须明确说明,不能假装通过。 + +## 12. Git 与协作流程 + +- 改动前说明目标、范围和将修改的文件。 +- 每次只处理一个模块或一个纵向切片。 +- 需求基准变化时,先做差异和影响分析。 +- 修改接口前确认领域模型、字段映射、前端影响和测试范围。 +- 不修改与当前任务无关的用户变更。 +- 修改后运行项目已配置的检查命令。 +- Git commit message 使用中文,清楚说明本次提交的业务或技术变更。 + +## 13. 后端提交前检查清单 + +- [ ] Controller 是否没有直接访问 Mapper 或外部 Adapter? +- [ ] 外部 DTO 是否没有进入领域模型? +- [ ] DTO、Entity、Domain、Response 是否没有混用? +- [ ] 跨模块调用是否通过稳定接口完成? +- [ ] 写接口是否有幂等、版本或审计设计? +- [ ] 数据库变更是否通过 migration 管理? +- [ ] Java 复杂逻辑是否有必要中文注释? +- [ ] 是否没有提交真实 Secret、真实客户数据或敏感报文? +- [ ] 是否运行了项目后端检查命令或说明了无法运行原因? diff --git a/docs/import/reusable/frontend-development-guidelines.md b/docs/import/reusable/frontend-development-guidelines.md new file mode 100644 index 0000000..d1caf44 --- /dev/null +++ b/docs/import/reusable/frontend-development-guidelines.md @@ -0,0 +1,234 @@ +# 通用前端开发规范 + +## 1. 文档定位 + +本文记录可跨项目复用的前端开发约定,适用于以页面展示、交互、状态管理、接口调用和用户体验为核心的前端项目。 + +复制到新项目后,应根据实际技术栈、目录结构、启动命令、接口契约、设计系统和业务约束做项目级补充。当前项目的业务专属规则不应写入本文。 + +## 2. 技术栈原则 + +具体版本以项目内依赖文件为准,例如 `client/package.json`、锁文件和构建配置。 + +通用要求: + +- 使用 TypeScript 时应开启严格类型检查。 +- 构建、Lint、类型检查、测试命令必须可重复执行。 +- 不引入与项目规模不匹配的大型模板或重型依赖。 +- UI 组件库、路由、状态管理和请求库应在项目级文档中明确。 +- 生成代码应进入专门目录,并标记为禁止手工修改。 +- 新项目必须明确 Node.js、包管理器、框架、语言、构建工具、Lint、类型检查和测试框架的兼容关系。 +- TypeScript 版本必须与类型检查、Lint 和框架工具链支持范围一致。 +- Vue 单文件组件项目应配置 `vue-tsc` 或等价工具覆盖 `.vue` 文件类型检查。 + +## 3. 目录约定 + +推荐目录: + +```text +client/src +├── components +│ └── common +├── composables +├── generated +├── i18n +│ └── locales +├── layouts +├── router +├── services +├── stores +├── styles +├── tests +├── types +└── views +``` + +目录规则: + +- API 请求封装放入 `src/services`。 +- 手写类型定义放入 `src/types`。 +- OpenAPI 或其他工具生成代码放入 `src/generated`,禁止手工修改。 +- 可复用组合逻辑放入 `src/composables`。 +- 路由定义放入 `src/router`。 +- 客户端状态放入 `src/stores`。 +- i18n 入口和语言包放入 `src/i18n`。 +- 页面级组件放入 `src/views`。 +- 可复用组件放入 `src/components`。 +- 通用布局放入 `src/layouts`。 +- 全局样式和设计 token 放入 `src/styles`。 + +## 4. 组件规范 + +- 页面组件负责展示、交互和页面编排,不直接承载复杂业务规则。 +- Props、Emits、响应式状态和服务返回值必须有明确类型。 +- 避免在模板中写复杂业务逻辑,复杂逻辑放入 computed、composable 或服务层。 +- 不在组件里直接拼接后端 URL,统一通过 services。 +- 不在组件里直接访问浏览器全局存储保存业务事实。 +- 不把中文或英文显示文案作为业务判断依据。 +- 可复用组件应通过清晰 props 和 emits 对外暴露能力。 +- 大组件应按职责拆分,避免一个页面文件同时承担数据请求、复杂表单、表格、弹窗和业务判断。 + +## 5. 状态管理规则 + +客户端状态和服务端数据要分开管理。 + +客户端状态适合保存: + +- 当前用户上下文。 +- 语言、主题和页面偏好。 +- 轻量 UI 状态。 +- 当前页面临时筛选条件或展开状态。 + +服务端数据适合通过请求缓存库或服务层管理: + +- 列表、详情、统计、字典和远程配置。 +- Mutation 完成后按 query key 或明确缓存规则失效。 +- 不把服务端数据长期复制进客户端全局 Store。 +- 不用前端状态绕过后端权限、状态机或业务校验。 + +## 6. API 请求规范 + +- 浏览器默认只调用本项目后端。 +- 所有请求封装到 `src/services`。 +- 服务函数返回明确 TypeScript 类型。 +- 统一处理 JSON、错误结构、超时、取消请求和认证失效。 +- 前端不直接调用数据库、对象存储、持有 Secret 的第三方系统或内部 Provider。 +- 前端不发送后端 Secret、Provider API Key、数据库凭证或内部访问密钥。 +- 调试页面如果需要触发受控后端能力,应由后端提供 debug-only 包装接口,Secret 保留在后端。 + +## 7. 国际化与展示文案 + +- 新增页面和组件不得把业务逻辑绑定到展示文案。 +- 系统固定文案应使用稳定 i18n key。 +- 后端应返回稳定业务代码和必要 `labelKey`,前端按 key 显示。 +- 用户输入、外部来源原文和备注应保持原文,不做无依据翻译。 +- 日期、时间、数字和货币按当前语言、时区和币种配置格式化。 +- API 仍传递结构化原始值,不传本地化展示字符串作为业务参数。 + +如果项目不需要国际化,也应保留“业务判断不依赖展示文本”的规则。 + +## 8. 类型与业务代码 + +- TypeScript 类型应贴近后端 API 契约。 +- 稳定业务代码使用 string union、枚举型常量或后端生成类型,避免散落 magic string。 +- 动态字段使用稳定 `fieldKey`。 +- 表单字段展示使用 `labelKey` 或 i18n key。 +- 不用 `label`、中文标题或英文标题做字段标识。 +- 接口字段变更时,同步更新 `src/types`、services、页面和测试。 + +## 9. UI 与交互规范 + +- UI 应优先服务真实工作流,不堆叠无意义装饰。 +- 列表、详情、表单、弹窗、空状态、加载状态和错误状态必须完整。 +- 重要操作必须有明确反馈。 +- 危险操作必须有确认、权限或后端校验。 +- 复杂表单应区分草稿、提交中、提交成功、提交失败和版本冲突。 +- 涉及敏感信息时,应默认最小展示。 +- 组件样式应遵守项目设计 token,避免随意写一次性颜色、间距和字号。 +- 页面文本必须在移动端和桌面端都不溢出、不遮挡。 + +## 10. 前端安全规范 + +- 公开环境变量会暴露到浏览器构建产物,不能保存 Secret。 +- 前端不得保存数据库密码、Provider API Key、访问令牌、内部重放密钥或生产凭证。 +- 不在 LocalStorage、SessionStorage 或 URL 中保存敏感业务数据。 +- 错误提示不展示 Authorization、Cookie、Token、原始敏感正文或附件 URL。 +- 测试夹具不得使用真实客户、真实生产数据或真实支付信息。 + +## 11. 配置规范 + +常见公开配置示例: + +```text +VITE_API_BASE_URL=http://localhost:8080 +VITE_APP_ENV=local +VITE_DEFAULT_LOCALE=zh-CN +VITE_ENABLE_MOCKS=false +``` + +规则: + +- 公开配置可以放入前端环境变量。 +- Secret 一律不进入前端环境变量。 +- 生产需要运行时配置时,应由部署系统生成公开配置文件,例如 `/app-config.json`。 +- 需要秘密的外部调用一律经后端代理或适配器。 + +## 12. 路由规范 + +- 新增业务路由前确认对应后端 API、权限边界和页面恢复能力。 +- 详情页路由参数使用稳定 ID。 +- 页面刷新后必须能通过后端详情接口恢复必要状态,不依赖内存临时状态。 +- 未确认的业务入口不要提前硬编码到导航。 +- 路由守卫只做访问控制和基础上下文检查,不承载复杂业务流程。 + +## 13. 表单规范 + +- 表单字段应来自稳定契约或明确的本地模型。 +- 保存草稿时使用稳定字段名或 `fieldKey`。 +- 不把显示文案作为提交字段名。 +- 提交前前端可做基础格式校验,但最终业务校验在后端。 +- 发生版本冲突时,应提示用户刷新或重新确认,不静默覆盖。 +- 表单错误应能定位到字段或操作区域。 + +## 14. Agent 前端开发 Skill 使用原则 + +如果当前 agent 环境提供前端、设计、浏览器验证或可视化相关 skill,应按任务类型选择使用。Skill 是辅助能力,不替代项目技术栈、组件库、设计 token、接口契约和用户明确要求。 + +通用原则: + +- 新增页面、复杂组件、交互流程或明显视觉调整前,应优先使用设计或前端类 skill 辅助确认方案。 +- 重构已有页面视觉时,应优先使用现有项目审视和重构类 skill,避免破坏原有功能。 +- 根据截图、设计稿或视觉参考还原页面时,应使用图像到代码或视觉分析类 skill。 +- 设计 token、组件规范或样式体系调整时,应使用设计系统类 skill。 +- 需要生成图片资产时,可使用图像生成类 skill,但不得替代项目内已有品牌资产或图标规范。 +- 涉及可视化结果的前端改动,完成后应通过浏览器、截图或交互测试验证桌面端和移动端表现。 +- Skill 建议不得直接引入新的 UI 框架、组件库、状态管理方案或重型依赖;如确有必要,必须先确认。 +- 如果相关 skill 不可用,应按同等原则手动完成设计、实现和验证,并在交付说明中说明。 + +## 15. 测试与检查命令 + +前端项目应至少提供: + +```bash +cd client +pnpm lint +pnpm typecheck +pnpm test +pnpm build +``` + +如果项目不是 pnpm,应在项目级文档中替换为实际命令。 + +聚焦开发时可运行: + +```bash +cd client +pnpm test -- SomeSpecName.spec.ts +``` + +如果命令尚未配置或因环境问题无法运行,必须明确说明,不能假装通过。 + +## 16. Git 与协作流程 + +- 改动前说明目标、范围和将修改的文件。 +- 每次只处理一个模块、一个页面或一个纵向切片。 +- 不修改与当前任务无关的用户变更。 +- 前后端接口变化前,先确认 API 契约和字段映射。 +- 修改后运行项目已配置的检查命令。 +- Git commit message 使用中文,清楚说明本次提交的业务或技术变更。 + +## 17. 前端提交前检查清单 + +- [ ] 是否只调用本项目后端或明确允许的公开服务? +- [ ] 是否没有把 Secret 放入前端环境变量、源码、测试或 URL? +- [ ] 新文案是否按项目约定处理? +- [ ] 是否避免用中文或英文显示文本做业务判断? +- [ ] API 请求是否放在 `src/services`? +- [ ] 手写类型是否放在 `src/types`? +- [ ] 可复用逻辑是否放在 `src/composables`? +- [ ] 服务端数据是否没有长期塞进客户端全局 Store? +- [ ] 是否没有手工修改 `src/generated`? +- [ ] 是否覆盖加载、空状态、错误、成功和权限不足等关键状态? +- [ ] 涉及 UI、交互或视觉变更时,是否使用或说明未使用合适的前端 / 设计 skill? +- [ ] 涉及可视化结果时,是否做过浏览器、截图或响应式验证? +- [ ] 是否运行了项目前端检查命令或说明了无法运行原因? diff --git a/docs/import/reusable/general-development-guidelines.md b/docs/import/reusable/general-development-guidelines.md new file mode 100644 index 0000000..b28bbf1 --- /dev/null +++ b/docs/import/reusable/general-development-guidelines.md @@ -0,0 +1,150 @@ +# 通用开发协作规范 + +## 1. 文档定位 + +本文记录可跨项目复用的开发习惯、协作方式、工程边界和 agent 工作规则。 + +新项目可以复制本文为根目录 `AGENTS.md`,再补充项目特有的技术栈、目录、启动命令和业务约束。 + +## 2. 工作方式 + +- 先确认目标、边界和验收标准,再写代码。 +- 大改动前先说明目标、范围和预计修改的文件。 +- 每次只做一个明确 checkpoint,不顺手扩展无关功能。 +- 不修改与当前任务无关的用户变更。 +- 不回滚用户自己的改动,除非用户明确要求。 +- 遇到不确定的技术栈、目录、接口契约或数据模型,先确认再继续。 +- 新项目初始化或技术栈升级前,必须检查前端、后端、构建工具、测试工具和运行时版本兼容性。 +- 输出分层结构、目录树、数据模型、字段映射或接口示例时,必须补充中文说明,不能只依赖英文命名表达业务含义。 + +## 3. 分支与提交 + +- 稳定分支保持可交付。 +- 集成分支用于合并多个功能。 +- `feature/*` 用于具体开发。 +- commit message 使用中文,清楚说明本次业务或技术变更。 +- 提交前检查工作区,避免误提交本地文件、Secret、构建产物或真实业务数据。 + +## 4. 项目结构 + +- 前端、后端、文档和接口契约应分目录管理。 +- 前端只负责展示、交互和调用本项目后端。 +- 后端负责数据库、Secret、外部系统适配、业务规则、审计和安全脱敏。 +- 文档目录应保存设计文档、导入规范、接口说明和重要决策记录。 +- 接口契约要有唯一来源,避免前端和后端各写一套互相漂移的定义。 +- 架构图、目录树、模块边界、表结构和接口字段说明应优先使用中文解释职责、依赖方向和业务含义。 + +## 5. 技术栈版本兼容性 + +新项目建立规范或引入依赖前,应先形成最小版本矩阵,确认前端、后端、运行时、构建工具、测试工具和接口契约工具之间没有明显冲突。 + +最低检查范围: + +- 后端语言版本、语法版本、框架版本、ORM / Mapper、数据库迁移工具、OpenAPI 工具和测试框架。 +- 前端 Node.js 版本、包管理器、框架、语言、构建工具、Lint、类型检查、测试框架和 UI 组件库。 +- 前后端接口契约工具,例如 OpenAPI 生成器、类型生成器、序列化格式和日期时间格式。 +- 本地开发、CI、部署环境的运行时版本是否一致。 + +落地要求: + +- 项目级文档必须写清楚当前采用的版本和兼容约束。 +- 版本结论应优先来自官方文档、项目依赖文件、锁文件或实际验证命令。 +- 发现版本冲突时,先调整版本方案,再生成代码或项目骨架。 +- 升级核心依赖前,应先检查 breaking changes、运行时要求和配套插件支持范围。 +- 无法确认兼容性时,应在项目文档中标记为待确认,不能假装已经验证。 + +## 6. 低耦合与可维护性 + +项目各功能模块必须保持低耦合、高内聚和高可维护性。新增功能时,应先明确模块边界、输入输出、依赖方向和验收标准,再开始实现。 + +落地要求: + +- 每个模块只负责一个清晰业务能力。 +- 依赖方向必须单向清晰,通用能力不能反向依赖具体业务。 +- 跨模块调用优先通过 Service、Port、API 契约或事件完成,不直接访问对方 Mapper、Entity 或内部实现。 +- 外部系统能力通过 Adapter 隔离,业务层只依赖稳定端口。 +- DTO、Entity、Domain、Response、外部系统 DTO 不混用。 +- 公共代码只有在出现真实重复和稳定语义后再抽取。 +- 禁止提前设计大而全的通用工具、通用服务或通用模型。 +- 单个文件、类、方法或组件过大时,应按业务职责拆分。 +- 修改一个功能时,不应迫使无关模块跟着改;频繁连锁修改说明边界需要重新设计。 +- 测试应覆盖模块公开行为和关键边界,避免只测试内部实现细节。 + +## 7. 前端规范 + +- 使用 TypeScript 时应开启严格类型检查。 +- 页面组件负责展示和交互,不直接承载复杂业务规则。 +- API 请求统一封装,不在组件里拼接后端 URL。 +- 服务端数据不要长期复制进客户端全局状态。 +- 前端不得保存或传递后端 Secret、Provider API Key、数据库凭证或客户渠道 Token。 +- 不使用中文或英文显示文案做业务判断。 + +## 8. 后端规范 + +- Controller 只处理 HTTP 契约、参数校验、权限入口和响应映射。 +- Service 编排业务流程、事务、领域对象、Repository 和外部端口。 +- 外部系统通过 Port / Adapter 隔离,业务层不直接依赖厂商 SDK 或外部 DTO。 +- 数据库变更必须可追踪;已发布 migration 不直接修改。 +- 写接口要考虑幂等、并发版本、审计、失败恢复和脱敏。 + +Java 后端代码默认参考 Alibaba Java Coding Guidelines。可复用摘要见 `docs/import/reusable/alibaba-java-coding-guidelines-summary.md`。 + +后端基础结构、ID、审计字段、分页和 Mapper 规范可复用 `docs/import/reusable/backend-base-structure-pagination-guidelines.md`。 + +核心要求: + +- 命名清晰,不使用拼音、无意义缩写或随意缩写。 +- DTO、Entity、领域对象、VO / Response 不混用。 +- 不写魔法值,业务代码、状态码和固定字符串应抽为常量或枚举。 +- 集合、空值、字符串、时间、金额和 `BigDecimal` 使用安全写法。 +- 异常不吞掉,日志有上下文但不输出 Secret、Token 或个人敏感信息。 +- 分层结构、包结构、数据模型和字段映射必须配中文注释或中文说明,说明每层职责、依赖方向和关键字段含义。 +- 复杂流程、幂等、事务、外部字段映射和脱敏逻辑要写必要中文注释。 + +## 9. 接口契约 + +- API 返回稳定代码,不返回中文或英文文本作为前端业务判断依据。 +- 动态字段使用稳定 `fieldKey` 和可国际化 `labelKey`。 +- 错误响应不得回显 Secret、Token、原始消息正文、附件 URL 或个人敏感信息。 +- 接口变更前先确认领域模型、字段映射、前端影响和测试范围。 + +## 10. 安全规范 + +- Secret 只放环境变量、本地 `.env` 或部署平台 Secret。 +- 仓库只提交无真实值的 `.env.example`。 +- 禁止提交真实客户数据、Token、Cookie、API Key、数据库密码或支付信息。 +- 日志、错误响应和测试夹具不得暴露敏感信息。 +- `.DS_Store`、构建产物、依赖目录、IDE 临时文件和本地样本目录应忽略。 + +## 11. 测试与验证 + +- 修改后运行对应模块已有检查命令。 +- 如果检查命令尚未配置或因环境问题无法运行,必须明确说明原因。 +- 不假装测试通过。 +- 优先做小的可验证闭环,再逐步扩展业务能力。 +- 高风险改动需要补充更接近真实使用路径的测试。 + +## 12. Agent 协作规则 + +Coding agent 开始任务前应先读取: + +1. `AGENTS.md` +2. `README.md`,如果存在 +3. `docs/` 中与当前任务相关的文档 +4. 当前代码结构和最近 Git 状态 + +改文件前要说明计划;完成后要说明改了什么、如何验证、还有哪些风险或未完成项。 + +## 13. 新项目补充模板 + +复制到新项目后,建议补充: + +- 项目名称和业务定位。 +- 技术栈和版本。 +- 前后端与运行时版本兼容性检查结论。 +- 目录结构。 +- 分层结构、数据模型和字段映射的中文说明。 +- 本地启动、测试、构建命令。 +- 接口契约位置。 +- 不能随便改的目录或文件。 +- 当前第一个 checkpoint 和验收标准。 diff --git a/docs/import/reusable/integrations/superagent-agentbus-portable-integration-guide.md b/docs/import/reusable/integrations/superagent-agentbus-portable-integration-guide.md new file mode 100644 index 0000000..7eb1206 --- /dev/null +++ b/docs/import/reusable/integrations/superagent-agentbus-portable-integration-guide.md @@ -0,0 +1,563 @@ +# SuperAgent 与 AgentBus 通用对接指南 + +## 1. 文档定位 + +本文记录 SuperAgent 与 AgentBus 接入时可复用的工程边界、配置清单、验证顺序和安全要求。 + +本文不是官方协议文档,也不保存任何真实 Token、API Key、Session ID、Run ID、消息正文、附件 URL 或个人信息。接入新项目时,应以提供方最新协议、真实测试响应和当前项目业务规则为准。 + +如果新项目不使用 SuperAgent 或 AgentBus,可以不复制本文。 + +## 2. 职责边界 + +SuperAgent 和 AgentBus 不应被设计成同一个模块。 + +推荐边界: + +```text +AgentBus +→ 接收外部渠道消息 +→ 保存 SourceMessage Inbox +→ 受控 Replay 为业务可消费事件 +→ 调用 AI 能力端口 +→ SuperAgent Provider Adapter +→ 保存 AI 调用审计 +→ 业务 Schema 校验 +→ 人工确认或业务规则确认 +→ 正式业务写操作 +``` + +| 能力 | 定位 | 负责什么 | 不负责什么 | +| --- | --- | --- | --- | +| AgentBus | 外部消息通道适配器 | WebSocket 连接、接收入站 frame、保存原始来源事实 | 不做 AI 抽取、不创建正式业务任务、不自动回复用户、不调用业务写接口 | +| SuperAgent | 外部 AI / Agent 能力提供方 | 创建 Agent Session、发送消息、解析 SSE、返回建议或回答 | 不决定业务动作、不绕过确认、不直接写业务系统 | +| SourceMessage Inbox | 入站缓冲层 | 不可变保存来源消息和捕获状态 | 不表达 AI 结论或业务归属 | +| AgentCapabilityPort | AI 能力端口 | 隔离业务层和具体 Provider SDK / HTTP 协议 | 不暴露 Provider DTO 给领域层 | + +核心原则: + +- 前端不直接调用 SuperAgent 或 AgentBus,不接触任何 Provider Secret。 +- AgentBus 实时链路只落来源事实,不直接生成正式业务结果。 +- SuperAgent 返回内容只能作为建议、证据或审计结果,不能直接改变业务最终状态。 +- 业务写操作必须经过规则校验、权限控制、幂等控制和人工确认或业务确认。 + +## 3. 推荐模块拆分 + +Java / Spring Boot 项目接入时,建议按以下模块复制思路: + +```text +support +├── message +│ ├── SourceMessageInbox +│ ├── MessageEvent +│ └── Evidence +├── ai +│ ├── AgentCapabilityPort +│ ├── AgentCapabilityRequest +│ ├── AgentCapabilityResult +│ └── AiCapabilityInvocation +└── system + ├── SuperAgentProbeController + ├── AgentBusProbeStatusController + └── SourceMessageReplayController + +integrations +├── ai +│ └── superagent +└── messaging + └── agentbus +``` + +模块规则: + +- `support.message` 保存入站消息、回放和证据等平台能力。 +- `support.ai` 保存 AI 能力端口、请求响应模型和调用审计。 +- `integrations.ai.superagent` 保存 SuperAgent HTTP、SSE、认证和 DTO 细节。 +- `integrations.messaging.agentbus` 保存 AgentBus WebSocket、frame 解析和入站映射。 +- 业务模块只依赖 `AgentCapabilityPort` 和受控消息事件,不依赖 SuperAgent 或 AgentBus DTO。 + +## 4. SuperAgent 对接 + +### 4.1 运行时配置 + +最小配置建议: + +```text +AI_PROVIDER_ENABLED=false +SUPERAGENT_BASE_URL= +SUPERAGENT_OPEN_API_KEY= +SUPERAGENT_PROBE_ENABLED=false +SUPERAGENT_PROBE_ACCESS_KEY= +SUPERAGENT_CONNECT_TIMEOUT=15s +SUPERAGENT_READ_TIMEOUT=180s +SUPERAGENT_MAX_MESSAGE_CHARS=4000 +SUPERAGENT_EXTERNAL_SUBJECT_ID= +``` + +变量说明: + +| 变量 | 是否 Secret | 说明 | +| --- | --- | --- | +| `AI_PROVIDER_ENABLED` | 否 | 是否启用真实 SuperAgent Provider Adapter。默认关闭。 | +| `SUPERAGENT_BASE_URL` | 否 | SuperAgent Open API 地址。 | +| `SUPERAGENT_OPEN_API_KEY` | 是 | Open API Key,只能存在后端环境变量或 Secret Manager。 | +| `SUPERAGENT_PROBE_ENABLED` | 否 | 是否开放本项目自己的探针接口。生产默认关闭。 | +| `SUPERAGENT_PROBE_ACCESS_KEY` | 是 | 调用探针接口的本地访问密钥,不是 Provider API Key。 | +| `SUPERAGENT_CONNECT_TIMEOUT` | 否 | 建立连接超时。 | +| `SUPERAGENT_READ_TIMEOUT` | 否 | SSE 读取超时。 | +| `SUPERAGENT_MAX_MESSAGE_CHARS` | 否 | 单次发送给 Provider 的消息长度上限。 | +| `SUPERAGENT_EXTERNAL_SUBJECT_ID` | 否 | 创建 Agent Session 时使用的外部主体标识。 | + +### 4.2 Open API 调用形态 + +常见流程: + +```text +POST /api/open/agent-sessions +→ 获取 session_id +→ POST /api/open/agent-sessions/{sessionId}/messages/stream +→ 读取 text/event-stream +→ 解析最终 answer、run、profile、model、token usage +``` + +如果提供方要求 CSRF double-submit,应保证 Header 与 Cookie 使用同一个临时随机值: + +```text +X-CSRF-Token: +Cookie: csrf_token= +Authorization: Bearer +``` + +CSRF Token 由客户端实例临时生成,不写入配置,也不能当作 Secret 长期保存。 + +### 4.3 Session 请求示例 + +```json +{ + "external_subject_id": "", + "idempotency_key": "-superagent-session-", + "metadata": { + "source": "", + "purpose": "provider-connectivity-test" + } +} +``` + +### 4.4 SSE 消息请求示例 + +```json +{ + "message": "请介绍一下你是谁。", + "idempotency_key": "-superagent-message-", + "metadata": { + "source": "", + "purpose": "provider-flow-test" + } +} +``` + +### 4.5 SSE 解析口径 + +建议至少处理: + +- 调用元数据,例如 Run、Thread、Profile。 +- 流式消息增量或中间消息。 +- 阶段性或最终聚合状态。 +- SSE 正常结束标志。 + +解析最终答案时,不要简单拼接所有消息增量。应以提供方协议中明确的最终回答字段为准,并记录: + +- provider request id 或 run id。 +- profile id 与 profile version id。 +- model id 或 model name。 +- input tokens、output tokens 和 total tokens。 +- 已出现的 SSE event types。 + +如果没有收到结束事件,或无法找到最终 AI 回答,应视为协议失败,不要伪造成成功结果。 + +### 4.6 平台能力端口 + +建议定义稳定端口: + +```java +public interface AgentCapabilityPort { + AgentCapabilityResult invoke(AgentCapabilityRequest request); +} +``` + +领域层只依赖这个端口,不依赖 SuperAgent HTTP DTO、SSE event、Profile ID 或厂商 SDK。 + +建议 `AgentCapabilityResult` 至少包含: + +```text +providerCode +responseSchemaVersion +providerSessionId +providerRequestId +providerProfileId +providerProfileVersionId +providerModelId +outputText 或 outputReference +usageMetadata +``` + +### 4.7 调用审计 + +建议每次外部能力调用都写入不可变审计表。 + +审计表应记录: + +- provider code。 +- capability code。 +- request id / run id。 +- profile / model 信息。 +- 请求状态、耗时、错误代码。 +- token usage 或成本元数据。 +- 脱敏后的输入输出摘要。 + +审计表不应记录: + +- Provider API Key。 +- Cookie。 +- Authorization。 +- Chain of Thought。 +- Provider 内部 Plan / Memory。 +- 未脱敏的个人信息。 + +## 5. AgentBus 对接 + +### 5.1 运行时配置 + +最小配置建议: + +```text +AGENTBUS_PROBE_ENABLED=false +AGENTBUS_WS_URL= +AGENTBUS_WS_TOKEN= +AGENTBUS_BOT_ADDRESS= +AGENTBUS_WS_RECONNECT_DELAY=5s +AGENTBUS_CONNECT_TIMEOUT=15s +AGENTBUS_SAMPLE_ENABLED=false +AGENTBUS_SAMPLE_DIR=var/agentbus-samples +AGENTBUS_MAX_FRAME_BYTES=1048576 +AGENTBUS_MAX_SAMPLES=100 +AGENTBUS_CAPTURE_ENABLED=true +AGENTBUS_DEFAULT_CONTEXT_ID= +AGENTBUS_REPLY_MODE=NONE +``` + +变量说明: + +| 变量 | 是否 Secret | 说明 | +| --- | --- | --- | +| `AGENTBUS_PROBE_ENABLED` | 否 | 是否启用 AgentBus WebSocket 监听。默认关闭。 | +| `AGENTBUS_WS_URL` | 否 | AgentBus WebSocket 地址。 | +| `AGENTBUS_WS_TOKEN` | 是 | WebSocket 鉴权 Token。 | +| `AGENTBUS_BOT_ADDRESS` | 否 | 当前 Bot / Listener 地址。 | +| `AGENTBUS_WS_RECONNECT_DELAY` | 否 | 断线后的重连间隔。 | +| `AGENTBUS_CONNECT_TIMEOUT` | 否 | WebSocket 连接超时。 | +| `AGENTBUS_SAMPLE_ENABLED` | 否 | 是否保存本地原始 frame 样本。生产应默认关闭。 | +| `AGENTBUS_SAMPLE_DIR` | 否 | 本地样本目录,可能含敏感信息,不得提交。 | +| `AGENTBUS_MAX_FRAME_BYTES` | 否 | 单个入站 frame 最大字节数。 | +| `AGENTBUS_MAX_SAMPLES` | 否 | 最多保留的本地样本数。 | +| `AGENTBUS_CAPTURE_ENABLED` | 否 | 是否写入 SourceMessage Inbox。 | +| `AGENTBUS_DEFAULT_CONTEXT_ID` | 否 | Provider 未提供业务上下文时的默认上下文。 | +| `AGENTBUS_REPLY_MODE` | 否 | 调试回复模式。真实用户渠道应保持 `NONE`。 | + +### 5.2 WebSocket 连接 + +常见连接形态: + +```text +Authorization: Bearer +GET ?ready=1 +``` + +连接成功后应能收到 `session.ready` 或等价就绪事件。 + +状态查询接口只应返回连接状态、计数器和最近错误代码,不返回 Token 或原始消息。 + +### 5.3 入站 frame 处理边界 + +推荐处理顺序: + +```text +收到 raw WebSocket frame +→ 限制单帧大小 +→ 可选本地采样 +→ JSON 解析 +→ 忽略 session.ready / task.progress / task.result 等控制事件 +→ 将业务 payload 映射为 CaptureSourceMessageCommand +→ 写入 SourceMessage Inbox +``` + +实时链路禁止: + +- 自动发送 ACK。 +- 自动发送 `task.result`。 +- 自动回复用户。 +- 直接创建正式业务事件、业务任务、业务操作或业务回执。 +- 直接调用 ERP、支付系统、订单系统等业务写接口。 + +### 5.4 Payload 字段确认 + +接入前必须通过真实测试响应确认 payload 字段,不根据字段名猜测业务语义。 + +建议至少确认: + +- `source.channel` +- `source.external_message_id` +- `source.external_conversation_id` +- frame id +- session id +- sender +- subject 或标题 +- text / html / attachments 等消息内容字段 +- reply policy 或回复策略 + +捕获层只依赖少量稳定字段: + +| Provider 字段 | 平台字段 | +| --- | --- | +| `source.channel` | `channel` | +| `source.external_message_id` | `externalMessageId`,作为幂等键组成部分 | +| `source.external_conversation_id` | `externalConversationId` | +| frame id | `providerFrameId` | +| session id | `providerSessionId` | +| payload 规范 JSON | `payloadJson` 与 `payloadSha256` | + +不要根据 envelope 的 `from`、`to`、`conversation_id` 猜测业务归属或下游任务。 + +### 5.5 SourceMessage Inbox + +建议单独建表保存 AgentBus 入站事实。 + +推荐幂等键: + +```text +context_id + provider + channel + external_message_id +``` + +重复投递时返回已有 Inbox,不覆盖原始 payload,不创建重复记录。 + +如果 payload 缺少必要字段或格式不符合预期,也应保存为 `FAILED` Inbox,并记录安全错误摘要。错误摘要不得包含: + +- 消息正文。 +- HTML。 +- 附件 URL。 +- 完整邮箱地址或手机号。 +- Token / Cookie / Secret。 + +### 5.6 Replay 到业务事件 + +SourceMessage Inbox 不应等同于正式业务消息。建议增加受控 Replay: + +```text +POST /api/system/source-message-inbox/{inboxId}/replay +Header: X-Source-Message-Replay-Key +``` + +Replay 负责: + +- 从 Inbox payload 提取业务可消费字段。 +- 保存正文或正文引用。 +- 保存证据摘要或附件引用。 +- 记录 replay attempt。 +- 返回业务事件 ID 和状态。 + +Replay 接口默认关闭,仅在本地、UAT 或受控生产运维场景开启。 + +## 6. 最小落地顺序 + +### 阶段 1:SuperAgent 连通性 + +目标: + +```text +后端探针 +→ 创建 SuperAgent Session +→ 发送一条无敏感信息测试消息 +→ 解析 SSE 最终回答 +→ 返回非敏感元数据 +``` + +验收: + +- HTTP 连接成功。 +- SSE 收到结束事件。 +- 最终回答非空。 +- 日志不出现 API Key、Cookie、Session 原始值或个人信息。 + +### 阶段 2:AgentBus 连接 + +目标: + +```text +AgentBus WebSocket +→ session.ready +→ 状态接口可见 connected/sessionReady +``` + +验收: + +- 连接成功。 +- 可断线重连。 +- 不发送用户回复。 +- 不保存本地 raw sample,除非临时排障。 + +### 阶段 3:SourceMessage Inbox + +目标: + +```text +AgentBus 入站业务 frame +→ SourceMessage Inbox +``` + +验收: + +- 正常 payload 保存为 `RECEIVED`。 +- 无效 payload 保存为 `FAILED`。 +- 重复外部消息不重复入库。 +- 查询接口只返回安全摘要。 + +### 阶段 4:手动 Replay + +目标: + +```text +SourceMessage Inbox +→ 业务可消费事件 / Evidence +``` + +验收: + +- 同一 Inbox 可以按不同 `replayRunId` 多次 replay。 +- 相同 `replayRunId` 幂等。 +- Replay 失败有 attempt 记录。 +- 响应不返回消息正文、HTML、附件 URL 或 Token。 + +### 阶段 5:业务接入 SuperAgent + +目标: + +```text +业务事件 +→ AgentCapabilityPort +→ SuperAgent Adapter +→ AI 调用审计 +→ 业务 Schema 校验 +``` + +验收: + +- Provider 返回记录为审计,不直接触发业务写操作。 +- 结构化输出必须通过 Schema 校验。 +- 无法映射或不可信结果进入人工处理。 + +## 7. 安全与日志清单 + +必须放入 Secret 管理,不得提交仓库: + +- `SUPERAGENT_OPEN_API_KEY` +- `SUPERAGENT_PROBE_ACCESS_KEY` +- `AGENTBUS_WS_TOKEN` +- `SOURCE_MESSAGE_REPLAY_ACCESS_KEY` +- 数据库密码 +- 任何真实用户渠道 Token + +普通日志和错误响应不得输出: + +- Authorization。 +- Cookie。 +- CSRF Token。 +- Provider API Key。 +- AgentBus Token。 +- 消息正文和 HTML。 +- 附件 URL。 +- 姓名、邮箱、电话、证件号。 +- 支付信息。 + +本地采样要求: + +- `AGENTBUS_SAMPLE_ENABLED` 默认 `false`。 +- 只在隔离测试或排障时临时开启。 +- 样本目录必须被 `.gitignore` 忽略。 +- 排障结束后删除样本。 + +## 8. 测试建议 + +SuperAgent 建议覆盖: + +- 缺失 API Key 时启动或调用失败。 +- CSRF Header / Cookie 不一致时转换为受控错误。 +- 创建 Session 成功。 +- SSE 正常结束并解析最终回答。 +- SSE 缺少结束事件时失败。 +- SSE 缺少最终回答时失败。 +- HTTP 401 / 403 / 404 / 409 / 5xx 错误转换。 +- 连接超时和读取超时。 + +AgentBus 建议覆盖: + +- `session.ready` 只更新状态,不写 Inbox。 +- 控制事件不写 Inbox。 +- 正常 payload 写入 Inbox。 +- `captureEnabled=false` 时忽略业务 frame。 +- 无效 payload 写入 `FAILED` Inbox。 +- 超大 frame 被拒绝并记录错误代码。 +- 重复外部消息保持幂等。 +- 查询接口不返回原始 payload。 +- Replay 相同 run id 幂等。 + +## 9. 常见误区 + +### 9.1 把 AgentBus 当 AI Provider + +AgentBus 是消息入口,不是抽取模型。它可以传递外部渠道原始事实,但不应该直接产生业务最终判断。 + +### 9.2 把 SuperAgent 返回当业务事实 + +SuperAgent 返回的是 Provider 输出。即使返回结构化 JSON,也必须经过 Schema、业务规则、业务对象匹配和人工确认或业务确认。 + +### 9.3 让浏览器直接调用 Provider + +浏览器不能持有 Provider Key、AgentBus Token 或 replay access key。前端只调用本项目后端。 + +### 9.4 实时入口直接生成正式业务任务 + +实时 AgentBus 链路如果直接创建正式业务任务,会导致重复投递、字段不完整、后续协议变化和人工回溯都难处理。先落 Inbox,再 Replay,是更稳的路线。 + +### 9.5 在文档或测试里保存真实消息 + +真实消息、附件 URL、姓名和联系方式都可能是敏感数据。测试夹具应使用合成数据。 + +## 10. 接入前检查清单 + +接入 SuperAgent 前确认: + +- [ ] 已获得 Open API Key 和允许访问的 Base URL。 +- [ ] 已确认是否需要 CSRF double-submit。 +- [ ] 已确认 Session、Message、Run 的生命周期。 +- [ ] 已确认 SSE 最终答案或结构化结果所在字段。 +- [ ] 已定义 `AgentCapabilityPort` 和调用审计表。 +- [ ] 已确认 Provider 输出不会直接触发业务写操作。 + +接入 AgentBus 前确认: + +- [ ] 已获得 WebSocket URL、Token 和 Bot Address。 +- [ ] 已确认真实渠道 payload 字段。 +- [ ] 已确认外部消息稳定幂等键。 +- [ ] 已确认断线重连和重复投递语义。 +- [ ] 已确认是否允许 ACK 或用户回复;默认按禁止处理。 +- [ ] 已建立 SourceMessage Inbox 和 Replay attempt。 +- [ ] 已定义原始 payload 的保存、访问、保留和删除策略。 + +进入生产前确认: + +- [ ] 所有 Secret 均通过环境变量或 Secret Manager 注入。 +- [ ] `.env.example` 只有占位值。 +- [ ] 日志脱敏已验证。 +- [ ] 自动回复保持关闭。 +- [ ] 自动业务写操作保持关闭,除非经过单独评审。 +- [ ] 监控至少覆盖连接状态、失败次数、Replay 失败和 Provider 调用失败。 diff --git a/docs/project/README.md b/docs/project/README.md new file mode 100644 index 0000000..5327bd2 --- /dev/null +++ b/docs/project/README.md @@ -0,0 +1,12 @@ +# 当前项目专属文档 + +本目录保存只适用于当前项目的业务背景、架构边界、外部系统约束和实现决策。 + +这些文档可以作为后续项目参考,但不应整份复制到新项目。新项目可复用内容应优先沉淀到 `docs/import/reusable/`。 + +## 文档清单 + +- `backend-development-guidelines.md`:当前项目后端专属规范。 +- `frontend-development-guidelines.md`:当前项目前端专属规范。 +- `requirements/M001-source-message-inbox-prd.md`:M001 邮件来源入口 PRD,记录 AgentBus 邮件 JSON 入库、历史查询、原文读取和媒体引用边界。 +- `integrations/superagent-agentbus-project-integration-guide.md`:当前项目 SuperAgent 与 AgentBus 验证记录和项目级接入细节。 diff --git a/docs/project/backend-development-guidelines.md b/docs/project/backend-development-guidelines.md new file mode 100644 index 0000000..e1737cd --- /dev/null +++ b/docs/project/backend-development-guidelines.md @@ -0,0 +1,265 @@ +# TH Hotel 后端开发规范 + +## 1. 文档定位 + +本文整理 TH Hotel 当前后端开发约定,供本项目后端开发和其他 agent 协作参考。 + +本文是当前项目专属补充,不应整份复制到其他项目。可复用的通用后端规则应沉淀到 `docs/import/reusable/backend-development-guidelines.md`。 + +本项目后端是酒店多部门 AI 业务流程与 Case 协同平台的服务端。这里的 AI 只表示调用外部 +模型或 Agent 能力提供方并消费其结构化结果;本项目不开发模型、Prompt 优化平台、Agent +Runtime、Planner、Memory 或通用工具调用框架。 + +## 2. 技术栈 + +以 `server/pom.xml` 为准,当前后端技术栈如下: + +| 类别 | 当前选择 | +| --- | --- | +| Java | Java 17 LTS,语法版本 Java 17 | +| 框架 | Spring Boot 3.5.15 | +| Web | Spring MVC | +| 构建 | Maven Wrapper | +| 外部 HTTP | Spring `RestClient` 优先 | +| 数据库 | MySQL 8.0+ | +| ORM / Mapper | MyBatis-Plus 3.5.16,Spring Boot 3 使用 `mybatis-plus-spring-boot3-starter` | +| 数据库迁移 | Flyway | +| OpenAPI | springdoc-openapi 2.8.17 | +| 测试 | JUnit 5、Spring Boot Test、H2 MySQL Mode | + +升级 Java、Spring Boot、MyBatis-Plus、springdoc 或 Flyway 前,必须先做兼容性验证。 + +Maven 编译配置应显式使用 `maven.compiler.release=17`,并开启参数名保留,例如 `parameters=true`。除非单独确认升级方案,否则不得使用 Java preview 特性或 Java 21 / Java 25 专属语法。 + +引入 MyBatis-Plus 后,不再额外引入 `mybatis-spring-boot-starter`、`MyBatis-Spring` 或重复的原生 MyBatis starter,避免 starter 版本差异造成运行期问题。 + +## 3. 后端分层与包边界 + +推荐边界: + +```text +platform +├── ai +├── audit +├── evidence +├── message +├── operation +├── receipt +└── system + +workflows +└── reservation + +integrations +├── ai +├── document +├── external +├── messaging +└── ohip +``` + +中文说明: + +| 层级 | 中文职责 | 依赖规则 | +| --- | --- | --- | +| `platform` | 平台通用能力层,保存消息、证据、AI 调用审计、Operation、Receipt、审计等部门中立能力 | 可以被业务流程调用,不能反向依赖预订部等具体业务流程 | +| `workflows` | 业务流程层,保存具体部门或业务线的流程编排,当前优先是预订流程 | 可以依赖 `platform` 和稳定端口,不直接依赖外部系统 DTO | +| `integrations` | 外部系统适配层,隔离 OHIP、SuperAgent、AgentBus 等外部协议和认证细节 | 可以实现平台或业务端口,不能把外部 DTO 泄漏到领域模型 | + +后续输出包结构、目录树、数据模型、字段映射或接口示例时,必须补充中文说明,说明每层职责、依赖方向、可调用对象和禁止事项,不能只依赖英文命名表达含义。 + +职责规则: + +- `platform` 保存部门中立能力,例如消息、证据、AI 调用审计、Operation、Receipt、审计。 +- `workflows` 保存部门业务流程,当前明确的是 `reservation`。 +- `integrations` 保存外部系统适配器,例如 OHIP、SuperAgent、AgentBus。 +- 平台核心不得依赖预订部专有字段。 +- 部门工作流可以依赖平台核心,平台核心不能反向依赖部门模块。 +- 外部系统 DTO、Oracle DTO、Provider DTO、领域模型和 API Response 必须分离。 +- Oracle DTO 或生成代码只能位于 `integrations.ohip`,不得进入平台领域模型。 + +## 4. Controller / Service / Repository 规则 + +- Controller 只做 HTTP 契约、参数校验、权限入口和响应映射。 +- Controller 不直接访问 Mapper。 +- Controller 不直接调用外部适配器。 +- Application Service 编排事务、领域对象、Repository 和外部端口。 +- Domain 对象表达稳定业务语义,不引入 HTTP、JSON、MyBatis 或外部 Provider 细节。 +- Repository 是领域侧持久化接口。 +- Infrastructure / Persistence 负责 Entity、Mapper 和数据库细节。 +- 外部调用通过端口和 Adapter 隔离,业务层不依赖厂商 SDK 或厂商 DTO。 + +## 5. 数据建模规则 + +必须分别建模以下业务标识,不能共用模糊字段: + +```text +caseId +blockId +reservationId +confirmationNumber +groupCode +``` + +其他规则: + +- 房型、房量、人数、金额、日期必须使用结构化字段,不只保存展示字符串。 +- 状态使用稳定英文代码,中文和英文只用于显示。 +- 动态参数必须有稳定 `fieldKey` 和可国际化 `labelKey`。 +- 不能把某一种语言的显示文本当作接口契约或业务判断依据。 +- 至少区分外部提供方建议值、人工确认值、最终执行值。 +- Receipt 生成后不可覆盖修改;纠错通过新记录表达。 +- Task 执行必须支持幂等、并发版本校验和审计。 + +## 6. SourceMessage / AI / Task 边界 + +- `SourceMessage` 表示 Email、LINE、附件等渠道输入的原始来源事实。 +- AI 抽取输出的业务事件不是来源消息,也不是正式 Task。 +- 一条 SourceMessage 可以产生多个 AI Task Result、多个候选或多张 Task。 +- Task 与 SourceMessage、AI MessageEvent、Evidence 通过来源关联建模。 +- 不得用单个 `createdFromEventId` 固化一对一关系。 +- Case 匹配不明确时,必须创建可持久化、可审计的 Preflight / Need Manual Review 对象。 +- 只有人工关联已有 Case 或确认新增 Case 后,才创建正式 TaskCard。 +- Preflight / Need Manual Review 被拒绝或终止后不得删除,必须保留来源、候选版本、处理人、原因和时间。 + +## 7. AI / Agent Provider 边界 + +- 业务模块只依赖 `AiCapabilityPort` 一类稳定调用契约。 +- SuperAgent、模型 ID、Agent ID、认证配置位于 Adapter 层。 +- 真实 Provider 返回内容不得直接生成 Recognition、Case、Task、Operation、Receipt 或 OHIP 写入。 +- Provider 输出只能作为建议或证据。 +- 所有会引起业务写操作的参数必须经过规则校验和人工确认。 +- 平台可记录 provider、capability、request id、版本、耗时和用量,但不实现模型训练、Prompt 优化或 Agent 编排。 + +## 8. AgentBus 边界 + +- AgentBus 是消息入口适配器,不是 AI Provider。 +- 实时 AgentBus 链路只写 `platform_source_message_inbox`。 +- 不直接生成 `platform_message_event`、Evidence、Recognition、Case、Task、Operation、Receipt 或 OHIP 写入。 +- 不自动发送 ACK、`task.result` 或客户回复。 +- SourceMessage Inbox 到 MessageEvent / Evidence 必须通过受控 replay。 +- 原始 frame 本地采样默认关闭,生产不常态保存 raw frame。 + +## 9. OHIP / OPERA Cloud 边界 + +开发任何 OHIP 页面或执行器前,必须先更新字段映射文档,明确: + +- 页面字段 +- 领域字段 +- 内部 API 字段 +- OHIP 字段或 JSONPath +- 来源接口和版本 +- 是否必填 +- fallback +- Sandbox 验证状态 +- UAT 三方核对状态 + +禁止根据字段名猜 Oracle API 字段。未通过官方文档或真实响应确认的内容必须标记为“待确认”。 + +浏览器不得直接调用 OHIP。OHIP Secret 只能由后端环境变量或部署平台 Secret 注入。 + +## 10. 数据库与 Flyway 规范 + +- 新建表和改表必须通过 Flyway migration。 +- 已发布 migration 禁止直接修改。 +- 修正注释、索引或约束必须新增 migration。 +- 每张业务表必须有中文表级 `COMMENT`。 +- 每个业务字段必须有中文字段级 `COMMENT`。 +- SQL 文件应使用中文行注释划分表、索引、约束等主要结构。 +- 注释必须说明业务含义、来源或代码值范围。 +- 禁止使用“字段1”“备用字段”等模糊注释。 +- 业务时间以 UTC 写入数据库,API 层负责返回 ISO 8601。 +- JSON 字段只用于扩展元数据,不替代需要查询、约束或索引的正式列。 + +## 11. 后端代码注释规范 + +后端 Java 代码必须提供必要且准确的中文注释: + +- 架构文档、设计文档、目录结构、数据模型、字段映射和接口示例必须优先使用中文说明业务含义。 +- 领域对象、应用服务、外部适配器、Controller、配置属性和复杂参数对象应说明业务含义、边界或调用约束。 +- 复杂流程、幂等键、并发控制、事务边界、错误转换、外部系统字段映射和安全脱敏逻辑必须说明原因。 +- 注释不得只复述类名、方法名或字段名。 +- 不得用“TODO 待完善”替代真实说明。 +- 生成新后端代码时必须同步生成中文注释。 +- 修改旧代码时,应补齐触达代码的必要中文注释。 + +## 12. 安全与日志 + +Secret 只能通过 `.env`、环境变量或部署平台 Secret 注入。仓库只提交无真实值的 `.env.example`。 + +禁止提交: + +- 真实酒店凭证 +- Oracle Client Secret、Application Key、Integration Password +- SuperAgent API Key +- AgentBus Token +- Cookie、Access Token +- 真实客户邮件、附件 URL、个人数据 +- 完整支付信息 + +日志必须脱敏: + +- Authorization、Cookie +- Client Secret、Integration Password、Application Key +- 客人姓名、邮箱、电话、证件信息 +- 支付卡和账务敏感数据 +- 原始消息正文、HTML、附件 URL + +## 13. 配置规范 + +- Spring Boot 不会自动读取 `.env`,本地启动需由 shell、IDE、容器或部署平台注入环境变量。 +- 本地开发可复制根目录 `.env.example` 为 `.env`,真实值只留本机。 +- `TH_HOTEL_DB_URL` 包含 `&` 时必须加引号。 +- 后端 Secret 不得放入前端 `VITE_*`。 +- 生产环境应拆分 ConfigMap / 非敏感环境变量与 Secret / 密钥管理系统。 + +## 14. API 设计规范 + +- API 返回稳定代码,不返回中文或英文文本作为前端业务判断依据。 +- 动态表单字段使用稳定 `fieldKey` 和可国际化 `labelKey`。 +- 错误响应不得回显 Secret、原始正文、附件 URL 或个人信息。 +- 写接口必须考虑幂等、并发版本、审计和失败恢复。 +- 外部写操作结果不明确时,禁止盲目重试。 +- 调试接口必须默认关闭,并使用独立访问密钥。 + +## 15. 测试与检查命令 + +后端最低检查: + +```bash +cd server +./mvnw test +./mvnw verify +``` + +聚焦开发时可先运行相关测试: + +```bash +cd server +./mvnw -Dtest=SomeFocusedTest test +``` + +如果命令尚未配置或因环境问题无法运行,必须明确说明,不能假装通过。 + +## 16. Git 与协作流程 + +- 改动前说明目标、范围和将修改的文件。 +- 每次只处理一个模块或一个纵向切片。 +- 需求基准变化时,先做差异和影响分析。 +- 修改接口前确认领域模型和数据映射。 +- 不修改与当前任务无关的用户变更。 +- 修改后运行项目已配置的检查命令。 +- Git commit message 使用中文,清楚说明本次提交的业务或技术变更。 + +## 17. 后端提交前检查清单 + +- [ ] 是否遵守 platform / workflows / integrations 分层? +- [ ] Controller 是否没有直接访问 Mapper 或外部 Adapter? +- [ ] 外部 DTO 是否没有进入领域模型? +- [ ] 写接口是否有幂等、版本或审计设计? +- [ ] Flyway SQL 是否有规范中文注释? +- [ ] Java 复杂逻辑是否有必要中文注释? +- [ ] 是否没有提交真实 Secret 或客户数据? +- [ ] 是否没有把 Provider 输出直接当业务事实? +- [ ] 是否运行了 `./mvnw test` 或说明了无法运行原因? +- [ ] 是否运行了 `./mvnw verify` 或说明了无法运行原因? diff --git a/docs/project/frontend-development-guidelines.md b/docs/project/frontend-development-guidelines.md new file mode 100644 index 0000000..3789e5b --- /dev/null +++ b/docs/project/frontend-development-guidelines.md @@ -0,0 +1,282 @@ +# TH Hotel 前端开发规范 + +## 1. 文档定位 + +本文整理 TH Hotel 当前前端开发约定,供本项目 UI 开发和其他 agent 协作参考。 + +本文是当前项目专属补充,不应整份复制到其他项目。可复用的通用前端规则应沉淀到 `docs/import/reusable/frontend-development-guidelines.md`。 + +前端只负责展示、交互、人工确认、调试入口和调用本项目后端。前端不得直接调用 OHIP、 +SuperAgent、AgentBus 或任何持有 Secret 的外部系统。 + +## 2. 技术栈 + +以 `client/package.json` 为准,当前前端技术栈如下: + +| 类别 | 当前选择 | +| --- | --- | +| 运行时 | Node.js 22.13+ LTS | +| 框架 | Vue 3.5.x | +| 语言 | TypeScript ~6.0.x,Strict 模式 | +| 构建 | Vite 8.x | +| 组件写法 | Composition API,`