fix: Ref 게임 로직과 시나리오 풀 호환을 보정
월 경계, 전투 기술 상한, 연감과 베팅·설문·경매 정산 순서를 Ref 계약에 맞춘다.\n\n시나리오 일반 풀을 ENGINE mutation과 logical tick 기반으로 직렬화하고 914·915 catalog 및 조건부 100기 pool 실행 경계를 추가한다.\n\n경매 worker는 세대별 durable event만 만들고 ENGINE이 row lock 후 상태 전이와 정산을 단일 transaction으로 소유한다.
This commit is contained in:
@@ -97,6 +97,9 @@ const buildContext = (
|
||||
hasGeneral?: boolean;
|
||||
worldMeta?: unknown;
|
||||
liveLogs?: { history: string[]; action: string[] };
|
||||
liveNations?: Array<Record<string, unknown>>;
|
||||
liveCities?: Array<Record<string, unknown>>;
|
||||
liveGenerals?: Array<Record<string, unknown>>;
|
||||
} = {}
|
||||
): GameApiContext => {
|
||||
const db = {
|
||||
@@ -104,13 +107,13 @@ const buildContext = (
|
||||
general: {
|
||||
findFirst: async ({ where }: { where: { userId: string } }) =>
|
||||
options.hasGeneral === false ? null : { id: where.userId === 'owner-a' ? 1 : 2, userId: where.userId },
|
||||
findMany: async () => [],
|
||||
findMany: async () => options.liveGenerals ?? [],
|
||||
},
|
||||
city: {
|
||||
findMany: async () => [],
|
||||
findMany: async () => options.liveCities ?? [],
|
||||
},
|
||||
nation: {
|
||||
findMany: async () => [],
|
||||
findMany: async () => options.liveNations ?? [],
|
||||
},
|
||||
logEntry: {
|
||||
findMany: async ({ where }: { where: { category: unknown } }) => {
|
||||
@@ -326,4 +329,82 @@ describe('historical yearbook access from dynasty', () => {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('uses stored Ref nation projections, canonical neutral values, and descending power in the live month', async () => {
|
||||
const zeroCityStats = {
|
||||
population: 0,
|
||||
agriculture: 0,
|
||||
commerce: 0,
|
||||
security: 0,
|
||||
defence: 0,
|
||||
wall: 0,
|
||||
populationMax: 1,
|
||||
agricultureMax: 1,
|
||||
commerceMax: 1,
|
||||
securityMax: 1,
|
||||
defenceMax: 1,
|
||||
wallMax: 1,
|
||||
};
|
||||
const caller = appRouter.createCaller(
|
||||
buildContext(authFor('owner-a'), {
|
||||
liveNations: [
|
||||
{
|
||||
id: 0,
|
||||
name: '오염된 재야',
|
||||
color: '#ffffff',
|
||||
level: 9,
|
||||
gold: 0,
|
||||
rice: 0,
|
||||
tech: 0,
|
||||
meta: { power: 90, gennum: 90 },
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
name: '촉',
|
||||
color: '#ff0000',
|
||||
level: 7,
|
||||
gold: 0,
|
||||
rice: 0,
|
||||
tech: 0,
|
||||
meta: { power: 777, gennum: 9 },
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '위',
|
||||
color: '#0000ff',
|
||||
level: 7,
|
||||
gold: 0,
|
||||
rice: 0,
|
||||
tech: 0,
|
||||
meta: { power: 0, gennum: 2 },
|
||||
},
|
||||
],
|
||||
liveCities: [
|
||||
{ id: 0, name: '낙양', nationId: 0, ...zeroCityStats },
|
||||
{ id: 1, name: '성도', nationId: 1, ...zeroCityStats },
|
||||
{ id: 2, name: '허창', nationId: 2, ...zeroCityStats },
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
const result = await caller.yearbook.getHistory({ year: 220, month: 1 });
|
||||
|
||||
expect(result).toMatchObject({
|
||||
notModified: false,
|
||||
data: {
|
||||
nations: [
|
||||
expect.objectContaining({ id: 1, power: 777, generalCount: 9 }),
|
||||
expect.objectContaining({
|
||||
id: 0,
|
||||
name: '재야',
|
||||
color: '#000000',
|
||||
level: 0,
|
||||
power: 1,
|
||||
generalCount: 1,
|
||||
}),
|
||||
expect.objectContaining({ id: 2, power: 0, generalCount: 2 }),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user