Files
ai-kefu-admin/CLAUDE.md
T
浅念 0bf492c1e4 chore: Phase 1 收尾——引擎合并租户化完成(审计+清单核对+CLAUDE.md/清理单)
- 全量回归 459 passed(根目录与 tests/ 子目录双跑一致)
- 零同步 IO 审计: requests/urllib/time.sleep 在 app/ 零命中; 唯一 HTTP
  出站点 lead_push _do_post 为 httpx.AsyncClient; glm 同步路径经
  executor/to_thread 下卸; 结论写入 CLAUDE.md
- spec §6.2 合并清单逐项核对全部在位(jc 六项/上游吸收/三不带),
  核对明细写入 CLAUDE.md Phase 1 完成状态段
- CLAUDE.md 新增 Phase 2 清理单(10 项挂账含出处)与 Phase 2 计划
  编写注意(conftest 跨循环纪律/夹具复用);修正过时的 tests 目录描述
- README.md 扩为现状能力一览 + 本地跑法指向 CLAUDE.md

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-12 23:51:26 +08:00

65 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md — all-kefu 工作约定
## 项目定位
本项目 all-kefu 是**统一多租户 AI 客服平台**:一套引擎 + 租户配置包,消除"每客户复制一套代码"的旧模式。项目由 ai-kefu / ai-kefu-jc 两个复制分叉项目合并而来,**jc 为主线**(代码以 ai-kefu-jc 为基础迁移,再做租户化改造)。
## 硬约束
- **uvicorn 必须以 `--workers 1` 运行**。内存中的 token 缓存、限流状态、配置缓存、每租户 engine 缓存均假设单进程,多 worker 会导致状态割裂。任何启动脚本/部署配置不得改动此项。
- **Windows 环境**:跑 python / pytest 前设置 `PYTHONUTF8=1`(GBK 控制台遇 emoji / 中文 payload 会直接崩,血泪教训)。
## 本地开发访问方式
- 路由按 Host 解析租户:`/` 与 `/static` 也需要已知租户域名(未知 Host 一律 404,唯一豁免 `/health`,供部署健康检查 curl 用)。
- 本地访问二选一:改 hosts 把 `chat.agent.hnxinyouhe.com` / `chat2.agent.hnxinyouhe.com` 指到 `127.0.0.1`;或 curl 显式带 `-H "Host: chat2.agent.hnxinyouhe.com"`。
- uvicorn 起在 8018:`PYTHONUTF8=1 .venv/Scripts/python -m uvicorn app.main:app --port 8018 --workers 1`。
## 开发流程
- 改动 `seed_profiles` 后必须跑全量 pytest(出厂配置影响面大)。
- 全量回归命令:`PYTHONUTF8=1 .venv/Scripts/python -m pytest -q`(根目录与 tests/ 子目录均可跑,pytest.ini 已锚定根路径)。
## Phase 1 完成状态(2026-10-12 收尾核对)
**测试基线:459 passed**(根目录与 tests/ 子目录各跑一遍,数字一致;唯一 warning 为 starlette TestClient 对 httpx 的弃用提示,无害)。收尾提交前基线即此数,后续任务回归以此为准。
**零同步 IO 审计**(`grep -rn "requests\.\|urllib\|time\.sleep" app/`):
- 命中数 **0**——app/ 内无 requests 调用、无 urllib、无 time.sleep。
- 全库唯一 HTTP 出站点为 `app/engine/services/lead_push_service.py` `_do_post`,使用 `httpx.AsyncClient`(async with 上下文),异步路径成立。
- `app/engine/providers/glm.py` 的同步 token 生成与兜底同步调用分别经 `loop.run_in_executor` / `asyncio.to_thread` 下卸,事件循环不被阻塞。
- `app/engine/services/rate_limit.py` 的 `import time` 仅用 `time.time()` 读时钟(纯 CPU,非 IO);app/ 源码内无 `open()` 文件读取。
**spec §6.2 合并清单核对**(逐项,全部在位):
- 取自 jc:cc_completion 完整判定树+状态机+extractor `cc_reply`+e164 出站渲染(`app/engine/services/cc_completion.py`,conversation.py 双门控消费);多语言墙(€/£、西/葡/俄/阿词表在 `seed_profiles/jiancai/wall.json`、ES 迂回池 boundary_filter+wall.json、建材防误杀白名单为 pattern 级 comment+后顾断言 DN800/SDR11/PN16/"euro pallets" 排除);dual-contact 分步双要(cc_settled 串行门控邮箱轻补)+`_email_asked`;CC 强制墙(conversation.py cc_wall 裁决段)+零号码墙回显豁免收窄(boundary_filter.py:旧豁免移除,改 allow_number 回显确认轮白名单+防自锁线);XFF 服务端优先(chat_rest `_server_ip`/chat.py 握手期提取,均取第一段)、阿语数字归一(contact_pipeline 捕获源头 translate)、`resolve_region_code`(ip_service.py)。
- 上游吸收:input-placeholder 可配置化(品牌配置组,public.py 下发,widget/chat data-placeholder 管道);7 个测试文件(test_channel_hygiene / test_chat_rest_ip / test_lead_push_cc / test_cc_integration / test_ip_service_region / test_prompt_static / test_placeholder_static,commit d1aed8e)。
- 三不带:blog.html(static/ 无此文件)、Redis(app+scripts 零命中)、旧版 whatsapp-cc-completion(零命中,jc 版 cc_completion.py 取代)。
**当前能力一览**:多租户引擎(TenantRuntime 隔离边界,engine 不感知 platform);站点模型(tenant_config.Site,一租户多站点覆盖);词表/提示词/品牌全配置化(seed_profiles 出厂包 + platform.db 热加载);Host 路由(host_middleware,未知 Host 404);WS 防串库(租户化 client key + 会话站点标);WS 每 IP 连接上限(conn_limiter,租户级 ws_conn_limit 配置)。
## Phase 2 清理单(前序审查挂账,集中列此)
1. **FakeAI 三份拷贝收敛进 conftest**——下次吸收测试时先做(出处:上游吸收审查,tests/ 内多处 FakeAI 定义重复)。
2. **rate_limit 与 ws_conn_limit 的 0 语义统一 + 配置类型校验**——试金石批次(出处:配置接线审查)。
3. **name_to_region_extras / context_seed_map 等散装 resolver 收拢为 config_views 单入口**(出处:配置接线审查"种子映射消双路径"遗留)。
4. **AIService.from_runtime 类方法**——组装正典化(出处:引擎改造审查)。
5. **boundary_filter 视图常量退役**——admin 重写后旧测试迁移时(出处:引擎改造审查)。
6. **push enabled 布尔空槽语义**——admin 配置显式化时解决(出处:push 审查)。
7. **contact.template_languages 运行期接线**——后台批次(出处:配置 schema 审查)。
8. **话术含引号/换行的转义**——编辑器批次(`_format_deflection_pool` docstring 有注)。
9. **产品决策项**:国名纠正 e164 变化时是否补发更正邮件(上游行为更优);REST/WS 服务端 IP 口径是否统一(出处:上游吸收审查)。
10. **avatar 从 seed_profiles 迁 uploads 卷**——上传功能落地时(出处:品牌下发审查)。
## Phase 2 计划编写注意
- conftest 跨循环纪律:`async_db` 夹具用 NullPool;TestClient 必须走 portal 桥接事件循环;禁止 `asyncio.run` 直开租户 session_factory(三个坑都在 tests/conftest.py 有既成解法,照抄勿发明)。
- `build_app` / `app_client` / `TenantTestClient` 夹具已就绪,新测试优先复用而非自建 app 实例。
## 文档索引
- 设计文档(spec):`docs/superpowers/specs/2026-10-12-unified-kefu-platform-design.md`
- Phase 1 实施计划:`docs/superpowers/plans/2026-10-12-phase1-engine-merge-tenantization.md`
- 部署坑手册:Phase 4 补 `docs/deploy-production.md`(尚未存在)