Files
iistwin/migrations/0087_conv_message_idempotency.sql
Ильяс Султанов 9827b5df33 fix(chat): cross-tab lock реплея офлайн-очереди + идемпотентность мессенджера (conv_messages)
Клиентская часть гонки (вариант B): Web Locks API (navigator.locks) —
кросс-вкладочный мьютекс iistwin-offline-sync-replay на replay-проход в
useOfflineSync: первая вкладка под локом реплеит и удаляет записи, остальные
видят пустую очередь. Fallback для сред без Web Locks — старое поведение
(дубли гасит серверная идемпотентность). Race-тест: без locks → 2 POST,
с locks → 1 POST для одной записи очереди.

Мессенджер (conv_messages) — та же защита, что у task_messages:
- conversation_messages.client_message_id + partial unique (миграция 0087);
- POST /api/messenger/conversations/:id/messages: повтор с тем же
  clientMessageId → существующее сообщение без insert и без SSE/уведомлений,
  гонка insert'ов ловится по 23505;
- useChatController шлёт crypto.randomUUID(), attachment-реплей мессенджера
  тоже использует id записи очереди.
2026-09-29 20:31:59 +03:00

11 lines
706 B
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Идемпотентность сообщений мессенджера (conversation_messages): клиентский ключ.
-- Та же защита, что у task_messages (миграция 0086): multi-tab replay
-- офлайн-очереди, ретраи после сетевых сбоев, двойные клики.
-- Partial unique index: NULL-значения (старые сообщения, боты) не конфликтуют.
ALTER TABLE conversation_messages ADD COLUMN IF NOT EXISTS client_message_id varchar(64);
CREATE UNIQUE INDEX IF NOT EXISTS conv_messages_client_message_id_unique
ON conversation_messages (client_message_id)
WHERE client_message_id IS NOT NULL;