环境信息
线上地址 https://letcareme.com
服务器 8.138.11.105 (阿里云 ECS)
API 端口 8007 (容器内)
Web 端口 3012 (容器内)
登录凭证 admin / CKdyRPSqJA5KZTXuR8Qgfg
容器 qn-web / qn-api / qn-fetcher / qn-worker
30
前端页面
§1 共 11 个页面
47
后端 API
§2 共 5 个分组
8
安全测试
§3 认证/限流/校验
6
运维测试
§4 容器/持久化/日志
5
功能完整性
§5 端到端场景

一、前端页面测试

30 项 · 11 页面
1.1 登录页 /
#测试步骤预期结果通过
1 浏览器打开 https://letcareme.com 显示登录表单 (用户名+密码)
2 输入错误密码, 点登录 显示错误提示, 不跳转
3 输入 admin / CKdyRPSqJA5KZTXuR8Qgfg, 点登录 跳转到 /dashboard
4 未登录直接访问 /dashboard 自动重定向到 / 登录页
1.2 仪表盘 /dashboard
#测试步骤预期结果通过
5 登录后查看 dashboard 显示今日统计卡片 (对话数/分析数/告警数)
6 检查左侧 sidebar 含: 今日概览/买家全景/案例库/对话复盘/流失预警/每日日报/话术库/登录日志/用户管理/系统设置
7 点击深色/浅色模式切换按钮 主题正确切换
1.3 买家全景 /buyers
#测试步骤预期结果通过
8 点击 sidebar "买家全景" 显示买家列表 (应有 16 条)
9 点击某个买家行 展开详情, 显示 insights (情感分析/购买意向)
10 使用搜索框输入买家昵称 过滤结果正确
1.4 案例库 /cases
#测试步骤预期结果通过
11 点击 sidebar "案例库" 显示案例列表 (应有 19 条)
12 翻页 (如有分页) 分页正常, 数据不重复
13 点击 CSV 导出按钮 下载 .csv 文件, 内容完整
1.5 话术库 /scripts
#测试步骤预期结果通过
14 点击 sidebar "话术库" 显示话术列表 (3+ 条)
15 使用状态筛选: "草稿" 仅显示 draft 状态话术
16 使用状态筛选: "已批准" 仅显示 active 状态话术
17 点击 "新建话术" 弹出表单, 可输入名称/内容/场景
18 填写话术并提交 创建成功, 状态为 "草稿"
19 对草稿话术点击 "审批" 状态变为 "已批准"
20 对已批准话术点击 "下架" 状态变为 "已下架"
1.6 对话复盘 /conversations
#测试步骤预期结果通过
21 点击 sidebar "对话复盘" 显示对话列表
1.7 流失预警 /churn-alerts
#测试步骤预期结果通过
22 点击 sidebar "流失预警" 显示预警列表 (可为空)
1.8 每日日报 /daily-reports
#测试步骤预期结果通过
23 点击 sidebar "每日日报" 显示日报列表
24 选择日期 加载对应日期日报 (无数据显示空)
1.9 登录日志 /audit-log
#测试步骤预期结果通过
25 点击 sidebar "登录日志" 显示登录记录 (含本次登录)
26 翻页 分页正常
1.10 用户管理 /admin
#测试步骤预期结果通过
27 点击 sidebar "用户管理" 显示用户列表
1.11 系统设置 /settings
#测试步骤预期结果通过
28 点击 sidebar "系统设置" 显示 LLM Key 配置界面
29 查看已配置的 Key Key 显示为脱敏格式 (****xxxx)
30 修改密码 (底部按钮) 弹出修改密码对话框

二、后端 API 测试

47 项 · 5 分组
测试前获取 TOKEN:ssh root@8.138.11.105 "docker exec qn-api printenv QN_INTERNAL_TOKEN"
2.1 公开端点 (无需 Token)
#命令预期通过
31 curl https://letcareme.com/health 200, {"status":"ok"}
32 curl http://127.0.0.1:8007/ready 200, 含 checks 对象
33 curl http://127.0.0.1:8007/api/v1/qianniu-pc/version 200, {"latest":"0.8.0"}
2.2 认证保护验证
#命令预期通过
34 curl http://127.0.0.1:8007/api/v1/config (无 token) 401
35 curl -X POST http://127.0.0.1:8007/api/v1/analyze (无 token) 401
36 curl http://127.0.0.1:8007/api/v1/scripts (无 token) 401
37 curl http://127.0.0.1:8007/api/v1/qianniu-pc/sellers (无 token) 401
38 curl -H "X-Internal-Token: WRONG" http://127.0.0.1:8007/api/v1/config 401
2.3 受保护读取端点 所有命令加 -H "X-Internal-Token: $TOKEN"
# 端点 方法 预期状态 验证点 通过
39/api/v1/configGET200含 has_dashscope_key 字段
40/api/v1/scriptsGET200返回话术数组
41/api/v1/qianniu-pc/today-statsGET200含 conversations/analyzed 计数
42/api/v1/qianniu-pc/buyersGET200返回买家列表
43/api/v1/qianniu-pc/casesGET200返回案例列表
44/api/v1/qianniu-pc/cases.csvGET200Content-Type 含 csv
45/api/v1/qianniu-pc/churn-alertsGET200返回告警数组
46/api/v1/qianniu-pc/statusGET200含 events_24h 计数
47/api/v1/qianniu-pc/cost-statusGET200含 daily_limit_usd
48/api/v1/qianniu-pc/sellersGET200返回卖家列表
49/api/v1/qianniu-pc/cookie-statusGET200含 nick + h5tk_valid
50/api/v1/qianniu-pc/accountGET200返回账户信息
51/api/v1/qianniu-pc/settings/llm-keysGET200Key 脱敏显示
52/api/v1/qianniu-pc/settings/modelsGET200模型配置列表
53/api/v1/playbooks/statsGET200含 total_triggers
54/api/v1/playbooks/listGET200playbook 数组
55/api/v1/daily-reportsGET200日报列表
56/api/v1/qianniu-pc/buyer-insights/{nick}GET200insight 记录
2.4 写入/操作端点
# 端点 方法 请求体 预期 通过
57/api/v1/scriptsPOST{"name":"测试话术","content":"您好","scene":"greeting"}201, 返回 id
58/api/v1/scripts/{id}GET200, 状态 draft
59/api/v1/scripts/{id}/approvePOST200, 状态变 active
60/api/v1/scripts/{id}/retirePOST200, 状态变 deprecated
61/api/v1/scripts/{id}PUT{"content":"更新"}409 (deprecated 禁改)
62/api/v1/qianniu-pc/notify-changePOST{"hash":"x","seller_id":"test","worker_id":"w1"}200 或 422
63/api/v1/daily-reports/triggerPOST200, accepted
64/api/v1/scripts/assist/suggestPOST{"scene":"greeting","buyer_msg":"你好"}200 (LLM 建议) 或 429
65/api/v1/qianniu-pc/analyze-conversationPOST{"worker_id":"w","buyer_nick":"test","messages":[]}200 或 422
66/api/v1/qianniu-pc/append-messagesPOST{"sid":"test","messages":[]}200 或 422
67/api/v1/qianniu-pc/reanalyze/{nick}POST200 触发重分析
68/api/v1/qianniu-pc/refresh-cookiePOST{"cookie":"..."}200 或 422
69/api/v1/qianniu/send-replyPOST{"buyer_nick":"test","content":"你好"}200 或 422
70/api/v1/qianniu/send-reply/probePOST200 (probe disabled)
71/api/v1/qianniu-pc/buyer-cache/{nick}GET200 或 404 (无缓存)
72/api/v1/daily-reports/{date}GET200 或 404 (无该日报告)
73/api/v1/qianniu-pc/settings/llm-keysPUT{"provider":"qwen","api_key":"sk-test"}200
74/api/v1/qianniu-pc/settings/llm-keys/testPOST{"provider":"qwen","api_key":"sk-test"}200 或 422
75/api/v1/qianniu-pc/settings/modelsPUT{"screenshot":"qwen-vl-max"}200
2.5 激活端点
#端点请求体预期通过
76 POST /api/activate {"license_key":"SHORT"} 400/422 (格式错误)
77 POST /api/activate {"license_key":"AAAAAAAAAAAAAAAA"} 403 (无效 key)

三、安全测试

8 项 · 3 分组
3.1 认证边界
#测试预期通过
78 无 token 访问任意 /api/v1/* 端点 401
79 错误 token 访问 401
80 公开端点 (/health, /version) 无 token 200 (正常)
3.2 速率限制
#测试预期通过
81 连续 11 次 POST /api/v1/analyze (带 token) 前 10 次 200, 第 11 次 429
82 429 响应含 Retry-After 有, 值 > 0
83 连续 6 次 POST /api/activate 前 5 次正常, 第 6 次 429
3.3 输入校验
#测试预期通过
84 POST /api/v1/qianniu/send-reply 含违规话术 ("加我微信") 422, code=content_violation
85 POST /api/activate 超长 license_key (100 字符) 400/422 格式拒绝

四、运维测试

6 项 · 3 分组
4.1 容器健康
#测试预期通过
86 docker compose ps 4 容器全部 healthy
87 docker exec qn-api whoami appuser (非 root)
88 docker exec qn-web whoami node (非 root)
4.2 持久化
#测试预期通过
89 重启 qn-api, 检查 Redis 中 qn:analyzer:buf:* buffer 数据保留
90 重启 qn-fetcher, 检查 Redis 中 qn:fetcher:seen_mids mid 集合保留
4.3 日志
#测试预期通过
91 docker compose logs qn-api --tail 10 无 ERROR, 有 rate_limit/auth 日志

五、功能完整性测试

5 项 · 端到端
# 测试场景 步骤 预期 通过
92 话术完整生命周期 创建→审批→下架, 验证每步状态 draftactivedeprecated
93 买家 insights 查看 GET /buyers → 选买家 → GET buyer-insights/{nick} 返回情感分析数据
94 成本控制状态 GET /cost-status 显示日限/已用/百分比
95 Playbook 统计 GET /playbooks/stats 触发次数/采纳率
96 日报触发 POST /daily-reports/trigger → GET /daily-reports 异步接受, 后查可见
⚡ 快速回归脚本 — 一键跑所有 API 端点 (SSH 到服务器执行)
#!/bin/bash
TOKEN=$(docker exec qn-api printenv QN_INTERNAL_TOKEN)
BASE="http://127.0.0.1:8007"
PASS=0; FAIL=0; TOTAL=0

check() {
  local method=$1 path=$2 expect=$3 data=$4
  TOTAL=$((TOTAL+1))
  if [ -n "$data" ]; then
    code=$(curl -s -o /dev/null -w '%{http_code}' -X $method \
      -H "X-Internal-Token: $TOKEN" -H "Content-Type: application/json" \
      -d "$data" "$BASE$path")
  else
    code=$(curl -s -o /dev/null -w '%{http_code}' -X $method \
      -H "X-Internal-Token: $TOKEN" "$BASE$path")
  fi
  if [ "$code" = "$expect" ]; then
    echo "  PASS  $method $path -> $code"
    PASS=$((PASS+1))
  else
    echo "  FAIL  $method $path -> $code (expected $expect)"
    FAIL=$((FAIL+1))
  fi
}

echo "=== 公开端点 ==="
check GET /health 200
check GET /ready 200
check GET /api/v1/qianniu-pc/version 200

echo "=== 认证拒绝 (无 token) ==="
TOKEN_BAK=$TOKEN; TOKEN=""
check GET /api/v1/config 401
check GET /api/v1/scripts 401
check GET /api/v1/qianniu-pc/sellers 401
TOKEN=$TOKEN_BAK

echo "=== 受保护读取 ==="
check GET /api/v1/config 200
check GET /api/v1/scripts 200
check GET /api/v1/qianniu-pc/today-stats 200
check GET /api/v1/qianniu-pc/buyers 200
check GET /api/v1/qianniu-pc/cases 200
check GET /api/v1/qianniu-pc/churn-alerts 200
check GET /api/v1/qianniu-pc/status 200
check GET /api/v1/qianniu-pc/cost-status 200
check GET /api/v1/qianniu-pc/sellers 200
check GET /api/v1/qianniu-pc/cookie-status 200
check GET /api/v1/qianniu-pc/account 200
check GET /api/v1/qianniu-pc/settings/llm-keys 200
check GET /api/v1/qianniu-pc/settings/models 200
check GET /api/v1/playbooks/stats 200
check GET /api/v1/playbooks/list 200
check GET /api/v1/daily-reports 200

echo "=== 写入操作 ==="
check POST /api/v1/daily-reports/trigger 200

echo ""
echo "=============================="
echo "  PASS: $PASS / $TOTAL"
echo "  FAIL: $FAIL"
echo "=============================="

测试记录

日期 执行人 通过/总数 备注
2026-05-22 AI E2E 56 / 56 全量自动化, /config 漏洞已修复