supersam/supabase/migrations/20261002_confirmation_hones...

77 lines
4.8 KiB
PL/PgSQL
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.

-- 20261002_confirmation_honesty.sql
--
-- 1. Закрытие заказа без согласования больше не записывается как «Согласовано».
-- Триггер clear_manual_required_on_action ставил notification_status='confirmed'
-- на любой уход заказа с ручной работы — включая доставку, закрытую в 1С без даты
-- и без ответа клиента. Из-за этого:
-- • в реестре и карточке такие заказы читались как «Согласовано»;
-- • в аналитике стадия «Согласовано» (~42% групп) и блок «Чем подтвердили»
-- показывали эти заказы, причём канал подставлялся как «Ссылка из SMS».
-- Теперь «Согласовано» ставится только когда у заказа есть дата (её поставил логист
-- или выбрал клиент), иначе — новый статус 'closed_without_confirmation' («Без согласования»).
-- 2. Разово переводим уже испорченные строки (только те, где нет ни источника даты,
-- ни даты, ни подтверждённого приглашения — то есть подтверждения не было).
--
-- Применять от supabase_admin (владелец таблицы и функций):
-- docker cp 20261002_confirmation_honesty.sql supabase-db:/tmp/ && \
-- docker exec supabase-db psql -U supabase_admin -d postgres -f /tmp/20261002_confirmation_honesty.sql
--
-- ⚠️ На order_groups висит http-триггер "Delivered" (AFTER UPDATE, n8n-вебхук) — он
-- срабатывает на ЛЮБОЕ обновление. На время backfill он выключается в той же
-- транзакции (ACCESS EXCLUSIVE), чтобы не слать в n8n 128 событий «доставлено»
-- по заказам, которые на самом деле не менялись.
begin;
-- ── 1. Разрешаем новый статус ───────────────────────────────────────────────
alter table public.order_groups drop constraint if exists order_groups_notification_status_check;
alter table public.order_groups add constraint order_groups_notification_status_check
check (notification_status = any (array[
'link_ready', 'sms_sending', 'first_sms_sent', 'second_sms_sending', 'second_sms_sent',
'send_failed', 'manual_required', 'paid_storage_sending', 'paid_storage_sent',
'draft', 'not_started', 'confirmed', 'address_required', 'completed',
'closed_without_confirmation'
]::text[]));
-- ── 2. Триггер больше не подменяет «закрыт» на «согласовано» ────────────────
create or replace function public.clear_manual_required_on_action()
returns trigger
language plpgsql
security definer
set search_path = public
as $$
begin
if old.delivery_status in ('pending_confirmation', 'manual_confirmation_required')
and new.delivery_status not in ('pending_confirmation', 'manual_confirmation_required')
and old.notification_status = 'manual_required' then
-- Дата есть → согласование действительно было (логист проставил дату или клиент выбрал слот).
-- Даты нет → заказ закрыли без согласования: «Согласовано» писать нельзя.
if coalesce(new.delivery_date, new.pickup_date) is not null then
new.notification_status := 'confirmed';
else
new.notification_status := 'closed_without_confirmation';
end if;
end if;
return new;
end;
$$;
-- ── 3. Backfill: строки, где «Согласовано» не подтверждено ничем ────────────
alter table public.order_groups disable trigger "Delivered";
update public.order_groups og
set notification_status = 'closed_without_confirmation'
where og.notification_status = 'confirmed'
and og.delivery_date_source is null
and og.delivery_date is null
and og.pickup_date is null
and og.delivery_status not in ('pending_confirmation', 'manual_confirmation_required');
alter table public.order_groups enable trigger "Delivered";
commit;
-- Контроль после применения:
-- select notification_status, count(*) from order_groups group by 1 order by 2 desc;
-- select count(*) from order_groups where notification_status='closed_without_confirmation'; -- ожидали 128