From bf08c5e658a6e30b12dcc7045dadd82d401740b5 Mon Sep 17 00:00:00 2001 From: hided62 Date: Sun, 26 Jul 2026 05:45:45 +0000 Subject: [PATCH] Separate runtime profile identity from scenario --- app/game-api/src/config.ts | 2 +- app/game-api/test/config.test.ts | 28 +++++++++++++++++++ .../src/orchestrator/gatewayOrchestrator.ts | 1 + app/gateway-api/test/orchestratorPlan.test.ts | 1 + .../e2e/general-icon-lifecycle.spec.ts | 12 ++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 app/game-api/test/config.test.ts diff --git a/app/game-api/src/config.ts b/app/game-api/src/config.ts index 8bd5722..5ab333e 100644 --- a/app/game-api/src/config.ts +++ b/app/game-api/src/config.ts @@ -25,7 +25,7 @@ export interface GameApiConfig { export const resolveGameApiConfigFromEnv = (env: NodeJS.ProcessEnv = process.env): GameApiConfig => { const profile = env.PROFILE ?? env.SERVER_PROFILE ?? 'hwe'; const scenario = env.SCENARIO ?? 'default'; - const profileName = `${profile}:${scenario}`; + const profileName = env.GAME_PROFILE_NAME ?? `${profile}:${scenario}`; const secret = env.GAME_TOKEN_SECRET ?? env.GATEWAY_TOKEN_SECRET ?? ''; if (!secret) { throw new Error('GAME_TOKEN_SECRET is required for game token verification.'); diff --git a/app/game-api/test/config.test.ts b/app/game-api/test/config.test.ts new file mode 100644 index 0000000..2fedb5c --- /dev/null +++ b/app/game-api/test/config.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from 'vitest'; + +import { resolveGameApiConfigFromEnv } from '../src/config.js'; + +describe('resolveGameApiConfigFromEnv', () => { + it('keeps the deployment profile identity separate from the scenario id', () => { + const config = resolveGameApiConfigFromEnv({ + PROFILE: 'hwe', + SCENARIO: '1010', + GAME_PROFILE_NAME: 'hwe:2', + GAME_TOKEN_SECRET: 'test-secret', + }); + + expect(config.profile).toBe('hwe'); + expect(config.scenario).toBe('1010'); + expect(config.profileName).toBe('hwe:2'); + }); + + it('falls back to the legacy profile and scenario pair', () => { + const config = resolveGameApiConfigFromEnv({ + PROFILE: 'hwe', + SCENARIO: '2', + GAME_TOKEN_SECRET: 'test-secret', + }); + + expect(config.profileName).toBe('hwe:2'); + }); +}); diff --git a/app/gateway-api/src/orchestrator/gatewayOrchestrator.ts b/app/gateway-api/src/orchestrator/gatewayOrchestrator.ts index 273c083..a736029 100644 --- a/app/gateway-api/src/orchestrator/gatewayOrchestrator.ts +++ b/app/gateway-api/src/orchestrator/gatewayOrchestrator.ts @@ -300,6 +300,7 @@ export const buildProcessDefinitions = ( ...baseEnv, PROFILE: profile.profile, SCENARIO: profile.scenario, + GAME_PROFILE_NAME: profile.profileName, GAME_API_PORT: String(profile.apiPort), GAME_TRPC_PATH: `/${profile.profile}/api/trpc`, GAME_API_EVENTS_PATH: `/${profile.profile}/api/events`, diff --git a/app/gateway-api/test/orchestratorPlan.test.ts b/app/gateway-api/test/orchestratorPlan.test.ts index ae92d15..18089b7 100644 --- a/app/gateway-api/test/orchestratorPlan.test.ts +++ b/app/gateway-api/test/orchestratorPlan.test.ts @@ -89,6 +89,7 @@ describe('buildProcessDefinitions', () => { expect(definitions.api.cwd).toBe(path.join(buildWorkspace, 'app', 'game-api')); expect(definitions.api.script).toBe(path.join(buildWorkspace, 'app', 'game-api', 'dist', 'index.js')); expect(definitions.api.env).toMatchObject({ + GAME_PROFILE_NAME: 'che:2', GAME_TRPC_PATH: '/che/api/trpc', GAME_API_EVENTS_PATH: '/che/api/events', GAME_UPLOAD_PATH: '/che/api/uploads', diff --git a/app/gateway-frontend/e2e/general-icon-lifecycle.spec.ts b/app/gateway-frontend/e2e/general-icon-lifecycle.spec.ts index 5d92ade..f0ab0c7 100644 --- a/app/gateway-frontend/e2e/general-icon-lifecycle.spec.ts +++ b/app/gateway-frontend/e2e/general-icon-lifecycle.spec.ts @@ -55,6 +55,18 @@ const resetScenario = async (page: Page, scenarioId: string, sourceCommit: strin timeout: 30_000, }); await expect(profileStatus.locator('..').locator('.text-red-400')).toHaveCount(0); + await expect + .poll( + () => + page.evaluate(async () => { + const response = await fetch( + '/hwe/api/trpc/lobby.info,public.getMapLayout,public.getCachedMap?batch=1&input=%7B%7D' + ); + return response.status; + }), + { timeout: 60_000 } + ) + .toBe(200); }; const createGeneralAndInspectIcons = async (