85 lines
4.0 KiB
PL/PgSQL
85 lines
4.0 KiB
PL/PgSQL
-- ============================================================
|
||
-- SuperSam: Автодозвон — исключения номеров/префиксов (Фаза 8)
|
||
-- 08.09.2026. Аддитивная, безопасна для прод-базы.
|
||
-- Применять: docker exec supabase-db psql -U supabase_admin -d postgres -f <file>
|
||
-- ============================================================
|
||
|
||
-- 1) Таблица исключений
|
||
create table if not exists public.autocall_exclusions (
|
||
id bigint generated always as identity primary key,
|
||
rule_type text not null check (rule_type in ('prefix','phone')),
|
||
value text not null, -- '7918' или '79189521296'
|
||
reason text not null default '', -- 'МТС — кнопки не проходят'
|
||
active boolean not null default true,
|
||
created_by text, -- email логиста/админа, кто добавил
|
||
created_at timestamptz not null default now(),
|
||
unique (rule_type, value)
|
||
);
|
||
create index if not exists idx_autocall_excl_active on public.autocall_exclusions(active) where active;
|
||
comment on table public.autocall_exclusions is 'Исключения автодозвона: префиксы/номера, на которые робот не звонит';
|
||
|
||
grant select on public.autocall_exclusions to authenticated;
|
||
-- запись только для админов/логистов через RLS (включаем RLS)
|
||
alter table public.autocall_exclusions enable row level security;
|
||
|
||
-- политики: читать все залогиненные; писать только admin/mega_admin/logistician
|
||
do $$
|
||
begin
|
||
if not exists (select 1 from pg_policies where tablename='autocall_exclusions' and policyname='autocall_excl_select') then
|
||
create policy autocall_excl_select on public.autocall_exclusions
|
||
for select to authenticated using (true);
|
||
end if;
|
||
if not exists (select 1 from pg_policies where tablename='autocall_exclusions' and policyname='autocall_excl_write') then
|
||
create policy autocall_excl_write on public.autocall_exclusions
|
||
for all to authenticated
|
||
using (
|
||
exists (
|
||
select 1 from public.users u
|
||
where u.id = auth.uid()
|
||
and u.role in ('mega_admin','admin','logistician')
|
||
)
|
||
)
|
||
with check (
|
||
exists (
|
||
select 1 from public.users u
|
||
where u.id = auth.uid()
|
||
and u.role in ('mega_admin','admin','logistician')
|
||
)
|
||
);
|
||
end if;
|
||
end $$;
|
||
|
||
-- 2) RPC: проверка номера по исключениям (нормализуем телефон до 11 цифр без +7/8)
|
||
create or replace function public.autocall_exclusion_match(p_phone text)
|
||
returns table(rule_type text, value text, reason text)
|
||
language sql stable security definer
|
||
set search_path = public
|
||
as $$
|
||
with norm as (
|
||
select case
|
||
when length(regexp_replace(coalesce(p_phone,''), '\D', '', 'g')) = 11
|
||
then regexp_replace(coalesce(p_phone,''), '\D', '', 'g')
|
||
when length(regexp_replace(coalesce(p_phone,''), '\D', '', 'g')) = 10
|
||
then '7' || regexp_replace(coalesce(p_phone,''), '\D', '', 'g')
|
||
else regexp_replace(coalesce(p_phone,''), '\D', '', 'g')
|
||
end as phone
|
||
)
|
||
select e.rule_type, e.value, e.reason
|
||
from public.autocall_exclusions e, norm n
|
||
where e.active
|
||
and (
|
||
(e.rule_type = 'phone' and n.phone = e.value)
|
||
or
|
||
(e.rule_type = 'prefix' and n.phone like e.value || '%')
|
||
)
|
||
limit 1;
|
||
$$;
|
||
|
||
grant execute on function public.autocall_exclusion_match(text) to authenticated;
|
||
grant execute on function public.autocall_exclusion_match(text) to service_role;
|
||
|
||
-- 3) Стартовое правило — МТС диапазон, который мы точно знаем (неактивно по умолчанию? ставим активным — пользователь просил)
|
||
insert into public.autocall_exclusions (rule_type, value, reason, active, created_by)
|
||
values ('prefix', '7918952', 'МТС — DTMF не проходит (Miranda)', true, 'system')
|
||
on conflict do nothing;
|