Commit Graph

44 Commits

Author SHA1 Message Date
浅念 323588c54d feat(admin): site-import API 与模型纯函数
Task 8(TDD):草稿包→表单/保存序列/warnings 分级纯函数 + POST/GET
API 薄封装。事实源 app/platform/routes/site_import_routes.py(GET 五键
无 failed_phase——retry 对 failed 一律展示后端 409 兜底)与 generator.py
build() 的 spec §4 草稿包形状。保存序列沉淀 spec §5 顺序语义(brand 的
GET 在头像上传之后)与 deflections_contact 池形态分派注记,Task 9 装配
消费。前端 vitest 188 → 201。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-20 21:56:05 +08:00
浅念 e1eae007b4 feat(admin): 创建向导域名可跳过(纯路径模式租户)
步骤②本就无强制域名校验(validateWizardStep 只门控步骤 0/2,
提交侧 filter(Boolean) 空列表即 domains:[],后端 default_factory=list
默认空)——本次只补文案引导:ElStep 标题加(可跳过)、步骤内 tip 写明
留空即共享域名路径模式租户(嵌入代码在配置中心-品牌与外观生成)、
头注释同步。向导无摘要步骤,域名数 0 展示属正常,均无需改动。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-19 19:37:35 +08:00
浅念 5813fc91c7 feat(admin): 嵌入代码双形态 + shared_widget_domain 平台键
- 后端 GET /api/platform/settings/widget-domain:读平台设置键
  shared_widget_domain(settings_store 内存快照,PUT settings 后热刷新
  即时可见);platform_user 两种角色可读(超管配置/租户管理员生成嵌入
  代码——与 settings CRUD 的 require_super 不同,非密钥无敏感面);
  空串/非字符串视同未配置 → null
- config/center 嵌入卡双形态(spec 2026-10-19 §5):域名形态 +
  共享域名形态(/t/<slug>/static/widget.js,路径前缀即租户标识);
  可用性规则(两料齐双形态/无域名仅共享/共享未配仅域名/都无引导文案)
  与生效态回退;data-site 两形态通用
- normalizeSharedDomain 主机名字符集校验(拒引号/尖括号/空格——防
  配置侧把恶意字符注入生成的 script src 串)+ buildEmbedCode 纯函数,
  vitest 6 例钉位
- 平台设置页新增「共享域名」组(shared_widget_domain 推荐键,表驱动
  渲染自动生效);settings API 模块加 getWidgetDomain

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-19 19:24:56 +08:00
浅念 6d6d8a8e32 chore: Batch 4 收口——终审 Minor 处置记档 + WallAdvanced 注释修正
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 21:56:02 +08:00
浅念 1df1fc7922 fix(admin): 重建 watch 补 slug 源(防缺组租户切换草稿泄漏)
c6bd542 拆分后的分组 watch 只盯组 props 引用——seed 租户快照可能缺组
(如无 ai/contact/misc 组),两家租户都缺时切租户该组 prop 走
undefined→undefined 引用不变、watch 不触发,上一家租户的草稿留在当前
租户界面(dirty 也残留)。旧的全量耦合顺带防住了它,拆分后暴露。

修复:六个 pane 的重建 watch 源统一加 () => props.slug 兜底——slug 变化
即强制重建(缺组时空槽归位、dirty 归 false);单卡保存路径不受影响
(组引用照常换新触发)。覆盖 CredsPane 三卡 + WallPane / PromptsPane /
ContactFormPane / EngineFormPane / MiscFormPane(均已声明 slug prop,
index.vue 挂载处均已传 activeSlug,零接线改动)。

顺手:CredsPane 测试态注释仍提已删除的 resetAll → 改提三卡 watch;
计划文档 Task 15 段落末补 Batch 1 遗留打磨项处置注记(色列宽度/头像
提示样式经 Task 16 走查目检后定夺)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 21:40:29 +08:00
浅念 c6bd54229d fix(admin): CredsPane 单卡保存不再联动重置兄弟卡
旧 array-source watch 盯 [emailGroup, pushGroup, aiGroup] 三元数组——任一
组引用变化即 resetAll 三卡齐重建:单卡保存(如 email)后父层 onPaneSaved
换整份快照引用,push/ai 卡上未保存的编辑被静默丢弃(Task 14 评审挂账)。

改为三表各自 watch 本组 props 引用:父层保存回写是 {...snapshot, [group]:
config} 展开——只有被保存组引用换新,兄弟组引用不动 → 只重建该卡;切租户/
回滚时快照先置 null 再整份换新,三组引用齐变 → 三卡全量重置(行为保持)。
resetAll 相应拆为 resetEmailCard / resetPushCard / resetAiCard(备注/错误/
测试态随所属卡重置)。

自查两场景:改 email 保存 → push 草稿与 dirty 均保留;切租户 → 三卡齐重置。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 21:23:18 +08:00
浅念 f92a4be139 polish(admin): 各页空态与文案轻量打磨
- 会话列表/推送日志表空态给动作指引(empty-text,不再落 Element 默认「暂无数据」)
- 统计六图空态文案经 useChart 新增 emptyText 参数下发「暂无数据——产生会话后展示分析」
  (textContent 替代 innerHTML,缺省值不变,其余消费方零影响)
- 平台设置存储总览空表指引「暂无设置项——从上方推荐键开始」
- 租户详情站点表空态指引「暂无站点——点右上角「新建站点」创建」
- CredsPane 邮件测试 hint 的字面 **已保存** 星号改 <b>(模板不吃 markdown)
- 品牌预览卡右侧副标去掉与新增副标题重复的「本地简化」字样
- 仪表盘/租户列表/会话页既有 ElEmpty 已是动作指引文案,核对后无需改动

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 21:21:53 +08:00
浅念 26dc93bc31 fix(admin): 头像上传基线只回写持久化字段(防脏检测假阴性)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 21:14:23 +08:00
浅念 e2aa166701 fix(admin): 脏保护三缺陷(brand 丢弃空操作/头像假脏/取消高亮错位)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 21:08:57 +08:00
浅念 edf58ce0a0 feat(admin): 未保存离开保护(Batch 3 收口)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 20:42:18 +08:00
浅念 250ffdfa53 feat(admin): contact/engine/misc 表单 pane + JsonGroup 退役
Task 13(feature/config-ux Batch 3):contact/engine/misc 三组从通用
JSON 整组编辑退役为专用表单卡——ContactFormPane(双开关 + 模板语言)、
EngineFormPane(限流数值 + context_seed_keys 高级折叠)、MiscFormPane
(国名 → 区号行编辑),共用新 KeyValueEditor 行编辑器(直改 reactive
rows,与 ScenarioCard 同契约);JsonGroupPane.vue 删除,model.ts 通用
JSON 组区块(JsonGroupKey/jsonGroupDraft/parseJsonGroupDraft/
JSON_GROUP_FIELDS)与对应测试一并退役;rowsToRecord/recordToRows 补
JSDoc(Task 12 评审折入)。

vitest 182 passed(185 − 3 旧 JSON 组用例);vue-tsc + vite build 零错误。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 20:23:26 +08:00
浅念 4dd74d6682 feat(admin): contact/engine/misc 表单映射纯函数
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 20:03:09 +08:00
浅念 8b430565d6 feat(admin): PromptsPane 重组(company_facts 主面+引擎级折叠)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 19:50:03 +08:00
浅念 12b8dab5f0 feat(admin): WallPane 重组为场景卡+高级折叠(Batch 2 收口)
- 主面换 ConfigCard 卡壳:WALL_SCENARIOS 双状态场景卡 + no_contact 三键
  白话行编辑 + cc_templates 四组封闭语言集 + 试金石面板(整块平移)
- 高级区 WallAdvanced 挂载(正则/单正则/reminders,默认折叠);旧池区/
  正则区/提醒区/旧 collapse 结构与失效辅助全部删除(grep 零残留)
- 保存链加模板变量保护:collectRemovedWallVariables 集差检出被删的
  {intl}/{shown} 等运行期占位符 → ElMessageBox 二次确认(先于试金石)
- emits 追加 navigate;index.vue WallPane 挂载处接线 @navigate
- ScenarioCard 评审折入:requiredMissing 收紧(空白行保留但两池全空的
  必留语言也预警);× 删除钮键盘可达(role/tabindex/enter/space);
  addLang 严格正则注记(异常存量语言码可显示可删不可重加)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 19:34:31 +08:00
浅念 0553ccc32c feat(admin): WallAdvanced 高级折叠区(正则/提醒迁移)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 19:20:58 +08:00
浅念 ab0cf9f64e feat(admin): WallScenarioCard 双状态场景卡组件
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 19:08:59 +08:00
浅念 36fe534029 fix(admin): 变量集差替代配对递归(删尾行/整键检出)+ 标签契约钉位
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 19:03:36 +08:00
浅念 2e6811a55b feat(admin): wall 重组辅助纯函数(场景卡/语言并集/模板变量保护)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 18:49:04 +08:00
浅念 680c4bade6 feat(admin): 品牌卡套视觉基线(Batch 1 收口)
- 品牌表单 ElCard → ConfigCard(图标/副标题/信息条/footer/danger 行);
  表单双列 grid(标题|主色、WhatsApp|邮箱 同排;头像/欢迎语/话题/占位/隐私 span-2);
  保存备注移 footer-right、重置出厂移 #danger(既有 resetting/onResetBrand 逻辑不动)
- 预览卡头加副标题「本地简化预览(真机效果以嵌入站点为准)」(cc-subtitle 观感)
- CredsPane 挂载处补 @navigate=onGroupSelect 接线;email 卡 info 去「带 • 的」前缀
  (push/ai 卡核实无该串);头注释同步收口
- 剪除 pane 条件链尾部 v-else 占位死分支(activeGroupLabel/ALL_NAV_ITEMS/
  .placeholder-card/.save-bar 等配套同清)
- form-grid 样式与 CredsPane 同款规则就地复用(不建共用文件)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 18:34:09 +08:00
浅念 06e28e4435 feat(admin): 凭据页套视觉基线+SecretField 四件套
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 18:15:23 +08:00
浅念 712c5f9027 feat(admin): 配置中心导航分层双模式(常用/高级/版本独立)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 17:31:00 +08:00
浅念 46dfbef176 fix(admin): ConfigCard footer 守卫修正(footer-left/right 判定)+ 主题变量对齐
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 17:21:38 +08:00
浅念 2e00db16b9 feat(admin): ConfigCard 视觉基线卡壳
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 17:10:02 +08:00
浅念 6881ccc3cd feat(admin): SecretField 密钥四件套组件
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 17:02:19 +08:00
浅念 0a413526bb feat(admin): secretFieldState 密钥四态展示纯函数
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 16:52:25 +08:00
浅念 a20d53887d fix: 终审微修(admin no-cache/PII挂账/死配置清理)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 14:03:50 +08:00
浅念 7cdb4fc970 chore: 锁屏与通知组件删除(enabled:false的最终清理)
Phase 3 终审 M-1/M-2 摘入口后组件保留待决,本提交最终删除:
- art-screen-lock/ 与 art-notification/ 组件目录
- component.ts screen-lock 全局组件项、headerBar.ts notification 项
- types/config HeaderBarFeatureConfig.notification 字段、
  useHeaderBar shouldShowNotification
- art-header-bar 通知按钮/挂载/showNotice/visibleNotice/
  bodyCloseNotice 与 document 点击监听、.notice-button 样式
- components.d.ts 两条目;crypto-js 依赖全套(env.d.ts 声明/
  package.json/lockfile/optimizeDeps)——唯一消费方是锁屏
- en/zh 孤儿语言键(notice.* / lockScreen.* / topBar.user.lockScreen)
  与 mittBus openLockScreen 事件类型(无发射/订阅方)

grep 零残留;vitest 164 passed;build 通过(主 chunk 358.45→355.84 kB,
crypto-js 出预构建);auto-imports.d.ts 行尾漂移已还原。
CLAUDE.md Phase 4 清理单 6/7 结项(并补记 8/9 随 Task 5E/5D 结项)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 10:43:13 +08:00
浅念 b02326036f refactor: 租户切换器useTenantOptions收拢三页
新建 composables/useTenantOptions.ts:会话/配置/统计三页各自的
tenants/tenantsLoading/tenantsError/loadTenants 拷贝收拢为单一
composable。两种形态:
- 默认(会话/配置页):loadTenants 成功选中首个租户 +
  bootstrapTenantContext()(原两页 onMounted 公共体:超管拉列表/
  租户管理员固定自己/无 slug 防御不动),选中后的 watch 仍留各页
  (重置逻辑页面各异);
- selectFirst: false(统计页):纯下拉数据源,activeSlug 以
  tenantFilter 别名解构('' = 全部租户合并视图),模板零改动。

dashboard 控制台是租户卡片墙(非下拉切换),不在此列。
composable 显式 import vue API——vitest 不跑 unplugin-auto-import。
新增 8 个 composable 测试(mock api/auth store,不装 pinia)。

vitest 164 passed(156+8);build 通过;dts 行尾漂移已还原。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 10:36:30 +08:00
浅念 a50ed866ed perf: ECharts按需收窄
全仓 grep 确认存活消费方只有 views/stats/overview(line/bar/pie 系列
+ tooltip/grid/legend/title 组件)与 hooks/core/useChart(core 自带
的 init/setOption/resize/dispose);art-* 图表库组件(scatter/radar/
k-line 及 dataZoom/toolbox/brush/geo/visualMap/markLine/markPoint)
无任何页面挂载。

echarts.use 收窄为 Bar/Line/Pie + Title/Tooltip/Grid/Legend +
CanvasRenderer。graphic 与类型导出不动(未挂载库组件的 import 仍需
编译通过);组件文件保留,属模板库代码不在本任务删除范围。

构建对比(同机 pnpm build):
- echarts chunk: 767,864 B → 559,737 B(-208 KB / -27.1%;gzip
  251 KB → 187 KB)
- dist 总体积: 3,256,483 B → 2,983,300 B(-273 KB / -8.4%)
(chunk 内残留的 candlestick/radar/scatter 字样为核心 locale 名表
与主题色表,非图表实现。)

vitest 156 passed;build 通过;components.d.ts/auto-imports.d.ts
行尾漂移已还原。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 10:31:54 +08:00
浅念 d734ed6d2a feat: resolver回退链接入platform_settings(三级回退/快照热刷新)
- 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 <noreply@anthropic.com>
2026-10-14 10:10:52 +08:00
浅念 4f38522759 feat: admin生产服务(/admin SPA fallback+health分级) + Docker两阶段构建 + 生产compose
- app/main.py: AdminSPA 纯 ASGI 挂载 /admin(dist 存在=StaticFiles html
  + SPA fallback(非 /admin/api 的 404 回 index.html 200);缺失=503 说明页);
  ADMIN_DIST env 覆盖、请求期现势解析(构建后不重启生效/测试可注入)。
  /health 分级: {status, tenants:[{slug,status,engine_ok}], domains}——
  懒建未就绪 engine_ok=None 不探库;单租户库损坏只 degraded 仍 200,
  不让 healthcheck 杀容器。
- host_middleware: /admin 与 /admin/ 前缀豁免租户解析(平台面;/admin-evil
  仍 404,前缀精确到斜杠)。
- admin: .env.production VITE_BASE_URL=/admin/(产物资源引用与挂载同源,
  单一事实源,不靠构建期 env 注入);package.json 钉 packageManager
  pnpm@10.7.1(corepack 与本地同版本)。
- Dockerfile 两阶段: node:20-alpine 构建 admin/dist(corepack 按清单钉版)
  → python:3.13-slim 只带运行时(app/static/seed_profiles/scripts+dist,
  含 tzdata 使 TZ 生效)。
- docker-compose: 生产编排(8018/env_file 可缺省/TZ/数据 bind mount/
  mem_limit 768m/日志轮转/python urllib healthcheck/restart)。
- .dockerignore 防泄(.env 不进镜像)+ .gitattributes 钉部署文件 LF。
- tests/test_admin_serving.py: 假 dist 夹具 7 例(服务/fallback 边界/
  Host 豁免/缺失降级/health 分级含坏库 degraded)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 08:22:26 +08:00
浅念 6af8c186d8 fix: Phase3 终审修复(env入库/通用配置组面板/锁屏通知摘除/记档修正)
- I-2: admin/.env(被根 .gitignore 误伤)删除,内容并入入库的
  .env.development/.env.production(公共块两份都写,PORT 仅 dev)
- I-1: 配置中心补 contact/engine/misc 三组通用 JSON 编辑面板
  (JsonGroupPane:等宽 textarea 整组编辑 + JSON.parse 预检 +
  PUT 整组 + 重置出厂 + 顶部字段说明;挂进 GROUP_NAV 三入口);
  修组键缺失租户的禁存 bug(父层快照加载后挂载,空组可建组)
- I-3: config_routes.py docstring 改「接线归 Phase 4」;
  CLAUDE.md Phase 4 清理单补 resolver 回退链与 email/push test 限流
- M-1: 锁屏摘除入口(用户菜单项删 + 全局组件 enabled:false)
- M-2: 顶栏通知铃铛隐藏(headerBar notification.enabled:false)
- M-5/M-8: admin/README 换三行指针(删模板 README.zh-CN.md);
  quickLinks 删「登录」项
- M-3/M-4 不做记档入 Phase 4 清理单
- 测试基线:后端 pytest 595 / 前端 vitest 156(+3 通用 JSON 组)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 00:05:40 +08:00
浅念 65aad53e12 chore: Phase 3 收尾——平台设置页+全页冒烟+文档
Task 9(Phase 3 最后任务):
- 平台设置页实装(settings/platform):推荐键表单(ai.* 三键 /
  smtp.* 四键,键名为前端约定——PlatformSetting 是自由 KV 表)+
  存储总览表格;保存 = 逐键 PUT 只提交脏键(与 config 组整组替换
  不同);密钥键哨兵交互与凭据页同款(已设置占位 / 清除 / 恢复
  保持 / 端口 1-65535 校验);页头注记 resolver 回退链未接线、
  现阶段仅存储。
- api/settings.ts:fetchPlatformSettings / putPlatformSetting 实装
  (GET items 列表 / PUT 单键 upsert 形态钉在 docstring)。
- vitest +14(model 10 + api 4):掩码判定后端镜像、归一/脏检测/
  提交值/校验/展示全覆盖;前端基线 139 → 153。
- 全页面浏览器冒烟通过(登录→强制改密→仪表盘双视角→租户管理→
  会话与线索→配置中心全组→统计分析→平台设置→退出→租户管理员
  视角菜单收敛)。
- CLAUDE.md:新增 Phase 3 完成状态段(基线 595/153、本地起法、
  admin 能力一览、前端约定);Phase 3 清理单结项 7/11/12(掩码
  哨兵 / 站点权限 / push enabled 显式化);Phase 4 清理单增补四项
  (components.dts 行尾漂移 / 推送探测 env 回退真址 / 生产反代
  /api/public / VITE_TENANT_PREVIEW_HOST 单域名)。README 现状
  刷新至 Phase 3。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 23:29:31 +08:00
浅念 230eb2d86c feat: 统计分析(卡片/漏斗/趋势/分布/推送健康,ECharts)
- admin 统计分析页(views/stats/overview): 指标卡四张(口径文案沿用
  仪表盘)/ 漏斗横向条形(有序单色明度阶梯,标注 数量·占上一级%)/
  按日趋势双线(窗口内无数据日期前端补零)/ 意向环形(分类三槽固定
  指派,色随实体不随筛选)/ 来源·站点·国家 Top10 横向条形(名义类目
  统一单色)/ 推送健康表(四状态计数 + duplicated 子集行)
- 筛选一行作用全部图表: 时间档(今天/近7天/近30天/自定义区间,自定义
  不完整不发请求并提示)+ 租户切换(超管含"全部"合并选项,停用租户
  标注;租户管理员固定自己)
- charts.ts 纯函数层(选项构建 + 双模式主题档),配色经
  validate_palette.js 明暗双模式校验(分类/漏斗 ordinal 全过;
  意向饼语义红绿组 CVD 硬伤弃用改分类槽)
- statsRange.ts 扩展自定义区间解析(既有仪表盘导出不动);
  新增 charts/resolveStatsRange 单测 19 例(vitest 120→139)
- 修复 merge_stats distributions 尾随逗号 1 元组 bug(合并端点曾把
  distributions 序列化成 JSON 数组,单租户路径不受累)+ 回归钉子;
  后端 595 测试全过

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 22:33:55 +08:00
浅念 481243b958 feat: 配置中心-版本历史(列表/两版对比/回滚/组级重置出厂)
Task 7d——Phase 3 配置中心四连收尾:

- API(api/config.ts):fetchConfigVersions / fetchConfigVersionDetail /
  rollbackConfig / resetConfigGroup 四函数补齐(骨架端点与类型已就位;
  响应形态对照 config_routes 实测——列表无 config 本体、详情整份+掩码、
  reset 响应与 PUT 分组保存同形)
- VersionsPane:版本 tab 实装(导航占位转正)——列表倒序(版本/时间/
  作者/备注,当前版标记)+ 详情抽屉整份 JSON;勾两版(限两个,第三个
  自动撤销最早勾选行)并排等宽 JSON 对比(spec §7.3 最低形态,范围
  下拉可聚焦单组——wall 20KB+ 场景);回滚确认框明示「将产生新版本,
  历史不变」→ 响应内新快照直接回写页头版本/快照/品牌表单,无需再 GET
- 组级重置出厂:六个已实装编辑卡(品牌/提示词/词表/邮件/推送/AI)头部
  危险色小按钮 → reset.ts 共用确认入口(明示组名与「恢复出厂档案值」)
  → POST config/{group}/reset → 表单/密钥态/版本刷新(RESET_GROUP_
  LABELS 九组镜像后端 CONFIG_GROUPS,含待实装的联系方式/引擎/杂项)
- 测试:vitest 120(+13——API 四函数调用形态 5 条 + model 辅助 8 条);
  后端不动 595;冒烟 jiancai:v1-v10 列表 → v1/v10 并排对比(push 组
  __SET__ 掩码可见)→ 回滚 v1 产 v11 且品牌回 v1 值 → 改占位存 v12 →
  重置品牌产 v13 表单回档案值 → 回滚 v10 复原现场(v14)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 21:39:16 +08:00
浅念 bf923d9cf7 feat: 配置中心-凭据(邮件推送AI表单/掩码交互/SMTP测试/推送探测端点)
- 后端 POST /tenants/{slug}/email/test:resolve_email_settings 当前配置
  真发测试邮件(主题 [all-kefu] SMTP 测试邮件+租户名+UTC+8 时间);
  回退后 host/user 仍空 → 400;成败如实返回 {sent, error},密钥不进响应
- 后端 POST /tenants/{slug}/push/test:连通性探测——与 _do_post 同款
  连接形态 POST 空 messages 批量(红线:绝不携带线索数据);不可达
  reason 分类 dns/timeout/connect(Windows 裸 ConnectError 文案兜底),
  auth_ok 三态(2xx 真 / 401·403 假 / 其余 null),单次无重试
- email_service 抽 _smtp_send 共用连接逻辑(_send 契约不变)+
  send_test_email(成败+错误串如实返回,不走吞异常 bool)
- 前端 CredsPane:邮件/推送/AI 三组凭据表单(数值/邮箱前端预检 +
  后端 400 双层);密钥哨兵交互(__SET__ 占位符/不动保存保持库值/
  清除按钮显式清空可撤销);SMTP 测试与推送探测三态内联展示
- 测试:pytest 新增 18(email/test 7 + push/test 11),全量 595 通过;
  vitest 新增 20(model 哨兵往返/预检边界 + API 调用形态),107 通过

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 20:55:40 +08:00
浅念 39d72c53aa feat: 配置中心-提示词与词表(四件套编辑/结构化词表/试金石面板/保存前验证)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 20:05:42 +08:00
浅念 cac91e9e3e feat: 配置中心-品牌(表单/本地预览/嵌入代码/头像上传)+ 站点覆盖层编辑入口
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 19:27:08 +08:00
浅念 6f22e51908 feat: 租户管理与站点管理(创建向导/停用/域名/门面覆盖)
- API 层实装(api/tenants.ts):创建/详情/PATCH 租户、建站/改站、
  域名绑定解绑——400 撞车 detail(slug/域名归属/prefix 引导)经
  showErrorMessage:false 关全局 toast、由向导与绑域名弹窗内联常驻展示
- 租户列表:slug/名称/状态/域名数/版本/管理员概要 + 状态筛选 +
  行操作(详情/停用复启用/改名);停用确认框写明 503 服务暂停语义
- 创建向导(ElSteps 四步):名称+slug(^[a-z0-9-]+$ 与撞车内联拦截)
  → 域名多填 → 出厂档案(auto/jiancai 提示 prefix 全局唯一撞车引导
  改 blank;blank 提示墙与提示词取建材出厂档案)→ 管理员账号;
  201 后列表刷新并提示首登需改密
- 站点管理(详情抽屉):站点表/新建站(门面覆盖层表单——brand 组
  子集字段留空=继承租户默认)/停用复启用(404 语义提示)/域名绑定
  (撞车归属内联)与解绑(标签 × 确认)
- vitest +9(API 层 URL/方法/请求体契约);页面仅超管(菜单 roles 已挡)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 18:27:56 +08:00
浅念 ce668eaf2f feat: 会话与线索(列表/筛选/租户切换/详情消息流/推送日志/删除)
- 会话列表页签:分页表格 + 筛选(意向三值/站点精确/日期区间 daterange,
  筛选变化重置第一页)+ 行操作(详情抽屉/删除确认框,级联消息画像评估
  推送日志,末页删空自动回退一页)
- 租户切换器:超管专用(fetchTenantList 下拉,默认第一个,切换联动双页签
  并关抽屉);租户管理员固定登录态 tenant_slug,无切换器只有标签
- 详情抽屉:元数据(状态/来源/站点/IP 归国/session/设备)+ 画像 chips
  (ElTag 键值)+ 评估块(意向/理由/联系方式/更正次数)+ 消息流气泡
  (user 右 assistant 左,时间直显库内 naive UTC 不换算,与筛选同口径)
- 推送日志页签(列表平行):状态筛选(pending/success/failed/skipped)
  + 分页表格(类型/状态/尝试/outcome/HTTP/payload 大小/会话/错误)——
  列表接口不回大 payload,仅服务端 payload_size
- api/conversations.ts 实装调用函数并按 data_routes.py 实际响应修正类型
  (IntentLevel 三值/messages.time/详情扁平 evaluation+profile 块/
  PushLogItem 全字段),新增枚举中文映射(intentLabel 等,未知值回退原样)
- vitest +9(conversations API 契约:URL/参数/白名单/映射),总 45;
  后端不动(pytest 577 基线复核)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 17:31:12 +08:00
浅念 f640889f22 feat: 仪表盘(租户卡片墙/平台总览/时间切换)+ 顺手:409契约锁与死代码
- 仪表盘视图:超管=平台总览四指标卡(/api/platform/stats 合并视图)+
  租户卡片墙(逐租户 ?tenant= 下钻,含停用租户);租户管理员=自己
  指标卡(/tenants/{slug}/stats,slug 取登录态);口径文案照
  stats.py docstring(线索=留资三选一/成功率分母0显—等)
- 时间范围快捷切换(今天/近7天/近30天)→ from/to 本地日期串;
  utils/statsRange.ts 纯函数 + epoch 防快速切换过期响应竞写
- 空数据态:无租户 ElEmpty / 单租户零数据自然显 0 与 —
- api/stats.ts 补 fetchPlatformStats/fetchTenantStats;tenants.ts 补
  fetchTenantList(卡片墙枚举,其余仍留 Task 6)
- vitest +11(statsRange 6 + stats API 5,总 36)
- 顺手1:test_auth must_change 409 测试补 detail 断言,锁死前后端
  契约文案(client.ts MUST_CHANGE_DETAIL)
- 顺手2:删除 beforeEach.ts 的 isUnauthorizedError 死分支与 ApiStatus
  import(模板 isHttpError 判自建 ApiError 恒 false,分支不可达)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 16:59:12 +08:00
浅念 3973abea8b feat: API层与认证流(client拦截/守卫/登录改密实装/域API骨架/vitest)
- 自建轻量 axios client(src/api/client.ts):Bearer 注入、401 清会话跳登录
  (login 请求除外)、409 精确匹配"必须先修改初始密码"跳强制改密(区别于并发
  冲突 409)、429/网络错误统一 ElMessage、ApiError 标准化、showErrorMessage
  可opt-out——模板 utils/http 的 {code,msg,data} 信封与后端裸 HTTP 语义不符故弃用
- Pinia auth store(src/store/modules/auth.ts):token/role/tenant_slug/
  must_change 落地并持久化(all-kefu-auth key),login/logout/changePassword/
  会话过期/强制改密跳转(动态 import 断循环)
- 路由守卫:token 事实源判定、must_change 全站门(除改密页)、UserInfo 由登录
  快照派生(后端无用户信息端点);user store 残留自愈
- 登录页实装(去除角色调试开关)、强制改密页实装;用户菜单/锁屏对接真实 logout
- 域 API 骨架:tenants/config/conversations/stats/settings(类型+端点常量)
- mask 哨兵助手:__SET__ ↔ 已设置 表单语义
- vitest 25 例(client 11/store 8/mask 6);登录页拖拽验证 reset 空引用修复

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 16:28:11 +08:00
浅念 6afa31ec85 fix: 脚手架审查修复(dts入库保首跑/esnext注释/模板changelog清理)
- auto-imports.d.ts / components.d.ts 出 .gitignore 并入库(已重新生成):新克隆/CI 首跑 pnpm build 直接可用,Phase 4 部署依赖
- vite.config.ts build.target=esnext 补注释:Windows 本机 es2015 曾触发 esbuild 0xC0000409 原生崩溃,改后稳定;管理后台仅面向现代浏览器
- 删除模板自带 CHANGELOG.md / CHANGELOG.zh-CN.md(约 650 行 x2,与本项目无关)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 15:03:30 +08:00
浅念 78ff060420 feat: art-design-pro 脚手架落地与品牌化(八页骨架/代理配置/权限菜单)
- 模板 art-design-pro(MIT)GitHub 直连克隆后裁剪落地 admin/:删除演示页面/示例数据/mock/未用组件,保留构建与依赖清单
- 品牌化:应用名/标题/侧栏与登录页 logo/浏览器 favicon 全部替换为 all-kefu 自有资源(static/kefu-small.png),中文界面
- 八页骨架:login / force-change-password / dashboard / tenants / conversations / config / stats / settings 占位页 + 6 组路由模块
- 权限菜单:meta.roles 前端过滤,super 全量,tenant 隐藏 租户管理/平台设置(角色值与后端一致)
- 开发代理:/api 直转 + /api/public 与 /static 携带租户 Host 改写(VITE_TENANT_PREVIEW_HOST),适配后端 TenantHostMiddleware
- 认证 API 为开发桩(角色调试开关),Task 3 对接真实登录

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 14:51:24 +08:00