docs: record upstream model config fix
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
- 测试:T-601 已验证:`.\init.ps1` 通过(Python 3.12.3,依赖已满足,`manage.py check` 0 issues,打印启动命令);`py -3.12 -m py_compile apps\ai\catalog.py apps\api\views.py apps\api\urls.py apps\api\tests.py apps\portal\views.py apps\portal\urls.py apps\portal\tests.py` 通过;`py -3.12 manage.py check` 通过;`py -3.12 manage.py makemigrations --check --dry-run` 无变化;`git diff --check` 通过;`py -3.12 manage.py test apps.api.tests.ModelsCatalogApiTests apps.portal.tests.PortalAccountFlowTests.test_models_page_requires_session_login apps.portal.tests.PortalAccountFlowTests.test_models_page_lists_public_aliases_prices_and_unpriced_state --keepdb --noinput --verbosity 2` 首次运行时 3 条 API 测试已通过,portal `setUpClass` 阶段因远程 MySQL 连接 43.128.3.240 超时中断;随后 `Test-NetConnection 43.128.3.240 -Port 3306` 显示 `TcpTestSucceeded=True`,单独重跑两条 portal 测试通过,2 tests OK。T-403 已验证:`./init.ps1` 开工前通过;`py -3.12 manage.py check` 通过;`py -3.12 manage.py makemigrations --check --dry-run` 无变化;`py -3.12 manage.py findstatic portal/vendor/bootstrap/bootstrap.min.css portal/vendor/qrcode/qrcode.js --verbosity 1` 找到两个本地 static 文件;`py -3.12 manage.py check --deploy` 在当前开发 `.env` 下仅报预期安全配置警告,临时注入生产型安全环境变量(含 HSTS includeSubDomains/preload)后通过,0 issues;`py -3.12 manage.py collectstatic --dry-run --noinput` 通过,预期收集 169 个 static 文件;`py -3.12 manage.py createcachetable --dry-run cmhub_cache` 通过,输出 MySQL cache 表 DDL;`py -3.12 -m compileall config` 通过;尝试 `py -3.12 manage.py test apps.api --noinput --keepdb --verbosity 2` 时 25 条用例已通过,`GenerateApiTests` 14 条因远程 MySQL 连接重置/事务中断被记 ERROR,随后 `Test-NetConnection 43.128.3.240 -Port 3306` 端口可达,单独重跑 `py -3.12 manage.py test apps.api.tests.GenerateApiTests --noinput --keepdb --verbosity 2` 通过,14 tests OK。测试/迁移阶段仍有 allauth `account.EmailAddress` 条件唯一约束在 MySQL 上不可创建的 `models.W036` 警告;本项目用户账本邮箱唯一性由 `user.email` 唯一约束承担。
|
||||
- 最新验证:T-605 免邮箱验证策略已验证 `py -3.12 -m py_compile config\settings.py apps\portal\tests.py` 通过;`py -3.12 manage.py check` 通过,0 issues;`py -3.12 manage.py makemigrations --check --dry-run` 通过,No changes detected;更新后的注册 / 登录目标测试 3 tests OK;`py -3.12 manage.py test apps.portal --keepdb --noinput --verbosity 2` 通过,26 tests OK;`git diff --check` 通过,仅 Windows CRLF 提示。全量 `py -3.12 manage.py test --keepdb --noinput --verbosity 2` 已尝试,发现 131 tests,跑到 95 tests 后远程 MySQL `43.128.3.240` 出现连接超时 / WinError 10051,最终 22 errors;随后 `Test-NetConnection 43.128.3.240 -Port 3306` 显示 `TcpTestSucceeded=True`,单独复跑失败起点的 billing 分组时 17 条业务用例 OK,并发扣点用例本体打印 `ok` 后在测试库 flush 阶段再次因 MySQL 连接超时 / WinError 10060 记 ERROR。结论:T-605 相关测试已通过,全量单次绿受远程 MySQL 稳定性阻塞。
|
||||
- 最新验证:T-604 中文敏感词本地过滤已验证 `py -3.12 -m py_compile config\settings.py apps\api\generation.py apps\api\tests.py apps\moderation\apps.py apps\moderation\models.py apps\moderation\normalization.py apps\moderation\policy.py apps\moderation\services.py apps\moderation\signals.py apps\moderation\versioning.py apps\moderation\providers\base.py apps\moderation\providers\keyword.py apps\moderation\tests.py` 通过;`py -3.12 manage.py check` 通过,0 issues;`py -3.12 manage.py makemigrations --check --dry-run` 通过,No changes detected;`py -3.12 manage.py test apps.moderation --keepdb --noinput --verbosity 2` 通过,7 tests OK;新增生成接口目标测试 2 tests OK;`py -3.12 manage.py test apps.api.tests.GenerateApiTests --keepdb --noinput --verbosity 2` 通过,16 tests OK。测试期仅保留 allauth 在 MySQL 条件唯一约束上的既有 `models.W036` 警告。
|
||||
- 线上 AI 标题生成缺陷:2026-07-06 拉取最新代码并重启后,用 `api_key.txt` 第二个 Key(脱敏)联调 `https://cm.833729.com`:`GET /api/v1/balance` 成功并返回 `account`,`GET /api/v1/models` 显示 `title-standard` 已启用且 `pricing_status="priced"`、默认单价 1 点;但 `POST /api/v1/generate/title` 返回 `502 upstream_error` / 「上游模型配置不可用」。失败后复查余额仍为 1010,未扣点。结论:API Key、base URL、别名与计费规则正常,问题在服务端 `title-standard` 对应 `AiModel` 运行配置,优先检查 `AI_KEY_ENCRYPTION_KEY`、API Key 解密、`url`、`model`、`api_type` 与 Provider 支持;修复步骤已写入 `deployment.md`。
|
||||
- 线上 AI 标题生成缺陷已修复:2026-07-06 用当前线上 `AI_KEY_ENCRYPTION_KEY` 重新导入 `/secure/cmhub/ai_models.json`,修复 `title-standard` 对应 `AiModel.api_key_encrypted` 无法解密的问题。验证:`python3.12 manage.py check` 通过;`python3.12 manage.py smoke_ai_generation title` 真实调用成功,`model_used=gpt-5.5`,耗时约 16.9s,返回 3 个标题;用 `api_key.txt` 第二个 Key 调 `POST https://cm.833729.com/api/v1/generate/title` 成功返回 5 个标题,`points_cost=1`,余额从 1010 扣到 1009。
|
||||
- 线上热修验证:`/admin/billing/exchangerate/` 500 根因是 `ExchangeRateAdmin.date_hierarchy` 触发 MySQL `CONVERT_TZ`,而生产 MySQL 未加载时区表,Django 抛 `ValueError: Database returned an invalid datetime value`;已移除 `apps.billing.admin` 中 4 个 DateTime `date_hierarchy`,保留 `list_filter` 日期筛选。验证 `py -3.12 -m py_compile apps\billing\admin.py apps\billing\tests.py`、`py -3.12 manage.py check`、`py -3.12 manage.py test apps.billing.tests.BillingAdminTests.test_exchange_rate_changelist_renders_when_rates_exist --keepdb --noinput --verbosity 2` 均通过。
|
||||
- Mock 支付提示:`PAYMENT_CALLBACK_MODE=mock` 时,用户端 `/recharge` 的待支付订单区域会显示醒目测试模式提示,说明二维码只用于联调订单创建、页面渲染和状态轮询,不能使用微信或支付宝真实付款;`sdk` 模式不显示该提示。验证 `py -3.12 -m py_compile apps\portal\views.py apps\portal\tests.py`、`py -3.12 manage.py check`、`py -3.12 manage.py test apps.portal.tests.PortalAccountFlowTests.test_recharge_page_post_creates_pending_order_without_crediting_wallet_or_ledger apps.portal.tests.PortalAccountFlowTests.test_recharge_page_does_not_show_mock_notice_in_sdk_mode --keepdb --noinput --verbosity 2` 均通过。
|
||||
- 微信正式下单热修:线上微信 Native 下单失败根因是 `wechatpayv3` SDK 需要显式 `pay_type=WeChatPayType.NATIVE`,且成功响应为 `(status_code, json_string)` tuple 而非 dict;已兼容 tuple/json 响应并覆盖下单与主动查单。线上用修复后的 `_create_wechat_payment_order_with_sdk()` 创建 1 分诊断预支付请求,确认返回 `weixin://wxpay/bizpayurl` 票据。另:pending 订单主动查单异常不再让 `/api/v1/recharge/status` 返回 500,而是保持当前订单状态返回 200。
|
||||
@@ -29,7 +29,7 @@
|
||||
- 标准验证路径:Windows 用 `py -3.12 manage.py check` / `py -3.12 manage.py test`
|
||||
- 设计基线:**自助用户端 + 对外 API + 运营后台**三合一单体;用户模型 `User`(auth)/`UserWallet`(点数,锁 wallet 扣点)/`ApiKey`(1:N,哈希存储);对外两接口 + **能力别名 + Provider 适配器**(可插拔供应商);自助扫码充值;注册不送点数。详见 `04-architecture.md` 与 2026-06-29 / 2026-07-01 的 `progress.md` 决策
|
||||
- 配置基线:运行环境变量集中见 `docs/env.md`;真实密钥/支付凭证不得写入代码或文档样例。用户端注册策略固定为 `ACCOUNT_EMAIL_VERIFICATION="none"`:免邮箱验证、注册即可用、邮箱仍必填且唯一;`DJANGO_EMAIL_BACKEND` / `DJANGO_DEFAULT_FROM_EMAIL` 仅用于后续密码找回、通知或恢复邮箱验证等邮件能力,不作为当前注册登录前置条件。充值订单在创建时锁定汇率与预计点数,回调入账使用订单值,不按新汇率重算。支付回调与下单由 `PAYMENT_CALLBACK_MODE` 控制:本地/测试可用 HMAC `mock`,生产应为 `sdk`;二维码本地有效期提示由 `PAYMENT_QR_EXPIRES_MINUTES` 控制。T-306 起对外 API 安全配置包含 `API_GENERATE_THROTTLE_RATE`、`API_AUTH_FAILURE_THROTTLE_RATE`、`IMAGE_URL_MAX_BYTES`、`IMAGE_URL_MAX_REDIRECTS`、`IMAGE_URL_CONNECT_TIMEOUT_SECONDS`、`IMAGE_URL_READ_TIMEOUT_SECONDS`、`RECHARGE_MAX_AMOUNT_CNY`。T-403 起生产静态、共享 cache 与 HTTPS 安全配置包含 `STATIC_URL`、`STATIC_ROOT`、`DJANGO_CACHE_BACKEND`、`DJANGO_CACHE_LOCATION`、`DJANGO_CSRF_TRUSTED_ORIGINS`、`DJANGO_SESSION_COOKIE_SECURE`、`DJANGO_CSRF_COOKIE_SECURE`、`DJANGO_SECURE_SSL_REDIRECT`、`DJANGO_SECURE_PROXY_SSL_HEADER`、`DJANGO_SECURE_HSTS_SECONDS`。T-604 起内容安全配置包含 `MODERATION_ENABLED`、`MODERATION_PROVIDER=keyword`、`MODERATION_FAIL_CLOSED`、`MODERATION_BLOCK_ON_REVIEW`、`MODERATION_CACHE_VERSION_KEY`;生产多 worker 下必须使用共享 cache 承载敏感词版本号。
|
||||
- 当前 blocker:T-603 不再受邮箱验证口径阻塞;剩余阻塞是远程 MySQL 测试库长跑稳定性,完整测试需预留较长时间并优先用 `--keepdb` 串行跑,必要时改用更稳定的测试库。微信正式下单已能返回二维码,但线上微信回调曾出现 `PaymentVerificationError`,仍需单独修复并完成“付款后自动入账”闭环验收;支付宝恢复依赖开放平台把 `43.128.3.240` 加入可信 IP。线上真实标题生成已复现 `upstream_error: 上游模型配置不可用`,需先修复 `title-standard` 对应 `AiModel` 的加密密钥/API Key/URL/model/api_type/provider 配置,再跑真实 `smoke_ai_generation title` 与接口验收。图片同步真实耗时风险仍未退,T-403 已在 `deployment.md` 明确上线前必须记录真实图片 smoke 耗时;未跑通前只能按保守超时内测,不能声称已验证。
|
||||
- 当前 blocker:T-603 不再受邮箱验证口径阻塞;剩余阻塞是远程 MySQL 测试库长跑稳定性,完整测试需预留较长时间并优先用 `--keepdb` 串行跑,必要时改用更稳定的测试库。微信正式下单已能返回二维码,但线上微信回调曾出现 `PaymentVerificationError`,仍需单独修复并完成“付款后自动入账”闭环验收;支付宝恢复依赖开放平台把 `43.128.3.240` 加入可信 IP。线上真实标题生成已跑通并验证扣点;图片同步真实耗时风险仍未退,T-403 已在 `deployment.md` 明确上线前必须记录真实图片 smoke 耗时;未跑通前只能按保守超时内测,不能声称已验证。
|
||||
|
||||
## 当前目录要点
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
- 已完成:T-001 初始化 Django + DRF 项目骨架;T-002 建立 apps 目录、自定义 User 与配置;T-003 接通 django-admin 与最小测试;T-004 Phase 0 骨架审核修补;T-101 Provider 适配器层 + 移植 cmbot 调用;T-102 AiModel + ModelAlias 模型 + 别名解析;T-103 配置变更审计;T-104 跑通一次录制标题生成;T-105 Phase 1 AI 层审核修补;T-201 User / UserWallet / ApiKey / PointsLedger / CallRecord 模型;T-202 PricingRule / ExchangeRate 模型 + 计费计算;T-203 并发安全扣点 / 退点;T-204 Phase 2 计费核心审核加固;T-301 API Key 鉴权;T-302 生成标题 / 图片接口;T-303 余额查询接口;T-304 充值回调;T-305 扫码充值下单 + 轮询;T-306 Phase 3 对外 API 安全加固;T-501 注册 / 登录(allauth);T-502 API Key 自助管理页;T-503 个人中心 / 记录页;T-504 充值页(扫码 + 轮询到账);T-505 Phase 4 用户端审核优化;T-401 运营后台完善;T-402 完整验收 MVP;T-403 部署 / 运行文档;T-601 可用别名发现;T-602 django-admin 中文化(第 1-3 层);T-604 中文敏感词本地过滤;T-605 免邮箱验证策略落地。
|
||||
- 正在进行:无。
|
||||
- 待开始:T-603 待在稳定 MySQL 测试库上补跑完整验证;之后可继续处理真实支付、AI 模型导入与真实图片耗时验证,或从 Backlog 拆新任务。
|
||||
- 当前 blocker:T-603 的字段级中文化代码/迁移已完成,邮箱验证口径已由 T-605 解封;当前只剩远程 MySQL 长跑稳定性阻塞完整测试单次全绿。支付商户真实密钥/证书与生产 SDK 依赖仍待提供;真实 AI 标题生成已在线上复现 `upstream_error: 上游模型配置不可用`,需先修复模型运行配置后再执行真实 smoke。
|
||||
- 当前 blocker:T-603 的字段级中文化代码/迁移已完成,邮箱验证口径已由 T-605 解封;当前只剩远程 MySQL 长跑稳定性阻塞完整测试单次全绿。支付商户真实密钥/证书与生产 SDK 依赖仍待提供;真实 AI 标题生成已在线上跑通,图片生成真实耗时仍需补测。
|
||||
- 下一个可领取任务:T-603 补跑完整验证并根据结果收尾。
|
||||
|
||||
## 当前可运行内容
|
||||
|
||||
+17
@@ -1338,3 +1338,20 @@
|
||||
- `docs/api.md`:补充 `upstream_error` + 「上游模型配置不可用」的判定口径。
|
||||
- `docs/deployment.md`:新增 AI 上游配置故障处理步骤、shell 诊断命令和验收路径。
|
||||
- `docs/current-state.md`:记录线上复现结果,并把真实 AI blocker 从“待验证”改为“已复现模型配置不可用,需修模型运行配置”。
|
||||
|
||||
## 2026-07-06 线上修复:重新导入 AI 模型密钥并跑通标题生成
|
||||
|
||||
- 根因确认:VPS 上 `AI_KEY_ENCRYPTION_KEY` 已配置且长度正常,`title-standard` 别名、`AiModel.url`、`model`、`api_type`、`capabilities` 均存在,但 `model.to_resolved_model()` 抛 `AiKeyEncryptionError: AI api_key cannot be decrypted`。说明数据库里的 `AiModel.api_key_encrypted` 是旧 Fernet key 加密或与当前线上 key 不匹配。
|
||||
- 修复动作:
|
||||
- 本机确认 `D:\chengma\cmhub\ai_models.json` 含 `GPT-5.5 文本`、`GPT Image 2`、`Nano Banana 2` 三个 vectorengine 模型配置,且每项均有 API Key;检查过程不打印 key。
|
||||
- 在 VPS 创建 `/secure/cmhub`,权限 `700`;上传 `ai_models.json` 到 `/secure/cmhub/ai_models.json`,文件权限 `600`,不入 git。
|
||||
- 执行 `python3.12 manage.py import_ai_models /secure/cmhub/ai_models.json`,用当前线上 `AI_KEY_ENCRYPTION_KEY` 重新加密入库;结果 `created=1, updated=2, aliases=0`,未改现有默认别名。
|
||||
- 重新诊断 `title-standard`:`to_resolved_model()` 成功,`resolved_has_api_key=True`,`get_provider()` 成功,provider 为 `ChatCompletionsProvider`。
|
||||
- 重启 `cmhub-web.service` 与 `cmhub-generate.service`,两者均 `active`。
|
||||
- 验证:
|
||||
- `python3.12 manage.py check`:通过,0 issues。
|
||||
- `python3.12 manage.py smoke_ai_generation title`:真实调用成功,`model_used=gpt-5.5`,`elapsed_ms=16865`,`title_count=3`。
|
||||
- 用 `api_key.txt` 第二个 Key 调线上 `/api/v1/balance`:修复前余额 1010。
|
||||
- 调 `POST https://cm.833729.com/api/v1/generate/title`:成功返回 5 个中文标题,`alias=title-standard`,`model_used=gpt-5.5`,`points_cost=1`,`points_balance=1009`,`call_id=1`。
|
||||
- 再查 `/api/v1/balance`:余额 1009,确认真实扣点闭环正常。
|
||||
- 结论:标题生成的「上游模型配置不可用」已修复。后续仍需补测图片生成真实耗时与微信支付回调到账闭环。
|
||||
|
||||
Reference in New Issue
Block a user