diff --git a/app/game-api/src/router/general/index.ts b/app/game-api/src/router/general/index.ts index b2bc5971..8d3cc216 100644 --- a/app/game-api/src/router/general/index.ts +++ b/app/game-api/src/router/general/index.ts @@ -6,7 +6,6 @@ import { asRecord } from '@sammo-ts/common'; import type { GameApiContext } from '../../context.js'; import { - accessAuthedProcedure, accessEngineAuthedProcedure, accessEngineAuthedInputProcedure, accessLimitAuthedProcedure, @@ -790,7 +789,10 @@ export const generalRouter = router({ history: trimRecentRecords(history, input.lastWorldHistoryId), }; }), - getFrontStatus: accessAuthedProcedure.query(async ({ ctx }) => { + // 메인 화면은 SSE invalidation, 탭 복귀와 직접 갱신이 같은 read model을 + // 호출한다. 클라이언트가 주장하는 갱신 원인을 신뢰해 구분하지 않고 이 + // projection 전체를 무가점으로 두되, 이미 제한된 사용자의 gate는 유지한다. + getFrontStatus: accessLimitAuthedProcedure.query(async ({ ctx }) => { const me = await getMyGeneral(ctx); const worldState = await ctx.db.worldState.findFirst({ orderBy: { id: 'asc' }, diff --git a/app/game-api/src/services/generalAccess.ts b/app/game-api/src/services/generalAccess.ts index 662e721b..52e2e4d7 100644 --- a/app/game-api/src/services/generalAccess.ts +++ b/app/game-api/src/services/generalAccess.ts @@ -40,7 +40,6 @@ export const generalAccessEndpointWeights = { 'diplomacy.getLetters': 2, 'battle.getGeneralDetail': 1, 'betting.getList': 1, - 'general.getFrontStatus': 1, 'yearbook.getHistory': 1, 'world.getGlobalInfo': 1, 'nation.getBattleCenter': 1, @@ -85,14 +84,11 @@ export const generalAccessLimitEndpoints = new Set([ 'diplomacy.rollbackLetter', 'diplomacy.destroyLetter', 'betting.getList', - 'general.getFrontStatus', 'yearbook.getHistory', 'messages.send', 'turns.getCommandTable', ]); -export const generalAccessLimitBeforeRecordEndpoints = new Set(['general.getFrontStatus']); - export type GeneralAccessState = { generalId: number; refreshScore: number; diff --git a/app/game-api/src/trpc.ts b/app/game-api/src/trpc.ts index 496de08f..9a411680 100644 --- a/app/game-api/src/trpc.ts +++ b/app/game-api/src/trpc.ts @@ -9,7 +9,6 @@ import { IdempotentTurnDaemonTransport } from './daemon/idempotentTransport.js'; import { DuplicateInputEventError, executeInputEvent } from './inputEventBoundary.js'; import { formatGeneralAccessLimitMessage, - generalAccessLimitBeforeRecordEndpoints, generalAccessLimitEndpoints, getGeneralAccessState, recordGeneralAccessWeight, @@ -103,17 +102,8 @@ const generalAccessEndpointMiddleware = t.middleware(async ({ ctx, path, input, return next(); } const endpoint = path as GeneralAccessEndpoint; - if (generalAccessLimitBeforeRecordEndpoints.has(endpoint)) { - const state = await getGeneralAccessState(ctx); - if (state?.level === 2) { - throw new TRPCError({ - code: 'TOO_MANY_REQUESTS', - message: formatGeneralAccessLimitMessage(state), - }); - } - } await recordGeneralAccessWeight(ctx, weight); - if (generalAccessLimitEndpoints.has(endpoint) && !generalAccessLimitBeforeRecordEndpoints.has(endpoint)) { + if (generalAccessLimitEndpoints.has(endpoint)) { const state = await getGeneralAccessState(ctx); if (state?.level === 2) { throw new TRPCError({ diff --git a/app/game-api/test/generalAccessTracking.integration.test.ts b/app/game-api/test/generalAccessTracking.integration.test.ts index 0c138751..1d4e3235 100644 --- a/app/game-api/test/generalAccessTracking.integration.test.ts +++ b/app/game-api/test/generalAccessTracking.integration.test.ts @@ -383,6 +383,10 @@ integration('general access tracking persistence', () => { } as unknown as GameApiContext; const boundaryCaller = endpointBoundaryRouter.createCaller(context); + const dashboardCaller = appRouter.createCaller(context); + await expect(dashboardCaller.general.getFrontStatus()).resolves.toBeDefined(); + await expect(db.generalAccessLog.findUnique({ where: { generalId: endpointGeneralId } })).resolves.toBeNull(); + await expect(boundaryCaller.world.getGeneralDirectory({ accepted: false as true })).rejects.toMatchObject({ code: 'BAD_REQUEST', }); diff --git a/app/game-api/test/generalAccessTracking.test.ts b/app/game-api/test/generalAccessTracking.test.ts index 30439e66..10b818bb 100644 --- a/app/game-api/test/generalAccessTracking.test.ts +++ b/app/game-api/test/generalAccessTracking.test.ts @@ -101,7 +101,6 @@ describe('general access tracking', () => { 'diplomacy.getLetters': 2, 'battle.getGeneralDetail': 1, 'betting.getList': 1, - 'general.getFrontStatus': 1, 'yearbook.getHistory': 1, 'world.getGlobalInfo': 1, 'nation.getBattleCenter': 1, @@ -130,6 +129,7 @@ describe('general access tracking', () => { expect(resolveGeneralAccessEndpointWeight('yearbook.getHistory', {}, 'che')).toBe(1); expect(resolveGeneralAccessEndpointWeight('yearbook.getHistory', { serverID: 'che' }, 'che')).toBe(1); expect(resolveGeneralAccessEndpointWeight('yearbook.getHistory', { serverID: 'hwe' }, 'che')).toBeNull(); + expect(resolveGeneralAccessEndpointWeight('general.getFrontStatus', {}, 'che')).toBeUndefined(); expect(resolveGeneralAccessEndpointWeight('unknown.path', {}, 'che')).toBeUndefined(); });