feat: 직접 writer를 내구성 변화 저널에 연결

86개 API mutation을 분류하고 메시지 mailbox, 베팅, 국가 설정, 예약 명령의 revision/outbox 표식을 소유 transaction에 연결한다. 공개 SSE는 식별자 없는 invalidation만 노출한다.
This commit is contained in:
2026-08-16 18:38:08 +00:00
parent e4ac2a60b1
commit dd4645e4d0
22 changed files with 485 additions and 55 deletions
@@ -8,6 +8,13 @@ import { createEmptyRealtimeReadModelChanges, type RealtimeReadModelChanges } fr
const uniqueSortedIds = (values: Iterable<number>): number[] =>
[...new Set(values)].sort((left, right) => left - right);
export const readModelOutboxPayloadToMessageMailboxes = (
payload: ReadModelOutboxPayloadV1
): readonly number[] =>
uniqueSortedIds(
payload.changes.flatMap(([domain, entityId]) => (domain === 'messages.mailbox' ? [entityId] : []))
);
export const parseReadModelOutboxPayload = (value: unknown): ReadModelOutboxPayloadV1 | null => {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
return null;
@@ -73,6 +80,8 @@ export const readModelOutboxPayloadToChanges = (
case 'nation.content':
nationIds.push(entityId);
break;
case 'dashboard.global':
break;
case 'world.content':
changes.worldChanged = true;
break;
@@ -113,6 +122,7 @@ export const readModelOutboxPayloadToChanges = (
reservedGeneralIds.push(entityId);
break;
case 'access.general':
case 'messages.mailbox':
case 'tournament':
case 'betting':
// These domains have no browser-wide dashboard invalidation.