From d03160a4b38d0be01148c622e7eac274d9dd2199 Mon Sep 17 00:00:00 2001 From: hided62 Date: Thu, 13 Aug 2026 16:28:04 +0000 Subject: [PATCH] fix(gateway): use Korean server labels by default --- app/gateway-api/src/adminRouter.ts | 4 +-- .../src/lobby/profileStatusService.ts | 4 +-- app/gateway-api/src/profileOrder.ts | 18 ++++++++++++ app/gateway-api/test/adminOperations.test.ts | 2 +- app/gateway-api/test/profileOrder.test.ts | 29 ++++++++++++++++++- 5 files changed, 51 insertions(+), 6 deletions(-) diff --git a/app/gateway-api/src/adminRouter.ts b/app/gateway-api/src/adminRouter.ts index 6bed55bf..86c84a6f 100644 --- a/app/gateway-api/src/adminRouter.ts +++ b/app/gateway-api/src/adminRouter.ts @@ -20,7 +20,7 @@ import { import type { GatewayApiContext } from './context.js'; import { resolveLocalAccountProfilePolicy } from './auth/localAccountPolicy.js'; import { GATEWAY_BUILD_STATUSES, GATEWAY_PROFILE_STATUSES } from './orchestrator/profileRepository.js'; -import { orderGatewayProfiles } from './profileOrder.js'; +import { orderGatewayProfiles, resolveGatewayProfileKoreanName } from './profileOrder.js'; import { purifyGatewayNoticeHtml } from './security/gatewayNoticeHtml.js'; const zProfileStatus = z.enum(GATEWAY_PROFILE_STATUSES); @@ -1585,7 +1585,7 @@ export const adminRouter = router({ instanceKey: profile.instanceKey, currentScenario: profile.currentScenario, meta: { - ...(typeof profile.meta.korName === 'string' ? { korName: profile.meta.korName } : {}), + korName: resolveGatewayProfileKoreanName(profile.profile, profile.meta.korName), }, })); }), diff --git a/app/gateway-api/src/lobby/profileStatusService.ts b/app/gateway-api/src/lobby/profileStatusService.ts index 5b2e5597..5db1c7e5 100644 --- a/app/gateway-api/src/lobby/profileStatusService.ts +++ b/app/gateway-api/src/lobby/profileStatusService.ts @@ -4,7 +4,7 @@ import type { GatewayProfileRepository, GatewayProfileStatus, } from '../orchestrator/profileRepository.js'; -import { orderGatewayProfiles } from '../profileOrder.js'; +import { orderGatewayProfiles, resolveGatewayProfileKoreanName } from '../profileOrder.js'; export type LobbyMapSnapshot = { updatedAt: string | null; @@ -102,7 +102,7 @@ export class RepositoryProfileStatusService implements GatewayProfileStatusServi battleSimRunning: false, tournamentRunning: false, }, - korName: (meta.korName as string | undefined) ?? row.profile, + korName: resolveGatewayProfileKoreanName(row.profile, meta.korName), color: (meta.color as string | undefined) ?? '#ffffff', }; } diff --git a/app/gateway-api/src/profileOrder.ts b/app/gateway-api/src/profileOrder.ts index 02f1ecef..442eb023 100644 --- a/app/gateway-api/src/profileOrder.ts +++ b/app/gateway-api/src/profileOrder.ts @@ -1,6 +1,24 @@ export const GATEWAY_PROFILE_ORDER = ['che', 'kwe', 'pwe', 'twe', 'nya', 'pya', 'hwe'] as const; +export const GATEWAY_PROFILE_KOREAN_NAMES = { + che: '체', + kwe: '퀘', + pwe: '풰', + twe: '퉤', + nya: '냐', + pya: '퍄', + hwe: '훼', +} as const satisfies Record<(typeof GATEWAY_PROFILE_ORDER)[number], string>; + const gatewayProfileOrder = new Map(GATEWAY_PROFILE_ORDER.map((profile, index) => [profile, index])); +const gatewayProfileKoreanNames = new Map(Object.entries(GATEWAY_PROFILE_KOREAN_NAMES)); + +export const resolveGatewayProfileKoreanName = (profile: string, configuredName?: unknown): string => { + if (typeof configuredName === 'string' && configuredName.trim()) { + return configuredName.trim(); + } + return gatewayProfileKoreanNames.get(profile) ?? profile; +}; export const compareGatewayProfiles = ( left: { profile: string; instanceKey: string }, diff --git a/app/gateway-api/test/adminOperations.test.ts b/app/gateway-api/test/adminOperations.test.ts index e8e0954c..4c9f5877 100644 --- a/app/gateway-api/test/adminOperations.test.ts +++ b/app/gateway-api/test/adminOperations.test.ts @@ -366,7 +366,7 @@ describe('admin profile navigation API', () => { profile: 'che', instanceKey: '2', currentScenario: '2', - meta: {}, + meta: { korName: '체' }, }, ]); expect(harness.getRuntimeStateListCount()).toBe(0); diff --git a/app/gateway-api/test/profileOrder.test.ts b/app/gateway-api/test/profileOrder.test.ts index 3e712918..8dd710b4 100644 --- a/app/gateway-api/test/profileOrder.test.ts +++ b/app/gateway-api/test/profileOrder.test.ts @@ -1,6 +1,11 @@ import { describe, expect, it } from 'vitest'; -import { GATEWAY_PROFILE_ORDER, orderGatewayProfiles } from '../src/profileOrder.js'; +import { + GATEWAY_PROFILE_KOREAN_NAMES, + GATEWAY_PROFILE_ORDER, + orderGatewayProfiles, + resolveGatewayProfileKoreanName, +} from '../src/profileOrder.js'; describe('orderGatewayProfiles', () => { it('uses the public server order instead of alphabetical profile order', () => { @@ -29,3 +34,25 @@ describe('orderGatewayProfiles', () => { expect(profiles[0]?.profile).toBe('zeta'); }); }); + +describe('resolveGatewayProfileKoreanName', () => { + it('uses the canonical Korean labels for every public profile', () => { + expect(GATEWAY_PROFILE_ORDER.map((profile) => resolveGatewayProfileKoreanName(profile))).toEqual( + GATEWAY_PROFILE_ORDER.map((profile) => GATEWAY_PROFILE_KOREAN_NAMES[profile]) + ); + expect(GATEWAY_PROFILE_ORDER.map((profile) => `${resolveGatewayProfileKoreanName(profile)}섭`)).toEqual([ + '체섭', + '퀘섭', + '풰섭', + '퉤섭', + '냐섭', + '퍄섭', + '훼섭', + ]); + }); + + it('preserves configured and unknown profile names', () => { + expect(resolveGatewayProfileKoreanName('che', ' 천하서버 ')).toBe('천하서버'); + expect(resolveGatewayProfileKoreanName('custom')).toBe('custom'); + }); +});