docs: 归档任务 #200

This commit is contained in:
chengma
2026-08-14 09:49:55 +08:00
parent 018da3f732
commit 2f51126e1d
@@ -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)