From add7ab96d15a5a8f7bb8f6eb75432f9b28b059a3 Mon Sep 17 00:00:00 2001 From: hided62 Date: Tue, 18 Aug 2026 16:27:45 +0000 Subject: [PATCH] =?UTF-8?q?fix(migration):=20=EB=A0=88=EA=B1=B0=EC=8B=9C?= =?UTF-8?q?=20=EA=B0=9C=EC=9E=A5=20=EC=8B=9C=EA=B0=81=20=EC=84=BC=ED=8B=B0?= =?UTF-8?q?=EB=84=90=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/legacy-db-migration/src/game.ts | 11 ++++++++++- tools/legacy-db-migration/test/game.test.ts | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tools/legacy-db-migration/src/game.ts b/tools/legacy-db-migration/src/game.ts index 9203b17b..d897d7da 100644 --- a/tools/legacy-db-migration/src/game.ts +++ b/tools/legacy-db-migration/src/game.ts @@ -83,7 +83,16 @@ const asJsonRecord = (value: JsonValue): Record => export const resolveLegacyGameOpenedAt = (env: JsonValue, legacyDate: Date, context: string): Date => { const record = asJsonRecord(env); const candidate = record.opentime ?? record.starttime; - return candidate === null || candidate === undefined || candidate === '' ? legacyDate : toDate(candidate, context); + if (candidate === null || candidate === undefined || candidate === '') { + return legacyDate; + } + try { + return toDate(candidate, context); + } catch { + // 후기 레거시 기수는 개장 전 sentinel(-324000000/0)을 기록하기도 한다. + // raw_env는 그대로 보존하고, 유효한 ng_games.date만 파생 시각에 사용한다. + return legacyDate; + } }; const migrateSimpleTable = async ( diff --git a/tools/legacy-db-migration/test/game.test.ts b/tools/legacy-db-migration/test/game.test.ts index 96878524..79b86ef4 100644 --- a/tools/legacy-db-migration/test/game.test.ts +++ b/tools/legacy-db-migration/test/game.test.ts @@ -114,6 +114,20 @@ describe('legacy archive game migration', () => { expect(resolveLegacyGameOpenedAt({}, new Date('2020-01-01T00:00:00.000Z'), 'fixture').toISOString()).toBe( '2020-01-01T00:00:00.000Z' ); + expect( + resolveLegacyGameOpenedAt( + { opentime: -324000000, starttime: 0 }, + new Date('2026-08-10T22:00:00.000Z'), + 'fixture' + ).toISOString() + ).toBe('2026-08-10T22:00:00.000Z'); + expect( + resolveLegacyGameOpenedAt( + { opentime: 'not-a-date' }, + new Date('2026-08-10T22:00:00.000Z'), + 'fixture' + ).toISOString() + ).toBe('2026-08-10T22:00:00.000Z'); }); it('keeps dry-run target-read-only while reporting normalized formats', async () => {