49 Commits

Author SHA1 Message Date
lili
2a7906c74e test(handoff): P2 agent 兑现真后端 e2e + seed market agent fixture
global-setup #13:seed market 类型 agent(固定 agent_key)+ active version + work4 槽位绑定,
每轮幂等复位(子表先删再重建);供 market→agent 跨空间 handoff e2e(market→agent 资产物化未接,
此处为预置 fixture)。

handoff-agent.spec(真后端,反假绿):
- 正路:bind-precheck(targetOwner=agent)→ createHandoff 签一次性 token → agent precheck
  (market_agent + token):后端 verify+consume+放宽接纳 market 类型 agent → bind 落槽位(slotRevision=2)
- 负路:伪造 token 调 agent precheck → 后端 verify 拒(code≠0),不放宽、0 写

验证:V27 已应用共享 muse_slice_live(flyway "now at version v27",用户拍板应用);handoff-agent
2/2 passed(真 PG + 真 token + V27 真列);全量 e2e 50 passed(唯一 flaky=knowledge-disable-restore
全量时序、单跑 2/2 绿、用 KB id=1 与 handoff 用 work4 无关,非 P2 回归)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 13:09:47 -07:00
lili
86bdba7974 test(handoff): P1 knowledge 兑现端到端真后端 e2e + fixture 复位
handoff-knowledge.spec(真后端 48080, MSW off):
- 正路:市场资产→获取授权→bind-precheck 就绪→前往绑定(createHandoff token)→落地页(URL token 经 replaceState
  清除)→确认→kbBindPrecheck(后端核验+核销 token)→createBinding→绑定完成。证红线兑现闭环真生效。
- 负路:伪造 handoffToken 直打 kbBindPrecheck→后端 verify 拒(code 非 0)。证"不信客户端 token"红线后端真拦截。
- 用 work4(creator=test1、未占 uk);work1+kb1 已被 installed binding 占,避 uk_muse_knowledge_binding_work_kb 冲突。

global-setup #12:每轮清理 handoff 兑现产生的 market_kb 绑定(work4+kb1,按 source_snapshot_id 精准删),供闭环幂等重跑。

验证:handoff-knowledge 2 passed + 二次幂等绿;全量 48 passed。
(knowledge-disable-restore 全量时序 flaky——单跑 2 passed,预存在共享 fixture 时序、与本改动无关:handoff 不碰 KB id=1。)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 10:31:18 -07:00
lili
ab83735f6f feat(studio): 资产详情页治理影响接入真后端(A 类:消费者治理 C14 读端)
A 类(后端就绪、前端 0 消费):02F GET /marketplace/assets/{id}/governance-impact 就绪
(curl code:0 + 真实 governanceResult:resultType/reason/操作限制 + affectedAuthorizations/
suggestedActions),但 studio 详情页无展示(盘点 C14 消费者治理缺口)。接入:
- useGovernanceImpact hook + openapi 导出 GovernanceImpactResult
- MarketAssetDetailPage「治理影响」区:结果类型(下架/召回/吊销/可申诉)+ 操作限制(停止获取/安装/绑定/生成)+ 建议动作
- mock handler + vitest 契约 + market-governance-impact.spec.ts 真后端 e2e
- 修 spec 块注释内 affected*/ 的 */ 意外闭合(tsc 不覆盖 e2e、playwright esbuild 暴露)

验证:全量 e2e 46→47/0;vitest 81→82;tsc/eslint 绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 07:49:08 -07:00
lili
7408615037 feat(studio): 个人中心 New-API 绑定摘要接入真后端(A 类:接已就绪后端)
A 类(后端就绪、前端 0 消费):02G GET /account/new-api-binding 后端就绪(curl code:0、
未绑定时 fail-closed 返 bindingStatus=unbound),但 studio 无任何展示(盘点 02G ❌ 缺口)。接入:
- useAccountNewApiBinding hook + openapi 导出 NewApiBindingSummary
- PersonalCenter「New-API 绑定」区:bindingStatus 中文徽标(已绑定/未绑定/同步失败/同步中)+ 上次同步时间
- mock handler + vitest 契约 + account-newapi-binding.spec.ts 真后端 e2e

验证:全量 e2e 45→46/0;vitest 80→81;tsc/eslint 绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 07:37:22 -07:00
lili
cac3b8837f feat(studio): 市场推荐位接入真后端 recommendations(A 类:接已就绪后端)
A 类(缺口盘点:后端已就绪、前端 0 消费):02F GET /marketplace/recommendations 后端就绪
(curl code:0 + 真实推荐资产 + recommendationReason),但 studio 从不调用、推荐理由仅 mock
造、UI 未渲染(盘点 C3)。接入:
- useMarketRecommendations hook(返回 MarketAssetCard[],推荐失败不阻断主列表)
- MarketBrowse「为你推荐」区:渲染推荐资产 + recommendationReason,点击进详情
- mock handler + vitest 推荐契约;market-recommendations.spec.ts 真后端 e2e
- 连带修 live-read market 断言加 .first()(推荐位与列表可同时渲染同名资产→strict mode)

验证:全量 e2e 44→45/0;vitest 79→80;tsc/eslint 绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 07:29:14 -07:00
lili
a581fec913 fix(studio): 正文保存补真后端 e2e + 修 block/work revision 字段漂移(D 类反假绿)
D 类(缺口盘点最高优先):正文自动保存是写作台心脏却零 e2e、仅 MSW 掩盖。补
block-autosave.spec.ts 真打 PUT /works/{id}/blocks/{id} 暴露并修真 bug:
- block revision 漂移:WorkspacePage 裸读 activeBlock.version(真后端返 revision、无 version)
  → expectedRevision 恒为 1 → 真后端乐观锁必冲突(1041000002,curl 实证)。提 blockRevision()
  到 useBlockStructure 共享、WorkspacePage 复用。
- work revision 漂移(tsc -b 增量重检暴露):WorkVO 类型无 revision、真后端 detail 返 revision,
  chapter create/work delete 裸读致 TS 报错。加 workRevision() helper。
- MuseEditor saveBlock 返回 { revision }(非 openapi 标的 newVersion),L110 改 revision 优先兜底。
- market 申诉 deadline fixture 老化(纯时间推进、非代码):reviewedAt+7天过期致提交被拒
  1044000027,globalSetup 刷新被驳回 request.reviewed_at 到近期。

验证:block-autosave + block-structure/chapter/work 回归 4/4 绿;全量 e2e 44/0;tsc/eslint/vitest 79/79。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 07:02:13 -07:00
lili
a752626286 test(content): V26 应用后 chapter-create-delete e2e 转正(全量 43/0 全绿)
V26(章节/Block order_no uk 改 partial index WHERE deleted=false)已 flyway 应用(now at v26),
curl 实证建 order=2 章节(之前撞软删行 → 500)→ code:0。chapter-create-delete.spec.ts 由 test.fixme
转回 test(),建→删配对通过;全量 e2e 43/0(原 +1 fixme 现转正、0 skipped)。

content 写路 + 软删 uk 修复完整闭环:chapter create/work delete 前端契约 + chapter/block order_no
后端 schema 双修验证通过。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 00:32:48 -07:00
lili
172261f540 fix(content): V26 修章节/Block 软删后 order_no uk 碰撞(partial index,待人类应用 flyway)+ 软删 uk 全仓审计
审计(用户授权):Explore 扫 177 uk,22 高危/137 中危/18 安全(yudao 软删 + ~99% uk 漏 WHERE deleted=false)。
精炼剔假阳(幂等/递增键不复用),真可复用业务键 uk = content order_no×2(确证)+ meta/ai/knowledge *_key×13。
全仓 ON CONFLICT 仅引用 command_id/id/asset/kb/validation/source,22 高危均不被引用→改 partial 安全。

V26 修 chapter+block order_no 改 partial index WHERE deleted=false(block create L294 确证同 selectCount+1 bug)。
应用需重启 48080 跑 flyway(DDL 改真 PG,auto-mode 归人类执行,未绕过)。chapter-create-delete e2e 保持
test.fixme、注释指向 V26,人类应用后转正。其余 13 业务键 uk 建议 V27 按模块逐步修(账本有清单)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:09:59 -07:00
lili
59d139637a fix(editor): 修删除作品缺契约字段致真后端 400(反假绿挖出,纯前端修复)
前端 useWorkDelete 此前 api.delete 不传 body,而后端 deleteWork 要 @Valid RevisionCommandReqVO
(commandId 幂等 + expectedRevision 作品乐观锁)→ 真后端删作品必 400(dev mock 不校验长期掩盖)。
又因列表 VO(GET /works)不含 revision 字段(仅 detail 有),无法直接取乐观锁版本;故 useWorkDelete
改为删除前先读 work 详情拿 revision,再带 commandId 提交删除(删除低频、额外一次 GET 可接受)。

补 work-create-delete.spec.ts(配对自清理 e2e:建作品→删作品,验 DELETE 200/code:0 + 列表无残留)。
curl 实证后端 work create→delete code:0(无 chapter 那类 order_no schema bug)。

tsc/eslint 0,vitest 79/79,全量 e2e 42/0(+1 chapter fixme)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 14:08:08 -07:00
lili
ca33c8e006 fix(editor): 修新建章节缺契约字段致真后端 400(反假绿挖出)+ 标注暴露的后端 order_no 软删 bug
前端 useChapterCreate 此前只传 {title},而后端 ChapterCreateReqVO 强制 commandId(幂等)+
expectedWorkRevision(作品乐观锁),缺失被 @Valid 拦成 400——dev mock 不校验、长期掩盖,真后端建章必败。
修:useChapterCreate 补 commandId + expectedWorkRevision;ChapterPanel 经 props 接 work.revision、
WorkspacePage 传入;建章后失效 workDetail 缓存避免后续写命令复用旧 revision。

补 chapter-create-delete.spec.ts(配对自清理 e2e),暂 test.fixme:前端修复后请求合法到达后端,
又暴露独立后端 bug——createChapter orderNo=selectCountByWorkId(active)+1,章节软删后行仍在、
uk_muse_content_chapter_work_order 不含 deleted(同文件 command uk 是 partial index 却此处遗漏)
→ 删章节后再建 order_no 冲突 500。属 schema/软删语义,需人类定 DDL 修法,fixme 待修。

tsc/eslint 0,studio vitest 79/79,全量 e2e 41/0(+1 fixme)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:54:34 -07:00
lili
1dbbfc78b5 test(account): 补权益配额/用量归属真后端 e2e(UsageStats,account 面收口)
GET /account/entitlements(套餐/配额/发布能力)+ /account/usage(Token 用量/归属分布)
此前无专门 e2e(live-read 仅断言 nickname、未覆盖 UsageStats);curl 证两端 code:0 就绪。
补 account-usage.spec.ts(验 200/code:0 + 「权益与配额」/「归属分布」区块渲染)。
全量 e2e 41/0。至此个人中心 account 面真后端 e2e 全闭环(profile 读写 + 权益配额 +
用量归属 + 购买/授权/发布三件套 + 安全事件 ack)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:31:00 -07:00
lili
3ffee3599a test(e2e): global-setup 清理 agent-create 累积污染(修 live-read ai 稳定红)
agent-create.spec uniqueName=`活体智能体-e2e-${Date.now()}` 不幂等,每跑新建一个自建 agent,
累积 22 条后按 updatedAt 倒序把种子「活体测试智能体」挤出后端默认分页第一页,致 live-read
「智能体列表渲染真实 Agent」断言 timeout(随历史跑次增多从绿变稳定红)。global-setup 加第 11 节
删 e2e 前缀 agent、保留种子。全量 e2e 39/0。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:19:34 -07:00
lili
f3ea06c154 fix(account): 修个人中心资料更新 jsonb 类型错致 update 500(反假绿挖出)
AccountProfileMapper.updateByAccountUserIdAndVersion 用 LambdaUpdateWrapper.set
写 profile_snapshot(PG jsonb 列),默认不走 DO 上 @TableField 的 JsonbStringTypeHandler,
按 varchar 绑定 →「column is jsonb but expression is character varying」→ update 500
(insert 走 typeHandler 故首次 create 侥幸 OK、对已存在 profile 的 update 必 500)。
set 显式指定 JsonbStringTypeHandler 与 insert 路径对齐。

新增 account-profile-update.spec.ts(真后端写路 e2e:改公开署名→PATCH /profile→
code:0+version 乐观锁自增+UI 回显;只改署名不动昵称以不破坏 live-read 的 nickname 断言)
正是它暴露此 bug——curl 实证旧 jar PATCH 500、rebuild 后 code:0。全量 e2e 39/0。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:19:16 -07:00
lili
db63b2d57e test(account): 补个人中心购买/授权记录真后端 e2e(市场记录三件套补完)
purchases(GET /account/purchases)/licenses(/account/licenses)与已有「我的发布」同源
(AccountMarketRecordService 读 muse_account_record_projection 投影表),此前有 UI+hook
但缺真后端 e2e 验证(假绿风险)。补两 test:验 200/code:0 + 「我的购买」/「我的授权」区
真后端读通渲染。全量 e2e 38/0(原 36/0)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 12:55:50 -07:00
lili
d4c530524e feat(studio): 已安装知识库停用/恢复 UI(G)
- useInstalledKnowledgeDisable/Restore hook(POST installed-knowledge-bases/{installId}/disable|restore,CommandReqVO 仅 commandId)
- KnowledgePage「从市场安装的」卡片:按 binding_status 切换停用/恢复按钮,保留卸载
- mock + vitest(installed disable/restore status 翻转)
- e2e 真后端(muse_knowledge_binding.binding_status 切换;global-setup section10 复位 binding id=1)

#30 第4缺口。验证:vitest 6/6+全套79/79、tsc/eslint 0、e2e 1 passed(真后端)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 10:42:27 -07:00
lili
fa651682b4 test(studio): work-schema-binding e2e 修 flaky(waitForResponse 前置)
schema-options 由 CreateWorkModal(首页即挂载、staleTime 60s)预取,全量跑(后端热)请求常
早于 waitForResponse 注册→race→30s timeout;注册移到 goto 前,覆盖请求早发/晚发两种时机。
全量 e2e 复跑该 spec 转绿(单跑本就绿、仅全量 flaky)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 10:20:28 -07:00
lili
494f3b5fd6 feat(studio): 知识库停用/恢复 UI + e2e 真跑
F——补自建知识库停用/恢复端面(后端 disable/restore 端点已有,缺 UI):
- useKnowledge: useKnowledgeDisable/useKnowledgeRestore mutation hook
- KnowledgePage: 自建 KB 卡片按 status 切换「停用」(confirm)/「恢复」按钮
- mock: 补 restore handler(disable 已有)
- 核实真后端 SummaryRespVO.processingStatus = kb.getStatus(),启用状态(disabled/searchable)
  经其透出可观测,排除"RespVO 缺启用状态字段"误判,确认无需改后端
- vitest useKnowledge 5/5(disable→disabled→restore→active)+ 全套 78/78,tsc/eslint 0
- e2e knowledge-disable-restore 真后端 1 passed;global-setup section 9 复位 KB1 status='draft'

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 09:42:29 -07:00
lili
cc57c595d8 feat(studio): E 来源归因查看 - 数据层+UI+e2e 真跑[P1]
studio 缺 UI 端面补齐(第 2 个,可验证缺口)。openapi export SourceAttribution;useSourceAttribution hook(只读);content mock source-attribution handler;SourceAttributionPanel(来源类型/贡献中文标签+许可+谱系);WorkspacePage 右侧加「来源」Tab(block 级,需 activeBlock)。

验证:useSourceAttribution 2/2 + SourceAttributionPanel 2/2 + 全套 vitest 77/77(无回归) + tsc 0 + eslint 0 + playwright source-attribution 1 passed(真后端 user_original→用户原创)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 09:11:28 -07:00
lili
c76cdec60a test(studio): D-c block 分割/合并 e2e 真跑 + 幂等复位[P1]
- block-structure.spec.ts:真后端端到端——进 work1 workspace→章节结构条(1 小节)→分割(真实 split POST 200→2 小节)→合并(真实 merge POST 200→1 小节);'N 个小节'来自 chapterDetail 真数据,证明 split 真产生 block。

- global-setup section 8:幂等复位 work1 chapter1 为单 Block(删 split 残留,保留 order_no 最小首 Block)。

- BlockStructureBar.extractText 兼容纯文本 content(基础种子 block content 为纯文本非 ProseMirror JSON,JSON.parse 失败时退回原串,使 split 可用)。

验证:playwright block-structure 1 passed(真后端活体) + eslint 0。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 09:01:11 -07:00
lili
355cdec314 test(studio): B5 planning 编辑器 e2e 真跑 + meta-schema fixture[P1]
- global-setup.ts 种 2 个 active MetaSchema(setting/worldview,novel_work)+字段+版本级可见性+绑 work1(此前 muse_slice_live 无 active schema→meta-projection unavailable)。

- planning-edit.spec.ts:真后端端到端——进 work1 workspace→作品规划 Tab→meta-projections 真实返回 setting→选 setting 渲染字段→填 time_period→PUT /planning/setting(验 usedFieldKeys 含 time_period+content)→切回验 value 回填。

验证:playwright planning-edit 1 passed + 直查 DB 确认 captureFieldSnapshot 真落库(muse_content_planning_field_snapshot 有 time_period/schema_id=1 行、planning section content_payload={time_period:古代})。B 字段级链路端到端真实贯通。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 04:50:08 -07:00
lili
b615a70a44 fix(studio): work 创建补 commandId + D1 work-schema e2e 真跑[P1]
D1-4 e2e 真跑暴露既有缺陷:useWorkCreate 漏传 commandId(后端 @NotBlank),真实后端 400(vitest mock 不校验故长期潜伏,work 创建此前无真实 e2e)。补 crypto.randomUUID() 幂等键。

新增 work-schema-binding.spec.ts 端到端验证 D1 链路:真实 GET /works/schema-options 200 渲染 Schema 下拉 → 真实 POST /works 200 + workSchemaId 字段贯通前后端。

验证:e2e 1 passed(真实后端,新 jar 含 D1-1/2/3);vitest useWorks 6/6 不破。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 01:09:51 -07:00
lili
f760ee6043 feat(knowledge): studio 知识库发布到市场可发布性预检(诚实呈现受阻)+ e2e
P1 真缺口补全(7/7,收官):知识库工作台自建库新增「发布」入口——源侧 publish-prechecks 预检。useKBPublishReadiness→POST /knowledge-bases/{kbId}/publish-prechecks(commandId+version);KnowledgePublishModal 打开即预检,呈现 blocked+受阻原因+权利/隐私/处理三态;KnowledgePage 自建 KB 卡片加「发布」按钮。

诚实处理:平台外部权利隐私校验器未配置(EXTERNAL_RIGHTS_PRIVACY_VALIDATOR_NOT_CONFIGURED)→ precheck 恒 blocked,UI 如实呈现「暂不可发布」+受阻原因,不伪造可发布、不提供伪造确认入口。

顺带修真后端兼容 bug:normalizeKnowledgeBase/normalizeInstalledKnowledgeBase 的 kbId 未强转字符串,真后端数字 id 被 isKnowledgeBaseSummary 守卫全部过滤→KB 列表空(此前仅 mock 测过未暴露);改 String() 强转(对字符串幂等,不破坏 mock)。

验证:vitest knowledge 13/13(加 publish-precheck 契约)、tsc 0 错;新增 e2e knowledge-publish-precheck.spec.ts 真后端绿(发布→预检 200+blocked:true+「暂不可发布」),全量 30/30 无回归。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:48:14 -07:00
lili
3dff0e1735 feat(account): studio 个人中心补齐市场记录三件套之三「我的发布」+ e2e
P3 真缺口补全(6/7):PersonalCenter 此前只有购买记录+授权记录,缺发布记录(账户台账视角)——补齐三件套对称。useAccountPublishRecords→GET /account/publish-records(AppPublishRecordRespVO:reviewStatus/marketStatus/blockingReason);PersonalCenter 加「我的发布」区。

查重结论:不与 market 模块 useMyPublishRecords 重复——后者是发布工作流操作台(草稿/提交/申诉,my-publish-records),本接口是账户中心历史台账(account/publish-records,member 模块,与购买/授权并列)。

验证:vitest account 3/3(加 publish-records URL+reviewStatus 契约)、tsc 0 错;新增 e2e account-publish-records.spec.ts 真后端绿(GET 200+「我的发布」渲染),全量 29/29 无回归。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:36:20 -07:00
lili
9c84c05e62 feat(market): studio 资产详情页加「绑定到作品授权预检」(来源侧 handoff 预检) + e2e
P2 真缺口补全(5/7):资产详情页新增「绑定到作品」区——获取授权 + 来源侧 bind-precheck(展示授权摘要/兼容性/就绪态/绑定策略)。useBindPrecheck→POST /assets/{id}/bind-precheck(targetOwner=knowledge/targetAction=bind/targetWorkId,commandId 走 body);详情页接 useAcquireMarketAsset 获取授权 + 预检结果回显。

诚实边界:只做来源侧只读预检(返回授权摘要,不产生绑定事实);完整交接 token 由知识域消费(Market 不消费 token),消费端 UI 不在本切片——故不做 create handoff token(避免一侧设计)。

反假绿:probe 真后端确认链路——bind-precheck 需先 acquire(否则 1044000006 授权不存在);asset 须 listed(asset 2 not_listed→1044000004);agent 资产 targetOwner=knowledge/action=bind 通(ai/install 报 1044000021 模板不支持)。

验证:vitest market 4/4(加 bind-precheck URL+body 契约)、tsc 0 错;新增 e2e market-handoff-precheck.spec.ts 真后端绿(acquire→预检→handoffReady:true),全量 28/28 无回归。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:31:27 -07:00
lili
7a16d19211 feat(market): studio 资产许可详情页(详情+许可条款+收藏)接通真后端 + e2e
P2 真缺口补全(4/7):列表页仅 licenseSummary 单行,新增资产详情页呈现完整许可——路由 /market/assets/:assetId + MarketAssetDetailPage;useMarketAssetDetail→GET /marketplace/assets/{id}(licenseInfo:类型/价格/有效期/允许·禁止用途);useFavoriteAsset→POST favorite;MarketBrowse 资产名改为详情 Link 入口。

反假绿:favorite 首跑返 1044000001(MARKET_COMMAND_ID_REQUIRED)——查出 favorite 的 commandId 走 X-Command-Id 请求头(market 端点契约,异于 acquire/install 的 body commandId),改用底层 request 注入该头修复。

验证:vitest 53/53(market contract 加 detail/favorite URL)、tsc 0 错;新增 e2e market-asset-detail.spec.ts 真后端绿(列表→详情→许可渲染→收藏 POST code:0),全量 27/27 无回归。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:21:45 -07:00
lili
c119b90919 feat(knowledge): studio 图谱实体编辑 + 新建关系接通真后端 + e2e
P1 真缺口补全(3/7,价值最高):KnowledgeGraphPanel 从只读→可维护正式轨——useUpdateEntity→PUT /entities/{id}(编辑实体名,经后端 normalizedName 规范化)、useCreateRelation→POST /entities/{id}/relations(源→目标 + relationType);均带 commandId,graph node.id=实体 id 直接复用。UI:每实体 inline 编辑 + 底部源/目标/类型新建关系表单。

验证:vitest 52/52(contract 加 PUT/POST URL+body+targetEntityId 转 number)、tsc 0 错;新增 e2e knowledge-entity-crud.spec.ts 2 例真后端绿(编辑名回显规范化值、建关系回显新边),全量 26/26 无回归。反假绿:编辑回显失败暴露后端 normalizedName 去连字符规范化,e2e 适配真实规范化用稳定值断言、非掩盖。种子:global-setup #2c work2 三实体(与 graph 的 work1 隔离、按 description marker 复位)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:13:20 -07:00
lili
e5ee1fdb58 feat(knowledge): studio 草稿「忽略/重新校验」接通真后端 + e2e
P1 真缺口补全(2/7):KnowledgeDraftPanel 在「确认入库」旁加「重新校验」「忽略」两动作,接已就绪后端端点——useIgnoreKnowledgeDraft→POST /knowledge-drafts/{id}/ignore(审而不入,草稿转 ignored 移出)、useRecheckKnowledgeDraft→POST /knowledge-drafts/{id}/recheck(来源重验异步任务,草稿留 pending);均带 commandId 幂等键,照 useConfirmKnowledgeDraft 模式。

验证:vitest 51/51(contract test 加 ignore/recheck URL+commandId 断言)、tsc 0 错;新增 e2e knowledge-draft-actions.spec.ts 2 例真后端绿(recheck→queued、ignore→ignored+移出),全量 e2e 24/24 无回归。种子:global-setup #2b 固化 work2 下 recheck-e2e/ignore-e2e 两草稿(与 confirm 的 work1 隔离、各用独立草稿避免 recheck 改态影响 ignore)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 19:59:40 -07:00
lili
99f8fcd2e0 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>
2026-06-20 13:53:29 -07:00
lili
5a137f1861 test(studio): bindings 读回 live e2e spec(ready-but-unrun,镜像 graph spec)
muse-studio/e2e/knowledge-bindings.spec.ts:nav /knowledge/1→捕获真实 GET /works/1/knowledge-bindings→断 200/code:0/active 绑定 + 面板渲染(作品已绑定的知识来源/市场知识库/生效中)。playwright --list 确认编译有效可发现(1 test)。

尝试活体运行受阻(诚实,非假绿):远端 PG 宿主 100.64.0.8:5433 离线(不在 tailnet 节点列表)、本机无 PG 兜底,全栈 muse-server 起不来。PG 宿主恢复后按 .agents/knowledge §六 起栈(redis 本机可启、jar 需重建含 GET 端点、muse_slice_live seed work1 绑定)即可跑。后端 218 + studio 50/tsc/build 已绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 22:49:46 -07:00
lili
9d5430b62c test(studio): add live agent create e2e 2026-06-19 07:35:53 -07:00
lili
6fd483ea1d test(studio): e2e globalSetup 直连真实 PG 自动复位每轮 fixture(可入库,替代一次性 /tmp 种子)
新增 e2e/global-setup.ts:用 pg 直连真实 PG(凭据从 infra.env 环境变量读,不入库)幂等复位 graph/confirm-draft/accept(block3→rev1)/security-ack(事件→未确认+清 ack)/appeal(→supplementing)等每轮被消费的 fixture;playwright.config 接 globalSetup + workers:1(共享活体 DB 串行避竞态)。

证:消费态下 source infra.env 后 pnpm 直跑整套→globalSetup 复位→20/20 单次全绿,零手工种子(反假绿可复现)。E2E_SKIP_SEED=1 可跳过;缺 MUSE_POSTGRES_* 报清晰错。tsc -b 干净。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:35:51 -07:00
lili
3ed40a3187 feat(studio): 知识图谱视图(先审后入"正式轨"成果)rendered-UI 活体证
知识库工作台(/knowledge/:workId)新增「知识图谱」面板:经 GET /works/{id}/graph 读真实 muse_knowledge_entity/relation,渲染已确认入库的 Canonical 实体(节点)与关系(边)——与「待确认草稿面板」构成双轨主权闭环(候选 Shadow → 人工确认 → 正式图谱可见)。新增 useKnowledgeGraph hook;confirm 成功后失活图谱缓存联动刷新。

活体证(MSW off,chromium 直连 48080):knowledge-graph.spec.ts 绿(GET graph code:0、节点 huotituopusuqing/huotituopuqingzhou + huoti_related 边渲染);curl 实证后端真返节点/边。tsc -b 干净、vitest 47/47 无回归。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 08:34:36 -07:00
lili
90daa3088b feat(market): 我的发布记录回显 appealStatus(生产者飞轮端到端收口)
my-publish-records 经 MuseMarketAppealMapper.selectLatestByAssetIdAndUser +
resolveAppealStatus 回填该物化资产被当前发布者发起的最新申诉态到记录 appealStatus
(无物化资产/无申诉则 null;marketAssetId 与 appealStatus 两路共用各只查一次)。
前端 MarketPublish 发布记录副文本以中文徽标渲染「申诉:<待处理/审核中/已关闭…>」。

活体证(反假绿,MSW off 直连重建后单体 48080):
- market-publish.spec.ts 第 8 例 chromium 绿(recId=5/marketAssetId=2 回显 appealStatus=closed→「申诉:已关闭」)。
- 后端 MarketPublishServiceTest 14/14 回归通过(appealMapper 注入无 NPE);前端 tsc 干净 + vitest 47/47 + market-publish 8/8。

至此市场生产者飞轮端到端完整:发布(草稿→检查→提交)→上架状态可视化→
申诉(提交/补充材料/撤回)全生命周期 + 申诉态回显。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 07:08:09 -07:00
lili
ce6bbd8625 feat(market): 申诉补充材料/撤回 UI——补 app-api 我的申诉列表端点
同类 gap:生产者本无「自己申诉」的 app-api 列表端点(只有 admin 列表),
故 supplement/withdraw 无从取 appealId+状态。

后端(muse-module-market):新增 GET /marketplace/appeals(appListMyAppeals +
MuseMarketAppealMapper.selectListByUser + MarketMyAppealItemRespVO),
返回当前发布者全部申诉,并派生 canSupplement(supplementing 态)/canWithdraw(非终态)。

前端(muse-studio):MarketPublish「我的申诉」区列申诉 + 中文状态徽标;
- canWithdraw 放开「撤回」→ useWithdrawAppeal → POST .../withdraw(expectedStatus 乐观锁)→ closed;
- canSupplement 放开「补充材料」→ useSupplementAppeal → POST .../supplements(privacyConfirmed)→ reviewing。

活体证(反假绿,MSW off 直连重建后单体 48080):
- market-publish.spec.ts 第 6/7 例 chromium 绿(撤回→已撤回、补充→材料已补充)。
- DB 证:withdraw→muse_market_appeal status=closed;supplement→muse_market_appeal_material 追加行(e2e 点击产 material#2)。
- 后端 MarketAppealServiceTest 15/15 + AppMuseMarketAppealControllerTest 6/6 回归通过;前端 tsc 干净 + vitest 47/47 + market-publish 7/7。
- 种子 /tmp/SetAppealSup.java(置 supplementing;提交后→reviewing 故每轮重置)。

仍 ⬜:发布记录上 appealStatus 回显(my-publish-records 未 join 申诉表)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 06:53:55 -07:00
lili
a00c7581c9 feat(market): 申诉(appeal)写路 UI 打通——后端暴露物化 assetId 解 gap
根因:my-publish-records 的 assetId 是 publish-record id(草稿/申请占位),
非 submitAppeal.requireAsset 所需的物化 muse_market_asset.id(资产仅在 admin
审核通过 markListed 时物化),生产者侧 UI 取不到正确 assetId。

后端最小契约改动(muse-module-market):
- PublishRecordItem / MarketPublishRecordItemRespVO 加 marketAssetId 字段;
- MarketPublishServiceImpl.resolveMarketAssetId:request.asset_id 命中真实
  muse_market_asset 且归属当前发布者才返回其 id,否则 null(fail-closed,不放开入口)。

前端(muse-studio):
- useSubmitAppeal hook(POST /marketplace/appeals,新 commandId 幂等);
- MarketPublish「我的发布记录」:仅 marketAssetId 非空 + 状态可申诉
  (rejected/compliance_blocked→review_rejection、delisted→delist、recalled→recall)
  的记录放开「发起申诉」→ 面板填理由 → 提交 → 申诉已提交(pending)。

活体证(反假绿,MSW off 直连重建后单体 48080):
- market-publish.spec.ts 第 5 例 chromium 绿(点发起申诉→填→提交→pending)。
- DB 证:muse_market_appeal 追加行 status=pending、commandId 为前端 UUID(e2e 点击产 appealId=3)。
- curl 正负路:自有已驳回→appealId/pending;他人资产→1044000024 无权访问;不存在→1044000003 资产不存在。
- 后端 MarketPublishServiceTest 14/14 回归通过;前端 tsc 干净 + vitest 47/47 + market-publish 5/5。
- 种子 /tmp/SeedAppeal.java(asset(pub=1)+rejected request,asset_id=物化资产)。

仍 ⬜:补充材料(supplements)/撤回(withdraw)申诉 UI、记录上 appealStatus 回显。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 06:33:44 -07:00
lili
0ec0955779 feat(studio): 市场发布上架状态可视化(生产者飞轮进度反馈)
「我的发布记录」新增发布生命周期中文徽标(草稿/已提交/审核中/已通过/
已上架/已驳回/需补充材料/已撤回/已下架/已召回)+ nextAction/appealStatus
副文本。上架=审核通过自动 markListed(非生产者动作),生产者侧通过本徽标
看到 publish→review→list 进度反馈。

活体证(反假绿,MSW off 直连单体 48080):
- market-publish.spec.ts 第 4 例 chromium 绿:断言 listed→「已上架」、
  rejected→「已驳回」徽标渲染(种子 /tmp/SetReqStatus.java 置 req#2→listed、#3→rejected;
  curl my-publish-records 证状态反映)。
- market-publish 4/4 + vitest 47/47 + tsc 干净。

申诉(appeal)后端经 curl 验证为 real+fail-closed(自有已驳回资产→appealId/pending;
他人资产→1044000024 无权访问;不存在资产→1044000003 资产不存在),但申诉 UI 后置:
真实 gap——my-publish-records 暴露的 assetId 是 publish-record id,非 submitAppeal
所需的物化 muse_market_asset.id(资产仅在 admin 审核通过 markListed 时物化),
UI 入口取不到正确 assetId,收口需后端额外暴露物化 assetId 或经真实审核通过物化流。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 05:36:36 -07:00
lili
0cf1ef3462 feat(studio): 安全事件「确认」写路(account 深页活体切片)
个人中心「安全事件」区:未确认事件展示「确认」按钮,点击经
useAcknowledgeSecurityEvent(每次发新 commandId,后端按 commandId 幂等)
真打 POST /account/security-events/{id}/acknowledge(action=acknowledged)→
列表失活重取翻「已确认」、按钮消失(构成 acked→无动作 UI 不变量)。

活体证(反假绿,MSW off 直连单体 48080):
- 正路:account-security-ack.spec.ts chromium 绿(点确认→翻已确认);
  curl acknowledge 真实事件→code:0 + 列表 acknowledged 翻 true。
- 负路:acknowledge 不存在 eventId→404、非法 action→400,均 fail-closed。
- DB 双证:muse_member_security_event.acknowledged 翻 true +
  muse_account_security_event_ack 追加 1 行(action=acknowledged、
  commandId 为前端 UUID=权威处理历史,非覆盖)。
- 种子可重置(/tmp/SeedSec.java:事件B写锚点每轮重置未确认,写路 e2e 可重复)。
- 本轮实跑:account-security-ack 1/1 + live-read 6/6 + vitest 47/47 + tsc 干净。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 05:20:50 -07:00
lili
b58a704ffa feat(studio): 个人中心渲染真实安全事件(account 深页活体切片)
PersonalCenter 新增「安全事件」区,渲染 GET /account/security-events 真实摘要
(useAccountSecurityEvents→AccountPageResult<SecurityEventSummaryRespVO>),
eventType/severity 徽标 + 已确认/待确认状态。

活体证(反假绿,MSW off 直连单体 48080):
- 正路:live-read.spec.ts 第 6 例 chromium 绿,断言种子事件「活体安全事件·异地登录提醒」渲染;
  curl 列表 total=1 含该事件。
- 负路:acknowledge 不存在 eventId→404「安全事件不存在」、非法 action→400 参数校验,
  均 fail-closed 非许可桩。
- 种子幂等(/tmp/SeedSec.java,account_user_id=1/tenant=1,DB id=1)。
- 本轮实跑:live-read 6/6 + vitest 47/47 + tsc 干净。

security-events 后端端点本就可用(无 facade gate),本切片接通 UI 消费侧。
exports/downloads/new-api 深页仍为正确 fail-closed 外部依赖,非接线缺口。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 04:30:43 -07:00
lili
c7c65a97f2 feat(studio): 个人中心渲染真实购买/授权记录(account 深页活体切片)
承 account facade 活体订正(单体内 /account/{purchases,licenses,publish-records} 经 market 跨模块
MarketAccountProjectionProvider 本就可用),把已确认可用的后端接进 UI:
- PersonalCenter 新增「我的购买 / 我的授权」两区,渲染 market→account 投影真实记录;
- useAccount 加 useAccountPurchases / useAccountLicenses(GET /account/{purchases,licenses})。
- live-read.spec.ts 加第 5 例(chromium, MSW off, 真连 48080):/account 渲染真实资产「活体市场资产·测试」。

验证:整套 e2e 12/12、vitest 47/47、tsc 绿。进度总账 §五C 个人中心就地更新。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 03:11:20 -07:00
lili
288fce955f feat(studio+market): 市场发布提交审核全链(草稿→检查→提交)活体绿 + V22 补 review_event 索引
承上一提交(草稿切片),完成创作者发布全链到「提交审核」:
- MarketPublish 加 licenseType / 权利声明字段 + 「提交审核」按钮(save→运行检查→检查通过则提交申请);
  useMarketPublish 加 useRunPublishCheck / useSubmitPublishRequest。
- market-publish.spec.ts 3/3 绿(草稿正 / 缺标题负 / 提交全链),DB 证 muse_market_publish_request=submitted
  + muse_market_review_event=submitted 落库;全链测用唯一名→可重复跑。
  整套 e2e 11/11、vitest 47/47 无回归、tsc 绿。

修复:submitPublishRequest 的 writeSubmittedReviewEvent 命中 muse_market_review_event 同款部分索引
ON CONFLICT 不匹配 bug(submit 500);V22 迁移 + muse_slice_live 增补 review_event 索引(部分→完整,共 4 表)。
遗留:handoff/appeal/authorization_summary 等 market 表同类部分索引待对应流程活体时收口。

进度总账 §五C 已就地更新(市场生产侧:发布草稿 + 提交审核全链 ✅)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 02:10:12 -07:00
lili
0b6b1e8887 feat(studio+market): 市场生产侧发布草稿活体纵切 + 修 publish 部分索引 ON CONFLICT 潜伏 bug
studio 生产侧首切片(创作者飞轮起点):新增 /market/publish 发布表单(MarketPublish + useMarketPublish hook),
保存发布草稿经唯一合法入口 POST /marketplace/publish-drafts → my-publish-records 真实回读;
MarketBrowse 加「我要发布资产」入口。market-publish.spec.ts(chromium, MSW off, 真连 48080)正+负绿,
DB 证 muse_market_publish_draft 落库(status=draft);命令幂等键按材料 hash 派生→自包含可重复跑、无需预种。

附带修真实潜伏后端 bug(链路从未活体跑过):publish draft/check/request 的 (tenant_id,command_id)
被 V15 建为部分唯一索引(WHERE command_id IS NOT NULL),而各 mapper insertIgnore 发无谓词
ON CONFLICT (tenant_id,command_id)→PostgreSQL 无法用部分索引作仲裁器→savePublishDraft 500
(BadSqlGrammarException: no unique or exclusion constraint matching the ON CONFLICT specification)。
修=部分→完整唯一索引,对齐 muse_market_command/purchase 既有约定(V22 迁移 + muse_slice_live 已应用,
零 Java 改动/零重启)。遗留:handoff/appeal 等 market 表同类部分索引待对应流程活体时收口。

验证:整套 e2e 10/10 绿、vitest 47/47 无回归、tsc 绿。进度总账 §五C/§四/per-BC 已就地更新。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 02:01:18 -07:00
lili
8a6c809696 test(studio): studio e2e 全套 MSW-off 自起复现 8/8 全绿 + 修 webServer/workspace 假绿
承 MVP#1 前端长板收口。整套 playwright(chromium)在关 MSW、直连真实单体(48080)下 8/8 全绿,
经「移开 .env.local + 无预跑 vite + playwright 自起」验证可独立复现(非仅依赖手起 vite 被 reuse)。

修复(经验证):
- playwright.config.ts webServer.command:`pnpm dev` 在 playwright 派生的 /bin/sh 下报
  「pnpm: command not found」(exit 127,pnpm 不在该 PATH),改用等价 `./node_modules/.bin/vite`;
  并加 `env: VITE_API_MOCK=false`,使关 MSW 在 CI/自起场景可复现(此前仅 reuse 手起 vite 才绿,潜伏假绿)。
- workspace.spec.ts:原断言 mock「星海迷途」在 MSW-off 下必红(MSW 假绿反模式),
  改写为不依赖 mock 的工作台壳渲染冒烟,消除最后一处 MSW 互斥红。

覆盖(均 MSW off 真连、write 路径 DB 核验):accept-suggestion 正+负
(block3 rev1→2 + AI摘要正文 + ai_suggestion 归因落库)、knowledge-confirm
(draft→confirmed + 新建 Canonical entity)、live-read content/market/account/ai、workspace 壳。

进度总账 §五C/§四:记 8/8 里程碑;订正 suggestion 合并后留 pending 根因
(merge 不同事务回写 AI 域、靠 outbox→AI 异步翻,读 ContentSourceServiceImpl 确认,非产品 bug)。

遗留:e2e 暂依赖 muse_slice_live 预置 fixture(/tmp 助手手动 reseed),待补 playwright global-setup 自播种。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 01:29:35 -07:00
lili
749c5b2471 feat(knowledge): 知识库工作台前端先审后入(确认草稿→Canonical)rendered-UI 活体证
后端:SummaryRespVO 暴露 confirm 所需并发/源令牌(sourceSnapshotId/authorizationSnapshotId/revision),
否则前端无法构造合法 confirm 请求(非破坏性新增,不改 confirm 语义);转换器填充。
前端:useKnowledgeDrafts/useConfirmKnowledgeDraft hooks(回显令牌)+ KnowledgeDraftPanel(待确认草稿+确认入库)
+ KnowledgePage(/knowledge/:workId)接入。e2e knowledge-confirm:chromium MSW-off 点确认入库→真 confirm
→ draft confirmed+entityId(DB 证 draft5 confirmed/entity_id=3)。tsc 0。
遗留:confirm 对已存在同名 Canonical 实体抛未处理 DuplicateKeyException(500),应改干净 conflict(另 flag)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:41:58 -07:00
lili
f63247fb8f test(studio): live-read e2e 补 ai-agent 读旅程(4/4 绿)
智能体列表 rendered UI 渲染真实 agent(MSW off 直连活体)。前端 in-UI 既有页面扫描完成:
content(列表读+采纳写)/ai(agent读+采纳)/market(浏览读)/account(个人中心读)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:28:18 -07:00
lili
6d3eeed068 test(studio): content/market/account 读旅程 rendered-UI 活体 e2e(3/3 绿)
live-read.spec.ts:MSW off 直连活体单体,chromium 验作品列表/市场浏览/个人中心均渲染真实后端数据,
证 client.ts tenant-id 修复后 studio 可跨 BC 直取活体数据、真实数据形态与渲染契约对齐。
前端 in-UI 覆盖:content(列表读+采纳写)/ai/market(浏览读)/account(个人中心读)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:26:13 -07:00
lili
73355b69fa feat(studio): MVP#1 AI候选采纳 rendered-UI 活体 e2e 打通(happy+negative)
main.tsx 加 VITE_API_MOCK=false 开关关 MSW、前端直连活体单体(activeb 联调/e2e 用,默认 dev 仍 MSW 开)。
accept-suggestion happy-path 用 page.route stub AI 生成(发真实 suggestionId,采纳 POST 直打真后端)→
chromium 实跑:生成→点采纳替换→真合并,DB 证 block rev1→2、正文=候选;negative-path 乐观锁拒绿。
§五C 记前端 in-UI 模式打通 + 遗留(种子状态依赖/MSW on-off 拆 project/suggestion 留 pending 待确认)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:22:33 -07:00
lili
b50cd45d23 fix(studio): client 注入 tenant-id(活体集成缺口)+ MVP#1 negative-path e2e 绿
活体对接暴露:client.ts 只注入 Bearer/版本号、漏 tenant-id,真实后端报「租户标识未传递」(MSW 不校验故 dev 未暴露)。
新增 auth.readTenantId(mock 单租户默认 1,真实登录应写入)+ client 注入 tenant-id 头。
e2e/accept-suggestion 负路径补 tenant-id 头、填活体种子常量(work/block/suggestion=3);
playwright(chromium)实跑:rendered app→vite 代理→真后端→乐观锁 1041000002 拒,绿。tsc 0 / vitest 47。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:13:22 -07:00
lili
fe75b666b9 feat(p1-mvp): AI候选采纳入正文纵切——前端接 suggestion-merges + 后端 real-PG 机械门禁
据现状基线 §6.3 #1(前端 AI 候选闭环断链)整改:

前端(muse-studio):
- WorkspacePage 真实编辑器接入唯一合法入口 POST .../suggestion-merges(新增 useAcceptSuggestion),
  去除 EditorPage 仅本地 setContent 的绕过(违背 Shadow→Canonical 主权)
- client.ts 注入 Authorization Bearer(后端 Sa-Token 鉴权);新增 auth.ts 统一令牌读取,sse.ts 复用去重
- AIPanel 透传 suggestionId;connectAIStream 复用 createEventStreamParser 对齐真后端 SSE event: 线(修旧 data.type 漂移);
  sse.ts onDone 类型对齐 {taskId,suggestionId};CandidatePanel 异步采纳+防双写
- tsc / 47 单测 / build 全绿

后端(muse-cloud):
- 新增机械门禁 P1rContentMergeSuggestionIT:真实 PG + 真实 AiSuggestionMergeProjectionFacade 读真种 muse_ai_suggestion
- 5/5 绿:正向写 Canonical(rev1→2)/revision 冲突不脏写/幂等回放/非 pending/「审」字段缺失

未达(诚实):活体全栈 UI e2e 未跑——阻塞于①远端 dev 库缺 yudao 基座 schema(全栈 app 起不来)
②AI 运行时未写「审」字段(生成流候选不可合并,chip task_092cfc32);均范围外。
connectAIStream 的 SSE parser 漂移已在本提交修复。e2e/accept-suggestion.spec.ts 只写不跑。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 09:29:56 -07:00
zizi
79c0633c3a fix(studio): 对齐 P2 用户端工作台契约
修复 P2 review 发现的编辑器 Block 保存、AI task stream、知识库命令写入、草稿同步状态和 diff 性能边界问题。补充契约测试、Vitest coverage 和 Playwright e2e 冒烟入口。
2026-05-26 07:50:07 +08:00