fix: 커맨드 차등 생명주기와 로그 그래프를 보강

장수 55종과 수뇌 35종의 상태, 로그, 메시지, 예약 턴 비교를 닫습니다.

실제 시나리오 프로필과 대표 PostgreSQL 수명주기, 즉시 외교와 출병 회귀를 추가하고 발견된 Ref 로그 및 생성 장수 저장 차이를 교정합니다.
This commit is contained in:
2026-08-23 21:48:29 +00:00
parent 85591c68ad
commit c63a49bd07
128 changed files with 8615 additions and 848 deletions
+43 -7
View File
@@ -1,4 +1,6 @@
import {
isGeneralTurnCommandKey,
isNationTurnCommandKey,
loadGeneralTurnCommandSpecs,
loadNationTurnCommandSpecs,
type GeneralTurnCommandSpec,
@@ -9,7 +11,7 @@ import type { ItemModule } from '@sammo-ts/logic/items/types.js';
import { resolveLegacyPurchasableItemKeys } from '@sammo-ts/logic/rewards/legacyUniqueItemPool.js';
import { z } from 'zod';
import { loadTurnCommandProfile } from '@sammo-ts/game-engine/turn/turnCommandProfile.js';
import { loadScenarioTurnCommandProfile } from '@sammo-ts/game-engine/turn/turnCommandProfile.js';
export type TurnCommandOptionValue = string | number;
@@ -345,22 +347,35 @@ export const buildTurnCommandInputFields = (
return Object.entries(properties).map(([key, schema]) => buildField(key, schema, required.has(key)));
};
export const loadTurnCommandSpecs = async () => {
const profile = await loadTurnCommandProfile();
export const loadTurnCommandSpecs = async (scenarioConst?: unknown) => {
const resolution = await loadScenarioTurnCommandProfile({ scenarioConst });
const profile = resolution.profile;
const [general, nation] = await Promise.all([
loadGeneralTurnCommandSpecs(profile.general),
loadNationTurnCommandSpecs(profile.nation),
]);
return { general, nation };
return {
general,
nation,
generalGroups: resolution.generalGroups,
nationGroups: resolution.nationGroups,
};
};
export const parseReservedTurnArgs = async (
export const parseRegisteredTurnArgs = async (
scope: 'general' | 'nation',
action: string,
rawArgs: unknown
): Promise<Record<string, unknown>> => {
const specs = await loadTurnCommandSpecs();
const spec = specs[scope].find((entry) => entry.key === action);
const specs =
scope === 'general'
? isGeneralTurnCommandKey(action)
? await loadGeneralTurnCommandSpecs([action])
: []
: isNationTurnCommandKey(action)
? await loadNationTurnCommandSpecs([action])
: [];
const spec = specs[0];
if (!spec) {
throw new Error(`Unknown ${scope} turn command: ${action}`);
}
@@ -369,3 +384,24 @@ export const parseReservedTurnArgs = async (
}
return spec.argsSchema.parse(rawArgs);
};
export const assertReservedTurnActionAvailable = async (
scope: 'general' | 'nation',
action: string,
scenarioConst?: unknown
): Promise<void> => {
const specs = await loadTurnCommandSpecs(scenarioConst);
if (!specs[scope].some((entry) => entry.key === action)) {
throw new Error(`Unknown ${scope} turn command: ${action}`);
}
};
export const parseReservedTurnArgs = async (
scope: 'general' | 'nation',
action: string,
rawArgs: unknown,
scenarioConst?: unknown
): Promise<Record<string, unknown>> => {
await assertReservedTurnActionAvailable(scope, action, scenarioConst);
return parseRegisteredTurnArgs(scope, action, rawArgs);
};