From d734ed6d2a4512bd802d47302a3dcb6f5060a387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Wed, 14 Oct 2026 10:10:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20resolver=E5=9B=9E=E9=80=80=E9=93=BE?= =?UTF-8?q?=E6=8E=A5=E5=85=A5platform=5Fsettings=EF=BC=88=E4=B8=89?= =?UTF-8?q?=E7=BA=A7=E5=9B=9E=E9=80=80/=E5=BF=AB=E7=85=A7=E7=83=AD?= =?UTF-8?q?=E5=88=B7=E6=96=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app/platform/settings_store.py 新模块: lifespan 启动把 platform_settings 全表快照进进程内存(load_snapshot/get/refresh,workers=1 单进程纪律); PUT /api/platform/settings 提交后 refresh 热刷新,回退链即时生效 - config_views email/ai 两组改三级回退: 租户槽位 → 平台设置快照 (键名对齐平台设置页推荐键 ai.*/smtp.*)→ env settings(env 键名 不变做最终兜底);push 无平台推荐键保持两级;smtp.port 自由 KV 容错 归一(数字串转 int,脏值视同未设置落 env) - conftest autouse 复位快照(resolver 直调测试隔离);新增 test_platform_settings_fallback 六测(启动装载/三级链/端口容错/ push 不接线钉死/PUT 即时生效) - 平台设置页"仅存储"注记移除(CLAUDE.md 与前端页头同步改为已接线) - 回归: 后端 627 passed(621+6)/ 前端 vitest 156 / build 零错误 Co-Authored-By: Claude Code --- CLAUDE.md | 4 +- admin/src/views/settings/platform/index.vue | 12 +- admin/src/views/settings/platform/model.ts | 8 +- app/main.py | 5 + app/platform/config_views.py | 75 ++++++-- app/platform/routes/config_routes.py | 14 +- app/platform/settings_store.py | 63 +++++++ tests/conftest.py | 11 ++ tests/test_platform_settings_fallback.py | 186 ++++++++++++++++++++ 9 files changed, 341 insertions(+), 37 deletions(-) create mode 100644 app/platform/settings_store.py create mode 100644 tests/test_platform_settings_fallback.py diff --git a/CLAUDE.md b/CLAUDE.md index 2a493b9..b9a01a8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -123,7 +123,7 @@ - 会话与线索:列表(筛选 / 分页 / 租户切换)/ 详情消息流 / 推送日志 / 删除。 - 配置中心:品牌(表单 / 本地简化预览 / 嵌入代码 / 头像上传)、提示词四件套与结构化词表、试金石面板、凭据(邮件 / 推送 / AI 表单 + SMTP 测试 + 推送探测)、contact/engine/misc 三组通用 JSON 编辑(终审 I-1 补齐 spec §7.3 全组覆盖)、版本历史(两版对比 / 回滚 / 组级重置出厂)。 - 统计分析:卡片 / 转化漏斗 / 按日趋势 / 意向·来源·站点·国家分布(ECharts)/ 推送健康表;时间与租户筛选(口径同 stats.py docstring 口径表)。 -- 平台设置(仅超管):自由 KV 表的推荐键表单(ai.* / smtp.*,键名是前端约定)+ 存储总览表格;保存 = 逐键 PUT(只提交脏键)。**当前仅存储与展示——resolver 的平台默认回退链未接线(页头注记),引擎不读取这些值**;密钥键掩码哨兵交互与凭据页同款(清除 / 恢复保持)。 +- 平台设置(仅超管):自由 KV 表的推荐键表单(ai.* / smtp.*,键名是前端约定)+ 存储总览表格;保存 = 逐键 PUT(只提交脏键)。**Phase 4 Task 5A 起推荐键已接线 resolver 平台默认回退链(租户槽位 → 平台设置快照 → env),保存后即时生效**;密钥键掩码哨兵交互与凭据页同款(清除 / 恢复保持)。 **前端实现约定**(后续维护须知): @@ -146,7 +146,7 @@ 2. 推送探测 env 回退真址:租户 push URL 空槽时 `resolve_push_settings` 回退 env `PUSH_API_URL`(默认即真 UniService 生产址)——后台点「探测」会对真实服务发空批量 POST(`{"messages": []}`,按契约文档应为无操作,但属真实出站)。收口 = 部署设 stub 域或探测端点拒绝 env 回退 URL。 3. 生产反代需规划 admin 域的头像/品牌公开端点:`/api/public/*` 按租户 Host 解析,admin 域直挂必 404——开发期靠 Vite Host 改写代理,生产要么同源反代改 Host(单租户形态)要么前端改用租户域名绝对 URL。 4. `VITE_TENANT_PREVIEW_HOST` 单一预览域名:开发代理只指向一个租户 Host,切换租户时头像等公开资源预览不准(.env.development 已注记)。 - 5. **resolver 平台默认回退链接入 platform_settings**(终审 I-3 记档):平台设置当前仅存储与展示(admin 页头有注记),引擎不读取——回退链接线是 Phase 4 的功能项。 + 5. ~~resolver 平台默认回退链接入 platform_settings~~(Phase 4 Task 5A 完成:`app/platform/settings_store.py` 内存快照 + lifespan 装载 + PUT settings 后 refresh 热刷新;config_views 的 email/ai 两组改三级回退(租户槽位 → 平台设置快照 → env),push 无平台推荐键保持两级;平台设置页"仅存储"注记移除)。 6. **email/test 与 push/test 速率限制**(终审 I-3 记档):两测试端点无限流,复用登录限流器模式收口。 7. **锁屏功能已摘除入口**(终审 M-1):用户菜单项删除 + 全局组件 enabled:false 不再挂载(AES 存 localStorage + 公开模板默认密钥,防御价值为零);代码待 Phase 4 决定删否。 8. **租户切换器 composable 收拢**(终审 M-3 不做记档):仪表盘/会话/配置三页各自内联实现同一模式,收拢归后续。 diff --git a/admin/src/views/settings/platform/index.vue b/admin/src/views/settings/platform/index.vue index 73be125..2bd8ff1 100644 --- a/admin/src/views/settings/platform/index.vue +++ b/admin/src/views/settings/platform/index.vue @@ -10,19 +10,11 @@ '__SET__' → 输入框留空 + 占位符「已设置,输入新值覆盖」;不动不提交; 「清除」按钮 = 显式清空意图(提交空串),可「恢复保持」撤销。 - 页头注记(CLAUDE.md Phase 3 取舍):resolver 的平台默认回退链尚未接入 - platform_settings——本页现阶段仅存储与展示,引擎不读取这些值。 + 回退链已接线(Phase 4 Task 5A):ai.*/smtp.* 推荐键经后端内存快照接入 + resolver 的平台默认回退链(租户槽位 → 平台设置 → env),保存后即时生效。 -->