P0/M1: 四部分重构——frontend→ui、backend→sdk 改名 + 引用修复 + 骨架

- git mv 保留历史:ui/(Vue3+Vite)、sdk/(BFF 中间层)
- 路径语义修正:db_path/figures_cache 改相对 sdk/(BFF cwd),
  历史库 sdk/backend/data 迁移至 sdk/data/(会话/图片缓存无损)
- 引用修复 ~15 处:config.py、deploy/*.sh、vitest/playwright 配置、
  单测导入路径、docs、README、gitignore、.env.example
- 骨架:agent/{qa,methodology,legacy-rag,vendor}、knowledge/manifest.yaml、
  tooling/{compile,kb,crypto,assemble,audit,tools,scripts} + README
- 门禁验证:sdk pytest 125 通过、ui vitest 158 通过、
  生产 BFF 脚本重启四上游全绿 + 静态托管 + 会话库无损

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jerry
2026-08-31 12:56:47 +08:00
co-authored by Claude Fable 5
parent 71189567ee
commit 0875bb036c
159 changed files with 222 additions and 174 deletions
+2 -2
View File
@@ -40,7 +40,7 @@
- 验收脚本:`deploy/m5_acceptance.js`(15 断言,chromium headless)
- 运行位置:远端(真实 BFF 8090 生产形态 + Vite 5180 开发形态双链路)
- 用时:约 3 分钟(含一次真实 QA ≈ 50s)
- 期间修复:BFF 静态托管 dist 路径解析(`backend/frontend/dist` → 项目根解析,2026-08-25 PM)
- 期间修复:BFF 静态托管 dist 路径解析(`sdk/ui/dist` → 项目根解析,2026-08-25 PM)
## 5. 结论
@@ -49,4 +49,4 @@
下一步建议(用户决策,不在本次范围):
- DeepSeek 充值 → 验证自然语言答案质量
- 长期运行监控(/api/health 轮询、上游探活)
- 可选:laptop 档 E2E project 补齐、tests/backend L2 respx 独立测试
- 可选:laptop 档 E2E project 补齐、tests/sdk L2 respx 独立测试
+19 -19
View File
@@ -61,11 +61,11 @@
| BFF 监听 | `127.0.0.1:8090`(占用则退 8091) |
| Vite dev | `127.0.0.1:5180`(占用则退 5181) |
| BFF conda 环境 | `plantai-bff`(Python 3.11,新建,**不复用** `gfpy312`) |
| SQLite 路径 | `backend/data/plantai.db`(WAL 模式) |
| SQLite 路径 | `sdk/data/plantai.db`(WAL 模式) |
| 前端工具链 | Vite **5.4.x** + @vitejs/plugin-vue **5.2.x** + Vue **3.5.x** + Pinia **2.3.x** |
| Node | v18.19.1(已 EOL)——**禁止升级 Vite 至 7**(需 Node 20+),**禁止用 `npm create vite`** |
生产形态:`npm run build` 产出 `frontend/dist`,BFF 用 `StaticFiles` 挂载,单进程从 `:8090` 提供服务。
生产形态:`npm run build` 产出 `ui/dist`,BFF 用 `StaticFiles` 挂载,单进程从 `:8090` 提供服务。
---
@@ -83,7 +83,7 @@
```bash
rsync -az --delete \
--exclude 'node_modules' --exclude '__pycache__' --exclude '.venv' \
--exclude 'backend/data' --exclude 'frontend/dist' --exclude '.pytest_cache' \
--exclude 'sdk/data' --exclude 'ui/dist' --exclude '.pytest_cache' \
/Users/jerry/haiguji/PlantAI-rag-new/ \
100.109.52.26:/home/xzq/5090/teamWorkspace/zh/PlantAI-rag-new/
```
@@ -91,7 +91,7 @@ rsync -az --delete \
**规则**:
- 所有 agent **只在本地路径写文件**,绝不用 SSH heredoc 改代码。
- 同步由 **PM 统一执行**,agent 不自行 rsync(避免半成品覆盖远端)。
- `backend/data`(数据库)、`node_modules`、`dist` 不同步,属远端运行时产物。
- `sdk/data`(数据库)、`node_modules`、`dist` 不同步,属远端运行时产物。
- 文档最终必须在远端 `docs/` 下可查——每次里程碑结束由 PM 同步一次。
---
@@ -102,17 +102,17 @@ rsync -az --delete \
| Agent | 职责 | 独占路径 |
|---|---|---|
| **PM** | 契约文档、集成、缺陷派发、验收、rsync | `docs/{PRD,API,UI_SPEC,ARCHITECTURE,TEST_PLAN,ACCEPTANCE,CHANGELOG}.md`、`deploy/**`、`src/i18n/labels.js`、`src/config/modes.js`、`backend/mock/**` |
| **PM** | 契约文档、集成、缺陷派发、验收、rsync | `docs/{PRD,API,UI_SPEC,ARCHITECTURE,TEST_PLAN,ACCEPTANCE,CHANGELOG}.md`、`deploy/**`、`src/i18n/labels.js`、`src/config/modes.js`、`sdk/mock/**` |
| **D0 探测** | 上游探测与选型 | `docs/DISCOVERY.md` |
| **A1 后端·骨架** | app 工厂、配置、SQLite、会话与消息 CRUD、归一化器、错误信封 | `backend/pyproject.toml`、`backend/run.sh`、`backend/.env.example`、`backend/app/{main,config,db,schemas,upstream}.py`、`backend/app/routers/{health,sessions}.py`、`backend/app/services/normalize.py` |
| **A2 后端·QA** | QA 代理、SSE 中继、阶段映射、重试与看门狗 | `backend/app/routers/qa.py`、`backend/app/services/sse_relay.py` |
| **A3 后端·图谱与抽取** | Neo4j Bolt 直连、抽取代理与回落 | `backend/app/routers/{kg,extraction}.py`、`backend/app/services/{neo4j,extraction}.py` |
| **B1 前端·基础** | 令牌层、AppShell、四档响应式框架、主题、顶栏/底栏、通用 UI、健康轮询 | `frontend/{package.json,vite.config.js,vitest.config.js,index.html}`、`frontend/src/{main.js,App.vue}`、`frontend/src/styles/**`、`frontend/src/components/{layout,ui}/**`、`frontend/src/stores/{theme,health}.js`、`frontend/src/api/http.js`、`tests/frontend/unit/b1/**` |
| **B2 前端·会话与对话** | 会话列表与抽屉、对话区、作曲器、流水线卡、SSE 客户端 | `frontend/src/components/{session,chat}/**`、`frontend/src/stores/{sessions,chat}.js`、`frontend/src/sse/**`、`frontend/src/api/{qa,sessions}.js`、`tests/frontend/unit/b2/**` |
| **B3 前端·工作台** | 右侧四个 tab:检索过程、文献来源、提取任务、知识图谱 | `frontend/src/components/bench/**`、`frontend/src/stores/bench.js`、`frontend/src/api/{kg,extraction}.js`、`tests/frontend/unit/b3/**` |
| **T 测试** | 用例编写与执行、缺陷报告 | `tests/backend/api/**`、`tests/e2e/**`、`playwright.config.js`、`docs/TEST_CASES.md`、`docs/TEST_REPORT_*.md` |
| **A1 后端·骨架** | app 工厂、配置、SQLite、会话与消息 CRUD、归一化器、错误信封 | `sdk/pyproject.toml`、`sdk/run.sh`、`sdk/.env.example`、`sdk/app/{main,config,db,schemas,upstream}.py`、`sdk/app/routers/{health,sessions}.py`、`sdk/app/services/normalize.py` |
| **A2 后端·QA** | QA 代理、SSE 中继、阶段映射、重试与看门狗 | `sdk/app/routers/qa.py`、`sdk/app/services/sse_relay.py` |
| **A3 后端·图谱与抽取** | Neo4j Bolt 直连、抽取代理与回落 | `sdk/app/routers/{kg,extraction}.py`、`sdk/app/services/{neo4j,extraction}.py` |
| **B1 前端·基础** | 令牌层、AppShell、四档响应式框架、主题、顶栏/底栏、通用 UI、健康轮询 | `ui/{package.json,vite.config.js,vitest.config.js,index.html}`、`ui/src/{main.js,App.vue}`、`ui/src/styles/**`、`ui/src/components/{layout,ui}/**`、`ui/src/stores/{theme,health}.js`、`ui/src/api/http.js`、`tests/ui/unit/b1/**` |
| **B2 前端·会话与对话** | 会话列表与抽屉、对话区、作曲器、流水线卡、SSE 客户端 | `ui/src/components/{session,chat}/**`、`ui/src/stores/{sessions,chat}.js`、`ui/src/sse/**`、`ui/src/api/{qa,sessions}.js`、`tests/ui/unit/b2/**` |
| **B3 前端·工作台** | 右侧四个 tab:检索过程、文献来源、提取任务、知识图谱 | `ui/src/components/bench/**`、`ui/src/stores/bench.js`、`ui/src/api/{kg,extraction}.js`、`tests/ui/unit/b3/**` |
| **T 测试** | 用例编写与执行、缺陷报告 | `tests/sdk/api/**`、`tests/e2e/**`、`playwright.config.js`、`docs/TEST_CASES.md`、`docs/TEST_REPORT_*.md` |
后端各 agent 的单测放在各自归属子树内(`backend/app/**/test_*.py`,随代码一起交付),运行 `pytest backend/app -q`;T 的 L2 接口测试与 L5 e2e 放在 `tests/`。
后端各 agent 的单测放在各自归属子树内(`sdk/app/**/test_*.py`,随代码一起交付),运行 `pytest sdk/app -q`;T 的 L2 接口测试与 L5 e2e 放在 `tests/`。
### 跨归属的接缝
@@ -131,10 +131,10 @@ rsync -az --delete \
## 6. 并行解耦:mock server
前端三个 agent **不等待后端**。M0 阶段 PM 产出 `backend/mock/mock_server.py`:
前端三个 agent **不等待后端**。M0 阶段 PM 产出 `sdk/mock/mock_server.py`:
- FastAPI,监听 `127.0.0.1:8099`
- 实现 `API.md` 中**全部**接口,返回 `backend/mock/fixtures/*.json` 里的固定数据
- 实现 `API.md` 中**全部**接口,返回 `sdk/mock/fixtures/*.json` 里的固定数据
- 包含一条**可回放的 SSE 事件序列**(按真实时序 sleep),让流式 UI 能在无上游时开发
- 支持 `?scenario=` 查询参数切换场景:`normal` / `empty`(空结果)/ `slow`(慢响应)/ `error`(上游故障)/ `degraded`(部分降级)
@@ -166,7 +166,7 @@ PlantAI-rag-new/
├── deploy/
│ ├── sync.sh # 本地 → 远端 rsync
│ └── start-dev.sh # 拉起 BFF + vite,打印隧道命令
├── backend/
├── sdk/
│ ├── pyproject.toml run.sh .env.example
│ ├── data/ # plantai.db(不入库、不同步)
│ ├── mock/
@@ -176,7 +176,7 @@ PlantAI-rag-new/
│ ├── main.py config.py db.py schemas.py upstream.py
│ ├── routers/ health.py sessions.py qa.py kg.py extraction.py
│ └── services/ normalize.py sse_relay.py neo4j.py extraction.py
├── frontend/
├── ui/
│ ├── package.json vite.config.js index.html vitest.config.js
│ └── src/
│ ├── main.js App.vue
@@ -192,8 +192,8 @@ PlantAI-rag-new/
│ ├── chat/ ChatPanel、MessageList、Composer、PipelineCard、ToolCard …
│ └── bench/ BenchPanel、RetrievalPane、SourcesPane、ExtractionPane、KgPane …
├── tests/
│ ├── backend/ # pytest
│ ├── frontend/ # vitest
│ ├── sdk/ # pytest
│ ├── ui/ # vitest
│ └── e2e/ # playwright
└── playwright.config.js
```
+5 -5
View File
@@ -5,8 +5,8 @@
- **计划批准**:新前端 + 薄适配层方案获批。端口 8090(BFF)/ 5180(Vite dev),并行部署不切换。
- **M0 启动**:远端目录树建立;8090/5180 端口复核空闲;本地 staging 目录 `/Users/jerry/haiguji/PlantAI-rag-new/` 建立。
- **契约文档定稿**:`PRD.md`(81 个 FR)、`API.md`、`UI_SPEC.md`、`ARCHITECTURE.md`、`TEST_PLAN.md` 完成并锁定。
- **Mock 层完成**:`backend/mock/mock_server.py` + 21 个 fixtures(含 SSE 回放序列)。
- **共享前端文件完成**:`frontend/src/i18n/labels.js`、`frontend/src/config/modes.js`。
- **Mock 层完成**:`sdk/mock/mock_server.py` + 21 个 fixtures(含 SSE 回放序列)。
- **共享前端文件完成**:`ui/src/i18n/labels.js`、`ui/src/config/modes.js`。
- **环境就绪**:`plantai-bff` conda 环境(3.11);npm 依赖 187 包(Vite 5.4.11/Vue 3.5.13);Playwright + Chromium headless shell 131 下载完成;mock server 在 8099 运行并全接口验证通过。
- **D0 探测完成**(`DISCOVERY.md`,345 行)。**契约偏差修正**(基于真实上游):
- Neo4j 当选 `neo4j-plant-srt-direct-v1-full`(bolt 18788,QA 7920 实际使用)。schema 为 **canonical**(`SRT2CanonicalEntity`/`SRT2CanonicalAssertion`),非假设的 `:Entity`;**无全文索引**,名字检索走 `name_norm` 前缀索引(0.09s)。
@@ -21,8 +21,8 @@
- **M0 验收达成**:契约文档、mock(8099 运行中且已按真实上游对齐:canonical schema / queued-runing 派生进度 / run-log JSON)、conda 环境、npm 依赖、Playwright、本地 staging + 远端副本、BFF 骨架 import 通过。
- **本地开发环境补齐**:`.venv-backend`(3.12,供后端 agent 本地自测)+ 本地 node_modules;`deploy/sync.sh` 排除规则修正(`.venv-backend`)。
- **跨归属占位脚手架**:backend/app 全部模块 + frontend main.js/App.vue 占位,由各 agent 在 M1 以真实实现替换。
- **M1 发射**:A1/A2/A3(后端三线)+ B1/B2/B3(前端三线)+ T(测试用例)七个 agent 并行。前端三入口占位组件已由 PM 提供;文件归属含测试目录拆分(`tests/frontend/unit/b1|b2|b3`,后端单测随代码 `backend/app/**/test_*.py`)。
- **跨归属占位脚手架**:sdk/app 全部模块 + ui main.js/App.vue 占位,由各 agent 在 M1 以真实实现替换。
- **M1 发射**:A1/A2/A3(后端三线)+ B1/B2/B3(前端三线)+ T(测试用例)七个 agent 并行。前端三入口占位组件已由 PM 提供;文件归属含测试目录拆分(`tests/ui/unit/b1|b2|b3`,后端单测随代码 `sdk/app/**/test_*.py`)。
- **A1 完成**(15 文件,29 单测全过):config/db/schemas/normalize/upstream/health/sessions/main + pyproject + run.sh + .env.example。7 条偏差全部 PM 裁决通过并回填 API.md(hop 中间态字段、来源聚合取首条、search answer 空串、PATCH 空 body 幂等、title_manual 保护、凭据仅入 BFF 配置、新增 python-multipart)。
- **待办**:A1 报告 A3 的 17 个测试失败(`test_kg.py` 用 ASGITransport 直挂裸 router 与 fastapi 0.141 不兼容;`test_extraction.py` 两处 respx 失败)——待 A3 汇报后统一派发。
- **B3 完成**(工作台四 tab,54 单测全过,`vite build` 通过):BenchPanel/RetrievalPane/SourcesPane/SourceRow/ChainGroup/ExtractionPane/ProgressItem/KgPane/KgGraphView(手写 SVG 力导向,无第三方库)/KgEntityDetail/graphLayout/bench store/两 API 模块。15 条工作台文案已由 PM 合并进 labels.js,benchLabels.js 改为薄别名。
@@ -62,7 +62,7 @@
- **R1 修复集成(PM)**:本地全量回归后端 121 测/前端 156 测全绿;mock 本地远端 md5 一致;BFF 重启后 health 无索引误报;R2 全量回归已派发 T。
- **R2 全量回归通过(T)**:后端 121/121、前端 156/156、Playwright 48 条(35 pass/12 skip 依赖充值/1 flake 复跑通过)、上游 smoke 7/7、行覆盖 87%/80.59%、FR 追溯 81/81。**R1 八缺陷全确认修复**(含 E2E-01 刷新恢复补验三档全通)。无新缺陷。唯一失败为环境性 flake(tablet 主流程 300s 超时,单独复跑 52.3s 通过,上游 QA 串行排队所致)。T 清理了全部测试污染会话数据。
- **M4 判定(PM)**:主/辅门禁全达标、产品用例全 pass → 按 TEST_PLAN 纪律收尾。收尾前采纳两处加固:① E2E 真实流超时 480s/终态等待 360s(T 测试代码);② Vite 忽略 coverage 目录(测试期覆盖率文件触发 198 次页面重载,干扰 E2E 与浏览器访问)。
- **M5 最终验收通过(PM,2026-08-25)**:`deploy/m5_acceptance.js` 15/15 全过。生产形态打通(BFF 8090 单进程静态托管,修复 dist 路径解析:backend/frontend/dist → 项目根;sync 排除 dist 需单独同步)。真实 SQLite 历史恢复(相位卡 5/5、引用 chip 高亮定位)、真实问答全链路(答案 698 字 + 4 引用)、三档视口档位全正确。`docs/ACCEPTANCE.md` 归档。**项目收官**——遗留唯一外部依赖:DeepSeek 余额(充值即恢复,零代码改动)。
- **M5 最终验收通过(PM,2026-08-25)**:`deploy/m5_acceptance.js` 15/15 全过。生产形态打通(BFF 8090 单进程静态托管,修复 dist 路径解析:sdk/ui/dist → 项目根;sync 排除 dist 需单独同步)。真实 SQLite 历史恢复(相位卡 5/5、引用 chip 高亮定位)、真实问答全链路(答案 698 字 + 4 引用)、三档视口档位全正确。`docs/ACCEPTANCE.md` 归档。**项目收官**——遗留唯一外部依赖:DeepSeek 余额(充值即恢复,零代码改动)。
## DeepSeek 恢复与 QA 修复(2026-08-25 下午)
+12 -12
View File
@@ -603,24 +603,24 @@
```bash
# L1 后端单元(远端 plantai-bff conda 环境;A 组自测,T 复跑确认)
cd backend && pytest tests -m unit -q
cd sdk && pytest tests -m unit -q
# L2 后端接口(respx mock 上游;用例见 L2 标注项)
cd backend && pytest tests -m api -q
cd sdk && pytest tests -m api -q
# L2s 上游 smoke(仅集成点 M2 与验收前手动各跑一次;远端本机执行)
bash tests/smoke_upstreams.sh
# L3+L4 前端(vitest;远端 frontend/)
cd frontend && npx vitest run
# L3+L4 前端(vitest;远端 ui/)
cd ui && npx vitest run
# L5 E2E(三档视口;dev server 由 playwright webServer 自动拉起或复用已启动的 5180)
cd frontend && npx playwright test # playwright 未安装时:npx playwright@1.49.1 test
cd ui && npx playwright test # playwright 未安装时:npx playwright@1.49.1 test
```
### 3.2 Mock 场景使用(ARCHITECTURE.md §6)
mock server:`python backend/mock/mock_server.py`(127.0.0.1:8099),场景经查询参数或请求头 `X-Mock-Scenario` 切换。E2E 中由测试代码在请求头注入或 mock 路由拦截实现:
mock server:`python sdk/mock/mock_server.py`(127.0.0.1:8099),场景经查询参数或请求头 `X-Mock-Scenario` 切换。E2E 中由测试代码在请求头注入或 mock 路由拦截实现:
| scenario | 用途 | 使用用例示例 |
|---|---|---|
@@ -643,14 +643,14 @@ mock server:`python backend/mock/mock_server.py`(127.0.0.1:8099),场景
### 3.4 L5 运行环境一次性准备(已验证)
- **Node 18(远端)**:`npx playwright@1.49.1 test` 首次运行自动下载 chromium 1148(≈150MB)。实测 CDN 可达(Mac 直连 2.9MB/s)。
- **`@playwright/test` 模块解析**:spec 文件位于 `tests/e2e/`,在 `frontend/node_modules` 之外,Node 默认解析路径找不到 `@playwright/test`,会报 `ERR_MODULE_NOT_FOUND`。**已在 Mac 本地验证**(playwright 1.61.1 实测复现;1.49.1 CJS 变换同样回退到默认 ESM 解析,机制相同)。运行处须一次性执行(不污染任何 agent 归属文件——`node_modules` 不入库不同步):
- **`@playwright/test` 模块解析**:spec 文件位于 `tests/e2e/`,在 `ui/node_modules` 之外,Node 默认解析路径找不到 `@playwright/test`,会报 `ERR_MODULE_NOT_FOUND`。**已在 Mac 本地验证**(playwright 1.61.1 实测复现;1.49.1 CJS 变换同样回退到默认 ESM 解析,机制相同)。运行处须一次性执行(不污染任何 agent 归属文件——`node_modules` 不入库不同步):
```bash
# 远端,一次性
cd /home/xzq/5090/teamWorkspace/zh/PlantAI-rag-new
ln -sfn frontend/node_modules node_modules # 若目录已存在先确认其内容再覆盖
cd frontend && npm install --save-dev @playwright/test@1.49.1 # 写入 package.json 需 PM 裁决,见 §5 未决问题 4
ln -sfn ui/node_modules node_modules # 若目录已存在先确认其内容再覆盖
cd ui && npm install --save-dev @playwright/test@1.49.1 # 写入 package.json 需 PM 裁决,见 §5 未决问题 4
```
Mac 本地本次验证的等价做法(未改动 `frontend/package.json`):安装到 `/tmp/pw-test-runner` 后 `ln -sfn /tmp/pw-test-runner/node_modules/@playwright/test frontend/node_modules/@playwright/test`,再 `ln -sfn frontend/node_modules <repo>/node_modules`,以 playwright 1.61.1(匹配本机已缓存 chromium-1228)跑通 6/6。
Mac 本地本次验证的等价做法(未改动 `ui/package.json`):安装到 `/tmp/pw-test-runner` 后 `ln -sfn /tmp/pw-test-runner/node_modules/@playwright/test ui/node_modules/@playwright/test`,再 `ln -sfn ui/node_modules <repo>/node_modules`,以 playwright 1.61.1(匹配本机已缓存 chromium-1228)跑通 6/6。
- **本地 Node 26 已知问题**:playwright 1.49.1 的 `module.register()` loader 在 Node 26 + 系统高负载下启动极慢/挂起;远端 Node 18 无此问题。本地验证用 playwright 1.61.1 替代。
- **本机验证结果(M0 冒烟)**:`6 passed`(mobile/tablet/desktop × 2 条冒烟)。冒烟断言对 B1 已交付的 AppShell 走真实分支(`.app-shell/.top-bar/.status-bar`,移动端 `.status-bar` 按 FR-RESP-004 断言隐藏),M0 占位期走占位回退分支。
@@ -660,7 +660,7 @@ mock server:`python backend/mock/mock_server.py`(127.0.0.1:8099),场景
| 文件 | 内容 |
|---|---|
| `frontend/playwright.config.js` | 三项目 mobile(iPhone 14 390×844,触摸+UA)/tablet(iPad 768×1024)/desktop(1440×900);chromium;baseURL `http://127.0.0.1:5180`;webServer `npm run dev -- --strictPort`(已有 dev 复用);失败保留 trace/screenshot |
| `ui/playwright.config.js` | 三项目 mobile(iPhone 14 390×844,触摸+UA)/tablet(iPad 768×1024)/desktop(1440×900);chromium;baseURL `http://127.0.0.1:5180`;webServer `npm run dev -- --strictPort`(已有 dev 复用);失败保留 trace/screenshot |
| `tests/e2e/smoke.spec.js` | 2 条冒烟(TC-E2E-SMOKE-01/02),三档视口各跑一次共 6 条结果。AppShell 断言带 M0 占位回退(B1 交付后自动走真实分支,无需改测试) |
| `tests/smoke_upstreams.sh` | L2s 冒烟:QA 7920 health/info、抽取 8000 health/jobs、7900 health、Neo4j(HTTP 18575 Cypher 只读查询)、mock 8099 health;PASS/FAIL 表 + 非零退出码;支持 `QA_URL/EXTRACT_URL/ALT_URL/MOCK_URL/NEO4J_HTTP/TIMEOUT` 环境变量覆盖 |
@@ -671,5 +671,5 @@ mock server:`python backend/mock/mock_server.py`(127.0.0.1:8099),场景
1. 若干 UI 类断言依赖 UI_SPEC 类名(如 `agent-dot-item`、`p-step`);若 B1 实现时类名有偏差,需按 UI_SPEC §5.3 对齐(T 不自行改用例契约)。
2. TC-EXTRACT-005/007(上传进度/超限)依赖 B2/B3 上传 UI 与 50MB 校验落点(前端或 BFF)——已按「前端拦截或 422」双路径写预期,无需改用例。
3. TC-KG 节点详情在 Neo4j 不可用时的属性来源为「消息内 graph 块已有属性」;graph 块节点若不含属性字段,该断言在实现时需以实际块结构微调步骤(预期语义不变)。
4. **L5 依赖安装需 PM 裁决**:`tests/e2e/` 的 spec 需要解析 `@playwright/test`,而它位于 `frontend/node_modules` 之外。两个方案二选一:(a) 远端一次性 `npm install --save-dev @playwright/test@1.49.1`(写入 B1 归属的 `frontend/package.json`,需 PM 批准);(b) 保持 `npx playwright@1.49.1` 并在远端建 `node_modules` 根符号链接 + `@playwright/test` 符号链接(不改 package.json,M2 前由 T/PM 在远端一次性执行)。本波按 (b) 在 Mac 本地验证通过(6/6 pass),建议远端集成点采用 (b)。
4. **L5 依赖安装需 PM 裁决**:`tests/e2e/` 的 spec 需要解析 `@playwright/test`,而它位于 `ui/node_modules` 之外。两个方案二选一:(a) 远端一次性 `npm install --save-dev @playwright/test@1.49.1`(写入 B1 归属的 `ui/package.json`,需 PM 批准);(b) 保持 `npx playwright@1.49.1` 并在远端建 `node_modules` 根符号链接 + `@playwright/test` 符号链接(不改 package.json,M2 前由 T/PM 在远端一次性执行)。本波按 (b) 在 Mac 本地验证通过(6/6 pass),建议远端集成点采用 (b)。
5. **task 验证命令差异**:任务书给的验证命令 `npx playwright test`(无版本)在本机无已安装 playwright 时会从 npm 拉最新版;远端 Node 18 + `npx playwright@1.49.1` 仍会拉 1.49.1 的 chromium 1148(≈150MB,CDN 实测可达)。已在本文件 §3.4 记录完整步骤。
+9 -9
View File
@@ -10,10 +10,10 @@
| 层 | 工具 | 归属 | 覆盖对象 | 运行方式 |
|---|---|---|---|---|
| L1 后端单元 | pytest | A1/A2/A3 自测 | normalize 别名收敛、SSE 帧解析、阶段→相位映射、SQLite CRUD、错误信封 | `cd backend && pytest tests -m unit` |
| L1 后端单元 | pytest | A1/A2/A3 自测 | normalize 别名收敛、SSE 帧解析、阶段→相位映射、SQLite CRUD、错误信封 | `cd sdk && pytest tests -m unit` |
| L2 后端接口 | pytest + respx(mock 上游) | T 主写,A 组配合 | 每个 BFF 接口的正常/降级/超时/重试路径 | `pytest tests -m api` |
| L2s 上游 smoke | 脚本 | T | 对真实 7920/8000/Neo4j 的最小连通验证(**不在 CI 每轮跑**,仅集成点与验收前跑一次) | `bash tests/smoke_upstreams.sh` |
| L3 前端单元 | Vitest | B 组自测 + T 补写 | stores、SSE parser、labels 映射、modes 参数集、工具函数 | `cd frontend && npx vitest run` |
| L3 前端单元 | Vitest | B 组自测 + T 补写 | stores、SSE parser、labels 映射、modes 参数集、工具函数 | `cd ui && npx vitest run` |
| L4 前端组件 | Vitest + @vue/test-utils | B 组自测 + T 补写 | 每个组件的全部状态(默认/悬停/激活/禁用/加载/空/错误) | 同上 |
| L5 端到端 | Playwright | T | 完整流程 × 三档视口 | `npx playwright test` |
| L6 验收 | 人工 + 浏览器 | PM | 真实上游 + 视觉走查 | 见验收脚本 |
@@ -30,10 +30,10 @@
| 项 | 值 |
|---|---|
| L1/L2 运行处 | 远端 `plantai-bff` conda 环境(pytest) |
| L3/L4 运行处 | 远端 `frontend/`(Vitest,Node 18) |
| L3/L4 运行处 | 远端 `ui/`(Vitest,Node 18) |
| L5 运行处 | 远端(Playwright chromium,headed 不强制),**或** Mac 本地通过 SSH 隧道打到远端 |
| L5 视口 | iPhone 14 390×844 | iPad 768×1024 | Desktop 1440×900 |
| mock 服务 | `python backend/mock/mock_server.py`,端口 8099,scenario 参数切场景 |
| mock 服务 | `python sdk/mock/mock_server.py`,端口 8099,scenario 参数切场景 |
| 真实上游 | 7920 / 8000 / 7900 / Neo4j(按 DISCOVERY.md 选型) |
## 4. 缺陷分级
@@ -74,16 +74,16 @@
```bash
# 后端(远端,plantai-bff 环境)
cd backend && pytest tests -m unit -q # L1
cd backend && pytest tests -m api -q # L2(respx mock)
cd sdk && pytest tests -m unit -q # L1
cd sdk && pytest tests -m api -q # L2(respx mock)
bash tests/smoke_upstreams.sh # L2s 真实连通(手动触发)
# 前端(远端)
cd frontend && npx vitest run # L3+L4
cd frontend && npx playwright test # L5(三档视口配置在 playwright.config.js)
cd ui && npx vitest run # L3+L4
cd ui && npx playwright test # L5(三档视口配置在 playwright.config.js)
# mock(开发与 L5 的 error/degraded 场景)
python backend/mock/mock_server.py # 127.0.0.1:8099
python sdk/mock/mock_server.py # 127.0.0.1:8099
```
## 8. 报告模板(TEST_REPORT_R{n}.md 必须包含)
+6 -6
View File
@@ -10,11 +10,11 @@
|---|---|
| 被测版本 | M1 集成后(PM 已修复集成问题清单,见协调通知) |
| 运行环境 | 远端 plantai-bff 机(100.109.52.26);BFF 8090(真实上游 7920/8000/7900/Neo4j 18788 全通);Vite 5180 → 8090;mock 8099 运行中 |
| L1/L2 运行 | `backend` 全量 pytest(conda plantai-bff,pytest 9.1.1;本轮补充安装 pytest/pytest-asyncio/pytest-cov) |
| L3/L4 运行 | `frontend` vitest 2.1.8(137 用例) |
| L1/L2 运行 | `sdk` 全量 pytest(conda plantai-bff,pytest 9.1.1;本轮补充安装 pytest/pytest-asyncio/pytest-cov) |
| L3/L4 运行 | `ui` vitest 2.1.8(137 用例) |
| L5 运行 | Playwright 1.49.1 + chromium-1148,三档视口 42→48 条测试 |
| L2s 运行 | `bash tests/smoke_upstreams.sh`(本轮修复 Neo4j 认证缺陷后重跑) |
| 轮次纪律 | 只跑测试与写报告,未修改任何产品代码(`frontend/src/**`、`backend/app/**` 零改动;测试脚本自身缺陷修复除外) |
| 轮次纪律 | 只跑测试与写报告,未修改任何产品代码(`ui/src/**`、`sdk/app/**` 零改动;测试脚本自身缺陷修复除外) |
## 2. 首页统计
@@ -91,15 +91,15 @@
## 5. 遗留问题与风险
1. **QA LLM 402 余额不足(已知,非缺陷)**:chat 答案为 fallback 证据列表而非自然语言。涉及答案内容的断言(TC-CHAT-027 等)按 TEST_CASES §3.3 回退结构断言;**依赖充值的用例未在本轮验证最终答案质量**。BUG-R1-06(markdown)恰由 fallback 列表暴露——充值后自然语言答案同样会命中,修复不受 402 影响。
2. **L2 独立接口测试未建立**:`tests/backend/` 仍为空(A 组单测已覆盖 routers 层 119 条)。TEST_CASES 中标注 L2 的用例(检查点节奏、级联删除、INVALID_CITATION 重试等)在后续轮次需补齐 respx mock 测试,当前靠 A 组单测 + L5 间接覆盖。
2. **L2 独立接口测试未建立**:`tests/sdk/` 仍为空(A 组单测已覆盖 routers 层 119 条)。TEST_CASES 中标注 L2 的用例(检查点节奏、级联删除、INVALID_CITATION 重试等)在后续轮次需补齐 respx mock 测试,当前靠 A 组单测 + L5 间接覆盖。
3. **E2E-01 步骤 7–8 被 BUG-R1-06 阻断未执行**:刷新后历史恢复(TC-CHAT-013 的 L5 路径)待修复后补验;L1 侧 `test_sessions_api.py` 已覆盖持久化,风险低。
4. **Laptop 档(1024–1279)无独立 Playwright project**:TEST_CASES 的 TC-RESP-002 档位用例(左栏自动折叠 64px/右栏 340px)本轮未跑,建议下轮加 laptop 项目或在该视口手动验证。
5. **本轮 T 自身操作事故**(已恢复,记录备查):为测前端覆盖率在远端执行 `npm install --save-dev`,短暂改写了 B1 的 `frontend/package.json` 并打断 Playwright 依赖(一次运行中途崩溃)。已还原 package.json 至 B1 原版并用 `--no-save` 重装。后续 T 在远端装包一律 `--no-save`,写入 package.json 的需求走 PM。
5. **本轮 T 自身操作事故**(已恢复,记录备查):为测前端覆盖率在远端执行 `npm install --save-dev`,短暂改写了 B1 的 `ui/package.json` 并打断 Playwright 依赖(一次运行中途崩溃)。已还原 package.json 至 B1 原版并用 `--no-save` 重装。后续 T 在远端装包一律 `--no-save`,写入 package.json 的需求走 PM。
6. **测试数据污染**:R1 新建会话已按前缀清理(R1主流程/R1检索/R1会话/R1中断 等),远端 SQLite 中 `水稻SPL基因家族…` 等自动标题会话为测试产生,已尽量清理,PM 若在意可执行一次数据盘点。
7. **48 条 L5 中 12 条 skip 为档位门控设计**(如 mock 场景仅桌面代表、E2E-05 仅桌面),已在 TEST_CASES 执行说明中记录;如需三档全跑需 PM 确认(真实上游流成本高:每档主流程 ≈1 分钟、检索 ≈92s)。
## 6. 证据归档
- 远端日志:`/tmp/r1_pytest.log`(119 passed)、`/tmp/r1_cov.log`(87%)、`/tmp/r1_vitest_cov.log`(137 passed,81.54%)、`/tmp/r1_pw_rest.log`(L5 主批次)、`/tmp/r1_pw_target.log`(mock 场景桌面批次)、`/tmp/r1_pw_full2.log`(首轮全量,含 6/6 smoke)
- 失败截图/trace:远端 `frontend/test-results/`(按用例目录归档;7 个缺陷各有一式三份视口证据,其中 BUG-R1-04/05 为桌面证据)
- 失败截图/trace:远端 `ui/test-results/`(按用例目录归档;7 个缺陷各有一式三份视口证据,其中 BUG-R1-04/05 为桌面证据)
- smoke 输出:本文件 §2.1 引用;修复后 7/7 PASS
+5 -5
View File
@@ -10,11 +10,11 @@
|---|---|
| 被测版本 | M4 第二轮:R1 的 8 个缺陷修复后(修复清单见协调通知) |
| 运行环境 | 远端 plantai-bff 机;BFF 8090(真实上游 7920/8000/7900/Neo4j 全通,health 无索引误报);Vite 5180→8090(HMR 已同步修复);mock 8099(本地/远端 md5 一致) |
| L1/L2 | `backend` pytest 全量 + `--cov=app` |
| L3/L4 | `frontend` vitest 全量 + `--coverage` |
| L1/L2 | `sdk` pytest 全量 + `--cov=app` |
| L3/L4 | `ui` vitest 全量 + `--coverage` |
| L5 | Playwright 1.49.1 + chromium-1148,三档视口 48 条 |
| L2s | `bash tests/smoke_upstreams.sh` |
| 铁律 | 只跑测试与写报告;未修改任何产品代码(`frontend/src/**`、`backend/app/**` 零改动) |
| 铁律 | 只跑测试与写报告;未修改任何产品代码(`ui/src/**`、`sdk/app/**` 零改动) |
## 2. 首页统计
@@ -80,7 +80,7 @@
1. **tablet E2E-01 全量中的 flake(唯一失败)**:final3 中 tablet 档主流程 300s 超时(trace 显示流未在时限内终态,afterEach 清理正常执行),单独复跑 52.3s 通过;mobile/desktop 同轮 53.2s/53.6s 通过。判定为**上游 QA 排队/偶发慢**(同一 spec 三档三次全量中 2/3 通过),非产品缺陷。建议下轮把真实流 E2E 的 test timeout 提到 480s、终态等待上限 360s,消除环境抖动误报。
2. **12 条 skip 维持**(设计门控):mock 场景仅桌面代表、E2E-05 仅桌面(真实流成本高,跨档行为一致)。如需三档全跑需 PM 确认。
3. **Laptop 档(1024–1279)仍无 Playwright project**(R1 遗留问题 4):TC-RESP-002(左栏自动折叠 64px/右栏 340px)本轮仍未 L5 覆盖,需 PM 决定是否加档。
4. **`tests/backend/` L2 respx 独立测试仍空**(R1 遗留问题 2):L2 用例(检查点节奏、级联删除、INVALID_CITATION 重试等)靠 A 组单测 + L5 间接覆盖。
4. **`tests/sdk/` L2 respx 独立测试仍空**(R1 遗留问题 2):L2 用例(检查点节奏、级联删除、INVALID_CITATION 重试等)靠 A 组单测 + L5 间接覆盖。
5. **QA LLM 402 仍存在**:chat 答案为 fallback 证据列表;「依赖充值」断言维持结构回退。若这是最后一轮,充值后的答案质量断言移交 L6 验收。
6. **共享数据**:R2 测试会话已全部清理(按 ID 快照 + 时间窗删除 58 条),远端 SQLite 现仅剩 PM 集成期 7 条会话。
7. **T 自身测试缺陷修复(R2 内)**:E2E-07 接受降级列表形态、E2E-01 等 md-text 终态(弃等 stream-wrap 消失的脆断言)、markdown 触发条件收紧、E2E-05 改位置定位、清理改 ID 快照——均已同步远端。
@@ -88,7 +88,7 @@
## 6. 证据归档
- 远端日志:`/tmp/r2_pytest.log`、`/tmp/r2_cov.log`(121 passed,87%)、`/tmp/r2_vitest_cov.log`(156 passed,80.59%)、`/tmp/r2_smoke.log`(7/7)、`/tmp/r2_pw_final3.log`(L5 全量)、`/tmp/r2_pw_m1.log`(mobile 补跑)、`/tmp/r2_pw_t1.log`(tablet 补跑)
- 失败截图/trace:`frontend/test-results/`(final3 tablet E2E-01 一份,为 flake 证据)
- 失败截图/trace:`ui/test-results/`(final3 tablet E2E-01 一份,为 flake 证据)
- 归档:`/home/xzq/5090/teamWorkspace/zh/r1_test_evidence/`(R1 证据保留;R2 日志在 /tmp 保留至 PM 决定归档)
## 7. 轮次结论
+3 -3
View File
@@ -8,7 +8,7 @@
---
## 1. 设计令牌(`frontend/src/styles/tokens.css`)
## 1. 设计令牌(`ui/src/styles/tokens.css`)
### 1.1 深色主题(默认)`[data-theme="dark"]`
@@ -84,7 +84,7 @@
---
## 2. 动画规格(`frontend/src/styles/animations.css`)
## 2. 动画规格(`ui/src/styles/animations.css`)
| 动画 | 时长/缓动 | 用途 | 关键帧要点 |
|---|---|---|---|
@@ -213,7 +213,7 @@ grid: columns 260px minmax(0,1fr) 380px
---
## 5. 四档响应式(`frontend/src/styles/responsive.css`,覆盖 §3)
## 5. 四档响应式(`ui/src/styles/responsive.css`,覆盖 §3)
| 档位 | 规则 | 具体行为 |
|---|---|---|