fix(logs): restore legacy history and cursor limits
This commit is contained in:
@@ -414,10 +414,10 @@ export const generalRouter = router({
|
||||
generalId: me.id,
|
||||
scope: LogScope.GENERAL,
|
||||
category: categoryMap[input.type],
|
||||
...(input.beforeId ? { id: { lt: input.beforeId } } : {}),
|
||||
...(input.type !== 'generalHistory' && input.beforeId ? { id: { lt: input.beforeId } } : {}),
|
||||
},
|
||||
orderBy: { id: 'desc' },
|
||||
take: 24,
|
||||
...(input.type === 'generalHistory' ? {} : { take: 24 }),
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -12,6 +12,7 @@ export const getGeneralLog = authedProcedure
|
||||
z.object({
|
||||
generalId: z.number().int().positive(),
|
||||
type: zGeneralLogType,
|
||||
beforeId: z.number().int().positive().optional(),
|
||||
})
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
@@ -43,12 +44,7 @@ export const getGeneralLog = authedProcedure
|
||||
if (target.nationId !== me.nationId) {
|
||||
throw new TRPCError({ code: 'FORBIDDEN', message: '같은 나라의 장수가 아닙니다.' });
|
||||
}
|
||||
if (
|
||||
input.type === 'generalAction' &&
|
||||
target.npcState < 2 &&
|
||||
target.id !== me.id &&
|
||||
permissionLevel < 2
|
||||
) {
|
||||
if (input.type === 'generalAction' && target.npcState < 2 && target.id !== me.id && permissionLevel < 2) {
|
||||
throw new TRPCError({
|
||||
code: 'FORBIDDEN',
|
||||
message: '권한이 부족합니다. 유저 장수의 개인 기록은 수뇌만 열람 가능합니다.',
|
||||
@@ -67,9 +63,10 @@ export const getGeneralLog = authedProcedure
|
||||
generalId: target.id,
|
||||
scope: LogScope.GENERAL,
|
||||
category: categoryMap[input.type],
|
||||
...(input.type !== 'generalHistory' && input.beforeId ? { id: { lt: input.beforeId } } : {}),
|
||||
},
|
||||
orderBy: { id: 'desc' },
|
||||
take: 30,
|
||||
...(input.type === 'generalHistory' ? {} : { take: 30 }),
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -79,6 +79,7 @@ const createContext = (options: {
|
||||
nationMeta?: Record<string, unknown>;
|
||||
requestCommand?: ReturnType<typeof vi.fn>;
|
||||
accessToken?: string;
|
||||
logs?: Array<{ id: number; text: string }>;
|
||||
}) => {
|
||||
const me = options.me === undefined ? buildGeneral() : options.me;
|
||||
const targets = options.targets ?? (me ? [me] : []);
|
||||
@@ -118,7 +119,12 @@ const createContext = (options: {
|
||||
},
|
||||
logEntry: {
|
||||
groupBy: vi.fn(async () => []),
|
||||
findMany: vi.fn(async () => [{ id: 1, text: '기록' }]),
|
||||
findMany: vi.fn(async (query?: { where?: { id?: { lt?: number } }; take?: number }) => {
|
||||
const source = options.logs ?? [{ id: 1, text: '기록' }];
|
||||
const beforeId = query?.where?.id?.lt;
|
||||
const filtered = beforeId ? source.filter((entry) => entry.id < beforeId) : source;
|
||||
return query?.take ? filtered.slice(0, query.take) : filtered;
|
||||
}),
|
||||
},
|
||||
};
|
||||
const redisClient = { get: async () => null, set: async () => null };
|
||||
@@ -192,6 +198,19 @@ describe('in-game my information ownership', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the complete personal history while preserving bounded action pages', async () => {
|
||||
const logs = Array.from({ length: 61 }, (_, index) => ({ id: 61 - index, text: `기록-${61 - index}` }));
|
||||
const fixture = createContext({ logs });
|
||||
const caller = appRouter.createCaller(fixture.context);
|
||||
|
||||
await expect(caller.general.getMyLog({ type: 'generalHistory' })).resolves.toMatchObject({
|
||||
logs,
|
||||
});
|
||||
await expect(caller.general.getMyLog({ type: 'generalAction' })).resolves.toMatchObject({
|
||||
logs: logs.slice(0, 24),
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the three legacy front-page record streams for the session-owned general', async () => {
|
||||
const fixture = createContext({});
|
||||
const caller = appRouter.createCaller(fixture.context);
|
||||
@@ -436,4 +455,26 @@ describe('battle-center general and user permissions', () => {
|
||||
.nation.getGeneralLog({ generalId: otherUser.id, type: 'generalAction' })
|
||||
).resolves.toMatchObject({ generalId: otherUser.id });
|
||||
});
|
||||
|
||||
it('returns all nation history and paginates action logs in legacy 30-row pages', async () => {
|
||||
const logs = Array.from({ length: 61 }, (_, index) => ({ id: 61 - index, text: `기록-${61 - index}` }));
|
||||
const fixture = createContext({
|
||||
me: buildGeneral({ officerLevel: 5 }),
|
||||
logs,
|
||||
});
|
||||
const caller = appRouter.createCaller(fixture.context);
|
||||
|
||||
await expect(caller.nation.getGeneralLog({ generalId: 7, type: 'generalHistory' })).resolves.toMatchObject({
|
||||
logs,
|
||||
});
|
||||
await expect(caller.nation.getGeneralLog({ generalId: 7, type: 'generalAction' })).resolves.toMatchObject({
|
||||
logs: logs.slice(0, 30),
|
||||
});
|
||||
await expect(
|
||||
caller.nation.getGeneralLog({ generalId: 7, type: 'generalAction', beforeId: 32 })
|
||||
).resolves.toMatchObject({ logs: logs.slice(30, 60) });
|
||||
await expect(
|
||||
caller.nation.getGeneralLog({ generalId: 7, type: 'generalAction', beforeId: 2 })
|
||||
).resolves.toMatchObject({ logs: logs.slice(60) });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user