feat: NPC 판단 당시 합성 정책을 기록하고 조회한다
This commit is contained in:
@@ -3,6 +3,39 @@ import { z } from 'zod';
|
||||
import type { GamePrisma } from '@sammo-ts/infra';
|
||||
import { auditProcedure, monthOrdinal, readAudit, readAuditWorld, zAuditMonth } from './shared.js';
|
||||
|
||||
const zEffectivePolicy = z.object({
|
||||
schemaVersion: z.literal(1),
|
||||
general: z.object({ priority: z.array(z.string()), flags: z.record(z.string(), z.boolean()) }),
|
||||
nation: z.object({
|
||||
priority: z.array(z.string()),
|
||||
flags: z.record(z.string(), z.boolean()),
|
||||
values: z.object({
|
||||
reqNationGold: z.number(),
|
||||
reqNationRice: z.number(),
|
||||
reqHumanWarUrgentGold: z.number(),
|
||||
reqHumanWarUrgentRice: z.number(),
|
||||
reqHumanWarRecommandGold: z.number(),
|
||||
reqHumanWarRecommandRice: z.number(),
|
||||
reqHumanDevelGold: z.number(),
|
||||
reqHumanDevelRice: z.number(),
|
||||
reqNpcWarGold: z.number(),
|
||||
reqNpcWarRice: z.number(),
|
||||
reqNpcDevelGold: z.number(),
|
||||
reqNpcDevelRice: z.number(),
|
||||
minimumResourceActionAmount: z.number(),
|
||||
maximumResourceActionAmount: z.number(),
|
||||
minNpcWarLeadership: z.number(),
|
||||
minWarCrew: z.number(),
|
||||
minNpcRecruitCityPopulation: z.number(),
|
||||
safeRecruitCityPopulationRatio: z.number(),
|
||||
properWarTrainAtmos: z.number(),
|
||||
cureThreshold: z.number(),
|
||||
}),
|
||||
combatForce: z.record(z.string(), z.array(z.number()).length(2)),
|
||||
supportForce: z.array(z.number()),
|
||||
developForce: z.array(z.number()),
|
||||
}),
|
||||
});
|
||||
const zId = z.string().regex(/^[a-f0-9]{64}$/);
|
||||
const zTick = z
|
||||
.string()
|
||||
@@ -71,7 +104,11 @@ const zStep = z.intersection(
|
||||
)
|
||||
.max(5),
|
||||
}),
|
||||
z.object({ kind: z.literal('DECISION_START'), reservedAction: z.string() }),
|
||||
z.object({
|
||||
kind: z.literal('DECISION_START'),
|
||||
reservedAction: z.string(),
|
||||
effectivePolicy: zEffectivePolicy.optional(),
|
||||
}),
|
||||
z.object({ kind: z.literal('DECISION_END'), action: z.string().nullable(), reason: z.string().nullable() }),
|
||||
z.object({ kind: z.literal('DECISION_ERROR') }),
|
||||
z.object({ kind: z.literal('PROCEDURE_START'), procedure: z.string() }),
|
||||
|
||||
@@ -2317,7 +2317,9 @@ integration('game API security over HTTP transport', () => {
|
||||
{
|
||||
decisionId: decisionIds[0]!,
|
||||
ordinal: 0,
|
||||
steps: Array.from({ length: 128 }, (_, sequence) => ({ ...step, sequence })),
|
||||
steps: Array.from({ length: 128 }, (_, sequence) => sequence === 127
|
||||
? { ...step, sequence, kind: 'DECISION_START', reservedAction: '휴식', effectivePolicy: {"schemaVersion":1,"general":{"priority":["징병"],"flags":{"징병":true,"출병":false}},"nation":{"priority":["천도"],"flags":{"천도":true},"values":{"reqNationGold":4321,"reqNationRice":100,"reqHumanWarUrgentGold":100,"reqHumanWarUrgentRice":100,"reqHumanWarRecommandGold":100,"reqHumanWarRecommandRice":100,"reqHumanDevelGold":100,"reqHumanDevelRice":100,"reqNpcWarGold":100,"reqNpcWarRice":100,"reqNpcDevelGold":100,"reqNpcDevelRice":100,"minimumResourceActionAmount":100,"maximumResourceActionAmount":100,"minNpcWarLeadership":100,"minWarCrew":100,"minNpcRecruitCityPopulation":100,"safeRecruitCityPopulationRatio":100,"properWarTrainAtmos":100,"cureThreshold":100},"combatForce":{"1":[2,3]},"supportForce":[4],"developForce":[5],"secret":"decision-secret"},"secret":"decision-secret"} }
|
||||
: ({ ...step, sequence })),
|
||||
},
|
||||
{
|
||||
decisionId: decisionIds[0]!,
|
||||
@@ -2398,6 +2400,8 @@ integration('game API security over HTTP transport', () => {
|
||||
},
|
||||
});
|
||||
expect(JSON.stringify(decisionPage.body)).not.toContain('decision-secret');
|
||||
expect(JSON.stringify(decisionPage.body)).toContain('effectivePolicy');
|
||||
expect(JSON.stringify(decisionPage.body)).toContain('4321');
|
||||
expect((await get('decisionDetail', admin, { ...decisionDetailInput, cursor: 0 })).body).toMatchObject({
|
||||
result: {
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user