From 9c96535073684a619adc7e161f588894cc4c44cf Mon Sep 17 00:00:00 2001 From: kdletters Date: Thu, 4 Jun 2026 05:14:23 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=94=B6=E5=8F=A3=20Bark=20Battle?= =?UTF-8?q?=20=E8=8D=89=E7=A8=BF=E6=81=A2=E5=A4=8D=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .hermes/shared-memory/decision-log.md | 6 ++-- docs/README.md | 2 +- ...arkBattleWorkCache草稿状态收口计划-2026-06-04.md | 8 +++-- .../PlatformEntryFlowShellImpl.tsx | 19 ++---------- .../barkBattleWorkCache.test.ts | 31 +++++++++++++++++++ .../platform-entry/barkBattleWorkCache.ts | 22 +++++++++++++ 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/.hermes/shared-memory/decision-log.md b/.hermes/shared-memory/decision-log.md index 8f23f1bc..46ec8486 100644 --- a/.hermes/shared-memory/decision-log.md +++ b/.hermes/shared-memory/decision-log.md @@ -18,9 +18,9 @@ ## 2026-06-04 Bark Battle Work Cache 草稿状态收口 -- 背景:`PlatformEntryFlowShellImpl.tsx` 仍内联维护 Bark Battle 草稿三图完整性、生成状态归一,以及草稿 / 已发布作品进入 runtime 前的 `BarkBattlePublishedConfig` 字段映射,导致结果页试玩、作品架启动和公开详情启动都要理解同一份资产字段清单。 -- 决策:扩展 `src/components/platform-entry/barkBattleWorkCache.ts`,以 `hasBarkBattleDraftRequiredImages`、`resolveBarkBattleDraftGenerationStatus`、`buildBarkBattlePublishedConfigFromDraft`、`buildBarkBattlePublishedConfigFromWork`、`buildBarkBattlePublishSnapshot` 和 `mergeBarkBattlePublishedConfigAssets` 收口 Bark Battle 纯规则。平台壳只保留 API、缓存刷新、React state、URL 和 stage 副作用。 -- 影响范围:Bark Battle 草稿生成完成、结果页保存、草稿试玩、作品架 / 公开详情启动正式 runtime,以及后续 Bark Battle 资产字段或 ruleset 默认值调整。 +- 背景:`PlatformEntryFlowShellImpl.tsx` 仍内联维护 Bark Battle 草稿三图完整性、生成状态归一、作品架摘要恢复草稿配置,以及草稿 / 已发布作品进入 runtime 前的 `BarkBattlePublishedConfig` 字段映射,导致结果页试玩、作品架启动、草稿恢复和公开详情启动都要理解同一份资产字段清单。 +- 决策:扩展 `src/components/platform-entry/barkBattleWorkCache.ts`,以 `hasBarkBattleDraftRequiredImages`、`resolveBarkBattleDraftGenerationStatus`、`buildBarkBattleDraftConfigFromWorkSummary`、`buildBarkBattlePublishedConfigFromDraft`、`buildBarkBattlePublishedConfigFromWork`、`buildBarkBattlePublishSnapshot` 和 `mergeBarkBattlePublishedConfigAssets` 收口 Bark Battle 纯规则。平台壳只保留 API、缓存刷新、React state、URL 和 stage 副作用。 +- 影响范围:Bark Battle 草稿生成完成、结果页保存、作品架摘要恢复草稿、草稿试玩、作品架 / 公开详情启动正式 runtime,以及后续 Bark Battle 资产字段或 ruleset 默认值调整。 - 验证方式:`npm run test -- src/components/platform-entry/barkBattleWorkCache.test.ts`、针对 Bark Battle Work Cache Module 与平台壳执行 ESLint、`npm run typecheck`、`npm run check:encoding`。 - 关联文档:`docs/technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md`。 diff --git a/docs/README.md b/docs/README.md index 4c79cdd5..8b402e03 100644 --- a/docs/README.md +++ b/docs/README.md @@ -67,7 +67,7 @@ AI 文字游戏模板接入以 [AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_ 平台入口个人钱包本地 delta、dashboard 乐观更新与服务端快照对账规则收口到 `src/components/platform-entry/platformProfileWalletDeltaModel.ts`,平台壳只保留 API、ref 与 state 副作用,规则见 [【前端架构】PlatformProfileWalletDeltaModel收口计划-2026-06-04.md](./technical/【前端架构】PlatformProfileWalletDeltaModel收口计划-2026-06-04.md)。 -Bark Battle 草稿三图完整性、生成状态归一、发布快照 / 发布回包资产兜底和草稿 / 已发布作品进入 runtime 前的 `BarkBattlePublishedConfig` 映射收口到 `src/components/platform-entry/barkBattleWorkCache.ts`,规则见 [【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md](./technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md)。 +Bark Battle 草稿三图完整性、生成状态归一、作品架摘要恢复草稿配置、发布快照 / 发布回包资产兜底和草稿 / 已发布作品进入 runtime 前的 `BarkBattlePublishedConfig` 映射收口到 `src/components/platform-entry/barkBattleWorkCache.ts`,规则见 [【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md](./technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md)。 平台首页推荐 runtime 的匿名 Runtime Guest Token、已登录 background auth、非 embedded no-op 和拼图 isolated/default auth mode 计划收口到 `src/components/platform-entry/platformRecommendRuntimeAuthModel.ts`,规则见 [【前端架构】PlatformRecommendRuntimeAuthModel收口计划-2026-06-04.md](./technical/【前端架构】PlatformRecommendRuntimeAuthModel收口计划-2026-06-04.md)。 diff --git a/docs/technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md b/docs/technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md index 14936e1e..2db7284f 100644 --- a/docs/technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md +++ b/docs/technical/【前端架构】BarkBattleWorkCache草稿状态收口计划-2026-06-04.md @@ -2,7 +2,7 @@ ## 背景 -`PlatformEntryFlowShellImpl.tsx` 仍内联维护 Bark Battle 草稿三图完整性、生成状态归一,以及草稿 / 已发布作品进入 runtime 前的 `BarkBattlePublishedConfig` 映射。壳层因此需要同时理解三图资产字段、`partial_failed` 与 `pending_assets` 的差异、`publishedAt` 兜底和草稿试玩配置默认值。 +`PlatformEntryFlowShellImpl.tsx` 仍内联维护 Bark Battle 草稿三图完整性、生成状态归一、作品架摘要恢复草稿配置,以及草稿 / 已发布作品进入 runtime 前的 `BarkBattlePublishedConfig` 映射。壳层因此需要同时理解三图资产字段、`partial_failed` 与 `pending_assets` 的差异、`publishedAt` 兜底、作品摘要字段和草稿试玩配置默认值。 这些规则属于 Bark Battle 作品摘要与草稿缓存的纯模型。若留在平台壳层,后续发布、作品架刷新、公开详情启动或草稿试玩都容易重复一份字段清单。 @@ -12,6 +12,7 @@ - `hasBarkBattleDraftRequiredImages(draft)`:判断草稿是否已具备玩家形象、对手形象和竞技背景三图。 - `resolveBarkBattleDraftGenerationStatus(draft, partialFailed)`:三图齐备返回 `ready`,否则按是否部分失败返回 `partial_failed` 或 `pending_assets`。 +- `buildBarkBattleDraftConfigFromWorkSummary(work)`:把作品架摘要恢复成可编辑 / 可试玩的 `BarkBattleDraftConfig`。 - `buildBarkBattlePublishedConfigFromDraft(draft)`:把草稿结果页试玩所需配置映射为 `BarkBattlePublishedConfig`。 - `buildBarkBattlePublishedConfigFromWork(work)`:把作品架 / 公开详情启动正式 runtime 所需配置映射为 `BarkBattlePublishedConfig`。 - `buildBarkBattlePublishSnapshot(draft)`:拼装发布接口所需的最终草稿快照。 @@ -23,6 +24,7 @@ - 草稿三图必须同时具备 `playerCharacterImageSrc`、`opponentCharacterImageSrc` 和 `uiBackgroundImageSrc` 的非空值,才视为 `ready`。 - 未齐三图且 `partialFailed=true` 时返回 `partial_failed`,否则返回 `pending_assets`。 +- 作品摘要恢复草稿时,`draftId` 缺失回退 `workId`,`description` 来自 summary,三图 null 归一为 `undefined`,`configVersion=1` 且 `rulesetVersion='bark-battle-ruleset-v1'`。 - 草稿试玩配置的 `workId` 优先使用草稿稳定 `workId`,缺失时回退 `draftId`。 - 草稿试玩配置的 `configVersion` 与 `rulesetVersion` 使用草稿值,缺失时回退 `1` 与 `bark-battle-ruleset-v1`。 - 已发布作品配置的 `publishedAt` 缺失时回退 `updatedAt`,保持旧 runtime 启动语义。 @@ -31,8 +33,8 @@ ## Depth / Leverage / Locality -- **Depth**:壳层传入草稿或作品摘要,即可得到生成状态或 runtime 配置;字段归一、默认值和三图完整性藏入 Module Implementation。 -- **Leverage**:结果页试玩、作品架启动、公开详情启动和缓存刷新可复用同一组 Bark Battle 规则。 +- **Depth**:壳层传入草稿或作品摘要,即可得到生成状态、草稿配置或 runtime 配置;字段归一、默认值和三图完整性藏入 Module Implementation。 +- **Leverage**:作品架草稿恢复、结果页试玩、作品架启动、公开详情启动和缓存刷新可复用同一组 Bark Battle 规则。 - **Locality**:Bark Battle 资产完整性与配置映射集中到纯测试面,后续变更三图字段或规则集默认值时无需搜索巨型平台壳。 ## 验收 diff --git a/src/components/platform-entry/PlatformEntryFlowShellImpl.tsx b/src/components/platform-entry/PlatformEntryFlowShellImpl.tsx index d2ebd2bf..d6b7b155 100644 --- a/src/components/platform-entry/PlatformEntryFlowShellImpl.tsx +++ b/src/components/platform-entry/PlatformEntryFlowShellImpl.tsx @@ -380,6 +380,7 @@ import { } from '../visual-novel-creation/visualNovelEntryGeneration'; import { createMockVisualNovelRunFromDraft } from '../visual-novel-runtime/visualNovelMockData'; import { + buildBarkBattleDraftConfigFromWorkSummary, buildBarkBattlePublishedConfigFromDraft, buildBarkBattlePublishedConfigFromWork, buildBarkBattlePublishSnapshot, @@ -11006,23 +11007,7 @@ export function PlatformEntryFlowShellImpl({ return; } - const nextDraft: BarkBattleDraftConfig = { - draftId: item.draftId ?? item.workId, - workId: item.workId, - title: item.title, - description: item.summary, - themeDescription: item.themeDescription, - playerImageDescription: item.playerImageDescription, - opponentImageDescription: item.opponentImageDescription, - onomatopoeia: item.onomatopoeia, - playerCharacterImageSrc: item.playerCharacterImageSrc ?? undefined, - opponentCharacterImageSrc: item.opponentCharacterImageSrc ?? undefined, - uiBackgroundImageSrc: item.uiBackgroundImageSrc ?? undefined, - difficultyPreset: item.difficultyPreset, - configVersion: 1, - rulesetVersion: 'bark-battle-ruleset-v1', - updatedAt: item.updatedAt, - }; + const nextDraft = buildBarkBattleDraftConfigFromWorkSummary(item); setBarkBattleDraftConfig(nextDraft); enterCreateTab(); selectionStageRef.current = isPersistedBarkBattleDraftGenerating(item) diff --git a/src/components/platform-entry/barkBattleWorkCache.test.ts b/src/components/platform-entry/barkBattleWorkCache.test.ts index 8115dde9..feeecf3e 100644 --- a/src/components/platform-entry/barkBattleWorkCache.test.ts +++ b/src/components/platform-entry/barkBattleWorkCache.test.ts @@ -6,6 +6,7 @@ import type { BarkBattleWorkSummary, } from '../../../packages/shared/src/contracts/barkBattle'; import { + buildBarkBattleDraftConfigFromWorkSummary, buildBarkBattlePublishedConfigFromDraft, buildBarkBattlePublishedConfigFromWork, buildBarkBattlePublishSnapshot, @@ -29,6 +30,7 @@ function buildBarkBattleWork( themeDescription: '阳光草坪声浪竞技场', playerImageDescription: '戴红色围巾的柯基选手', opponentImageDescription: '蓝色护目镜哈士奇对手', + onomatopoeia: ['汪', '破阵'], playerCharacterImageSrc: '/generated-bark-battle/player.png', opponentCharacterImageSrc: '/generated-bark-battle/opponent.png', uiBackgroundImageSrc: '/generated-bark-battle/background.png', @@ -184,6 +186,35 @@ test('builds work runtime config with publishedAt fallback', () => { expect(config.playerCharacterImageSrc).toBe('/generated-bark-battle/player.png'); }); +test('builds draft config from work summary with stable defaults', () => { + const config = buildBarkBattleDraftConfigFromWorkSummary( + buildBarkBattleWork({ + draftId: null, + playerCharacterImageSrc: null, + opponentCharacterImageSrc: null, + uiBackgroundImageSrc: null, + }), + ); + + expect(config).toMatchObject({ + draftId: 'BB-cache-race-12345678', + workId: 'BB-cache-race-12345678', + title: '汪汪测试杯', + description: '测试声浪赛', + themeDescription: '阳光草坪声浪竞技场', + playerImageDescription: '戴红色围巾的柯基选手', + opponentImageDescription: '蓝色护目镜哈士奇对手', + onomatopoeia: ['汪', '破阵'], + difficultyPreset: 'normal', + configVersion: 1, + rulesetVersion: 'bark-battle-ruleset-v1', + updatedAt: '2026-05-21T10:00:00.000Z', + }); + expect(config.playerCharacterImageSrc).toBeUndefined(); + expect(config.opponentCharacterImageSrc).toBeUndefined(); + expect(config.uiBackgroundImageSrc).toBeUndefined(); +}); + test('builds publish snapshot without empty asset fields', () => { const snapshot = buildBarkBattlePublishSnapshot( buildBarkBattleDraft({ diff --git a/src/components/platform-entry/barkBattleWorkCache.ts b/src/components/platform-entry/barkBattleWorkCache.ts index b56520db..26450eb6 100644 --- a/src/components/platform-entry/barkBattleWorkCache.ts +++ b/src/components/platform-entry/barkBattleWorkCache.ts @@ -142,6 +142,28 @@ export function buildBarkBattlePublishedConfigFromWork( }; } +export function buildBarkBattleDraftConfigFromWorkSummary( + work: BarkBattleWorkSummary, +): BarkBattleDraftConfig { + return { + draftId: work.draftId ?? work.workId, + workId: work.workId, + title: work.title, + description: work.summary, + themeDescription: work.themeDescription, + playerImageDescription: work.playerImageDescription, + opponentImageDescription: work.opponentImageDescription, + onomatopoeia: work.onomatopoeia, + playerCharacterImageSrc: work.playerCharacterImageSrc ?? undefined, + opponentCharacterImageSrc: work.opponentCharacterImageSrc ?? undefined, + uiBackgroundImageSrc: work.uiBackgroundImageSrc ?? undefined, + difficultyPreset: work.difficultyPreset, + configVersion: 1, + rulesetVersion: 'bark-battle-ruleset-v1', + updatedAt: work.updatedAt, + }; +} + export function shouldPreserveLocalBarkBattleWorkOnRefresh( item: BarkBattleWorkSummary, refreshed: readonly BarkBattleWorkSummary[],