65 Commits

Author SHA1 Message Date
lili
43a08624f8 feat(studio): S7c 采纳恒回传完整正文(所见即所写)+ 流健壮性
分支①第三步(纯前端,无需改后端):采纳恒以 merge_after_edit + modify_then_merge 语义上送用户在
候选面板审定的完整正文作 finalContent(改没改过都送、原样发),使 Canonical 由客户端回传正文写入,
而非后端存的 60/80 字摘要——修掉「原样采纳(accept_as_is)把摘要写进 Canonical」的潜伏缺陷。
后端契约已亲验:ContentSourceServiceImpl.resolveMergedContent 的 merge_after_edit 分支直接落
finalContent、只校验非空、不要求"必须改过";accept_as_is 才用摘要。

流健壮性:done 仅带 taskId/suggestionId/可选 summary、无完整性信号,故按前端可得信号三分——①流非空
(原子 SSE chunk 已收全)→happy;②流非空但短于 done.summary→疑似断连截断,提示重生成、绝不静默采纳;
③流为空→回源只得脱敏摘要,标 degraded 由候选面板明确警告、不当完整正文静默采纳。

验证:tsc -b / vitest 32 files 121 passed / vite build / eslint 均 EXIT=0;MSW-off e2e
accept-suggestion.spec 真后端48080+真 New-API 3 passed——采纳后 acceptMode=merge_after_edit、
revision 180→181、Canonical content_text===客户端回传 finalContent(所见即所写端到端证实)。
改动严格 8 文件全在 muse-studio。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 00:53:56 -07:00
lili
9af471289a fix(solo): 修复 2.0.0 单人版 live 后端启动(DB 口径对齐 + moderation 关停)
标准启动默认落陈旧的 muse_local(仅 V0 baseline、缺 yudao 基座、update_updated_at_column()
函数属第三个角色 muse)→ Flyway V1 CREATE OR REPLACE FUNCTION 报 "must be owner"。唯一健康
的 live 库是 root@muse_slice_live(已迁 V34、含基座+登录种子)。将 application-infra.yaml 与
start-muse-server-infra.sh 的默认库/用户改为 muse_slice_live/root(真实值仍由 infra.env 覆盖)。

S4 关停 spring.ai.model.* 时漏了 moderation;OpenAiModerationAutoConfiguration 默认
matchIfMissing=true → 全量 boot 实例化 openAiModerationModel、无 OpenAI key 直接抛
"OpenAI API key must be set" 使单体启动失败。在 monolith 真正加载的 muse-server/application.yaml
与 ai-server/application.yaml 两处补 moderation: none(单人形态输出合规走自研 MuseAiCandidateReviewService)。

workspace.spec 冒烟原缺 token 注入,被 S5 新增的 AuthGuard 拦重定向 /login → 补 test1 token 注入。
external-deps 记录 Dify 实例被游戏/Muse 共用、workspace 须隔离的约束。

验证:muse-server 干净启动(Started in 22.4s、Flyway up-to-date 零 owner error);MSW-off 创作主线
e2e 33 passed/0 failed/31 隔离(候选采纳/导入/导出/知识草稿/图谱/绑定/agent 生命周期/AI 真生成全绿);
run-p1r-verification.sh local 65 tests/0 fail BUILD SUCCESS。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 22:41:12 -07:00
zizi
6dcabf69fb feat(solo): 收口治理入口并裁剪 studio 表面
完成 2.0.0 S4 的外部 AI、admin、account 与 solo SQL 收口,并推进 S5 studio 市场/handoff/旧编辑器入口裁剪。S5 的前端单测、构建与 route-only e2e 已留证;MSW-off 创作主线 e2e 仍因本地后端活体启动口径待修正,已在总账标为未完成验收。
2026-07-08 11:45:26 +08:00
lili
a5619a3566 feat(content): 补齐导入导出真链路
Some checks failed
Backend Maven CI / backend-local (push) Has been cancelled
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 07:40:10 -07:00
lili
3585219637 feat(mvp): 收束1.0.0线A交付闭环
Some checks failed
Backend Maven CI / backend-local (push) Has been cancelled
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 10:52:10 -07:00
lili
8b3258e22f test(market): U-verify D0-fork 端到端真验收(真 PG+真 RAGFlow、第四单元)
D0-fork 最后单元:真 PG17+真 RAGFlow 端到端验收、2 IT 真绿(独立复跑确认 57s)。P1rMarketKbForkMaterializationIT(muse-server、跨 knowledge+market 两 BC 须同 Spring 上下文):①fork→安装→物化 installed_ref→检索命中(no_dataset 消除、副本与活 dataset 物理分离);②发布者私有不泄露真证(发布者上架后往活 dataset 真传私有 magic、安装者检索副本拿 magic 当 query 仍只返公开 chunk 不含 magic→d0ForkIsolationProven、U0 spike 反向基线);③幂等+多安装者共享1副本;④AFTER_COMMIT 时序(committedAssetForked/rolledBackAssetForked false:提交才 fork 回滚不 fork);⑤_test 库铁律(muse_p1r_fork_mat_test 绝未指 muse_slice_live)。

market-install-kb-retrieval.spec.ts(studio e2e):检索命中+私有不泄露无独立 UI 入口由 IT 证;安装物化 e2e 标 test.fixme 待 global-setup 补 fork 就绪资产(不伪绿、骨架就位 tsc 过)。召回回滚(D9)如实标开放项:recallAsset 仍 writeSourceStatusBlocked、knowledge 无召回消费者→不自动停用 installed_ref;需新增 market→knowledge 召回传播才闭环(不伪造、不引用不存在的 muse_source_propagation_target)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:58:56 -07:00
lili
d1917b4f77 test(studio-e2e): 收窄 agent-slot-bind 断言到槽位面板容器,根治 strict mode 歧义 flaky
agent-slot-bind:94 之前 flaky(~64% 失败):getByText(当前:xxx v1)全局 strict 命中 2 元素(AgentPage 沙盒试用区 selectedAgent 回显 + SlotBindingPanel 槽位 boundAgentName、选中 agent==已绑时同文案),与槽位异步读时机竞速。收窄到 div.rounded-2xl filter 作品槽位绑定 槽位面板容器内断言(仿套件其他 spec 的 locator().filter() scope、不改产品)。

验证:10 次独立 playwright test 循环(每轮重跑 globalSetup 复位 revision=1、非 --repeat-each 避 fixture 漂移伪红)10/10 全绿、无 strict mode violation。预存 flaky(commit 1fbe7ae 引入、非本轮回归);至此 studio e2e 56/56。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:16:07 -07:00
lili
0b152d9c6d fix(knowledge): 修 KB 绑 ≥2 作品停用/删除必 500 真后端 bug + 补真 PG IT(studio e2e 真连揪出)
studio e2e knowledge-disable-restore 真连揪出 mock 单测掩盖的生产 bug:任何用户把知识库绑到 ≥2 作品后无法停用/删除(disable POST HTTP 200 但 body code:500)。根因:updateStatusByKbId 给该 KB 所有未删 binding 写同一停用 commandId→违反 uk_muse_knowledge_binding_command(tenant_id,command_id)唯一索引→DuplicateKeyException。

command_id 语义=「创建/最后改写该 binding 的命令」行级幂等键(单行写路径 create/delete/updateInstalled 各写一行;对称 source projection 无 command_id、用 last_event_id 印证 KB 级 fan-out 不占行级幂等槽);KB 级停用是 KB 维度单命令(commandId 已记 muse_knowledge_base+source_event)、非 binding 创建命令。修(候选①传播不覆盖 command_id):updateStatusByKbId(Long,String,String)→(Long,String)删 setCommandId 只翻 binding_status;propagateKbBlocked 去 commandId 参传 sourceEventId;disableGlobalKnowledgeBase(:190)/changeUserStatus(:452 user disable+delete)2 调用点同步。

影响面=全局/用户 KB disable+用户 KB delete 三传播路径,行为变化仅不再改写 binding.command_id(binding_status/affectedBindings/source projection 不变);对外契约不变、纯修 500;回滚 git checkout。

mock 单测掩盖根因(mock updateStatusByKbId 返行数、不触发真唯一索引)。补真 PG IT P1rKnowledgeBaseDisableMultiBindingIT(真 PG+Flyway V14+真 service/mapper):KB 绑 2 作品 disable/delete 传播成功+两 binding 各保留 command_id;反假绿用例直写同 command_id 仍被唯一约束拒(SQLState 23505)。修后 3/3 绿;临时重引入 bug→2/3 DuplicateKeyException 证真回归门禁。独立核实:e2e 连跑 3 次 2 passed(修前红);psql 复核 KB1 2 binding(work1+work2)全 disabled、command_id 各异无冲突;global-setup 补 9b 多 binding 锚点(KB1+work2)令 e2e 真走 ≥2 binding 传播路径。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:20:50 -07:00
lili
ca0e04c9a9 test(studio-e2e): source-attribution 解耦到 pristine block3 根治测试间来源污染 flaky
source-attribution 只读 spec 期望 block1 来源=user_original,但全量串行时前序 accept-suggestion(写 ai_suggestion)/block-autosave/block-structure 按字母序先跑且都写 block1,block1 顶层 revision 来源在 user_original/ai_suggestion 漂移→偶发渲染"AI 生成"红;global-setup 每轮仅跑一次、无法撤销跑中途污染。修:spec 改读 pristine work3/block3(grep 确认无人导航 /workspace/3、无人写 block3)+global-setup §3 每轮删净 block3 归因并重建唯一 user_original rev1 行(幂等)。断言未放宽仍真断言 user_original。免疫验证:强灌 block1 顶层 ai_suggestion(旧 spec 必红条件)新 spec 仍绿;独立连跑 source-attribution 3 次全绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:35:19 -07:00
lili
de5f4d0bf9 test(studio-e2e): global-setup 补 asset1/work1 fixture 复位(环境污染致 7 spec 偶发红)
studio e2e 全量核查 run1 7 红,根因测试间环境污染、global-setup 复位不全:①asset1「活体市场资产·测试」被历史操作 delisted(应 listed/active)→bind-precheck 返 1044000003 资产不存在→连带 handoff-agent/content/knowledge+live-read 市场浏览+market-governance-impact+market-handoff-precheck 6 红;②work1 残留多余 writing.expansion active 槽位(spec 假设仅 continuation)→agent-slot-bind strict 命中 2 元素红。修:§17 复位 asset1→listed/active、§18 删 work1 非 continuation 槽位。验证:重新污染→自愈后 7 spec 全绿、全量回归持续绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:47:28 -07:00
lili
37e7a8dc27 fix(market): 修 install 用户可见假绿——isAcquired/isInstalled/canInstall 按真实授权安装态 enrich
三路盘点发现 market install 头号用户可见假绿:install 后端真实已验(P1rMarketLicenseInstallCompletedApprovalIT 批18 绿),但 MarketAssetQueryServiceImpl 把 isAcquired/isInstalled 裸硬编 false(toCard:181-182 列表 + userActions:386-387 详情 + canInstall:383),致 studio MarketBrowse(assetType!=work && isAcquired && !isInstalled)安装按钮在真后端永不渲染,mock 伪造状态位才现身;批17 IT 把 isAcquired=false 断言为正确→假绿固化。

后端 enrich(读模型、未碰 install 写逻辑/授权语义):仿 isFavorite 范式加 isAcquired(active 授权)/isInstalled(installation)/isInstallable(类型集),与 install 写端口 MarketInstallServiceImpl 严格同源(selectActiveByOwnerAndAsset + INSTALLABLE_ASSET_TYPES={agent,knowledge_base}),避免"显示可装但装不了"新假绿;canInstall=listed && isInstallable && acquired && !installed(对齐 studio assetType!=work 门);批量加载(整页 2 次 IN vs 3N)避免放大 isFavorite 既有 N+1;mapper 加 selectActiveByOwnerAndAssetIds/existsByUserAndAsset/selectByUserAndAssetIds;批17 IT 改三态断言+订正裸写注释。

前端 MarketBrowse 补 onError(install/acquire 失败内联可见提示,对齐 AgentCreateForm/SlotBindingPanel,不再静默吞 ApiError);e2e 新增 market-install.spec(MSW-off:purchase 前置→断安装按钮真渲染→install→psql 验,连跑 2 次)+ global-setup #16 market 表复位。

活体真验(muse_slice_live,重启新 jar 10:08):purchase→isAcquired=T/canInstall=T(修前恒 false)→install→isInstalled=T/canInstall=F;独立 psql+GET 复核 asset1/4(owner1)isAcquired/isInstalled=true。批17 IT 5/5 三态绿(首跑遇 .m2 stale jar 假红、mvn install 刷新转真绿)、market 单测 9/9+11/11+7/7、UI e2e 连跑 2 次 passed。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:28:33 -07:00
lili
2ede7cb384 test(studio): accept-suggestion 改真生成删 stub,清除 line176② 最后 AI 假绿(采纳断层已修)
采纳断层修复后(commit a16c596 ADR-020,真候选 authz 字符串 envelope 可采纳),accept-suggestion 正路删 /ai/tasks+/stream stub,复用 ai-generation 真链路:WorkspacePage→AIPanel→真 AI task→SSE done→CandidatePanel 采纳替换→真 suggestion-merges code=0+newRevision 自增。反假绿:authz 真 rpe-local 字符串(非种子数值)、sourceAttribution.parentSuggestionId==真生成 id(证非种子)、block revision 实读动态比对(漂移不影响重复跑)。连跑 2 次 2/2 绿(suggestionId 25→26 revision 72→74)+ ai-generation/agent-slot-bind 回归绿。line176② AI 生成 stub 假绿完全清除。flaky:真 SSE 冷启动偶慢(与 ai-generation 同源,CI retries:2)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 01:24:01 -07:00
lili
180181e4c7 docs(studio): 订正 accept-suggestion stub 根因为真生成候选 authorization_snapshot_id=null(反假绿调研)
正路仍桩 /ai/tasks 的根因经实测订正(非旧注释"AI 本机不可用/缺审字段"):真生成候选已产审三件套+content,唯一缺 authorization_snapshot_id=null→采纳被拒 1041001001"外部 owner 暂不可用"。根因=真 runtime envelope 是字符串 rpe-local-uuid,MuseAiRuntimeProjectionService.numericEnvelopeId Long.parseLong 失败落 null。**揭 P1rContentMergeGeneratedSuggestionIT 假绿**(注入数值 envelope 9001,真 New-API runtime 不产数值→IT 绿≠活体真候选可采纳)。注释 only 无逻辑改,stub 保留(桩生成段、采纳+负路乐观锁全真打后端反假绿),accept-suggestion 2/2 可重复 + agent-slot-bind/ai-generation 回归绿、tsc 0。后续主线:让真生成链产数值授权快照(numericEnvelopeId 解析 rpe-local-* 或列承载字符串 envelope,后端缺口)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 22:08:41 -07:00
lili
494c9e9b89 test(studio): 补 AIPanel AI 生成真后端 e2e + 修 connectAIStream 漏鉴权头(反假绿暴露真 bug)
补 ai-generation.spec(真后端不 stub,消除 accept-suggestion stub 假绿,进度总账 line176②):真浏览器 WorkspacePage→AIPanel 发送指令→真后端 AI task→SSE→真 New-API LLM→suggestion 落库。**反假绿暴露真 bug**:connectAIStream(src/lib/sse.ts)漏带 Authorization+tenant-id 头→活体 SSE 必 401/400→done 永收不到→候选永不渲染(被 accept-suggestion 的 stub 长期掩盖)。修:补头,与 connectEventStream/client.ts 同源 @/api/auth。SSE 真行为:后端"持久化事件回放+5s 轮询",运行时只落 done 不落 chunk(streamContent 真链路恒空),真 LLM 文本在 suggestion 记录→断言落 suggestion(API+DB 双证)。四断言反假绿:POST 2xx+code0+taskId / suggestion 真 LLM 文本(非空+阈值+主题宽集合不硬编码句子) / CandidatePanel 采纳按钮 / DB muse_ai_suggestion 新行。自验+子代理连跑 4 次绿(suggestionId 12→13→14→15 各不同真 LLM,11-21s 稳定);vitest 102/102(sse.test 16/16);"AI 本机不可用"旧判断已过时(New-API 在线真生成)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:59:10 -07:00
lili
1fbe7ae73c test(studio): 补 agent 槽位绑定 UI e2e(AgentPage→真后端替换槽位,反假绿)
承 02D 死锁修复(9115d4f)+ AgentPage 作品选择器(4c069d4),补端到端 UI e2e(进度总账 line176② 缺口)。agent-slot-bind.spec:真浏览器 goto /agents→selectOption work1→点 agent1 卡片→点"绑定选中智能体"→真后端 precheck→bind。三重反假绿:DB 起点 revision=1 + bind 响应 code=0/slotRevision=2 + UI"绑定已更新"提示 + DB 终态 revision 1→2 active agent1。global-setup §15 每轮复位 work1 writing.continuation 槽位(agent1 revision1 active)保证可重复(bind 成功 revision+1 漂移、不复位二次跑红)。MSW off 真连 muse_slice_live;自验 + 子代理各跑均 passed 可重复、tsc 零报错。诚实范围:只覆盖"替换已有槽位",首次创建 UI 仍缺槽位骨架(Override Slot Contract=方案 B,人类架构决策域未做)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:19:44 -07:00
lili
26425b1755 test(handoff): P3 content asset_use 真后端 e2e + global-setup #14
handoff-content.spec(48080+真 PG+V28 真表):正路 bind-precheck(content)→
createHandoff(content/asset_use)→asset-use-precheck(后端 verify+consume)→asset-uses
落使用事实(单表转 consumed、assetUseId=precheckId);负路伪造 token 被后端 verify 拒(0 写)。
global-setup #14 每轮清 work4 asset_use precheck(asset_use 不绑实体、无需 seed fixture)。

验证:handoff-content 2 passed、全量 e2e 50→52(1 flaky knowledge-disable-restore 单跑绿、非回归)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 23:48:40 -07:00
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