refactor: 收口方洞 session profile 映射
This commit is contained in:
@@ -536,6 +536,7 @@ import {
|
||||
import {
|
||||
buildJumpHopPendingSession,
|
||||
buildPuzzleRuntimeWorkFromSession,
|
||||
buildSquareHoleProfileFromSession,
|
||||
buildWoodenFishPendingSession,
|
||||
buildWoodenFishSessionFromWorkDetail,
|
||||
} from './platformMiniGameSessionMappingModel';
|
||||
@@ -751,40 +752,6 @@ function mapVisualNovelWorkDetailToSession(
|
||||
};
|
||||
}
|
||||
|
||||
function buildSquareHoleProfileFromSession(
|
||||
session: SquareHoleSessionSnapshot | null,
|
||||
): SquareHoleWorkProfile | null {
|
||||
const draft = session?.draft;
|
||||
if (!session || !draft?.profileId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const now = session.updatedAt || new Date().toISOString();
|
||||
return {
|
||||
workId: draft.profileId,
|
||||
profileId: draft.profileId,
|
||||
ownerUserId: 'current-user',
|
||||
sourceSessionId: session.sessionId,
|
||||
gameName: draft.gameName,
|
||||
themeText: draft.themeText,
|
||||
twistRule: draft.twistRule,
|
||||
summary: draft.summary,
|
||||
tags: draft.tags,
|
||||
coverImageSrc: draft.coverImageSrc ?? null,
|
||||
backgroundPrompt: draft.backgroundPrompt,
|
||||
backgroundImageSrc: draft.backgroundImageSrc ?? null,
|
||||
shapeOptions: draft.shapeOptions,
|
||||
holeOptions: draft.holeOptions,
|
||||
shapeCount: draft.shapeCount,
|
||||
difficulty: draft.difficulty,
|
||||
publicationStatus: 'draft',
|
||||
playCount: 0,
|
||||
updatedAt: now,
|
||||
publishedAt: null,
|
||||
publishReady: Boolean(draft.publishReady),
|
||||
};
|
||||
}
|
||||
|
||||
function mergePuzzleWorkSummary(
|
||||
current: PuzzleWorkSummary,
|
||||
updated: PuzzleWorkSummary,
|
||||
|
||||
@@ -8,6 +8,10 @@ import type {
|
||||
PuzzleResultDraft,
|
||||
} from '../../../packages/shared/src/contracts/puzzleAgentDraft';
|
||||
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
||||
import type {
|
||||
SquareHoleResultDraft,
|
||||
SquareHoleSessionSnapshot,
|
||||
} from '../../../packages/shared/src/contracts/squareHoleAgent';
|
||||
import type {
|
||||
WoodenFishAudioAsset,
|
||||
WoodenFishImageAsset,
|
||||
@@ -17,6 +21,7 @@ import type {
|
||||
import {
|
||||
buildJumpHopPendingSession,
|
||||
buildPuzzleRuntimeWorkFromSession,
|
||||
buildSquareHoleProfileFromSession,
|
||||
buildWoodenFishPendingSession,
|
||||
buildWoodenFishSessionFromWorkDetail,
|
||||
} from './platformMiniGameSessionMappingModel';
|
||||
@@ -123,6 +128,100 @@ function buildJumpHopSummary(
|
||||
};
|
||||
}
|
||||
|
||||
function buildSquareHoleDraft(
|
||||
overrides: Partial<SquareHoleResultDraft> = {},
|
||||
): SquareHoleResultDraft {
|
||||
return {
|
||||
profileId: 'square-hole-profile-1',
|
||||
gameName: '星桥方洞',
|
||||
themeText: '星桥机关',
|
||||
twistRule: '只允许相同颜色形状入洞',
|
||||
summary: '把星桥机关里的形状送入正确孔洞。',
|
||||
tags: ['星桥', '机关'],
|
||||
coverImageSrc: '/square-hole-cover.png',
|
||||
backgroundPrompt: '星桥机关背景',
|
||||
backgroundImageSrc: '/square-hole-background.png',
|
||||
shapeOptions: [
|
||||
{
|
||||
optionId: 'shape-1',
|
||||
shapeKind: 'star',
|
||||
label: '星形',
|
||||
targetHoleId: 'hole-1',
|
||||
imagePrompt: '星形积木',
|
||||
imageSrc: '/shape-star.png',
|
||||
},
|
||||
],
|
||||
holeOptions: [
|
||||
{
|
||||
holeId: 'hole-1',
|
||||
holeKind: 'star-hole',
|
||||
label: '星形洞',
|
||||
imagePrompt: '星形洞口',
|
||||
imageSrc: '/hole-star.png',
|
||||
},
|
||||
],
|
||||
shapeCount: 6,
|
||||
difficulty: 3,
|
||||
publishReady: true,
|
||||
blockers: [],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function buildSquareHoleSession(
|
||||
overrides: Partial<SquareHoleSessionSnapshot> = {},
|
||||
): SquareHoleSessionSnapshot {
|
||||
return {
|
||||
sessionId: 'square-hole-session-1',
|
||||
currentTurn: 2,
|
||||
progressPercent: 100,
|
||||
stage: 'draft_ready',
|
||||
anchorPack: {
|
||||
theme: {
|
||||
key: 'theme',
|
||||
label: '主题',
|
||||
value: '星桥机关',
|
||||
status: 'confirmed',
|
||||
},
|
||||
twistRule: {
|
||||
key: 'twistRule',
|
||||
label: '扭转规则',
|
||||
value: '只允许相同颜色形状入洞',
|
||||
status: 'confirmed',
|
||||
},
|
||||
shapeCount: {
|
||||
key: 'shapeCount',
|
||||
label: '形状数量',
|
||||
value: '6',
|
||||
status: 'confirmed',
|
||||
},
|
||||
difficulty: {
|
||||
key: 'difficulty',
|
||||
label: '难度',
|
||||
value: '3',
|
||||
status: 'confirmed',
|
||||
},
|
||||
},
|
||||
config: {
|
||||
themeText: '星桥机关',
|
||||
twistRule: '只允许相同颜色形状入洞',
|
||||
shapeCount: 6,
|
||||
difficulty: 3,
|
||||
shapeOptions: [],
|
||||
holeOptions: [],
|
||||
backgroundPrompt: '星桥机关背景',
|
||||
coverImageSrc: null,
|
||||
backgroundImageSrc: null,
|
||||
},
|
||||
draft: buildSquareHoleDraft(),
|
||||
messages: [],
|
||||
lastAssistantReply: null,
|
||||
publishedProfileId: null,
|
||||
updatedAt: '2026-06-01T12:30:00.000Z',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const woodenFishImageAsset: WoodenFishImageAsset = {
|
||||
assetId: 'asset-hit',
|
||||
imageSrc: '/hit.png',
|
||||
@@ -284,6 +383,50 @@ describe('platformMiniGameSessionMappingModel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('builds square hole draft profile from session', () => {
|
||||
expect(buildSquareHoleProfileFromSession(buildSquareHoleSession())).toEqual({
|
||||
workId: 'square-hole-profile-1',
|
||||
profileId: 'square-hole-profile-1',
|
||||
ownerUserId: 'current-user',
|
||||
sourceSessionId: 'square-hole-session-1',
|
||||
gameName: '星桥方洞',
|
||||
themeText: '星桥机关',
|
||||
twistRule: '只允许相同颜色形状入洞',
|
||||
summary: '把星桥机关里的形状送入正确孔洞。',
|
||||
tags: ['星桥', '机关'],
|
||||
coverImageSrc: '/square-hole-cover.png',
|
||||
backgroundPrompt: '星桥机关背景',
|
||||
backgroundImageSrc: '/square-hole-background.png',
|
||||
shapeOptions: buildSquareHoleDraft().shapeOptions,
|
||||
holeOptions: buildSquareHoleDraft().holeOptions,
|
||||
shapeCount: 6,
|
||||
difficulty: 3,
|
||||
publicationStatus: 'draft',
|
||||
playCount: 0,
|
||||
updatedAt: '2026-06-01T12:30:00.000Z',
|
||||
publishedAt: null,
|
||||
publishReady: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('returns null for square hole profile without session draft or profile id', () => {
|
||||
expect(buildSquareHoleProfileFromSession(null)).toBeNull();
|
||||
expect(
|
||||
buildSquareHoleProfileFromSession(
|
||||
buildSquareHoleSession({
|
||||
draft: null,
|
||||
}),
|
||||
),
|
||||
).toBeNull();
|
||||
expect(
|
||||
buildSquareHoleProfileFromSession(
|
||||
buildSquareHoleSession({
|
||||
draft: buildSquareHoleDraft({ profileId: '' }),
|
||||
}),
|
||||
),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
test('builds wooden fish pending session from work summary', () => {
|
||||
expect(buildWoodenFishPendingSession(buildWoodenFishSummary())).toEqual({
|
||||
sessionId: 'wooden-fish-session-1',
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { JumpHopSessionSnapshotResponse, JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
|
||||
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
||||
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
|
||||
import type { SquareHoleSessionSnapshot } from '../../../packages/shared/src/contracts/squareHoleAgent';
|
||||
import type { SquareHoleWorkProfile } from '../../../packages/shared/src/contracts/squareHoleWorks';
|
||||
import type {
|
||||
WoodenFishSessionSnapshotResponse,
|
||||
WoodenFishWorkProfileResponse,
|
||||
@@ -52,6 +54,40 @@ export function buildPuzzleRuntimeWorkFromSession(
|
||||
};
|
||||
}
|
||||
|
||||
export function buildSquareHoleProfileFromSession(
|
||||
session: SquareHoleSessionSnapshot | null,
|
||||
): SquareHoleWorkProfile | null {
|
||||
const draft = session?.draft;
|
||||
if (!session || !draft?.profileId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const now = session.updatedAt || new Date().toISOString();
|
||||
return {
|
||||
workId: draft.profileId,
|
||||
profileId: draft.profileId,
|
||||
ownerUserId: 'current-user',
|
||||
sourceSessionId: session.sessionId,
|
||||
gameName: draft.gameName,
|
||||
themeText: draft.themeText,
|
||||
twistRule: draft.twistRule,
|
||||
summary: draft.summary,
|
||||
tags: draft.tags,
|
||||
coverImageSrc: draft.coverImageSrc ?? null,
|
||||
backgroundPrompt: draft.backgroundPrompt,
|
||||
backgroundImageSrc: draft.backgroundImageSrc ?? null,
|
||||
shapeOptions: draft.shapeOptions,
|
||||
holeOptions: draft.holeOptions,
|
||||
shapeCount: draft.shapeCount,
|
||||
difficulty: draft.difficulty,
|
||||
publicationStatus: 'draft',
|
||||
playCount: 0,
|
||||
updatedAt: now,
|
||||
publishedAt: null,
|
||||
publishReady: Boolean(draft.publishReady),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildJumpHopPendingSession(
|
||||
item: JumpHopWorkSummaryResponse,
|
||||
): JumpHopSessionSnapshotResponse {
|
||||
|
||||
Reference in New Issue
Block a user