From 63fd977df7c1d6e2ea699a728178b01bab5e6c57 Mon Sep 17 00:00:00 2001 From: lili Date: Mon, 15 Jun 2026 08:36:23 -0700 Subject: [PATCH] =?UTF-8?q?docs(progress):=20=E6=80=BB=E8=B4=A6=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E2=80=94=E2=80=94=E7=9F=A5=E8=AF=86=E5=9B=BE=E8=B0=B1?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=20+=20confirm=20=E9=87=8D=E5=90=8D=20500=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D(=E7=9F=A5=E8=AF=86=E5=BA=93=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=8F=B0=E6=94=B6=E5=8F=A3=E6=8E=A8=E8=BF=9B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §五C 知识库工作台:graph UI ✅(仍剩 bindings/publish);confirm 重名实体 500→干净冲突 1043002004 已修;per-BC tracker(knowledge)+ §四时间线同步。 Co-Authored-By: Claude Opus 4.8 --- docs/mvp/进度总账.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/mvp/进度总账.md b/docs/mvp/进度总账.md index 87fb8020..c8e2c1ff 100644 --- a/docs/mvp/进度总账.md +++ b/docs/mvp/进度总账.md @@ -86,6 +86,7 @@ 2026-06-15 ✅ **studio 市场生产侧发布草稿纵切活体绿 + 修真实潜伏后端 bug**(承前端长板,goal 主攻):新增 `MarketPublish`(/market/publish)生产侧表单 + `useMarketPublish` hook;保存发布草稿(POST /marketplace/publish-drafts)→ my-publish-records 真实回读,`market-publish.spec.ts` chromium MSW-off 正+负绿,DB 证 muse_market_publish_draft 落库(status=draft);整套 e2e 10/10 + vitest 47/47 无回归。**修真实 bug**:publish draft/check/request 的 (tenant_id,command_id) 部分唯一索引(V15)与 mapper 无谓词 `ON CONFLICT` 不匹配→PG 报 no unique constraint matching→savePublishDraft 500(链路从未活体跑过、潜伏至本切片);修=部分→完整唯一索引(V22 迁移 + muse_slice_live 已应用)。遗留:其余 market 表(handoff/appeal 等)同类部分索引待收口。 2026-06-15 🔎 **account facade 活体订正(无净代码改动,反假绿)**:user 据 §五A"account 21 端 UNAVAILABLE"选"account 后端 facade 真实化"。Explore 静态分析判 MarketAccountProjectionFacade 阻塞 purchases/licenses/publish-records;**实测推翻**——单体内 market `MarketAccountProjectionProvider`(@Service)本身 implements MarketAccountProjectionFacade、对三类型放行,`@ConditionalOnMissingBean` 使其压过 member 的 Unavailable 兜底 → 三端在单体本就可用。curl 真返投影(含 market-publish e2e 写入的 publish-records 5 条=market→account 端到端)。曾据 Explore 加 member-local `RealMarketAccountProjectionFacade`+改 autoconfig、rebuild+restart 验证;**可逆翻转测试(全局 purchase=0 仍返回空而非 UNAVAILABLE)证实活跃 facade 是 Provider 而非我的 count-gating facade → 单体 no-op 且违背原设计,已回退**(member 模块工作树干净)。顺带:restart 时 Flyway 真实应用 `V22`(market 索引修复)"Successfully applied 1 migration ... v22"。结论:单体无 account facade 接线缺口待补;export/new-api 为正确 fail-closed 外部依赖。教训:跨 BC facade 判定必须以单体实跑为准,静态分析会漏 monolith 跨模块 bean 绑定。 2026-06-15 ✅ **market 残余 partial-index 系统性收口 + 真实 PG IT(V23)**:续 V22,修 handoff_event/appeal_material/authorization_summary/appeal_event/appeal 5 表 (tenant_id,command_id) 部分→完整唯一索引(grep 实证其 mapper 发无谓词 ON CONFLICT,潜伏同 publish 链路 bug)。新增 `P1rMarketCommandIndexFlywayMigrationIT`:真实 PG clean→迁移 V1→V23(Flyway "Successfully applied 23 migrations ... v23")→断言 V22/V23 修复的 9 个命令索引均完整唯一(可作 ON CONFLICT 仲裁器),**Tests run 1, Failures 0, Errors 0, Skipped 0**(与 target=V15 的 `P1rMarketFlywayMigrationIT`「断言历史 partial 态」互补)。V23 已应用 muse_slice_live + 全新 `muse_p1r_cmdidx_test` 库迁移验证。其余 market 部分 command 索引未被当 arbiter,保持不变。 +2026-06-15 ✅ **知识库工作台知识图谱视图 + 修 confirm 重名潜伏 500(承前端长板,goal 主攻)**:①前端新增 `KnowledgeGraphPanel`(/knowledge/:workId)经 GET /works/{id}/graph 读真实 muse_knowledge_entity/relation,渲染已入库 Canonical 实体(节点)+关系(边),与草稿面板成"候选→确认→正式图谱可见"双轨闭环;`knowledge-graph.spec.ts` chromium MSW-off 绿 + curl 证 code:0/节点 huotituopusuqing+huoti_related 边。②**修真实潜伏后端 bug(反假绿,task_497da70f)**:confirm 重名实体(同 work+类型+规范名+范围)原触发 uk_muse_knowledge_entity 唯一冲突→未捕获 DuplicateKeyException 冒泡 HTTP 500;改 `writeCanonicalEntity` 前置 `selectByIdentity` 预检(镜像约束列、不滤 deleted)→`markConflicted`(REQUIRES_NEW)+`KNOWLEDGE_ENTITY_DUPLICATE`(1043002004);必须前置预检——PG 约束冲突使当前事务 aborted,catch 后任何写必失败。活体证:colliding 草稿 confirm→code 1043002004(非 500)、DB 草稿转 conflicted+实体数不变(无伪造重复);正路径 knowledge-confirm e2e 回归绿;tsc -b 干净 + vitest 47/47。 ``` --- @@ -96,7 +97,7 @@ > **goal 主攻 = 活体纵切·每 BC 一条端到端用户旅程,在跑起来的单体(48080)上 curl 实证(正+负路径),验收=achieve the product goal。** per-BC 活体度量: > - **content+ai**(AI 候选→采纳入正文):✅ 活体证(MVP#1;正:newRevision=2+正文写入;负:乐观锁 1041000002)+ ✅ **前端 rendered UI e2e**(chromium,关 MSW 直连活体:生成→采纳→真合并 happy + 乐观锁 negative,见 §五C) -> - **knowledge**(确认草稿 Shadow→Canonical 实体):✅ 活体证(2026-06-14;正:GET pending→POST confirm→`muse_knowledge_entity` 落库+草稿 confirmed;负:revision 1043002001 / source-stale 1043002002→草稿 conflicted)+ ✅ **前端 rendered UI**(确认入库 e2e chromium,见 §五C) +> - **knowledge**(确认草稿 Shadow→Canonical 实体):✅ 活体证(2026-06-14;正:GET pending→POST confirm→`muse_knowledge_entity` 落库+草稿 confirmed;负:revision 1043002001 / source-stale 1043002002→草稿 conflicted)+ ✅ **前端 rendered UI**(确认入库 e2e chromium,见 §五C)+ ✅ **知识图谱视图**(graph rendered-UI 活体证,2026-06-15)+ ✅ 修 confirm 重名 500→干净冲突 1043002004 > - **market**(资产采纳/安装):✅ 活体证(2026-06-14;正:GET listed 资产→purchase `licenseId:1/active`→install `installationId:1/installed`;DB:授权快照+购买事实 completed+安装 installed 三落库;purchase 经 MarketAccountProjectionProvider 投影 account) + ✅ **生产侧发布草稿 rendered-UI e2e**(2026-06-15;/market/publish→publish-drafts→my-publish-records,DB 证 publish_draft 落库;附带修 publish 部分索引 ON CONFLICT bug→V22,见 §五C) > - **account/member**(个人中心:profile/purchases/licenses/entitlements/usage 读):✅ 活体证(2026-06-14;profile 返回脱敏 PII;**purchases/licenses 含上一步 market 购买+安装的投影=market→account 跨 BC 端到端通**;entitlements/usage 干净空数据)。**重要订正**:此前 account 读 500 真因是基座 schema 漏 `member_user.register_terminal` 列 + 缺 `infra_api_error_log_seq`(非 facade 缺口),已补基座文件 `yudao-base-schema-postgres.sql`(可复现);baseline "21/33 阻于 facade" 部分被推翻——投影通、卡在基座。 > - **agent(ai)**(创建/列表):✅ 活体证(2026-06-14;POST /muse/agents→`agentId:1`→GET 列表含之 active;试用 New-API 外部,非阻) @@ -124,7 +125,7 @@ - 现状:其余旅程仍 ~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 取数、真实数据形态与页面渲染契约对齐。 -- 🔧 知识库工作台:**✅ 确认草稿(先审后入)rendered-UI 活体证(2026-06-14)**——`KnowledgeDraftPanel`(/knowledge/:workId)列待确认草稿+「确认入库」→ 真 confirm 物化 Canonical 实体(`knowledge-confirm.spec.ts` chromium MSW-off 绿,DB 证 draft confirmed+entity_id);后端补 `SummaryRespVO` 暴露 confirm 并发/源令牌。**仍 ⬜**:bindings/publish/graph UI;**遗留 bug**:confirm 对已存在同名实体抛 500(应干净 conflict,已 flag task_497da70f)。 +- 🔧 知识库工作台:**✅ 确认草稿(先审后入)rendered-UI 活体证(2026-06-14)**——`KnowledgeDraftPanel`(/knowledge/:workId)列待确认草稿+「确认入库」→ 真 confirm 物化 Canonical 实体(`knowledge-confirm.spec.ts` chromium MSW-off 绿,DB 证 draft confirmed+entity_id);后端补 `SummaryRespVO` 暴露 confirm 并发/源令牌。**✅ graph(知识图谱视图)rendered-UI 活体证(2026-06-15)**:`KnowledgeGraphPanel` 经 GET /works/{id}/graph 读真实 muse_knowledge_entity/relation,渲染已入库 Canonical 实体(节点)+关系(边),与草稿面板成"候选→确认→正式图谱可见"闭环(`knowledge-graph.spec.ts` chromium MSW-off 绿 + curl 证 code:0/节点+huoti_related 边)。**✅ 修真实潜伏 bug(反假绿,task_497da70f 已闭)**:confirm 重名实体原冒泡 HTTP 500→改 `writeCanonicalEntity` 前置 `selectByIdentity` 预检→`markConflicted`(REQUIRES_NEW)+`KNOWLEDGE_ENTITY_DUPLICATE`(1043002004)干净拒绝(curl 证 1043002004 非 500、DB 草稿 conflicted 且无伪造重复)。**仍 ⬜**:bindings/publish UI。 - 🔧 市场生产侧:**✅ 发布草稿 + 提交审核全链(创作者飞轮)rendered-UI 活体证(2026-06-15)**——`MarketPublish`(/market/publish):①「保存发布草稿」(`POST /marketplace/publish-drafts`)→`my-publish-records` 真实回读;②「提交审核」做 save→运行检查(`POST .../checks`)→检查通过提交申请(`POST /publish-requests`)全链(licenseType+权利声明为检查硬门槛)。`market-publish.spec.ts` chromium MSW-off **8/8 绿**(草稿正 / 缺标题负 / 提交全链 / 上架生命周期徽标 / 申诉提交·撤回·补充材料写路 / appealStatus 回显),DB 证:`muse_market_publish_draft`=draft、`muse_market_publish_request`=submitted、`muse_market_review_event`=submitted 落库;草稿测幂等自包含、全链测唯一名可重复跑。MarketBrowse 加「我要发布资产」入口。**附带修真实潜伏后端 bug**:publish draft/check/request/review_event 的 (tenant_id,command_id) 为**部分**唯一索引(V15 `WHERE command_id IS NOT NULL`),mapper insertIgnore 却发无谓词 `ON CONFLICT (tenant_id,command_id)`→PG 无法用部分索引作仲裁器→save/check/submit 500(链路从未活体跑过故潜伏);修=部分→完整唯一索引对齐 command/purchase 约定(`V22__fix_market_publish_command_unique_index.sql` 4 表 + muse_slice_live 已应用,零 Java 改动/零重启)。**✅ 上架状态可视化(读,2026-06-15)**:「上架=审核通过自动 `markListed`」(`AdminMarketReviewServiceImpl`,**非生产者动作**),生产者侧 `MarketPublish`「我的发布记录」新增**发布生命周期中文徽标**(草稿/已提交/审核中/已通过/**已上架**/**已驳回**/需补充…)+ nextAction/appealStatus 副文本,使创作者看到 publish→review→list 进度反馈(`market-publish.spec.ts` 第 4 例断言 listed→「已上架」、rejected→「已驳回」渲染;种子 /tmp/SetReqStatus.java 置 req#2→listed、#3→rejected)。**申诉(appeal):后端已验证 real+fail-closed(2026-06-15)**——curl:对自有已驳回资产 `POST /marketplace/appeals`(review_rejection)→`appealId/pending`;负路 他人资产→`1044000024 无权访问`、不存在资产→`1044000003 资产不存在`(fixture=asset(pub=1)+rejected request,见 /tmp/SeedAppeal.java)。**✅ 申诉(appeal)写路 UI——gap 已解(2026-06-15)**:根因=my-publish-records 的 assetId 是 publish-record id,**非** `submitAppeal.requireAsset` 所需的物化 `muse_market_asset.id`(资产仅 admin 审核通过 `markListed` 物化)。**后端最小契约改动**:`PublishRecordItem`/`MarketPublishRecordItemRespVO` 加 `marketAssetId`(=request.asset_id 命中真实 muse_market_asset 且归属当前发布者才给,否则 null=fail-closed 不放开入口),`MarketPublishServiceImpl.resolveMarketAssetId` 解析(已重建 jar + 重启单体 26483)。**前端**:仅 marketAssetId 非空 + 状态∈{rejected/compliance_blocked→review_rejection、delisted→delist、recalled→recall} 的记录放开「发起申诉」→ 面板填理由 → `useSubmitAppeal`(新 commandId 幂等)真打 `POST /marketplace/appeals`→`申诉已提交(pending)`(`market-publish.spec.ts` 第 5 例 chromium MSW-off 绿)。**DB 证(反假绿)**:`muse_market_appeal` 追加行 status=pending、commandId=前端 UUID(e2e 点击产 appealId=3);curl 正负路(自有已驳回→appealId/pending;他人→`无权访问`;不存在→`资产不存在`);后端 `MarketPublishServiceTest` 回归通过。种子 /tmp/SeedAppeal.java(asset(pub=1)+rejected request,asset_id=物化资产)。**✅ 申诉补充/撤回 UI(2026-06-15)**:同类 gap——生产者本无自己申诉的列表端点,故新增 app-api `GET /marketplace/appeals`(`appListMyAppeals`+`MuseMarketAppealMapper.selectListByUser`+`MarketMyAppealItemRespVO`,带 `canSupplement`/`canWithdraw` 派生)。`MarketPublish`「我的申诉」区列申诉 + 中文状态徽标(待处理/审核中/待补充材料/维持原判/已恢复/已关闭…);`canWithdraw`(非终态)放开「撤回」→`useWithdrawAppeal`→`POST .../withdraw`(expectedStatus 乐观锁)→closed;`canSupplement`(supplementing 态)放开「补充材料」→`useSupplementAppeal`→`POST .../supplements`(privacyConfirmed)→reviewing。`market-publish.spec.ts` 第 6/7 例 chromium MSW-off 绿(撤回→已撤回、补充→材料已补充),**DB 证(反假绿)**:withdraw→`muse_market_appeal` status=closed、supplement→`muse_market_appeal_material` 追加行(e2e 点击产 material#2);后端 `MarketAppealServiceTest` 15/15 + `AppMuseMarketAppealControllerTest` 6/6 回归通过。种子 /tmp/SetAppealSup.java(置 supplementing;提交后→reviewing 故每轮重置)。**✅ appealStatus 记录回显(2026-06-15)**:`my-publish-records` 经 `MuseMarketAppealMapper.selectLatestByAssetIdAndUser` + `resolveAppealStatus` 回填该物化资产被当前发布者发起的最新申诉态到记录 `appealStatus`(无物化资产/无申诉则 null,marketAssetId 与 appealStatus 两路共用各只查一次);`MarketPublish` 发布记录副文本以中文徽标渲染「申诉:<待处理/审核中/已关闭…>」。`market-publish.spec.ts` 第 8 例 chromium 绿(recId=5/marketAssetId=2 回显 appealStatus=closed→「申诉:已关闭」);后端 `MarketPublishServiceTest` 14/14 回归通过。**至此市场生产者飞轮端到端完整**:发布(草稿→检查→提交)→上架状态可视化→申诉(提交/补充材料/撤回)全生命周期 + 申诉态回显。**遗留已收口(2026-06-15)**:handoff_event/appeal_material/authorization_summary/appeal_event/appeal 5 表(其 mapper 确发无谓词 ON CONFLICT)经 **V23 系统性修**(部分→完整唯一索引)+ 新增 `P1rMarketCommandIndexFlywayMigrationIT` **真实 PG 验证**(clean→迁移 V1→V23→断言 V22/V23 的 9 个命令索引均完整、可作 ON CONFLICT 仲裁器,Tests run 1/0F;与 V15-pinned `P1rMarketFlywayMigrationIT` 互补)。其余 market 部分 command 索引(favorite/auth_snapshot/installation/asset/governance_*/handoff/source_status_event/account_projection)未被当 command-arbiter,保持不变。 - 🔧 个人中心:**✅ profile/用量/权益 + 我的购买/我的授权 + 安全事件(读+确认写路)(rendered-UI 活体证,2026-06-15)**——PersonalCenter 新增「我的购买/我的授权」渲染 market→account 投影真实记录(`useAccountPurchases`/`useAccountLicenses`→`/account/{purchases,licenses}`;`live-read.spec.ts` 第 5 例 chromium MSW-off 绿,断言真实资产「活体市场资产·测试」渲染——证后端 account 读端在单体可用即被 UI 消费,见 §五A 活体订正);**新增「安全事件」区**渲染 `GET /account/security-events` 真实摘要(`useAccountSecurityEvents`→`AccountPageResult`;eventType/severity 徽标 + 已确认/待确认状态;`live-read.spec.ts` 第 6 例 chromium MSW-off 绿,断言种子事件「活体安全事件·异地登录提醒」渲染)。**确认写路**:未确认事件展示「确认」按钮→`useAcknowledgeSecurityEvent`(每次发新 commandId,后端按 commandId 幂等)真打 `POST /account/security-events/{id}/acknowledge`(action=acknowledged)→列表失活重取翻「已确认」、按钮消失(构成 acked→无动作 UI 不变量;`account-security-ack.spec.ts` chromium MSW-off 绿,种子事件 B「待确认演练」)。后端**正负路 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:事件A读锚点幂等插入 + 事件B写锚点每轮重置为未确认)。本轮实跑:account-security-ack **1/1** + live-read **6/6** + vitest 47/47 + tsc 干净。**仍 ⬜**:exports / downloads / new-api-binding 深页(后端均为**正确 fail-closed 外部依赖**:对象存储 / New-API 未配置,非接线缺口,见 §五A)。 - 收口口径:每切片"关 MSW→真连活体单体→playwright e2e 绿"才算完成(反假绿)。