docs: 实施计划——按审查意见修正(robocopy前缀/话术残留/ES池/mock端口/结构测试说明)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,566 @@
|
||||
# HESUPIPE 建材 AI 客服 实施计划
|
||||
|
||||
> **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:** 复制 D:\refactor\ai-kefu 汽车AI客服到本项目并完成建材(HESUPIPE 管道外贸)行业定制。
|
||||
|
||||
**Architecture:** 方案A"完整拷贝+定制"——保留参考项目全部架构(FastAPI+SQLite+智谱GLM、WebSocket/REST 双通道、三重输出墙、联系方式管道、邮件+UniService推送、管理后台、170+测试),只定制约15%行业相关内容(4个提示词、多语言正则墙、前端文案、品牌更名)。
|
||||
|
||||
**Tech Stack:** Python 3.13 / FastAPI / SQLAlchemy(async)+aiosqlite / 智谱GLM(glm-4-flash) / 原生HTML-JS-CSS前端 / pytest+pytest-asyncio / Docker+OpenResty
|
||||
|
||||
**设计文档:** `docs/superpowers/specs/2026-09-29-building-materials-ai-kefu-design.md`(本计划的所有决策依据)
|
||||
|
||||
**参考项目:** `D:\refactor\ai-kefu`(只读,绝不修改)
|
||||
|
||||
**重要约束:**
|
||||
- ⚠️ 绝不拷贝参考项目的 `.env`(含真实密钥)和 `data/cc_ai_kefu.db`(含生产数据)
|
||||
- 开发期 `PUSH_ENABLED=false`、NOTIFY_EMAIL 用测试邮箱(Task 11 验收通过后才切生产)
|
||||
- 每个任务结束必须 `pytest -q` 全绿后才能 commit
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 项目拷贝、清理与测试基线
|
||||
|
||||
**Files:**
|
||||
- Create: 整个项目骨架(从参考项目拷贝)
|
||||
- Delete: `static/blog.html`、redis 相关配置
|
||||
|
||||
- [ ] **Step 1: 拷贝项目(排除密钥/数据/缓存)**
|
||||
|
||||
```bash
|
||||
cd /d/refactor
|
||||
MSYS_NO_PATHCONV=1 robocopy "D:\\refactor\\ai-kefu" "D:\\refactor\\ai-kefu-jc" /E \
|
||||
/XD .git data __pycache__ .pytest_cache .ruff_cache .playwright-mcp .superpowers .vscode \
|
||||
/XF .env
|
||||
```
|
||||
|
||||
⚠️ Git Bash 下 MSYS 会把 `/E` `/XD` 等开关当路径转换导致 robocopy 报"无效参数",
|
||||
**必须加 `MSYS_NO_PATHCONV=1` 前缀**(实测验证;替代写法是 `//E //XD //XF` 双斜杠)。
|
||||
robocopy 返回码 0-7 都算成功(1=有文件拷贝),≥8 才是失败。
|
||||
`docs/superpowers/` 下会合入参考项目的汽车 specs/plans 归档,与本项目的建材设计文档共存,无冲突(文件名不同)。
|
||||
|
||||
**git 仓库说明**:本项目在设计阶段已 `git init` 并有 3 个 docs commit 在案;
|
||||
robocopy 的 `/XD .git` 只排除源目录的 .git,不影响目标已有仓库。Step 6 前用
|
||||
`git rev-parse --is-inside-work-tree` 确认输出 `true` 即可(若在全新环境重跑本计划则先 `git init`)。
|
||||
|
||||
- [ ] **Step 2: 验证拷贝结果**
|
||||
|
||||
```bash
|
||||
cd /d/refactor/ai-kefu-jc && ls app/ static/ tests/ scripts/
|
||||
# 预期:四个目录都在;确认不存在 .env 和 data/cc_ai_kefu.db
|
||||
test ! -f .env && echo OK-no-env
|
||||
mkdir -p data
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 清理无用件**
|
||||
|
||||
```bash
|
||||
rm static/blog.html
|
||||
```
|
||||
|
||||
移除 redis 三处:
|
||||
1. `requirements.txt` 删除 `redis>=5.0.0` 行
|
||||
2. `docker-compose.yml` 删除整个 redis service 块(`cc-ai-kefu-redis`)
|
||||
3. `.env.example` 删除 `REDIS_URL`/`REDIS_PASSWORD` 行及注释
|
||||
|
||||
- [ ] **Step 4: 安装依赖并建 .env 占位**
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt -r requirements-dev.txt
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
`.env` 中 `ZHIPU_API_KEY` 先留占位(跑测试不需真实 Key,LLM 全 mock)。
|
||||
|
||||
- [ ] **Step 5: 基线测试——未改任何代码前必须全绿**
|
||||
|
||||
```bash
|
||||
python -m pytest -q
|
||||
```
|
||||
|
||||
预期:170+ passed(参考项目全绿,拷贝后应同样全绿)。若有 Windows 环境性失败,先修复环境再继续(参考项目 conftest.py 头部有 Windows aiosqlite 清理说明)。
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "chore: 从汽车AI客服项目拷贝骨架并清理(blog页/redis)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 公司事实卡 company_facts.md
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/prompts/company_facts.md`(整体重写)
|
||||
- Test: `tests/test_company_facts.py`(更新断言)
|
||||
|
||||
- [ ] **Step 1: 抓取官网资料**
|
||||
|
||||
用 WebFetch 依次抓取(提取硬事实,忽略模板化文案):
|
||||
- `https://hesupipe.com/`(已抓取过:公司概况/十大产品线/联系方式)
|
||||
- `https://hesupipe.com/about-us/`(或等价关于页)
|
||||
- 产品分类页(HDPE/PVC/PPR 等主要品类页,取规格范围)
|
||||
- `https://hesupipe.com/certificates/`(认证清单)
|
||||
- `https://hesupipe.com/sales-network/`(销售网络/出口国家)
|
||||
- 新闻页 1-2 篇真实项目案例(如智利农业供水管项目)
|
||||
|
||||
- [ ] **Step 2: 重写事实卡**
|
||||
|
||||
保留参考项目事实卡的**结构框架和使用规则段**(防编造的"统一兜底/不扩展"原则原样保留),替换内容段。结构:
|
||||
|
||||
```markdown
|
||||
# HESUPIPE 公司事实卡
|
||||
## 公司概况
|
||||
(1998年成立/2007年起出口/河南郑州/高新技术企业——只写官网可验证的)
|
||||
## 产品线总表
|
||||
(HDPE管道及管件/HDPE波纹管/PVC管道及管件/PVC电工套管/PPR管道/球墨铸铁管/法兰阀门/HDPE渔网箱/门窗类——每类一行主要规格范围,如 DN20-DN1200)
|
||||
## 应用领域
|
||||
(市政给水/燃气油气/排水排污/农业灌溉/电气保护/疏浚/海水养殖)
|
||||
## 认证
|
||||
(证书页实际列出的,逐条;没有就整节省略,不编)
|
||||
## 销售网络与出口市场
|
||||
(官网实际提及的国家/地区)
|
||||
## 使用规则(原样保留参考项目的兜底原则)
|
||||
(未列出的一律说"转客户经理确认";禁止推测/扩展/编造)
|
||||
```
|
||||
|
||||
**红线自查**:不含价格、交期、MOQ、产能数字;不收录"world-class"类模板化空话。
|
||||
|
||||
- [ ] **Step 3: 更新 test_company_facts.py 断言**
|
||||
|
||||
改为断言建材关键词(如 `HESUPIPE`、`HDPE` 或实际产品词)存在、汽车词(`BYD`/`Hesu Auto`/`vehicle`)不存在。
|
||||
|
||||
- [ ] **Step 4: 跑测试**
|
||||
|
||||
```bash
|
||||
python -m pytest tests/test_company_facts.py -q
|
||||
```
|
||||
预期:PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "feat: HESUPIPE 公司事实卡(官网硬事实+防编造规则)"
|
||||
```
|
||||
|
||||
**⚠️ 审核关卡(设计文档§4.2)**:事实卡完成后请需求方业务侧过目确认后方可上线(可异步,不阻塞后续任务)。
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 系统提示词 system.md 重写
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/prompts/system.md`(整篇重写,框架保留)
|
||||
|
||||
- [ ] **Step 1: 重写 system.md**
|
||||
|
||||
保留参考项目的六段结构,逐段建材化:
|
||||
|
||||
1. **语言规则(最高优先级)**:保留"客户用什么语言就用什么语言回复,默认英语";**新增**:拒绝价格/交期/MOQ/样品费等实质问题时,回复中必须包含固定英文短句 `Please leave your contact and our manager will send the full quotation.`(保证输出墙正则可靠命中)
|
||||
2. **职能边界**:AI 只做需求了解+留资;价格/交期/MOQ/装柜方案/样品费/认证清单/库存→转客户经理;问实质问题时若已知意向品类:"确认品类+引导留资"一气呵成
|
||||
3. **红线**:不出现价格数字(含复述客户预算);不输出电话/邮箱;不再三索要已留资客户的联系方式
|
||||
4. **说话风格**:外贸销售式简短口语;时效承诺用 "reply within 12 hours"(不提中国作息)
|
||||
5. **对话推进**:预算路径改为 `"Which application? Water supply, gas, drainage or irrigation?"`;规格追问(口径/压力/标准);围绕已说品类推进
|
||||
6. **好差示例**:6-8 组管道场景(例:客户说 "PE100 water pipe DN110",差:泛问 what do you need;好:确认 SDR11/SDR17? + 询问工程量;中文话术示例同步改管道语境)
|
||||
|
||||
- [ ] **Step 2: 自查清单**
|
||||
|
||||
- [ ] 所有汽车词(car/vehicle/BYD/Toyota/test drive/提车/试驾/续航)已清零:`grep -in "car\b\|vehicle\|byd\|toyota\|test drive\|试驾\|提车\|续航" app/prompts/system.md` 预期无输出
|
||||
- [ ] 红线覆盖:MOQ、lead time、container loading、sample fee、certificate、price range
|
||||
- [ ] 固定英文拒绝短句原样出现(与 boundary_filter 的 DEFLECTIONS 措辞协调但不冲突——prompt 是"含义",墙是"兜底")
|
||||
|
||||
- [ ] **Step 3: 跑全量测试(system.md 变更影响的测试)**
|
||||
|
||||
```bash
|
||||
python -m pytest -q
|
||||
```
|
||||
预期:PASS(若有断言 system.md 内容的测试,同步更新)
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "feat: 系统提示词建材化(管道外贸人设+多语言拒绝短句)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 提取与评估提示词(extractor.md / evaluator.md)
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/prompts/extractor.md`、`app/prompts/evaluator.md`
|
||||
|
||||
- [ ] **Step 1: 重写 extractor.md 字段定义**
|
||||
|
||||
中文键画像字段改建材语义(设计文档§4.3):
|
||||
- `意向品类`(HDPE给水管/PVC排水管/PPR…)
|
||||
- `规格要求`:**自由文本保留客户原话**(如 "DN110 PE100 SDR11"),明确指示不拆分不过度结构化
|
||||
- `标准要求`:单独一列(ISO4427/ASTM/EN/SCH 系列,客户提到才记)
|
||||
- `采购数量`、`用途`(给水/燃气/排污/灌溉/…)、`项目类型`、`目标国家`、`预算提及`、`联系方式`字段原样保留参考项目机制
|
||||
|
||||
- [ ] **Step 2: 重写 evaluator.md 评估语义**
|
||||
|
||||
三级保留;示例改管道采购:明确品类+规格+数量=interested;仅泛泛浏览=pending;明确无采购计划=not_interested。
|
||||
|
||||
- [ ] **Step 3: 新增 extractor 字段静态断言测试(spec §9.1 第4条落地)**
|
||||
|
||||
`tests/test_company_facts.py` 风格,新建断言:extractor 提示词加载后包含
|
||||
`意向品类`、`规格要求`、`标准要求` 字段定义,且不含 `车型`/`意向品牌` 汽车字段。
|
||||
先跑红(当前还是汽车字段),重写后跑绿。
|
||||
|
||||
- [ ] **Step 4: 跑全量测试并 Commit**
|
||||
|
||||
```bash
|
||||
python -m pytest -q && git add -A && git commit -m "feat: 提取/评估提示词建材化(规格自由文本+标准单列)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 多语言输出墙 boundary_filter.py(TDD 核心)
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/services/boundary_filter.py`
|
||||
- Test: `tests/test_boundary_filter.py`
|
||||
|
||||
- [ ] **Step 1: 先写失败的多语言墙测试**
|
||||
|
||||
在 `tests/test_boundary_filter.py` 追加(沿用该文件现有参数化风格):
|
||||
|
||||
```python
|
||||
# ---- 多语言价格墙(建材市场扩充): 必须拦截 ----
|
||||
MULTILINGUAL_PRICE_HITS = [
|
||||
"El precio es 500 dólares", # 西语 词前置
|
||||
"Costo por tonelada 320", # 西语
|
||||
"O preço é 1200 reais", # 葡语(巴西)
|
||||
"Цена 500 за тонну", # 俄语
|
||||
"Стоимость 800 долларов", # 俄语
|
||||
"السعر 500 دولار", # 阿语
|
||||
"€500 per ton", # 欧元符号
|
||||
"£420 per container", # 英镑符号
|
||||
"500 dólares", # 数字+货币词后缀
|
||||
"Delivery in 15 días", # 西语时间承诺
|
||||
"Срок 2 недели", # 俄语时间承诺
|
||||
]
|
||||
# ---- 建材规格形态: 不得误杀 ----
|
||||
SPEC_NON_HITS = [
|
||||
"DN800 double wall corrugated pipe",
|
||||
"PN16 pressure rating",
|
||||
"SDR11 and SDR17 both available",
|
||||
"PE100 material",
|
||||
"600mm diameter",
|
||||
"SCH40 and SCH80",
|
||||
"3/4 inch and 2 inch sizes",
|
||||
"ISO4427 certified",
|
||||
"20ft container load", "40ft HQ",
|
||||
"5.8m and 11.8m lengths",
|
||||
"PE80 PE100 grades",
|
||||
]
|
||||
```
|
||||
|
||||
断言:前者每个 `violates_boundary(s)` 为 True;后者每个为 False。
|
||||
|
||||
- [ ] **Step 2: 跑测试确认失败**
|
||||
|
||||
```bash
|
||||
python -m pytest tests/test_boundary_filter.py -q
|
||||
```
|
||||
预期:多语言 HITS 用例 FAIL(现有正则拦不住)
|
||||
|
||||
- [ ] **Step 3: 扩充 PRICE_PATTERNS**
|
||||
|
||||
在 `PRICE_PATTERNS` 列表追加(保持参考项目"注释说明设计意图"的风格):
|
||||
|
||||
```python
|
||||
# ---- 多语言墙(建材市场: 欧/英/南美/俄语区/中东) ----
|
||||
# 货币符号: €/£ 参考项目只有 $
|
||||
re.compile(r"[€£]\s?\d"),
|
||||
# 价格名词前置(西/葡/俄/阿): 词后 0-20 非数字字符内出现数字
|
||||
re.compile(r"(?:precio|costo|custo|preço|цена|стоимость|سعر|ثمن)[^\d\n]{0,20}\d", re.I),
|
||||
# 货币名词后置(数字+货币词)
|
||||
re.compile(r"\d[\d,.]*\s*(?:d[óo]lares?|euros?\b|рублей|руб\.?)", re.I),
|
||||
# 多语言时间承诺(与英文 days/weeks 组同构)
|
||||
re.compile(r"\d+\s*[- ]?(?:d[ií]as?|semanas?|дн(?:ей|я)|недел[ьи]|أيام)\b"),
|
||||
```
|
||||
|
||||
同时审查现有汽车特定排除项:
|
||||
- `\d[\d,.]*\s*(usd|美元|块钱|万块?(?!\s*(公里|km)))` 的 `公里|km` 排除 → 建材语境已无里程语义,但保留无害;确认不误杀建材形态
|
||||
- `(两|三|四|五|六|七|八|九|十)\s*万(?!\s*(公里|km))` 保留(中文预算)
|
||||
- 时间承诺 `\d+\s*[- ]?(day|week|month)s?\b` 保留(英文交期承诺)
|
||||
|
||||
- [ ] **Step 4: 跑测试至全绿**
|
||||
|
||||
```bash
|
||||
python -m pytest tests/test_boundary_filter.py -q
|
||||
```
|
||||
预期:PASS(含原有全部用例不回归)
|
||||
|
||||
- [ ] **Step 5: 迂回话术建材化 + ES 话术池(spec §6 第3层)**
|
||||
|
||||
1. **行业残留清零**(用户可见输出,实测在参考项目 L54/L57):
|
||||
- `DEFLECTIONS_EN_CONTACT` 的 "Anything else about the cars?" → "...about pipes?"
|
||||
- `DEFLECTIONS_ZH_CONTACT` 的 "还想了解什么车?" → "还想了解什么管道产品?"
|
||||
- 全文件扫一遍 DEFLECTIONS/PIVOTS/NO_CONTACT 各池,确认无其他汽车措辞
|
||||
2. **新增 ES 话术池**(南美第一大流量,spec §6.3):
|
||||
- 新增 `DEFLECTIONS_ES`、`DEFLECTIONS_ES_CONTACT`、`PIVOTS_ES`、`PIVOTS_ES_CONTACT`
|
||||
(西语版话术,如 "El precio exacto te lo envía nuestro gerente por WhatsApp, ¿me lo dejas?")
|
||||
- `deflection_for()` / `pivot_for()` 现为"汉字→ZH,否则 EN"二分支,扩展为三分支:
|
||||
汉字 → ZH;西语特征(`re.search(r"[áéíóúñ¿¡]", msg)` 粗匹配,与参考项目
|
||||
汉字检测同构)→ ES;否则 → EN
|
||||
3. **测试**:`tests/test_boundary_filter.py` 追加——西语消息选 ES 池、英文选 EN、
|
||||
中文选 ZH;"cars"/"什么车" 不再出现在任何话术池
|
||||
|
||||
- [ ] **Step 6: 同步 scripts/breach_rate.py**
|
||||
|
||||
把上述新词表同步进 breach_rate.py 的统计模式(保持与墙一致,供上线观察期用)。
|
||||
|
||||
- [ ] **Step 7: 全量测试 + Commit**
|
||||
|
||||
```bash
|
||||
python -m pytest -q && git add -A && git commit -m "feat: 多语言输出墙(€/£/西葡俄阿价格词+时间承诺+ES话术池)+话术建材化+防误杀"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 会话编排与联系方式管道建材化
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/services/conversation.py`、`app/services/contact_pipeline.py`
|
||||
- Test: `tests/test_contact_pipeline.py`、`tests/test_context_seeding.py`
|
||||
|
||||
- [ ] **Step 1: 先写失败的阿语数字测试**
|
||||
|
||||
`tests/test_contact_pipeline.py` 追加:
|
||||
|
||||
```python
|
||||
def test_arabic_digits_normalized():
|
||||
# 阿语数字(中东买家)提取后应转 ASCII,CRM 可直接拨
|
||||
confirmed, _ = split_validate({"whatsapp": "+٩٦٦٥٠١٢٣٤٥٦٧"})
|
||||
assert confirmed["whatsapp"] == "+966501234567"
|
||||
```
|
||||
|
||||
(具体 API 名以参考项目实际函数签名为准——`split_validate`/canon 归一化入口。)
|
||||
|
||||
- [ ] **Step 2: 跑测试确认失败**
|
||||
|
||||
```bash
|
||||
python -m pytest tests/test_contact_pipeline.py -q -k arabic
|
||||
```
|
||||
预期:FAIL(号码原样保留阿语数字)
|
||||
|
||||
- [ ] **Step 3: 实现数字归一化**
|
||||
|
||||
`contact_pipeline.py` 顶部加:
|
||||
|
||||
```python
|
||||
# Unicode 十进制数字 → ASCII(阿语٠-٩/波斯语۰-۹), 中东买家号码 CRM 可直接拨
|
||||
_DIGIT_TRANSLATE = str.maketrans("٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹", "01234567890123456789")
|
||||
```
|
||||
|
||||
在归一化入口(normalize_contacts/digits_only 调用链的最前端)对值做 `v.translate(_DIGIT_TRANSLATE)`。注意:正则 `\d` Unicode 模式本就匹配阿语数字,位数校验能过——本步只解决"存进去的形式"。
|
||||
|
||||
- [ ] **Step 4: conversation.py 建材化**
|
||||
|
||||
1. `BOUNDARY_TRIGGER_RE`:确认已含 MOQ/lead time/delivery time/sample/certificate 类词;补 `container loading|装柜|起订`(以实际正则现状为准增补)
|
||||
2. context 种子白名单:`vehicle_name/vehicle_id` → `product_name/product_id`
|
||||
3. `_build_context_reminder`/`_enrich_short_message` 中的车型话术 → 产品方案话术
|
||||
4. 同步更新 `tests/test_context_seeding.py` 的键名
|
||||
|
||||
- [ ] **Step 5: 全量测试 + Commit**
|
||||
|
||||
```bash
|
||||
python -m pytest -q && git add -A && git commit -m "feat: 会话编排建材化+阿语号码转ASCII"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: 服务端杂项更名
|
||||
|
||||
**Files:**
|
||||
- Modify: `app/main.py`、`app/services/email_service.py`、`app/api/routes/chat_rest.py`、`app/services/rate_limit.py`、`app/config.py`(如有 DB 默认名)
|
||||
|
||||
- [ ] **Step 1: 逐文件更名**
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `app/main.py` | FastAPI(title="AI汽车客服") → title="HESUPIPE AI 客服" |
|
||||
| `app/services/email_service.py` | 发件人 `【XYH】` → `【HESUPIPE】`;确认无汽车字段引用 |
|
||||
| `app/api/routes/chat_rest.py` | docstring "HESU app" → HESUPIPE;种子键名若此处再有引用同步 |
|
||||
| `app/services/rate_limit.py` | docstring "Mirrors hesu's" 更新 |
|
||||
| `app/config.py` + `.env.example` | DATABASE_URL 默认 `data/hesupipe_ai_kefu.db` |
|
||||
|
||||
- [ ] **Step 2: 全局残留扫描**
|
||||
|
||||
```bash
|
||||
grep -rin "汽车\|vehicle\|byd\|toyota\|hesu auto\|borderlesscar\|VOLT\|XYH\|cc-ai-kefu\|cc_ai_kefu\|car\b\|cars\|什么车\|车型\|车价" app/ tests/ scripts/ --include="*.py" | grep -v "docs/"
|
||||
```
|
||||
预期:无输出(docstring/注释里的行业残留一并清零;`car\b|cars|什么车|车型` 抓 boundary_filter 话术池等用户可见输出)。
|
||||
|
||||
- [ ] **Step 3: 全量测试 + Commit**
|
||||
|
||||
```bash
|
||||
python -m pytest -q && git add -A && git commit -m "chore: 服务端品牌与行业残留更名清零"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 8: 部署配置更名
|
||||
|
||||
**Files:**
|
||||
- Modify: `docker-compose.yml`、`deploy.sh`、`openresty.conf`、`.env.example`
|
||||
|
||||
- [ ] **Step 1: 更名**
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `docker-compose.yml` | 容器名 `cc-ai-kefu`→`hs-ai-kefu`;端口 `8016:8000`→`8017:8000`(redis 服务已在 Task1 删) |
|
||||
| `deploy.sh` | 健康检查 URL 8016→8017 |
|
||||
| `openresty.conf` | upstream `cc_ai_kefu`→`hesupipe_ai_kefu`;127.0.0.1:8016→8017;alias `/www/cc_ai_kefu/`→`/www/hesupipe_ai_kefu/`;日志名同步(含注释掉的 HTTPS 段) |
|
||||
| `.env.example` | `APP_PORT=8017`;`PUSH_EXTERNAL_KEY_PREFIX=ai-kefu-jc`;`PUSH_ENABLED=false`(开发期) |
|
||||
|
||||
- [ ] **Step 2: 残留扫描**
|
||||
|
||||
```bash
|
||||
grep -rn "cc_ai_kefu\|cc-ai-kefu\|8016" docker-compose.yml deploy.sh openresty.conf .env.example
|
||||
```
|
||||
预期:无输出。
|
||||
|
||||
- [ ] **Step 3: 测试 + Commit**
|
||||
|
||||
```bash
|
||||
python -m pytest -q && git add -A && git commit -m "chore: 部署配置更名(hs-ai-kefu/8017/hesupipe_ai_kefu)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 9: 前端建材化(文案/主题/GDPR + 静态断言同步)
|
||||
|
||||
**Files:**
|
||||
- Modify: `static/chat.html`、`static/widget.js`、`static/js/chat.js`、`static/js/theme.js`、`static/admin.html`、`static/widget-test.html`
|
||||
- Test: `tests/test_invite_static.py`、`tests/test_theme_static.py`
|
||||
|
||||
- [ ] **Step 1: 了解静态测试的真实性质(避免走错路)**
|
||||
|
||||
`tests/test_invite_static.py`/`test_theme_static.py` 是**结构回归网**,不是文案断言——
|
||||
它们断言的是邀请卡面板出厂 hide、pointer-events、回流顺序、theme.js 与 widget.js
|
||||
调色板逐字同步、无残留旧色 hex 等结构性质。所以本任务的测试策略是:
|
||||
**直接改前端文件,然后跑结构回归测试防破坏**(它们会在你漏改某处色值/结构时指路)。
|
||||
|
||||
- [ ] **Step 2: 前端文案与配置**
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `chat.html` | 标题 `HESUPIPE Support`;描述管道场景;欢迎语 "What kind of piping project are you working on?";热门话题 Get Quotation / Pipe Specifications / Delivery & Shipping;WhatsApp `+8615937108317`;邮箱 `hesu@hesuu.com` |
|
||||
| `widget.js` | 默认 title/whatsapp/email 同上;邀请卡文案管道化(pipe specs, MOQ, delivery timing);话题按钮同步 |
|
||||
| `js/chat.js` | WhatsApp/email fallback 默认值同步 |
|
||||
| `admin.html` | VOLT → HESUPIPE(title/header/头像字母) |
|
||||
| `js/theme.js` | 默认品牌色橙 `#f08a31` → HESUPIPE 品牌蓝(从 hesupipe.com CSS 取实际主色值)。⚠️ 色值有**三处**要同步:`theme.js` 的 DEFAULT_COLOR、`widget.js` 的 DEFAULT_PALETTE(内联副本,测试强制两份一致)、`css/style.css` 的 `:root` 槽位值——漏任何一处 test_theme_static 会红 |
|
||||
| `widget.js` | **GDPR 行**:首次对话邀请卡/首条消息附加 "By chatting, you agree to our privacy policy."(链接指向 hesupipe.com 隐私政策页,URL 实施时与需求方确认,可先 `https://hesupipe.com/privacy-policy/` 占位) |
|
||||
| 头像 | `kefu.png`/`kefu-small.png` 替换(需求方提供 logo 或用品牌蓝底 "H" 字母临时生成) |
|
||||
|
||||
- [ ] **Step 3: 跑静态断言与全量测试至绿**
|
||||
|
||||
```bash
|
||||
python -m pytest tests/test_invite_static.py tests/test_theme_static.py -q
|
||||
python -m pytest -q
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 残留扫描 + Commit**
|
||||
|
||||
```bash
|
||||
grep -rin "HESU Support\|hesu auto\|vehicle\|VOLT\|borderlesscar\|1903717\|f08a31" static/ | grep -v blog
|
||||
git add -A && git commit -m "feat: 前端HESUPIPE品牌化+管道文案+GDPR提示"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 10: 全量回归与收尾扫描
|
||||
|
||||
**Files:** 无新增(验证任务)
|
||||
|
||||
- [ ] **Step 1: 全仓行业残留终扫**
|
||||
|
||||
```bash
|
||||
grep -rin "汽车\|vehicle\|byd\|toyota\|test drive\|试驾\|提车\|hesu auto\|borderlesscar\|VOLT\|XYH\|cc_ai_kefu\|cc-ai-kefu\|car\b\|cars\|什么车\|车型\|车价" app/ static/ tests/ scripts/ *.yml *.sh *.conf 2>/dev/null
|
||||
```
|
||||
预期:仅 docs/ 归档 changelog 里有(允许——历史档案)。
|
||||
|
||||
- [ ] **Step 2: 全量测试**
|
||||
|
||||
```bash
|
||||
python -m pytest -q
|
||||
```
|
||||
预期:全绿(170+,含新增多语言/阿语数字用例)
|
||||
|
||||
- [ ] **Step 3: 本地起服务冒烟**
|
||||
|
||||
```bash
|
||||
python -m uvicorn app.main:app --port 8017 &
|
||||
curl -s http://127.0.0.1:8017/health
|
||||
# 预期 {"status":"ok"} 类响应; 浏览器开 http://127.0.0.1:8017/ 与 /admin 目检
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Commit(如有收尾改动)**
|
||||
|
||||
---
|
||||
|
||||
### Task 11: 真人验收(真实 LLM + mock 推送联调)
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/test-checklist.md`(基于参考项目同名文件改写)
|
||||
- 临时: `.env` 填真实智谱 Key
|
||||
|
||||
- [ ] **Step 1: 编写真人验收清单**
|
||||
|
||||
按设计文档 §9.2 全项写入 `docs/test-checklist.md`(问价×2语言/MOQ/样品/交期/认证→转留资;留资→画像+邮件[测试邮箱]+mock推送;换号→更正邮件;已留资不再索要;规格聊天不误杀;后台三视图核对)。
|
||||
|
||||
- [ ] **Step 2: 起 mock UniService 并配置联调**
|
||||
|
||||
```bash
|
||||
python scripts/mock_uniservice.py & # 本地假CRM, 默认端口 9099
|
||||
```
|
||||
`.env`:`PUSH_ENABLED=true`、`PUSH_API_URL=http://127.0.0.1:9099/open/v1/inquiry/push`、
|
||||
`PUSH_API_KEY=test-key-123`(mock 脚本期待的固定 Key,不设会 401)、
|
||||
NOTIFY_EMAIL=测试邮箱、真实智谱 Key。
|
||||
|
||||
- [ ] **Step 3: 逐项真人验收**
|
||||
|
||||
按清单实聊(英文+西语+中文三种语言各至少一轮完整留资流程)。核对:邮件收到、mock 推送 accepted、admin 后台画像/意向/日志正确。
|
||||
|
||||
- [ ] **Step 4: 修复发现的问题直至清单全过 + Commit**
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "test: 真人验收清单+联调修复"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 12: 交付物(嵌入代码/说明/CLAUDE.md)
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/embed-guide.md`、`CLAUDE.md`、`README.md`
|
||||
|
||||
- [ ] **Step 1: 官网嵌入说明 docs/embed-guide.md**
|
||||
|
||||
内容:一段可粘贴的挂件代码(script 标签+data-* 配置示例:位置/主题色/WhatsApp/自动邀请),贴到 WordPress 哪里(页脚模板或主题设置)、隐私政策页要求。给官网管理员一页读完即可操作。
|
||||
|
||||
- [ ] **Step 2: CLAUDE.md 血缘记录**
|
||||
|
||||
记录:上游参考项目 `D:\refactor\ai-kefu`、85%同源、上游修bug需对照其 `docs/` changelog 手动同步、本项目 external_key 前缀 ai-kefu-jc、开发期 PUSH 关闭约定、上线观察期跑 breach_rate.py。
|
||||
|
||||
- [ ] **Step 3: README.md**
|
||||
|
||||
项目简介/本地启动(pip install、.env、uvicorn)/测试(pytest)/部署(deploy.sh+openresty)/管理后台入口。
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "docs: 官网嵌入指南+CLAUDE.md血缘+README"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 上线切换(验收全过后,需求方操作确认)
|
||||
|
||||
1. `.env` 切生产:`PUSH_API_URL` 指真实 UniService、真实 API Key、NOTIFY_EMAIL=客户经理邮箱
|
||||
2. 服务器部署:`deploy.sh`(端口 8017)+ openresty 域名配置(需求方提供,如 ai.hesupipe.com)
|
||||
3. 官网按 `docs/embed-guide.md` 嵌入挂件
|
||||
4. **第一周观察期**:跑 `scripts/breach_rate.py` 看漏放/误杀,发现即补正则(设计文档 §9.3)
|
||||
Reference in New Issue
Block a user