mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-18 14:59:01 +03:00
Триггерные функции enforce_tenant_fk/_user/_pair исполнялись как SECURITY INVOKER, поэтому их внутренний SELECT родительской строки подчинялся RLS. На кросс-тенантном пути без выставленного custocrm.organization_id (claim_next_outbox_event берёт событие любой организации) родитель не был виден, parent_org = NULL, и сравнение IS DISTINCT FROM ложно срабатывало: легитимный UPDATE падал с `cross-tenant relation on events_outboxevent.membership_id`. На проде это увело воркер в краш-петлю (1022 рестарта, ~18 часов простоя): первое же outbox-событие с membership_id заклинило очередь, а вместе с ней доставку приглашений на звонок в TG/MAX, поллинг входящих сообщений и серверные таймауты звонков. Веб-канал не пострадал — там приглашение проставляется синхронно, минуя outbox. Проверка не ослабляется: функции исполняются от custocrm_schema, настоящее нарушение по-прежнему приводит к RAISE. search_path закреплён, как того требует безопасность SECURITY DEFINER. Дополнительно claim_next_outbox_event обёрнут в try/except, чтобы отравленное событие впредь не роняло процесс целиком. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>