diff --git a/docs/task/200-Admin增加管理员AI服务商与模型配置.md b/docs/task/200-Admin增加管理员AI服务商与模型配置.md new file mode 100644 index 0000000..ef9d4af --- /dev/null +++ b/docs/task/200-Admin增加管理员AI服务商与模型配置.md @@ -0,0 +1,68 @@ +# 200 Admin:增加管理员 AI 服务商与模型配置 + +- 类型:需求 +- 父级大工单:#14 +- 所属 MVP / 版本:#199 / AI规格批量匹配 +- 状态:已完成 +- 日期:2026-08-14 +- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/200 + +## 背景与目标 + +AI 规格匹配需要在不重新发布 Admin 的情况下切换 OpenAI 兼容服务商和模型,同时确保 +API Key 不进入数据库、`data/`、日志、页面响应、工单或文档。配置入口及全部写操作仅 +允许管理员使用。 + +## 最终方案 + +- 使用 MySQL v20 保存服务商普通配置和非敏感操作审计;生成列唯一索引保证最多一个 + 服务商处于启用状态。 +- 增加 `AISecretStore`,把 API Key 写入部署指定的绝对路径。写入使用同目录临时文件、 + `fsync`、原子替换和 `600` 权限;页面只展示是否配置及尾四位掩码。 +- 增加仅管理员可访问的服务端渲染配置页,支持新增、编辑、替换/清除密钥、连接测试和 + 启停。普通配置或密钥变化后会停用并要求重新测试。 +- 外部端点只允许 HTTPS;拒绝 URL 凭据、环回、链路本地、元数据和未允许的私网地址, + 并在 DNS 解析、实际拨号和重定向阶段重复校验。私有端点只能通过部署静态允许列表开放。 +- 连接测试发送不含订单、店铺、用户和 Client 信息的最小请求,不保存完整响应。 + +## 改了哪些 + +- `admin/config.example.yaml`、`admin/config/config.go`:增加密钥路径和私有端点允许列表。 +- `admin/model/model.go`、`admin/repository/ai_config.go`、`admin/repository/mysql_db.go`: + 增加 AI 配置、审计模型和 MySQL v20 迁移、自检。 +- `admin/service/ai_secret.go`、`admin/service/ai_config.go`:实现密钥隔离、配置业务规则、 + 连接测试和 SSRF 防护。 +- `admin/handler/web/ai_config.go`、`admin/handler/web/web.go`、`admin/templates/ai/list.html`: + 增加管理员配置页面及全部操作。 +- `admin/*_test.go`、`admin/service/*_test.go`、`admin/repository/mysql_db_integration_test.go`: + 增加权限、模板、密钥、端点安全和迁移测试。 +- `docs/admin/`:同步需求、架构、数据模型、界面和安全基线。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 管理员可管理、测试和启停服务商,且最多一个启用项 | 通过(代码和自动化测试) | +| 采购员页面和全部写接口被服务端拒绝 | 通过 | +| API Key 不回显,只显示掩码尾号 | 通过 | +| 密钥不进入数据库、`data/`、日志和页面 | 通过(代码及假密钥测试) | +| 密钥原子写入且失败不破坏旧值 | 通过(单元测试);生产 Linux 路径待部署验证 | +| 测试失败不切换当前配置,成功后可热启用 | 通过 | +| 不安全 URL 和未允许私网地址被拒绝 | 通过 | +| 审计仅记录操作者、时间和非敏感内容 | 通过 | +| MySQL 8.4 `_test` 迁移和自检 | 未验证:本机未启用隔离测试库 | +| 固定 Go 1.23.0 build、test、vet | 通过 | + +## 测试 + +- 执行的命令: + - `go test ./config ./service ./repository` + - `go test . -run "Test(AI|MainPages)" -count=1` + - `$env:GOTOOLCHAIN="go1.23.0"; go build ./...; go test ./... -count=1; go vet ./...` +- 结果:固定 Go 1.23.0 的构建、全量测试和静态检查全部通过。 +- **没验证到的部分**:未连接 MySQL 8.4 `_test` 实库;未在生产 Linux 上验证 + `/etc/cmautobuy/ai-secrets.yaml` 的最终属主、权限和服务进程读写权限;未调用真实模型。 + +## 相关提交 + +- `018da3f` feat: 增加管理员 AI 模型配置 (#200)