refactor(游戏分发): AGC 发布身份本地字段改名 projectKey

- 网页发布服务 localProjectId 全部改名 projectKey,与共享契约、后端 project_key 列名对齐
- 网页发布单测与联调脚本同步改名
- 硬切不改兼容:模块未上线,无存量字段与调用方
This commit is contained in:
2026-10-07 18:17:49 +08:00
parent 7a710bb2b6
commit 2dca06be3c
3 changed files with 17 additions and 17 deletions
@@ -162,7 +162,7 @@ export type GameDistributionPublicationReadResult =
* 发布面板打开时由原生恢复本地绑定与线上作品状态。
*
* 原生按当前会话(账号 + origin)隔离绑定:切换账号/环境后不会接管他人作品;无本地绑定时
* 按作者作品的 `localProjectId` 精确匹配做一次性恢复。网络/401/5xx 返回 `unavailable`,
* 按作者作品的 `projectKey` 精确匹配做一次性恢复。网络/401/5xx 返回 `unavailable`,
* 调用方不得据此按首次发布继续。
*/
export async function readGameDistributionPublication(
@@ -235,10 +235,10 @@ function normalizeMetadata(
function toCreateGameRequest(
metadata: GameDistributionPublishMetadata,
localProjectId: string,
projectKey: string,
): GameDistributionCreateGameRequest {
return {
localProjectId,
projectKey,
title: metadata.title,
summary: metadata.summary,
description: metadata.description,
@@ -305,8 +305,8 @@ export async function publishLocalProjectGame(args: {
throw new Error('发布需要绑定本地项目');
}
const metadata = normalizeMetadata(args.manifest, args.metadata);
const localProjectId = args.manifest.projectId.trim();
if (!localProjectId) {
const projectKey = args.manifest.projectId.trim();
if (!projectKey) {
throw new Error('发布需要本地项目标识,请重新打开项目后再试');
}
const gameId = args.gameId?.trim() ?? '';
@@ -334,7 +334,7 @@ export async function publishLocalProjectGame(args: {
) {
throw new Error('缺少公开修订号,请重新打开发布面板后再试');
}
const gameMetadata = toCreateGameRequest(metadata, localProjectId);
const gameMetadata = toCreateGameRequest(metadata, projectKey);
const rootKey = args.idempotencyKey?.trim() ?? '';
// 发布编排、认证、origin、分片续传与送审都在 Rust 完成;渲染进程只传递
// 已归一化的资料、面板给出的本地媒体路径、项目版本和本地项目标识,不接触 token、
@@ -86,7 +86,7 @@ describe('Rust 发布 facade', () => {
coverPath: '',
screenshotPaths: [],
metadata: {
localProjectId: 'local-proj-1',
projectKey: 'local-proj-1',
coverObjectKey: 'generated/cover.png',
screenshots: ['generated/shot-1.png', 'generated/shot-2.png'],
},
@@ -138,7 +138,7 @@ describe('Rust 发布 facade', () => {
expect(calls[0]?.args).not.toHaveProperty('idempotencyKey');
expect(calls[0]?.args).toMatchObject({
projectPath: '/tmp/project',
metadata: { localProjectId: 'local-proj-1' },
metadata: { projectKey: 'local-proj-1' },
});
});
@@ -7,7 +7,7 @@
* npx vitest run apps/ai-game-creator-shell/tests/gameDistributionPublishLive.test.ts
*
* 开启后测试会注册一个临时作者,并通过真实 HTTP(而不是 mock 请求层)验证
* AGC 发布 facade 的请求合同,覆盖:创建游戏、同 `localProjectId` 复用游戏身份、
* AGC 发布 facade 的请求合同,覆盖:创建游戏、同 `projectKey` 复用游戏身份、
* 真实分片上传、送审与版本回读。jsdom 只替代 Tauri command 的原生执行。
*
* jsdom 里没有 Tauri 运行时,`upload_local_project_game_package` 由本测试按服务端
@@ -237,17 +237,17 @@ async function buildStagedPackage(): Promise<{
function createPublishAttemptLedger() {
const attempts = new Map<string, string>();
return {
resolve(localProjectId: string, packageSha256: string): string {
const key = `${localProjectId}:${packageSha256}`;
resolve(projectKey: string, packageSha256: string): string {
const key = `${projectKey}:${packageSha256}`;
const existing = attempts.get(key);
if (existing) return existing;
const rootKey = `agc-publish-live-${randomUUID()}`;
attempts.set(key, rootKey);
return rootKey;
},
clear(localProjectId: string): void {
clear(projectKey: string): void {
for (const key of [...attempts.keys()]) {
if (key.startsWith(`${localProjectId}:`)) attempts.delete(key);
if (key.startsWith(`${projectKey}:`)) attempts.delete(key);
}
},
};
@@ -435,7 +435,7 @@ liveTest(
const rootKey =
explicitKey ||
attempts.resolve(
String(metadata.localProjectId),
String(metadata.projectKey),
staged.packageSha256,
);
// 更新模式:带原 gameId 时跳过 create game,直接在原游戏上创建新版本。
@@ -483,7 +483,7 @@ liveTest(
// 创建版本:整份版本声明放在 `metadata` 文本 part,封面字节随 `cover` part 重传;
// 同样走被 stub 的全局 `fetch`,由桥生成 multipart boundary。
const versionRequest = {
localProjectId: metadata.localProjectId,
projectKey: metadata.projectKey,
packageSha256: staged.packageSha256,
packageBytes: staged.packageSizeBytes,
packageFileCount: staged.packageFileCount,
@@ -538,7 +538,7 @@ liveTest(
),
);
// 送审成功即服务端收口:原生账本同样在这里清除本次尝试。
attempts.clear(String(metadata.localProjectId));
attempts.clear(String(metadata.projectKey));
return {
gameId: game.id,
versionId: version.versionId,
@@ -624,7 +624,7 @@ liveTest(
expect(readResult.version.frozenMetadata?.screenshots).toEqual([]);
// 第二次发布:上一次已在送审成功时收口,账本清除,因此这里换新键——同
// localProjectId 必须复用同一 gameId 并新增版本。
// projectKey 必须复用同一 gameId 并新增版本。
const second = await publishLocalProjectGame({
invoke,
projectPath: '/data/dsk/Genarrative/tmp-agc-live-project',