test(e2e): 全量 e2e 9 spec/22 用例本地活体全绿 + binding 种子固化

PG 宿主 100.64.0.8 恢复在线→查出旧 jar(Jun-19 00:59)缺 GET bindings 端点(commit 3a7a72f Jun-19 13:30)致 405→rebuild Jun-20 新 jar(反假绿:不用过时 jar)→起栈 48080(local,infra,清 socks)→playwright MSW-off 真打:22 passed/0 failed/0 skipped/0 flaky(9.1s)。

覆盖:accept-suggestion 正负×2 + account-security-ack + agent-create + knowledge-bindings(06-19 PG 离线阻塞项 unblock) + knowledge-confirm + knowledge-graph + live-read×6 + market-publish×8 + workspace。

种子:核验 4/5 基础数据在,knowledge-bindings 投影固化进 e2e/global-setup.ts #6(可入库、下次自动补,补此前未覆盖项);0 红故无就地修。回写进度总账 §五C + 总览待办(受阻→完成) + spec 注释。附本会话 ce-brainstorm/ce-plan 产出文档。

诚实边界:本地全栈活体(rebuild jar + 真 PG muse_slice_live),非 CI(maven.yml 不跑 e2e/需活体后端+浏览器)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lili 2026-06-20 13:53:29 -07:00
parent 349cd73119
commit 99f8fcd2e0
6 changed files with 188 additions and 5 deletions

View File

@ -0,0 +1,58 @@
# Studio UI 端面补全与 e2e 真跑通 — 需求
- 日期2026-06-20
- 状态:方向已确认,进入执行
- 范围muse-studio用户端UI 端面 + 全量 e2e 真实跑通 + 测试结论
- 关联:上一轮"未完成验证盘点"(代码核查带 file:line[`docs/项目功能与进度总览.md`](../项目功能与进度总览.md)[`docs/mvp/进度总账.md`](../mvp/进度总账.md)
## 问题 frame
接口覆盖门 233/233 绿(机械口径)只验证了"后端接口层"**≠ 端到端可用**
- muse-studio 多个 UI 端面缺失或跑 MSW mock`muse-studio/src/api/mocks/handlers/` 仍有 account/knowledge/content/ai 完整 mock 层)。
- e2e 此前因 PG 宿主 `100.64.0.8:5433` 离线无法实跑("待实跑"妥协)。
**关键 unblock2026-06-20 坐实)**PG 恢复在线——直连可达、认证通过、Flyway 24 迁移全绿、`public` 165 表、Tailscale 直通无需绕代理。e2e "待实跑"前提消除。
## 目标与成果
1. 横向补全 muse-studio 4 组 UI 端面,每组接真实后端(去 MSW
2. **所有需要 e2e 的测试真实跑通**(不再"待实跑")。
3. 整理一份**测试结论**(哪些绿 / 红 / 阻塞 + 原因),回写进度台账。
## 范围与优先级
本轮纳入studio 用户端):
- **P0AI 候选采纳链 UI** — 编辑器挂 AIPanel/CandidatePanel、接真 `suggestion-merges`。Muse 核心"先审后入"闭环,后端已证、仅前端未接。
- P1知识库工作台剩余 UI草稿确认/忽略/recheck、实体关系 CRUD、发布工作流
- P2市场生产端 UI发布/handoff/申诉提交追踪/许可详情)
- P3个人中心 ~15 端点 UI安全事件/导出下载/New-API绑定/配额申请/购买授权记录)
不在本轮scope boundary
- admin 管理端 UIVben 模板相对完整、未核实缺口,另议)
- 两个未实现硬缺口Meta impact-preview、AI Security 权限链)——属"未实现"非"缺 UI",单独立项
## 完成标准success criteria
每个端面:① 前端去 MSW、调真实后端② 前端组件/契约测试绿;③ **e2e 端到端实跑绿**against 全栈muse-server 连 PG `100.64.0.8` + Redis + studio
全局:④ 既有 9 个 e2e specaccept-suggestion / knowledge-graph / market-publish / account-security-ack / knowledge-confirm / knowledge-bindings / live-read / agent-create / workspace全部真实跑一遍出结论。
## 执行计划
1. 坐实全栈起栈muse-server 编译 + 起 + 连 PG/Redisstudio 起 dev server。
2. 跑通既有 e2e先 knowledge-bindings 验证 PG unblock再全量
3. P0AI 候选采纳链 UI 补齐 + e2e。
4. P1P3 按序跟进。
5. 整理测试结论台账(回写进度总账,不新增过程文档)。
## 依赖与假设
- PG `100.64.0.8:5433` 持续在线(`muse_slice_live`user=root密码在 `~/.config/muse-repo/infra.env`,不入库不外显)。
- Redis `127.0.0.1:6379` 可用。
- 后端可编译起栈(**待坐实**——可能有配置坑)。
## Open questions
- 全栈起栈是否有未知配置坑(待探测)。
- MSW mock 层最终去留(拆除 vs 保留 dev fallback
- admin 管理端 UI 缺口是否纳入后续。

View File

@ -155,6 +155,7 @@
### C. 前端 muse-studio(B3,体量最大,最长的长板)
- ✅ **2026-06-15:整套 studio e2e 单次全绿 8/8**(chromium,MSW off 直连单体 48080)——accept-suggestion 正+负 / knowledge-confirm / live-read ×4(content·market·account·ai) / workspace 壳;MSW-off 已固化进 `playwright.config.ts` webServer `env`(CI 自起 vite 生效)+ `.env.local`(本地);`workspace.spec.ts` 原 mock 假绿(断言「星海迷途」,MSW 关后必红)**已改写为不依赖 mock 的活体壳冒烟**,消除最后一处 MSW 互斥红。下列各 ✅ 切片即构成此 8/8。**(套件此后随切片增长:live-read ×4→×6 增「购买/授权」「安全事件」深页 + market-publish ×3→×8 增上架生命周期徽标 + 申诉提交·撤回·补充材料写路 + appealStatus 回显 + account-security-ack ×1 写路 + agent-create ×1 自建智能体写路,`playwright test --list` 当前共 21 例(+knowledge-graph);每轮按改动旅程实跑验证——accept-suggestion/knowledge-confirm/security-ack/market 上架徽标·申诉 依赖手工重种子。**2026-06-15 reseed 全部每轮种子依赖后 `--workers=1` 串行整套 20/20 单次全绿**(真实后端 MSW-off;**2026-06-15 已落地可入库种子**:`e2e/global-setup.ts`(pg 直连真实 PG、凭据从 infra.env 读不入库)+ playwright `globalSetup`/`workers:1`,每轮自动复位 graph/confirm-draft/accept(block3→rev1)/security-ack/appeal fixture;`source infra.env && pnpm test:e2e`**20/20 单次全绿、零手工 `/tmp` 种子**(消费态下实证 globalSetup 复位后整套绿;新 agent-create 不消费这些 fixture,本轮以 `E2E_SKIP_SEED=1` 单例实跑)。)**
- ✅ **2026-06-20:全量 e2e 9 spec/22 用例本地活体单次全绿**(goal=全量e2e真跑通)。PG 宿主 100.64.0.8 恢复在线(直连可达、Flyway 24/public 165 表)→ 查出 jar(Jun-19 00:59)缺 GET bindings 端点(commit 3a7a72f Jun-19 13:30)致 405、**rebuild Jun-20 新 jar**(反假绿:不用过时 jar 跑)→ 起栈 48080(local,infra,清 socks)→ `playwright test` MSW-off 真打:**22 passed / 0 failed / 0 skipped / 0 flaky(9.1s)**——accept-suggestion 正负×2 + account-security-ack + agent-create + knowledge-bindings(**06-19 PG 离线阻塞项 unblock**) + knowledge-confirm + knowledge-graph + live-read×6 + market-publish×8 + workspace。基础种子:核验 4/5 在,**knowledge-bindings 投影固化进 `e2e/global-setup.ts` #6**(可入库、下次自动补);0 红故无就地修。**诚实边界**:本地全栈活体(rebuild jar + 真 PG muse_slice_live),**非 CI**(maven.yml 不跑 e2e/需活体后端+浏览器)。
- 现状:其余旅程仍 ~14% 真连、dev 默认 MSW;但 MVP#1 已打通"关 MSW→直连活体→playwright e2e"模式(见下),可复用到后续旅程。
- ✅ **AI 候选采纳(rendered UI 活体证,2026-06-14)**:`main.tsx``VITE_API_MOCK=false` 开关关 MSW、前端直连活体单体;`accept-suggestion.spec.ts` 在 chromium 实跑——**happy-path**(生成经 page.route stub 发真实 suggestionId→点"采纳替换"→真合并)隔离跑绿 + DB 证(block rev1→2、正文=候选);**negative-path**(陈旧 revision)绿(乐观锁 1041000002)。连带**真实修复 client.ts 注入 tenant-id**(活体集成缺口,dev MSW 不校验故没暴露)。**遗留**:happy-path 受种子状态依赖(合并后 block rev 变 + RQ 缓存,需 fresh 种子复跑);`workspace.spec.ts` 已改活体壳冒烟(2026-06-15,MSW 互斥红消除、整套 8/8 全绿);suggestion 合并后留 pending=merge 不在同事务回写 AI 域状态(靠 outbox→AI 异步翻,本机 dispatcher 节流故 DB 仍 pending,读 `ContentSourceServiceImpl` 确认,非产品 bug)。
- ✅ **content/market/account/ai-agent 读旅程(rendered UI 活体证,2026-06-14)**:`live-read.spec.ts` 4/4 绿(MSW off,chromium:作品列表/市场浏览/个人中心/智能体列表均渲染真实后端数据)——证 tenant-id 修复后 studio 直连活体单体跨 BC 取数、真实数据形态与页面渲染契约对齐。

View File

@ -0,0 +1,112 @@
# test: 全量 e2e 真跑通 + 测试结论台账
- 日期2026-06-20
- 类型test验证
- 深度Standard
- Origin[`docs/brainstorms/2026-06-20-studio-ui端面与e2e真跑通-requirements.md`](../brainstorms/2026-06-20-studio-ui端面与e2e真跑通-requirements.md)
- Target repooh-my-muse`muse-studio` e2e + `muse-cloud` 后端)
---
## Summary
把 muse-studio 既有 **9 个 playwright e2e spec** 在真实全栈muse-server 48080 + PG `muse_slice_live` + redis上**全部真实跑一遍**,消除"待实跑"妥协。配套:基础种子**固化为可入库脚本**(替代一次性 `/tmp/*.java`、补 global-setup 未覆盖项);跑红**就地修**(含后端潜伏 bug反假绿最终整理测试结论**回写进度台账**。
## Problem Frame
接口覆盖门 233/233 只验证后端接口层,≠ 端到端可用。e2e 此前因 PG 宿主 `100.64.0.8:5433` 离线停留在"待实跑"。**2026-06-20 PG 恢复在线**直连可达、Flyway 24 全绿、165 表),全栈起栈配方现成(`.agents/knowledge/external-deps-and-gotchas.md` §六),本会话已坐实 muse-server READY`Started in 19.437s`48080
最大不确定性有二:① **基础种子完整性**——`global-setup.ts` 每轮自动复位 5 类 fixture但假定基础数据已存在基础数据历史靠一次性 `/tmp/*.java`每会话丢失knowledge-bindings 投影 global-setup 未覆盖。② **首次全量真跑可能暴露潜伏红**——部分 spec如 knowledge-bindings从未活体运行过。
## Requirementstrace origin
- **R1**origin 目标 29 个 e2e spec 全部真实跑通(绿)。
- **R2**origin 目标 3测试结论台账——每 spec 状态/证据/修复,回写进度总账。
- **R3**origin 完成标准):端到端 e2e 实跑绿,非"待实跑";全栈真实后端 + 真 PG。
- **R4**(本轮 call-out 决策):基础种子固化为可入库;红用例就地修(含后端)。
## Key Technical Decisions
1. **基础种子固化为可入库**global-setup 扩展 / 独立 seed不再用一次性 `/tmp/*.java`——复利、反每会话丢失,延续 `global-setup.ts` 自身"可入库版替代 /tmp"的既定方向。
2. **红就地修**(含后端潜伏 bug——e2e 真绿才算完成,掩盖红=假绿。沿用历史模式publish 部分索引→V22、confirm 重名 500→预检
3. **起栈用 §六 现成配方**profile=`local,infra`、清 JVM socks`-DsocksProxyHost=`、AI 调度熄火(超大 delay`--muse.codegen.import-enable=false`
4. **PG = `muse_slice_live`100.64.0.8:5433**,凭据走 env`~/.config/muse-repo/infra.env`**绝不入库**。
5. **结论回写进度总账 + 总览**,不新增过程文档(单一台账偏好)。
---
## Implementation Units
### U1. 全栈起栈就绪(前置)
- **Goal**muse-server 单体在 48080 起栈,连 `muse_slice_live` + 本机 redisAI 调度熄火、socks proxy 清除。
- **Requirements**R3。
- **Dependencies**:无(起点)。
- **Files**`.agents/knowledge/external-deps-and-gotchas.md`(§六 配方,参照不改)、`muse-cloud/muse-server/target/muse-server.jar``~/.config/muse-repo/infra.env`(仓外凭据)。
- **Approach**:本机 redis`--requirepass`)→ `set -a; . infra.env; set +a` → 按 §六 `java -DsocksProxyHost= … -jar muse-server.jar --spring.profiles.active=local,infra --spring.flyway.baseline-on-migrate=true --muse.codegen.import-enable=false`。jar 现为 Jun-19 build本会话未改后端可复用若 U4 改后端则 `mvn -pl muse-server -am package`classifier=exec 已配)后重起。本会话已起栈 READY可直接复用。
- **Test scenarios**Covers R3. 健康探针 `curl --noproxy '*' -H "Authorization: Bearer test1" -H "tenant-id: 1" -H "X-API-Version: 1" http://localhost:48080/app-api/muse/works?pageNo=1&pageSize=5``code:0`;日志含 `Started MuseServerApplication`
- **Verification**48080 健康返回 `code:0`redis PONGPG 直连可达。
### U2. 基础种子核验 + 固化为可入库脚本
- **Goal**:核验 `muse_slice_live` 的 e2e 基础数据完整性,缺失项固化为**可入库基础种子**,补 global-setup 未覆盖的 knowledge-bindings 绑定投影。
- **Requirements**R1、R4。
- **Dependencies**U1。
- **Files**`muse-studio/e2e/global-setup.ts`(扩展基础种子段)或新建 `muse-studio/e2e/seed-base.ts`;参照历史已丢失的 `/tmp/{SeedSec,KnowledgeGraphSeed,SetReqStatus,SeedAppeal,SetAppealSup}.java`(按各 spec 注释 + global-setup 复位逻辑反推语义)。
- **Approach**:① 连 PG 核验基础数据存在性:`muse_content_block` id=3、`muse_ai_suggestion` id=3、`muse_member_security_event`「待确认演练」、`muse_market_appeal`/资产、账户/智能体、`muse_knowledge_source_binding_projection`(work_id=1/active/market_kb/kb4001)。② 缺失项写**幂等 upsert** 种子(对齐 global-setup 风格)。③ knowledge-bindings 投影种子补入 global-setup 或 seed-base。**注意**`muse_ai_suggestion.id``GENERATED ALWAYS`suggestion3 若缺需处理 id 对齐global-setup #3 假定其存在不重建)——若无法还原原 id需调整该 spec 的定位策略或基础种子以稳定 id。
- **Test scenarios**:种子幂等(重跑不产生重复/唯一冲突);跑后 global-setup 5 类复位**无 "基础种子缺失" warn**`GET /works/1/knowledge-bindings` 返回 active 绑定。
- **Verification**global-setup 跑无 warn9 spec 的基础前置全部满足。
### U3. 逐 spec 实跑 + 结果记录
- **Goal**playwright 跑全部 9 spec记录每个 pass/fail + 失败根因线索。
- **Requirements**R1、R2。
- **Dependencies**U1、U2。
- **Files**`muse-studio/e2e/{accept-suggestion,knowledge-graph,knowledge-confirm,knowledge-bindings,market-publish,account-security-ack,live-read,agent-create,workspace}.spec.ts``muse-studio/playwright.config.ts`webServer 自动起 vite 5173、`VITE_API_MOCK=false` 已固化)。
- **Approach**`set -a; . infra.env; set +a``cd muse-studio; ./node_modules/.bin/playwright test`。**先单跑 `knowledge-bindings`**(历史从未活体跑、最高风险,验证 PG unblock再全量。global-setup 每轮复位 fixture。记录每 spec 结果(绿/红 + trace
- **Test scenarios**spec 本身即测试。关键断言accept-suggestion 正/负(采纳写 Canonical rev1→2 / 乐观锁拒knowledge-confirmShadow→Canonical 入库 + 草稿 confirmedmarket-publish 6 例(发布草稿/申诉/撤回全链knowledge-bindings投影读回 200/code:0/activelive-read 5 读旅程agent-create / workspace 冒烟。
- **Verification**9 spec 结果明确(绿,或红 + 根因);首次全量真跑结果落账。
### U4. 红用例就地修(条件性)
- **Goal**:跑红的 spec 定位根因(前端断言/接线 or 后端潜伏 bug**就地修**至绿。
- **Requirements**R1、R3、R4。
- **Dependencies**U3。
- **Files**:视红而定——前端 `muse-studio/src/**` 或后端 `muse-cloud/**`(后端改动后回 U1 rebuild jar + 重起栈)。
- **Approach**:红多为"从未活体跑过的潜伏 bug"。前端红=断言/接线/SSE 漂移类;后端红=潜伏业务 bug就地修 + 补 Flyway 迁移/IT如 publish 索引→V22 先例)。
- **Execution note**:修红前先**复现 + 定位根因**,再 targeted 修,**勿掩盖**(反假绿);后端修须配真实 PG IT 或迁移,不靠放宽断言凑绿。
- **Test scenarios**:每修复点回归对应 spec 绿;后端修补对应迁移/IT如适用修复不引入其他 spec 回归(全量复跑)。
- **Verification**:原红 spec 转绿,根因 + 修复有记录;全量无回归。
### U5. 测试结论台账回写
- **Goal**:整理全量 e2e 测试结论(每 spec 状态/证据/修复/无法绿的根因),回写进度总账 + 总览。
- **Requirements**R2。
- **Dependencies**U3、U4
- **Files**`docs/mvp/进度总账.md``docs/项目功能与进度总览.md`
- **Approach**结论表spec × 状态 × 证据 × 修复。更新总览待办e2e「待实跑」→ 实跑结果)、必要时同步 `.agents/knowledge/module-reality-baseline.md`。回写进度总账时间线。**不新增过程文档**。
- **Test scenarios**none —— 纯文档台账回写,无行为变更。
- **Verification**:进度台账反映全量 e2e 真实结果;总览 e2e 行从「待实跑」更新为实跑结论。
---
## Scope Boundaries
- **不在本 plan**studio UI 4 组补全origin 目标 1、admin 管理端 UI、两个未实现硬缺口Meta impact-preview、AI Security 权限链)。
- **Deferred to Follow-Up Work**P0 = AI 候选采纳链 UI 补全(见 origin——本 plan 的全量 e2e 跑通是其前置基线。
## Risks & Dependencies
- **R-基础数据**:基础种子部分缺失(尤其 suggestion3 `GENERATED ALWAYS` id 难还原)→ U2 核验,可能需调 spec 定位或稳定 id 策略。
- **R-潜伏红**:首次全量真跑暴露潜伏 bugknowledge-bindings 从未活体跑)→ U4 就地修,可能触及后端 + rebuild jar。
- **R-jar 时效**jar 为 Jun-19 buildU4 改后端须 `mvn package` 重 build + 重起栈(耗时)。
- **R-fixture 共享**:多 spec 消费共享 fixturelive-read 多读旅程、market 申诉状态流转)→ global-setup 每轮复位缓解,但顺序敏感用例需注意。
- **R-PG 在线**`100.64.0.8` 依赖 Tailscale 在线(本会话可达,会话间可能再离线)→ 离线即全套阻塞,需 PG 宿主恢复。
- **依赖**:本机 redis、`muse-server.jar`、playwright chromium已装`infra.env` 凭据(仓外)。
## 完成条件Verification
1. 9 个 e2e spec **全绿**,或**诚实记录**无法绿的 spec + 根因(反假绿,不放宽断言凑绿)。
2. 基础种子**可入库、幂等**global-setup 无"基础种子缺失"warn。
3. 红用例根因 + 修复有记录;后端修配真实 IT/迁移。
4. 测试结论**回写进度总账 + 总览**e2e 行从「待实跑」更新为实跑结论。

View File

@ -159,7 +159,7 @@
| 🟡 中 | recheck 真外部校验 + outbox worker 启用 | knowledge | 默认关,待运维/外部源配置 |
| 🟡 中 | 平台基线 Schema 纳入 Flyway(现为 yudao 静态 dump) | platform | 历史基线未版本化 |
| ⚪ 外部依赖 | New-API 真端到端验收;FileService 字节投递;调用归属外部源 | ai/member | 待外部服务可用 |
| ⚪ 受阻 | 实时全栈 e2e(含 knowledge-bindings spec 已写未跑) | studio | PG 宿主 100.64.0.8 离线 |
| ✅ 完成 | 实时全栈 e2e:**9 spec/22 用例本地活体全绿**(2026-06-20) | studio | PG 恢复→rebuild jar→playwright MSW-off 真跑;非 CI,详见进度总账 §五C |
| 🟦 待决策 | **meta-schema 用量投影方向**:评审证伪地基(破坏字段集生产者 + schema_key 来源均须从零建),须人类定"全量+字段级+全真实"还是回退 Content-only+计数优先 | meta | 见 [执行版 v0.2](agent-specs/2026-06-20-meta-schema用量投影-execution.md) §九 |
---

View File

@ -111,7 +111,19 @@ async function globalSetup(): Promise<void> {
console.warn('[e2e globalSetup] ⚠️ 未找到当前用户的申诉(market 补充材料用例需基础申诉种子)');
}
console.log('[e2e globalSetup] 已复位每轮 fixture(graph/confirm-draft/accept/security-ack/appeal)');
// 6) knowledge-bindings:作品 1 一条<生效>的来源绑定读模型投影(此前 global-setup 未覆盖、基础种子缺失,
// 本轮固化为可入库;幂等:先删同 projection_id 再插,id 为 identity 自增故重跑不冲突)。
await client.query(
"DELETE FROM muse_knowledge_source_binding_projection WHERE tenant_id=1 AND projection_id='e2e-seed-w1-kb4001'"
);
await client.query(
`INSERT INTO muse_knowledge_source_binding_projection
(projection_id, source_owner, source_type, source_id, owner_user_id, work_id, kb_id, binding_id,
status, action_policy, projection_summary, tenant_id)
VALUES ('e2e-seed-w1-kb4001','market','market_kb','4001',1,1,4001,5001,'active','allowed','{}'::jsonb,1)`
);
console.log('[e2e globalSetup] 已复位每轮 fixture(graph/confirm-draft/accept/security-ack/appeal/binding)');
} finally {
await client.end();
}

View File

@ -11,9 +11,9 @@ import { expect, test, type Page } from '@playwright/test';
* 目的:rendered studio GET /works/1/knowledge-bindings
* , UI "绑定确认 → 读模型回填 → 读回展示"(, mock)
*
* (2026-06-19): spec <尚未> PG 宿(100.64.0.8:5433)线
* app ( docs/mvp/.md bindings "诚实边界")PG 宿
* + FE hook/ vitest//tsc/build (knowledge-server 218studio 50 + build 绿)
* (2026-06-20): spec 绿PG 宿 100.64.0.8:5433 线rebuild jar( GET bindings ) 48080
* playwright MSW-off 1 passed(207ms, 22/22 ); e2e/global-setup.ts #6
* (历史:2026-06-19 PG 宿线 env ; + FE hook/ vitest//tsc/build )
*/
const TOKEN = 'test1';