feat: 프로필 플레이 감사 기본 조회 화면 구현

This commit is contained in:
2026-09-16 03:18:56 +00:00
parent 7d5ee1348d
commit 8f3852662e
9 changed files with 1091 additions and 2 deletions
@@ -22,6 +22,38 @@ import {
export const playAuditRouter = router({
nationSeries,
nations: auditProcedure.input(zAuditPage.omit({ nationId: true })).query(({ ctx, input }) =>
readAudit(ctx, async (tx) => {
const world = await readAuditWorld(tx);
const identity = z.object({ id: z.number(), name: z.string(), color: z.string() });
if (input.at) {
const sample = await findAuditMonth(tx, world, input.at);
const rows = sample
? await tx.playAuditNation.findMany({
where: {
sampleId: sample.id,
nationId: input.cursor === undefined ? undefined : { gt: input.cursor },
},
orderBy: { nationId: 'asc' },
take: input.limit + 1,
select: { data: true },
})
: [];
return {
...world,
collected: Boolean(sample),
...pageResult(rows.map((row) => identity.parse(row.data)), input.limit, (row) => row.id),
};
}
const rows = await tx.nation.findMany({
where: { id: input.cursor === undefined ? undefined : { gt: input.cursor } },
orderBy: { id: 'asc' },
take: input.limit + 1,
select: { id: true, name: true, color: true },
});
return { ...world, collected: true, ...pageResult(rows, input.limit, (row) => row.id) };
})
),
capabilities: auditProcedure.query(({ ctx }) => ({
profileName: ctx.profile.name,
read: true,
@@ -2171,6 +2171,12 @@ integration('game API security over HTTP transport', () => {
return { status: response.status, body: (await response.json()) as unknown };
};
try {
await db.nation.createMany({
data: [
{ id: 99121, name: '현재감사국가1', color: '#ffffff' },
{ id: 99122, name: '현재감사국가2', color: '#ffffff' },
],
});
await db.worldState.update({
where: { id: fixtureWorldId },
data: {
@@ -2284,6 +2290,24 @@ integration('game API security over HTTP transport', () => {
})),
});
await db.worldState.update({ where: { id: fixtureWorldId }, data: { currentMonth: 7 } });
expect((await get('nations', admin, { at: { year: 190, month: 1 }, limit: 1 })).body).toMatchObject({
result: { data: { collected: true, items: [{ id: ownerNationId, name: '국가1' }] } },
});
expect((await get('nations', admin, { at: { year: 190, month: 7 } })).body).toMatchObject({
result: { data: { collected: false, items: [] } },
});
expect((await get('nations', admin, { limit: 201 })).status).toBe(400);
expect((await get('nations')).status).toBe(401);
expect((await get('nations', await token(['admin']))).status).toBe(403);
expect((await get('nations', admin, { limit: 1 })).body).toMatchObject({
result: {
data: {
collected: true,
nextCursor: expect.any(Number),
items: [expect.objectContaining({ id: expect.any(Number), name: expect.any(String) })],
},
},
});
const series = await get('nationSeries', admin, {
nationId: ownerNationId,
from: { year: 190, month: 1 },
@@ -2355,6 +2379,7 @@ integration('game API security over HTTP transport', () => {
await expect.poll(async () => (await get('capabilities', admin)).status).toBe(401);
} finally {
await db.playAuditMonth.deleteMany({ where: { serverId: seasonId } });
await db.nation.deleteMany({ where: { id: { in: [99121, 99122] } } });
await db.worldState.update({
where: { id: fixtureWorldId },
data: {