docs: Phase 3 实施计划(admin SPA 九任务,含掩码哨兵与站点权限两项前置决策)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-13 13:23:06 +08:00
parent 6839cb94d2
commit 584bb24091
@@ -0,0 +1,102 @@
# Phase 3:admin 后台 SPA(art-design-pro)实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 用 art-design-pro(Vue3+TS+Vite+Element Plus,MIT)搭建统一后台 SPA(admin/),对接 Phase 2 全部 /api/platform/* API:登录/强制改密、仪表盘、会话与线索、租户管理(含站点/域名/创建向导)、配置中心(品牌预览/提示词/词表试金石/版本回滚)、统计分析、平台设置。
**Architecture:** SPA 独立目录 admin/(模板落地+品牌化),开发期 vite proxy 到 FastAPI 8018;生产构建产物由 FastAPI 在管理域名下服务(打包集成归 Phase 4,本阶段验收=pnpm build 通过 + dev 模式浏览器冒烟)。认证走 Authorization: Bearer(无 Cookie),401→登录页、409→强制改密页;菜单级权限(超管/租户)+ 后端强制隔离(已就绪)。
**Tech Stack:** Vue 3 / TypeScript / Vite / Pinia / Element Plus / ECharts(模板自带或按需补);后端 FastAPI(已就绪)。
**参照 spec:** §7.1-7.4(工程/认证/页面/编辑形态)、§7.6(统计);CLAUDE.md 取舍清单 #11(密钥掩码——**本阶段第一件事**)、#12(站点管理权限)。
**关键前置决策(写入实现):**
- **#11 密钥掩码**:GET config/settings 对密钥字段(push.api_key/ai.api_key/email.smtp.password/平台设置里的集团凭据)返回 `"__SET__"` 哨兵(曾设置)或 ""(未设置);PUT 收到 `"__SET__"` 时保留库中现值不改;前端密码框 placeholder 显示"已设置(输入新值覆盖)"。后端小改+测试,Task 1。
- **#12 站点管理权限**:**放开为 _tenant_guard**(spec §7.3 原文即"租户管理员=同左(限自己租户)";租户全开是既定原则,站点是租户自己的门面)。后端一行级改+测试,Task 1。
- 试金石参数对齐(Phase 2 终审 M-1:allow_number/confirmed_channels 未传):**挂账不动**(编辑器场景无 CC 上下文,docstring 已声明),Phase 4 真机验收时复核。
---
### Task 1: 前置后端——密钥掩码哨兵 + 站点管理权限放开
**Files:**
- Modify: `app/platform/routes/config_routes.py`(GET 掩码/PUT 哨兵保留)、`app/platform/routes/tenant_routes.py`(sites/domains 端点 _tenant_guard)、`tests/test_config_api.py`、`tests/test_tenant_admin_api.py`
- [ ] 失败测试:①GET config 的 push.api_key 已设 → `"__SET__"`、未设 → `""`;②PUT 传 `"__SET__"` → 库值不变(版本照常+1)、传新值 → 覆盖;③平台设置同款;④租户管理员 PATCH 自己租户的站点 → 200(原 403)
- [ ] 实现:掩码助手(字段清单常量:push.api_key/ai.api_key/email.smtp.password + 平台设置递归对 key 含 key/password/secret 的值);PUT 侧哨兵替换逻辑(读当前快照还原原值再写版本);sites/domains 五端点 require_super → _tenant_guard(创建租户 POST /tenants 保持仅超管)
- [ ] 全量回归 + 提交 `feat: 密钥掩码哨兵(__SET__) + 站点管理权限放开租户管理员`
### Task 2: 脚手架落地与品牌化
**Files:**
- Create: `admin/`(模板落地)
- [ ] 环境检查:node ≥18、pnpm(缺则 npm i -g pnpm——开发机工具,报告说明)
- [ ] 取模板:git clone https://github.com/Daymychen/art-design-pro admin-tmp → 拷入 admin/(去 .git;**只保留 src/配置/依赖清单,删 demo 页/示例数据**——模板结构以实际为准,报告瘦身清单)
- [ ] 品牌化:应用名"all-kefu 管理后台"、logo 占位、中文、去掉模板统计/示例路由;.env.development 配 vite proxy(/api、/static → http://127.0.0.1:8018)
- [ ] 路由骨架:login / force-change-password / dashboard / tenants / conversations / config / stats / settings 八个空白页占位 + 菜单(超管全量;租户管理员隐藏 tenants/settings——前端菜单控制,后端已强制)
- [ ] 验收:pnpm install + pnpm dev 可起 + 浏览器打开见到骨架;pnpm build 通过
- [ ] 提交 `feat: art-design-pro 脚手架落地与品牌化`
### Task 3: API 层与认证流
**Files:**
- Create: `admin/src/api/`(client + 各域模块)、`admin/src/stores/auth.ts`、登录页与强制改密页实装、路由守卫
- Test: `admin/src/api/__tests__/`(vitest——若模板无 vitest 则配置之)
- [ ] 失败测试(vitest):client 的 401→跳登录、409→跳改密、token 注入 header;掩码哨兵在表单层的"已设置"语义转换
- [ ] 实现:fetch/axios 封装(统一错误 ElMessage);auth store(login/logout/changePassword/角色与租户信息持久化 localStorage);路由守卫(无 token→login;must_change→强制改密页);登录页/改密页对接真实 API(后端 8018 起 db 源+bootstrap 后实测)
- [ ] 浏览器冒烟:默认超管首登 → 强制改密 → 进入仪表盘骨架;坏密码限流提示
- [ ] 提交 `feat: API层与认证流(401/409路由守卫/强制改密/角色菜单)`
### Task 4: 仪表盘
- [ ] 超管:租户卡片墙(每租户今日会话/线索/推送成功率——GET stats?tenant= 逐个)+ 平台总览卡(合并视图);租户管理员:自己的指标卡
- [ ] 时间范围快捷切换(今天/7天/30天)
- [ ] 浏览器冒烟 + 提交 `feat: 仪表盘(租户卡片墙/平台总览/时间切换)`
### Task 5: 会话与线索
- [ ] 列表:分页/筛选(意向/站点/日期)/租户切换器(超管);行→详情
- [ ] 详情抽屉:画像 chips/消息流/评估;推送日志页签(状态筛选)
- [ ] 删除会话(确认框)
- [ ] 冒烟 + 提交 `feat: 会话与线索(列表/筛选/详情/推送日志/删除)`
### Task 6: 租户管理与站点管理
- [ ] 列表(状态/域名数/版本/管理员)+ 创建向导分步表单(名称→slug→域名→选档案 auto/jiancai/blank→管理员账号;提示 blank 的墙/提示词取建材出厂)
- [ ] 租户详情:停用/复启用(确认框+后果提示)、改名
- [ ] 站点管理:站点列表/新建(slug/名称/门面覆盖层表单——覆盖字段留空=继承提示)/停用;域名绑定/解绑(撞车错误展示归属)
- [ ] 冒烟 + 提交 `feat: 租户管理与站点管理(创建向导/停用/域名/门面覆盖)`
### Task 7: 配置中心
- [ ] 品牌表单:字段编辑 + **挂件实时预览**(iframe 嵌 widget-test 风格或本地渲染组件——选 iframe 简单)+ **嵌入代码复制块**(script 标签带租户域名)+ 头像上传
- [ ] 提示词四件套:markdown textarea(等宽字体)+ `$DEFLECTION_POOL` 注入变量提示 + 大小上限提示 + 保存备注必填
- [ ] 词表:结构化表格(价格正则/话术池/触发词/替换句——按 wall.json 结构分组编辑)+ **试金石面板**(句子列表→逐句判定展示)+ 保存前自动跑试金石提示
- [ ] 邮件/推送/AI 凭据表单:掩码哨兵交互("已设置,输入覆盖");SMTP 测试按钮(发测试邮件——**后端无此端点,前端先做连通性校验占位或加后端小端点**——选加后端 POST .../email/test,一并实现+测试);推送前缀唯一错误展示
- [ ] 版本历史抽屉:列表/回滚(确认框);重置出厂按钮(组级,确认框)
- [ ] 冒烟 + 提交 `feat: 配置中心(品牌预览/嵌入代码/提示词/词表试金石/凭据掩码/版本回滚/邮件测试)`
### Task 8: 统计分析
- [ ] 卡片行(会话/线索/高意向/推送成功率)+ 漏斗图 + 趋势折线(按日)+ 分布(意向饼图/来源/站点/国家 Top10 条形)+ 推送健康表格;时间范围+租户筛选
- [ ] ECharts 按需引入(模板自带则复用)
- [ ] 冒烟 + 提交 `feat: 统计分析(卡片/漏斗/趋势/分布/推送健康)`
### Task 9: 平台设置与 Phase 3 收尾
- [ ] 平台设置页(集团 AI 凭据/默认 SMTP——掩码交互;仅超管)
- [ ] pnpm build 产物检查(dist 生成、无报错);dev 全页面浏览器冒烟清单逐项过(报告勾选表)
- [ ] CLAUDE.md 更新(Phase 3 完成状态/本地起法【后端 8018+前端 pnpm dev】/Phase 4 清理单刷新——含取舍 #11/#12 已闭、试金石参数对齐复核提醒)
- [ ] 提交 `chore: Phase 3 收尾——admin SPA 完成`
---
## 显式不做(Phase 3 范围外)
Docker 两阶段构建与 FastAPI 服务 dist(Phase 4);真实浏览器 E2E 自动化(人工冒烟清单即可——后端 571 测试守 API 行为);提示词沙箱试聊(二期);多语言(中文单语)。
## 执行注意
后端改动(Task 1/7 的邮件测试端点)走既有 FastAPI 测试纪律;前端任务的验收=build 通过+dev 冒烟+关键交互说明;审查模式沿用轻量双审。pnpm/node 是开发机新工具链依赖(部署服务器零依赖——两阶段构建归 Phase 4)。