Files
th-hotel-simple/docs/project/backend-development-guidelines.md

11 KiB
Raw Blame History

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.16Spring 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-starterMyBatis-Spring 或重复的原生 MyBatis starter避免 starter 版本差异造成运行期问题。

3. 后端分层与包边界

推荐边界:

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. 数据建模规则

必须分别建模以下业务标识,不能共用模糊字段:

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. 测试与检查命令

后端最低检查:

cd server
./mvnw test
./mvnw verify

聚焦开发时可先运行相关测试:

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 或说明了无法运行原因?