fix: 토너먼트 단계의 메인 실시간 갱신을 연결
토너먼트 state의 stage 전이만 공용 실시간 채널에 발행하고 공개 invalidation으로 변환한다. 메인 dashboard store가 단계 값을 소유해 상단 문구와 메뉴 강조를 단일/다중 탭에서 함께 갱신한다. Redis 통합 테스트와 production Chromium 회귀 검증을 추가한다.
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
import type { GamePrisma, GamePrismaClient } from '@sammo-ts/infra';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
import { writeTournamentProjection, type TurnDaemonCommand, type TurnDaemonCommandResult } from '@sammo-ts/common';
|
||||
import {
|
||||
buildGameEventChannel,
|
||||
writeTournamentProjection,
|
||||
type TurnDaemonCommand,
|
||||
type TurnDaemonCommandResult,
|
||||
} from '@sammo-ts/common';
|
||||
|
||||
import type { GatewayAdminActionRecord, GatewayAdminActionResult } from './gatewayAdminActions.js';
|
||||
|
||||
@@ -74,8 +79,10 @@ const shiftTournamentClock = async (
|
||||
): Promise<boolean> => {
|
||||
const stateKey = `sammo:${profileName}:tournament:state`;
|
||||
const sourceKeys = {
|
||||
stateKey,
|
||||
sourceRevisionKey: `sammo:${profileName}:tournament:source-revision`,
|
||||
sourceRevisionChannel: `sammo:${profileName}:tournament:source-changed`,
|
||||
realtimeEventChannel: buildGameEventChannel(profileName),
|
||||
};
|
||||
const lockKey = `${stateKey}:mutation-lock`;
|
||||
const token = randomUUID();
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { asRecord, LiteHashDRBG, RandUtil, writeTournamentProjection } from '@sammo-ts/common';
|
||||
import {
|
||||
asRecord,
|
||||
buildGameEventChannel,
|
||||
LiteHashDRBG,
|
||||
RandUtil,
|
||||
writeTournamentProjection,
|
||||
} from '@sammo-ts/common';
|
||||
import type { RedisConnector } from '@sammo-ts/infra';
|
||||
import { LogCategory, LogFormat, LogScope } from '@sammo-ts/logic';
|
||||
import { simpleSerialize } from '@sammo-ts/logic/war/utils.js';
|
||||
@@ -69,12 +75,13 @@ export const createTournamentAutoStartHandler = (options: {
|
||||
now?: () => Date;
|
||||
}): TurnCalendarHandler => {
|
||||
const keys = {
|
||||
state: `sammo:${options.profileName}:tournament:state`,
|
||||
stateKey: `sammo:${options.profileName}:tournament:state`,
|
||||
participants: `sammo:${options.profileName}:tournament:participants`,
|
||||
matches: `sammo:${options.profileName}:tournament:matches`,
|
||||
betting: `sammo:${options.profileName}:tournament:betting`,
|
||||
sourceRevisionKey: `sammo:${options.profileName}:tournament:source-revision`,
|
||||
sourceRevisionChannel: `sammo:${options.profileName}:tournament:source-changed`,
|
||||
realtimeEventChannel: buildGameEventChannel(options.profileName),
|
||||
};
|
||||
return {
|
||||
onMonthChanged: async (context) => {
|
||||
@@ -85,7 +92,7 @@ export const createTournamentAutoStartHandler = (options: {
|
||||
if (!world || !redis || config.tournamentTrig !== true) {
|
||||
return;
|
||||
}
|
||||
const previousState = safeJsonParse<TournamentState>(await redis.get(keys.state));
|
||||
const previousState = safeJsonParse<TournamentState>(await redis.get(keys.stateKey));
|
||||
if (previousState && previousState.stage > 0) {
|
||||
return;
|
||||
}
|
||||
@@ -145,7 +152,7 @@ export const createTournamentAutoStartHandler = (options: {
|
||||
{ key: keys.participants, value: [] },
|
||||
{ key: keys.matches, value: [] },
|
||||
{ key: keys.betting, value: [] },
|
||||
{ key: keys.state, value: nextState },
|
||||
{ key: keys.stateKey, value: nextState },
|
||||
]);
|
||||
|
||||
const [typeText, generalTypeText] = TOURNAMENT_TEXT[type] ?? TOURNAMENT_TEXT[0];
|
||||
|
||||
Reference in New Issue
Block a user