feat(gateway): 프로필별 첫 기수 번호를 관리한다

첫 기수 번호를 완료 게임 수의 기준값으로 적용하고 0기를 API와 화면에서 보존한다. 시즌 번호와 독립된 RESET 계약을 관리 패널, 테스트, 운영 문서에 반영한다.
This commit is contained in:
2026-08-21 13:49:11 +00:00
parent 32d69d7049
commit 88be40f729
15 changed files with 192 additions and 19 deletions
+1
View File
@@ -1876,6 +1876,7 @@ export const adminRouter = router({
inGameNotice: z.string().max(4000).nullable().optional(),
profileImageUrl: z.string().max(2048).nullable().optional(),
nextSeasonIdx: z.number().int().min(0).nullable().optional(),
firstGameIdx: z.number().int().min(0).nullable().optional(),
localAccountAccessGraceDays: z.number().int().min(0).max(365).nullable().optional(),
localAccountGeneralCreationGraceDays: z.number().int().min(0).max(365).nullable().optional(),
resetDefaults: zProfileResetDefaults.nullable().optional(),
@@ -271,6 +271,12 @@ const readMetaNumber = (meta: Record<string, unknown>, key: string): number | nu
return null;
};
export const resolveProfileFirstGameIdx = (meta: Record<string, unknown>): number => {
const raw = meta.firstGameIdx;
const configured = typeof raw === 'number' ? raw : typeof raw === 'string' ? Number(raw) : Number.NaN;
return Number.isInteger(configured) && configured >= 0 ? configured : 1;
};
const normalizeStatus = (value: unknown): GatewayAdminActionStatus | null => {
if (typeof value === 'string') {
return value as GatewayAdminActionStatus;
@@ -1882,6 +1888,7 @@ export class GatewayOrchestrator implements GatewayOrchestratorHandle {
);
const profileMeta = normalizeMeta(profile.meta);
const nextSeasonIdx = readMetaNumber(profileMeta, 'nextSeasonIdx');
const firstGameIdx = resolveProfileFirstGameIdx(profileMeta);
const baseSeason = readMetaNumber(normalizeMeta(seedInfo.meta), 'season');
const season = nextSeasonIdx ?? baseSeason ?? 1;
await updateClaimedProfile({ status: 'STOPPED' }, () =>
@@ -1902,6 +1909,7 @@ export class GatewayOrchestrator implements GatewayOrchestratorHandle {
installOptions: {
...(installOptions ?? {}),
season,
firstGameIdx,
serverId,
installCommitSha: commitSha,
},