# fire-safety-ymd Go 后端开发规范 ## 1. 当前技术基线 | 项 | 当前选择 | 说明 | | --- | --- | --- | | Go module | `fire-safety-ymd` | 临时名称,正式仓库路径待确认 | | Go 工具链 | 本地 `1.26.6`;Docker builder `1.26.8` | 本地测试已验证;镜像版本已显式固定,目标服务器构建待验证 | | HTTP | 标准库 `net/http` | 当前无需 Web 框架 | | 测试 | `testing`、`httptest` | 当前无第三方测试库 | | 数据库 | PostgreSQL + PostGIS + `pgx/v5 v5.10.0` | 原生 pgxpool、固定只读 SQL;实库 SRID 严格 readiness 已通过 | | AI 集成 | SuperAgent Open API Adapter + MCP `2025-06-18` | 协议代码已实现并默认关闭;真实环境待联调 | 引入依赖前优先核对官方版本、Go 版本要求、维护状态、许可证和可替代性。核心依赖升级需要独立验证,不能只修改版本号。 ## 2. 目录职责和依赖方向 ```text 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 设计 - 包名短、小写、表达单一能力,不使用 `utils`、`common`、`base` 等无边界集合。 - 导出标识符必须有稳定的外部使用场景;默认保持在 `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 分离 `CreateSession` 与 `StreamMessage`;上层负责持久化本地会话映射,不能每轮隐式创建新 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. 测试与验证 基础命令: ```bash gofmt -w ./cmd ./internal go test ./... ``` 按风险增加: ```bash 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、接口、安全和相关设计文档已同步。