删除确认判据改看 marker,覆盖源准备阶段的免费占位
判据是 status === 'generating' && !perfectPixelOperation,而 perfectPixelOperation 要到源图解析/直传完成后才写入。未登记的本地图片要走 ticket → PUT → confirm, 预算上限 90 秒;这段窗口里占位是 generating、只有 requiresLiveSession、没有账本, 判据返回 true——用户删一个免费操作会被告知「已消耗的泥点不会返还」,与「完美像素 任何状态直接删、不弹确认」的决策直接矛盾。 perfectPixelOperationId marker 从占位创建那一刻就写上(operationId === dialogId 在创建时已知),判据改看 marker。marker 的语义也因此更准确:它表示「这个占位属于 一次完美像素操作」,而不是「账本已存在」。 未采纳「删掉弹窗入口」:删除入口全仓只有 requestRemoveCanvasGenerationDialog 一条, 右键、Delete、工具栏全部汇入,完美像素没有自己的删除路径可摘。「从本链路删入口」 等价于「让判据认得出本链路」,绕不开识别问题。 未采纳新增计费字段(今天唯一生产者只有完美像素,属过度设计),也未采纳判据加 requiresLiveSession(那只是换一个代理,而用短寿命字段的存在性判断长期属性正是本 缺陷的成因模式)。 连带影响已核:会话内到期清理不受影响(看的是 perfectPixelOperation 而非 marker); 只有加载时的快照清理会豁免源准备阶段的占位,使其显示为可删的失败卡而非被静默清掉, 这与「系统不替用户删」一致。 测试夹具原本带着 perfectPixelOperation,编码了与判据相同的错误假设,结构上覆盖不到 这个窗口。夹具补上 marker 还原真实形状,并新增「只有 marker、尚无账本」用例,回退 判据后报 expected true to be false。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6551,3 +6551,15 @@
|
||||
- 顺带记录的待办(不在本次范围):图集拆分的 catch 只做 `window.alert('拆分图集失败')`,不区分「确定失败」与「网关合成的未知结果」。服务端可能已经切完并落库 N 个 asset 却报失败,用户照提示重拆就会拿到双份——这属于谎报,落在主链路一侧,与「丢资源不阻断」不是一类问题。最小修法是复用现成的 `isGatewayUnknownOutcomeError` 改文案,十几行,不需要照搬 B 层。
|
||||
- 影响范围:仅文档。不改代码、不改测试。
|
||||
- 关联文档:`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`(已写入三层划分、B 层边界实测与清除条件)。
|
||||
|
||||
## 2026-08-05 删除确认判据改看 marker,覆盖源准备阶段的免费占位
|
||||
|
||||
- 缺陷:`requiresGenerationDeleteConfirmation` 的判据是 `status === 'generating' && !dialog.perfectPixelOperation`,而 `perfectPixelOperation` 要到源图解析 / 直传完成后才写入。未登记的本地图片要走 `ticket → PUT → confirm`,预算上限 90 秒;这段窗口里占位是 `generating`、只有 `requiresLiveSession: true`、没有账本,于是判据返回 true——用户删一个**免费**操作会被告知「已消耗的泥点不会返还」。与同日「完美像素占位恢复为可删除」里「任何状态直接删、不弹确认」的决策直接矛盾。已登记资源走短路解析、窗口接近于零,暴露只在未登记本地图片上成立。
|
||||
- 决策:`perfectPixelOperationId` marker 从占位**创建那一刻**就写上(`operationId === dialogId` 在创建时已知),判据改看 marker:`status === 'generating' && !dialog.perfectPixelOperationId`。marker 的语义也因此更准确——它表示「这个占位属于一次完美像素操作」,而不是「账本已存在」。
|
||||
- 未采纳「删掉弹窗入口」:删除入口全仓只有 `requestRemoveCanvasGenerationDialog` 一条,右键、Delete 快捷键、工具栏全部汇入,完美像素没有自己的删除路径可以摘除。「从本链路删除入口」在实现上等价于「让判据认得出本链路」,绕不开识别问题。真正删掉弹窗只能对所有生成占位一起做,那是另一个产品决定(对计费生成而言该文案是真实信息),不作为修此缺陷的副产品。
|
||||
- 未采纳「新增 `generationCostMudPoints` 字段让判据直接问是否计费」:语义上最正,但今天唯一的生产者只有完美像素,图集拆分根本不创建占位,第二个消费者并不存在,属于为一个调用方过度设计。
|
||||
- 未采纳「判据加 `requiresLiveSession === true`」:该字段全仓确实只有完美像素一处置位,一行即可修,但它的含义是「只能由本会话收口」而非「免费」。换一个代理不解决问题——**用短寿命字段的存在性判断长期属性**正是本缺陷(以及 F5)的成因模式。
|
||||
- 已核过的连带影响:会话内到期清理不受影响,`inlineGenerationPlaceholderExpiryAt` 看的是 `perfectPixelOperation` 而非 marker,源准备阶段被放弃的占位照常到期消失。受影响的只有加载时的快照清理 `dropDeadInlineGenerationPlaceholders`——它的豁免判据接受 marker,因此「源准备中途关标签页」的占位不再被静默清掉,而是在下次加载显示为可删的失败卡。这与「TTL 豁免 = 系统不替用户删,用户主动删除始终允许」一致,判为改善而非退化。id 撞车时 `openCanvasGenerationDialog` 会另生成 id,marker 会暂时指向旧值;它此刻只被当作存在性标记使用(效果仍是不弹确认),写 request 时按真实 dialogId 纠正,不影响任何判等。
|
||||
- 测试缺口的根因:原用例的夹具 `durablePerfectPixelDialog` 带着 `perfectPixelOperation`,编码了与判据相同的错误假设,结构上不可能覆盖 operation 形成之前的窗口。夹具已补上 marker 以还原真实形状,并新增「只有 marker、尚无账本」的用例,已实证:回退判据后报 `expected true to be false`。
|
||||
- 影响范围:`useCanvasGenerationDialogs.ts` 的判据、`useImageCanvasGenerationWorkflow.ts` 的占位创建。不修改服务端、SpacetimeDB schema 或对外契约。
|
||||
- 关联文档:`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`。
|
||||
|
||||
Reference in New Issue
Block a user