merge: 최신 main을 긴급천도 교정에 통합한다

This commit is contained in:
2026-08-24 04:51:07 +00:00
5 changed files with 52 additions and 2 deletions
@@ -54,6 +54,7 @@ export interface ScenarioInstallOptions {
season?: number; season?: number;
firstGameIdx?: number; firstGameIdx?: number;
serverId?: string; serverId?: string;
serverName?: string;
installOperationId?: string; installOperationId?: string;
installCommitSha?: string; installCommitSha?: string;
} }
@@ -315,6 +316,9 @@ export const seedScenarioToDatabase = async (options: ScenarioSeedOptions): Prom
if (typeof install?.serverId === 'string' && install.serverId.trim()) { if (typeof install?.serverId === 'string' && install.serverId.trim()) {
worldMeta.serverId = install.serverId.trim(); worldMeta.serverId = install.serverId.trim();
} }
if (typeof install?.serverName === 'string' && install.serverName.trim()) {
worldMeta.serverName = install.serverName.trim();
}
if (typeof install?.installOperationId === 'string' && install.installOperationId.trim()) { if (typeof install?.installOperationId === 'string' && install.installOperationId.trim()) {
worldMeta.installOperationId = install.installOperationId.trim(); worldMeta.installOperationId = install.installOperationId.trim();
} }
@@ -367,6 +367,7 @@ describeDb('scenario database seed', () => {
}, },
preopenAt: new Date('2030-01-01T01:00:00Z'), preopenAt: new Date('2030-01-01T01:00:00Z'),
openAt: new Date('2030-01-01T02:00:00Z'), openAt: new Date('2030-01-01T02:00:00Z'),
serverName: '훼',
}, },
}); });
@@ -400,6 +401,7 @@ describeDb('scenario database seed', () => {
(worldState.currentYear - (scenario.startYear ?? worldState.currentYear) + 10) * 2 (worldState.currentYear - (scenario.startYear ?? worldState.currentYear) + 10) * 2
); );
expect(meta.killturn).toBe(1600); expect(meta.killturn).toBe(1600);
expect(meta.serverName).toBe('훼');
const autorun = (meta.autorun_user ?? {}) as Record<string, unknown>; const autorun = (meta.autorun_user ?? {}) as Record<string, unknown>;
const autorunOptions = (autorun.options ?? {}) as Record<string, unknown>; const autorunOptions = (autorun.options ?? {}) as Record<string, unknown>;
expect(autorunOptions.develop).toBe(true); expect(autorunOptions.develop).toBe(true);
@@ -260,7 +260,12 @@ describe('persistUnificationFinalization', () => {
expect(hallCreate).toHaveBeenCalledWith( expect(hallCreate).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
data: expect.objectContaining({ data: expect.objectContaining({
aux: expect.objectContaining({ ownerDisplayName: '표시 이름', fgColor: '#000000' }), aux: expect.objectContaining({
ownerDisplayName: '표시 이름',
fgColor: '#000000',
serverName: '테스트',
serverIdx: 2,
}),
}), }),
}) })
); );
@@ -279,7 +284,10 @@ describe('persistUnificationFinalization', () => {
); );
expect(emperorCreate).toHaveBeenCalledWith( expect(emperorCreate).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
data: expect.objectContaining({ aux: { winnerNationId: 1, generationKey: input.generationKey } }), data: expect.objectContaining({
phase: '테스트2기',
aux: { winnerNationId: 1, generationKey: input.generationKey },
}),
}) })
); );
const archiveWrite = oldGeneralUpsert.mock.calls[0]?.[0] as { const archiveWrite = oldGeneralUpsert.mock.calls[0]?.[0] as {
@@ -23,6 +23,7 @@ import {
import { isRecord } from '@sammo-ts/common'; import { isRecord } from '@sammo-ts/common';
import { resolveGatewayPostgresConfigFromEnv } from '../gatewayPostgresConfig.js'; import { resolveGatewayPostgresConfigFromEnv } from '../gatewayPostgresConfig.js';
import { resolveGatewayProfileKoreanName } from '../profileOrder.js';
import { import {
buildTurboReleaseCommand, buildTurboReleaseCommand,
@@ -281,6 +282,13 @@ const buildServerId = (profileName: string, now: Date, installOperationId?: stri
return `${profileName}_${year}${month}${day}_${suffix}`; return `${profileName}_${year}${month}${day}_${suffix}`;
}; };
export const resolveProfileArchiveServerName = (
profile: Pick<GatewayProfileRecord, 'profileName' | 'profile' | 'meta'>
): string => {
const meta = normalizeMeta(profile.meta);
return resolveGatewayProfileKoreanName(profile.profile, meta.korName);
};
const readMetaNumber = (meta: Record<string, unknown>, key: string): number | null => { const readMetaNumber = (meta: Record<string, unknown>, key: string): number | null => {
const raw = meta[key]; const raw = meta[key];
if (typeof raw === 'number' && Number.isFinite(raw)) { if (typeof raw === 'number' && Number.isFinite(raw)) {
@@ -2010,6 +2018,9 @@ export class GatewayOrchestrator implements GatewayOrchestratorHandle {
season, season,
firstGameIdx, firstGameIdx,
serverId, serverId,
// Snapshot the Gateway display name into this season. Hall and
// dynasty archives must not fall back to the runtime instance key.
serverName: resolveProfileArchiveServerName(profile),
installCommitSha: commitSha, installCommitSha: commitSha,
}, },
adminUser, adminUser,
@@ -9,6 +9,7 @@ import {
buildSharedProfileFrontendCommands, buildSharedProfileFrontendCommands,
buildWorkspaceCommands, buildWorkspaceCommands,
planProfileReconcile, planProfileReconcile,
resolveProfileArchiveServerName,
resolveResetLifecycleStatus, resolveResetLifecycleStatus,
} from '../src/orchestrator/gatewayOrchestrator.js'; } from '../src/orchestrator/gatewayOrchestrator.js';
import { GATEWAY_PROFILE_ORDER } from '../src/profileOrder.js'; import { GATEWAY_PROFILE_ORDER } from '../src/profileOrder.js';
@@ -134,6 +135,30 @@ describe('resolveResetLifecycleStatus', () => {
}); });
}); });
describe('resolveProfileArchiveServerName', () => {
it('uses the configured Gateway name and never the runtime instance key', () => {
expect(
resolveProfileArchiveServerName({
...buildProfile(),
profile: 'hwe',
profileName: 'hwe:default',
meta: { korName: ' 훼 ' },
})
).toBe('훼');
});
it('uses the canonical profile label when Gateway has no override', () => {
expect(
resolveProfileArchiveServerName({
...buildProfile(),
profile: 'hwe',
profileName: 'hwe:default',
meta: {},
})
).toBe('훼');
});
});
describe('buildProcessDefinitions', () => { describe('buildProcessDefinitions', () => {
const processConfig = { const processConfig = {
workspaceRoot: '/srv/sammo/main', workspaceRoot: '/srv/sammo/main',