feat: 플레이 감사 최종 국가 표본 별도 조회 구현

This commit is contained in:
2026-09-16 03:30:05 +00:00
parent b12a899526
commit e1a05e27e7
6 changed files with 254 additions and 5 deletions
+26 -2
View File
@@ -1,4 +1,4 @@
import { nationSeries } from './nationSeries.js';
import { nationSeries, zAuditNation } from './nationSeries.js';
import { z } from 'zod';
import { canReadPlayAuditAccounts } from '@sammo-ts/common';
import { router } from '../../trpc.js';
@@ -22,6 +22,26 @@ import {
export const playAuditRouter = router({
nationSeries,
nationSnapshot: auditProcedure
.input(z.object({ nationId: z.number().int().nonnegative(), at: zAuditMonth }).strict())
.query(({ ctx, input }) =>
readAudit(ctx, async (tx) => {
const world = await readAuditWorld(tx);
const sample = await findAuditMonth(tx, world, input.at);
const row = sample
? await tx.playAuditNation.findUnique({
where: { sampleId_nationId: { sampleId: sample.id, nationId: input.nationId } },
select: { data: true },
})
: null;
return {
...world,
sample,
collected: Boolean(sample),
nation: row ? zAuditNation.parse(row.data) : null,
};
})
),
nations: auditProcedure.input(zAuditPage.omit({ nationId: true })).query(({ ctx, input }) =>
readAudit(ctx, async (tx) => {
const world = await readAuditWorld(tx);
@@ -42,7 +62,11 @@ export const playAuditRouter = router({
return {
...world,
collected: Boolean(sample),
...pageResult(rows.map((row) => identity.parse(row.data)), input.limit, (row) => row.id),
...pageResult(
rows.map((row) => identity.parse(row.data)),
input.limit,
(row) => row.id
),
};
}
const rows = await tx.nation.findMany({
@@ -1,4 +1,5 @@
import { projectCurrentGeneral } from '../src/router/playAudit/projection.js';
import { asRecord } from '@sammo-ts/common';
import fs from 'node:fs/promises';
import { createServer, type Server as HttpServer } from 'node:http';
import os from 'node:os';
@@ -2290,6 +2291,72 @@ integration('game API security over HTTP transport', () => {
})),
});
await db.worldState.update({ where: { id: fixtureWorldId }, data: { currentMonth: 7 } });
const finalNation = await db.playAuditNation.findUniqueOrThrow({
where: { sampleId_nationId: { sampleId: `${seasonId}:190:6`, nationId: ownerNationId } },
});
await db.playAuditMonth.create({
data: {
id: `${seasonId}:final`,
serverId: seasonId,
year: 190,
month: 6,
kind: 'FINAL',
settlementsComplete: true,
hash: 'http-final-fixture',
nations: {
create: {
nationId: ownerNationId,
data: {
...asRecord(finalNation.data),
gold: 999,
incomeGold: 999,
hiddenSecret: 'must-not-expose',
},
},
},
},
});
expect(
(
await get('nationSnapshot', admin, {
nationId: ownerNationId,
at: { year: 190, month: 6, kind: 'FINAL' },
})
).body
).toMatchObject({
result: {
data: { collected: true, sample: { kind: 'FINAL' }, nation: { gold: 999, incomeGold: 999 } },
},
});
expect(
JSON.stringify(
(
await get('nationSnapshot', admin, {
nationId: ownerNationId,
at: { year: 190, month: 6, kind: 'FINAL' },
})
).body
)
).not.toContain('must-not-expose');
expect(
(
await get('nationSnapshot', admin, {
nationId: ownerNationId,
at: { year: 190, month: 7, kind: 'FINAL' },
})
).body
).toMatchObject({ result: { data: { collected: false, nation: null } } });
expect(
(await get('nationSnapshot', admin, { nationId: 0, at: { year: 190, month: 6, kind: 'FINAL' } })).body
).toMatchObject({ result: { data: { collected: true, nation: null } } });
expect(
(
await get('nationSnapshot', await token(['admin']), {
nationId: ownerNationId,
at: { year: 190, month: 6, kind: 'FINAL' },
})
).status
).toBe(403);
expect((await get('nations', admin, { at: { year: 190, month: 1 }, limit: 1 })).body).toMatchObject({
result: { data: { collected: true, items: [{ id: ownerNationId, name: '국가1' }] } },
});