Files
fire-safety-ymd/docs/project/backend-development-guidelines.md
2026-09-05 15:46:37 +08:00

8.3 KiB
Raw Permalink Blame History

fire-safety-ymd Go 后端开发规范

1. 当前技术基线

当前选择 说明
Go module fire-safety-ymd 临时名称,正式仓库路径待确认
Go 工具链 本地 1.26.6Docker builder 1.26.8 本地测试已验证;镜像版本已显式固定,目标服务器构建待验证
HTTP 标准库 net/http 当前无需 Web 框架
测试 testinghttptest 当前无第三方测试库
数据库 PostgreSQL + PostGIS + pgx/v5 v5.10.0 原生 pgxpool、固定只读 SQL实库 SRID 严格 readiness 已通过
AI 集成 SuperAgent Open API Adapter + MCP 2025-06-18 协议代码已实现并默认关闭;真实环境待联调

引入依赖前优先核对官方版本、Go 版本要求、维护状态、许可证和可替代性。核心依赖升级需要独立验证,不能只修改版本号。

2. 目录职责和依赖方向

cmd/server            进程入口、信号处理、依赖装配
internal/app          应用生命周期与顶层 wiring
internal/config       配置读取、默认值和校验
internal/handler      HTTP/MCP 入站契约和响应映射
internal/service      用例编排、授权后的业务流程
internal/domain       稳定领域概念、值对象和业务规则
internal/repository   PostgreSQL/PostGIS 等持久化适配
internal/integration  SuperAgent 等外部系统协议适配
pkg                   真正需要对外复用的稳定包

依赖原则:

  • cmd/server 只装配,不承载业务逻辑。
  • Handler 不直接执行 SQL不直接依赖 SuperAgent 厂商 DTO。
  • Service 通过小接口使用持久化或外部系统;接口优先定义在使用方附近。
  • Domain 不依赖 HTTP、数据库驱动、MCP SDK 或 SuperAgent SDK。
  • Repository 负责参数化查询、行映射和数据库错误转换,不组织自然语言回答。
  • 避免为了分层而创建一一映射的空结构;只有出现真实职责时才增加文件和抽象。

3. 包与 API 设计

  • 包名短、小写、表达单一能力,不使用 utilscommonbase 等无边界集合。
  • 导出标识符必须有稳定的外部使用场景;默认保持在 internal 或不导出。
  • 接口应小,由调用方定义;不要先为每个结构体创建接口。
  • 构造函数显式传入必需依赖,依赖缺失应尽早失败。
  • 避免包级可变状态、隐式 init 副作用和 service locator。
  • context.Context 作为有取消、超时或请求范围操作的第一个参数,不保存在长期结构体字段中。
  • 时间使用 time.Time/time.Duration;跨系统时间格式、时区和精度必须在契约中明确。

4. 错误处理

  • 正常业务失败返回错误,不使用 panic
  • 使用 fmt.Errorf("动作和对象: %w", err) 添加上下文并保留错误链。
  • errors.Is/errors.As 判断语义,不比较错误文本。
  • Domain/Service 错误映射为稳定 API code客户端不依赖中英文 message 做逻辑判断。
  • HTTP 响应和日志不回显 SQL、凭证、Token、完整个人信息或第三方原始敏感响应。
  • 不静默吞掉影响正确性的错误;确实只能忽略时要有注释或受控观测方式。

5. HTTP 规范

  • 路由显式声明方法;不支持的方法返回 405。
  • JSON 响应设置 Content-Type: application/json; charset=utf-8
  • Handler 只做协议解析、格式校验、可信身份上下文读取、调用 Service 和响应映射。
  • 请求体设置合理大小上限;服务端设置 Header、请求、空闲和优雅关闭超时。
  • 后续统一错误格式、请求 ID 和日志关联字段,并在 Spec/OpenAPI 中形成唯一契约来源。
  • /health 当前是 liveness只说明进程可处理 HTTP依赖就绪检查应使用独立 readiness 端点,不能改变现有语义而不更新契约。

6. 配置与 Secret

  • 环境变量名称使用项目明确前缀,例如 FIRE_SAFETY_
  • 配置由 internal/config 一次读取、校验并作为不可变值注入。
  • Secret 不设置可误用的生产默认值,不写入仓库、命令参数、普通日志或错误响应。
  • 本地 .env 被忽略;需要示例时只提交无真实值且有注释的 .env.example
  • 启动时验证必需配置,错误指出配置键但不输出其值。

7. PostgreSQL/PostGIS 规范

数据库接入遵守:

  • 当前使用 pgx/v5 原生 pgxpool;升级前核对 Go/PostgreSQL 支持范围、安全变更和回归测试。
  • 所有值使用参数绑定,表名和排序字段使用代码白名单;绝不拼接模型生成 SQL。
  • 使用最小权限数据库角色MCP 第一阶段默认为只读。
  • 查询设置请求超时和数据库 statement timeout分页、数量上限和空间半径必须有限制。
  • 事务边界由 Service 用例决定Repository 不隐藏跨用例事务。
  • 已发布 migration 只追加,不原地篡改;导入原始 SQL 前单独审计 DROP、sequence、owner 和 extension 依赖。
  • geometry 的 SRID、实际类型和有效性先通过真实数据核验再决定字段约束与查询。
  • 经纬度距离计算明确选择合适的 geography、投影转换或测地算法,并以米等业务单位返回。
  • ST_DWithin 等可利用 GiST 索引的条件限制候选集,避免对整表逐行计算距离。
  • WKB、GeoJSON、经纬度和 MultiLineString/Polygon 映射必须有代表性测试。

8. SuperAgent 与 MCP 适配

  • 外部 SDK 和 DTO 只存在于适配层Service 使用项目自己的端口和领域对象。
  • 当前 SuperAgent Adapter 分离 CreateSessionStreamMessage;上层负责持久化本地会话映射,不能每轮隐式创建新 Session。
  • SSE 成功必须同时具备最终内容、成功 run.completed 和顶层 end;断流只恢复既有 Run不重新 POST 消息。
  • DashScope 风格兼容 Handler 只做入站协议转换,与原生 /api/chat 共享 Chat Service兼容 session_id 必须映射本地会话,不能直接暴露或接受 Provider Session。
  • 兼容 SSE v1 不透传 message.delta;只有严格成功后才以 finish_reason=stop 返回正文。若要真正逐字输出,必须先更新 Spec、安全失败语义和客户端验收条件。
  • 当前 MCP 只实现 2025-06-18 的 initialize、initialized notification、tools/list、tools/call 和同步 JSON 响应;扩展 SSE、session 或新协议版本前需更新 Spec。
  • 重试只用于可安全重试的操作,并设置次数、退避和总时限;避免重复创建会话或重复业务动作。
  • MCP 工具按领域能力命名,输入输出 schema 稳定、有限且有中文业务说明。
  • user_id、角色、租户/区域等授权上下文由服务端注入,不成为模型可自由选择的普通参数。
  • 工具结果保留结构化状态、来源和不确定性,不让 Agent 解析日志或数据库原始字段。

9. 测试与验证

基础命令:

gofmt -w ./cmd ./internal
go test ./...

按风险增加:

go vet ./...
go test -race ./...

测试要求:

  • 纯逻辑优先使用表驱动单元测试。
  • HTTP 使用 httptest 验证方法、状态码、Header、JSON 和错误边界。
  • Repository 集成测试使用隔离数据库和可重复迁移,不依赖个人长期数据库。
  • PostGIS 测试覆盖 SRID、点/线/面、边界点、空几何、无效几何、半径上限和排序稳定性。
  • 外部适配测试覆盖超时、取消、断流、限流、鉴权失败和不完整事件。
  • 测试夹具不得包含真实联系人、Token、生产坐标或客户数据。

10. 日志与可观测性

  • 使用结构化日志字段表达 request、tool、duration、result 和 error category避免拼接大段原始内容。
  • 不记录 Authorization、Cookie、数据库 DSN、完整用户问题中的敏感信息或完整 MCP 结果。
  • 后续为 HTTP、SuperAgent、MCP 和数据库调用建立统一 request/correlation ID。
  • 指标区分业务无结果、权限拒绝、上游失败、超时和内部错误,不能只看 HTTP 500 总数。

11. 提交前检查

  • 仅包含本 checkpoint 文件,没有覆盖用户已有变更。
  • gofmt 和相关测试已运行。
  • 新依赖有理由且 go.mod/go.sum 一致。
  • 没有 Secret、真实敏感数据、构建产物或 IDE 文件。
  • Project State、接口、安全和相关设计文档已同步。