refactor(game): invalidate field-level read-model projections

This commit is contained in:
2026-08-09 16:25:52 +00:00
parent 791006de26
commit e81b2da282
10 changed files with 728 additions and 37 deletions
+54 -1
View File
@@ -601,6 +601,15 @@ test('realtime read-model events skip clock-only work, merge bursts, patch in pl
generalIds: [7],
cityIds: [],
nationIds: [],
mapGeneralIds: [],
mapCityIds: [],
mapNationIds: [],
frontStatusGeneralIds: [],
frontStatusNationIds: [],
frontStatusActorIds: [],
frontStatusChanged: false,
lobbyGeneralIds: [],
lobbyChanged: false,
reservedGeneralIds: [],
recordGeneralIds: [],
worldChanged: false,
@@ -620,11 +629,12 @@ test('realtime read-model events skip clock-only work, merge bursts, patch in pl
await expect(page.locator('.general-title')).toContainText('부드럽게갱신된장수');
const changedOperations = state.operations.slice(operationsBeforeChangedBurst);
expect(changedOperations).toEqual(
expect.arrayContaining(['general.me', 'world.getMap', 'turns.getCommandTable', 'board.getAccess'])
expect.arrayContaining(['general.me', 'turns.getCommandTable', 'board.getAccess'])
);
expect(changedOperations).not.toEqual(
expect.arrayContaining([
'lobby.info',
'world.getMap',
'messages.getRecent',
'messages.getContacts',
'general.getRecentRecords',
@@ -633,6 +643,40 @@ test('realtime read-model events skip clock-only work, merge bursts, patch in pl
])
);
const operationsBeforeSurvey = state.operations.length;
await page.evaluate(() => {
(window as unknown as { __emitMainRealtime: (type: string, payload: unknown) => void }).__emitMainRealtime(
'readModelChanged',
{
at: new Date().toISOString(),
revision: 42,
changes: {
generalIds: [],
cityIds: [],
nationIds: [],
mapGeneralIds: [],
mapCityIds: [],
mapNationIds: [],
frontStatusGeneralIds: [],
frontStatusNationIds: [],
frontStatusActorIds: [],
frontStatusChanged: true,
lobbyGeneralIds: [],
lobbyChanged: false,
reservedGeneralIds: [],
recordGeneralIds: [],
worldChanged: false,
globalRecordsChanged: false,
worldHistoryChanged: false,
contactsChanged: false,
},
}
);
});
await expect.poll(() => state.operations.slice(operationsBeforeSurvey), { timeout: 3_000 }).toEqual([
'general.getFrontStatus',
]);
const profile = await page.evaluate(() => {
const probe = (
window as unknown as {
@@ -697,6 +741,15 @@ test('realtime read-model events skip clock-only work, merge bursts, patch in pl
generalIds: [7],
cityIds: [],
nationIds: [],
mapGeneralIds: [],
mapCityIds: [],
mapNationIds: [],
frontStatusGeneralIds: [],
frontStatusNationIds: [],
frontStatusActorIds: [],
frontStatusChanged: false,
lobbyGeneralIds: [],
lobbyChanged: false,
reservedGeneralIds: [],
recordGeneralIds: [],
worldChanged: false,