Files
agenciapsilmno/DBS/2026-03-11/root/full_dump.sql
2026-03-12 08:58:36 -03:00

10623 lines
394 KiB
PL/PgSQL

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
CREATE EXTENSION IF NOT EXISTS "pg_net" WITH SCHEMA "extensions";
COMMENT ON SCHEMA "public" IS 'standard public schema';
CREATE EXTENSION IF NOT EXISTS "btree_gist" WITH SCHEMA "public";
CREATE EXTENSION IF NOT EXISTS "citext" WITH SCHEMA "public";
CREATE EXTENSION IF NOT EXISTS "pg_graphql" WITH SCHEMA "graphql";
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "pg_trgm" WITH SCHEMA "public";
CREATE EXTENSION IF NOT EXISTS "pgcrypto" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "supabase_vault" WITH SCHEMA "vault";
CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA "extensions";
CREATE TYPE "public"."commitment_log_source" AS ENUM (
'manual',
'auto'
);
ALTER TYPE "public"."commitment_log_source" OWNER TO "supabase_admin";
CREATE TYPE "public"."determined_field_type" AS ENUM (
'text',
'textarea',
'number',
'date',
'select',
'boolean'
);
ALTER TYPE "public"."determined_field_type" OWNER TO "supabase_admin";
CREATE TYPE "public"."recurrence_exception_type" AS ENUM (
'cancel_session',
'reschedule_session',
'patient_missed',
'therapist_canceled',
'holiday_block'
);
ALTER TYPE "public"."recurrence_exception_type" OWNER TO "supabase_admin";
CREATE TYPE "public"."recurrence_type" AS ENUM (
'weekly',
'biweekly',
'monthly',
'yearly',
'custom_weekdays'
);
ALTER TYPE "public"."recurrence_type" OWNER TO "supabase_admin";
CREATE TYPE "public"."status_agenda_serie" AS ENUM (
'ativo',
'pausado',
'cancelado'
);
ALTER TYPE "public"."status_agenda_serie" OWNER TO "supabase_admin";
CREATE TYPE "public"."status_evento_agenda" AS ENUM (
'agendado',
'realizado',
'faltou',
'cancelado',
'remarcar'
);
ALTER TYPE "public"."status_evento_agenda" OWNER TO "supabase_admin";
CREATE TYPE "public"."status_excecao_agenda" AS ENUM (
'pendente',
'ativo',
'arquivado'
);
ALTER TYPE "public"."status_excecao_agenda" OWNER TO "supabase_admin";
CREATE TYPE "public"."tipo_evento_agenda" AS ENUM (
'sessao',
'bloqueio'
);
ALTER TYPE "public"."tipo_evento_agenda" OWNER TO "supabase_admin";
CREATE TYPE "public"."tipo_excecao_agenda" AS ENUM (
'bloqueio',
'horario_extra'
);
ALTER TYPE "public"."tipo_excecao_agenda" OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."__rls_ping"() RETURNS "text"
LANGUAGE "sql" STABLE
AS $$
select 'ok'::text;
$$;
ALTER FUNCTION "public"."__rls_ping"() OWNER TO "supabase_admin";
SET default_tablespace = '';
SET default_table_access_method = "heap";
CREATE TABLE IF NOT EXISTS "public"."subscriptions" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"user_id" "uuid",
"plan_id" "uuid" NOT NULL,
"status" "text" DEFAULT 'active'::"text" NOT NULL,
"current_period_start" timestamp with time zone,
"current_period_end" timestamp with time zone,
"cancel_at_period_end" boolean DEFAULT false NOT NULL,
"provider" "text" DEFAULT 'manual'::"text" NOT NULL,
"provider_customer_id" "text",
"provider_subscription_id" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"tenant_id" "uuid",
"plan_key" "text",
"interval" "text",
"source" "text" DEFAULT 'manual'::"text" NOT NULL,
"started_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"canceled_at" timestamp with time zone,
"activated_at" timestamp with time zone,
"past_due_since" timestamp with time zone,
"suspended_at" timestamp with time zone,
"suspended_reason" "text",
"cancelled_at" timestamp with time zone,
"cancel_reason" "text",
"expired_at" timestamp with time zone,
CONSTRAINT "subscriptions_interval_check" CHECK (("interval" = ANY (ARRAY['month'::"text", 'year'::"text"]))),
CONSTRAINT "subscriptions_owner_xor" CHECK (((("tenant_id" IS NOT NULL) AND ("user_id" IS NULL)) OR (("tenant_id" IS NULL) AND ("user_id" IS NOT NULL)))),
CONSTRAINT "subscriptions_status_check" CHECK (("status" = ANY (ARRAY['pending'::"text", 'active'::"text", 'past_due'::"text", 'suspended'::"text", 'cancelled'::"text", 'expired'::"text"])))
);
ALTER TABLE "public"."subscriptions" OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."activate_subscription_from_intent"("p_intent_id" "uuid") RETURNS "public"."subscriptions"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_intent record;
v_sub public.subscriptions;
v_days int;
v_user_id uuid;
v_plan_id uuid;
v_target text;
begin
-- lê pela VIEW unificada
select * into v_intent
from public.subscription_intents
where id = p_intent_id;
if not found then
raise exception 'Intent não encontrado: %', p_intent_id;
end if;
if v_intent.status <> 'paid' then
raise exception 'Intent precisa estar paid para ativar assinatura';
end if;
-- resolve target e plan_id via plans.key
select p.id, p.target
into v_plan_id, v_target
from public.plans p
where p.key = v_intent.plan_key
limit 1;
if v_plan_id is null then
raise exception 'Plano não encontrado em plans.key = %', v_intent.plan_key;
end if;
v_target := lower(coalesce(v_target, ''));
-- ✅ supervisor adicionado
if v_target not in ('clinic', 'therapist', 'supervisor') then
raise exception 'Target inválido em plans.target: %', v_target;
end if;
-- regra por target
if v_target = 'clinic' then
if v_intent.tenant_id is null then
raise exception 'Intent sem tenant_id';
end if;
else
-- therapist ou supervisor: vinculado ao user
v_user_id := v_intent.user_id;
if v_user_id is null then
v_user_id := v_intent.created_by_user_id;
end if;
end if;
if v_target in ('therapist', 'supervisor') and v_user_id is null then
raise exception 'Não foi possível determinar user_id para assinatura %.', v_target;
end if;
-- cancela assinatura ativa anterior
if v_target = 'clinic' then
update public.subscriptions
set status = 'cancelled',
cancelled_at = now()
where tenant_id = v_intent.tenant_id
and plan_id = v_plan_id
and status = 'active';
else
-- therapist ou supervisor
update public.subscriptions
set status = 'cancelled',
cancelled_at = now()
where user_id = v_user_id
and plan_id = v_plan_id
and status = 'active'
and tenant_id is null;
end if;
-- duração do plano (30 dias para mensal)
v_days := case
when lower(coalesce(v_intent.interval, 'month')) = 'year' then 365
else 30
end;
-- cria nova assinatura
insert into public.subscriptions (
user_id,
plan_id,
status,
started_at,
expires_at,
cancelled_at,
activated_at,
tenant_id,
plan_key,
interval,
source,
created_at,
updated_at
)
values (
case when v_target = 'clinic' then null else v_user_id end,
v_plan_id,
'active',
now(),
now() + make_interval(days => v_days),
null,
now(),
case when v_target = 'clinic' then v_intent.tenant_id else null end,
v_intent.plan_key,
v_intent.interval,
'manual',
now(),
now()
)
returning * into v_sub;
-- grava vínculo intent → subscription
if v_target = 'clinic' then
update public.subscription_intents_tenant
set subscription_id = v_sub.id
where id = p_intent_id;
else
update public.subscription_intents_personal
set subscription_id = v_sub.id
where id = p_intent_id;
end if;
return v_sub;
end;
$$;
ALTER FUNCTION "public"."activate_subscription_from_intent"("p_intent_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."admin_fix_plan_target"("p_plan_key" "text", "p_new_target" "text") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_plan_id uuid;
begin
-- (opcional) restringe targets válidos
if p_new_target not in ('clinic','therapist') then
raise exception 'Target inválido: %', p_new_target using errcode='P0001';
end if;
-- trava o plano
select id into v_plan_id
from public.plans
where key = p_plan_key
for update;
if v_plan_id is null then
raise exception 'Plano não encontrado: %', p_plan_key using errcode='P0001';
end if;
-- segurança: não mexer se existe subscription
if exists (select 1 from public.subscriptions s where s.plan_id = v_plan_id) then
raise exception 'Plano % possui subscriptions. Migração bloqueada.', p_plan_key using errcode='P0001';
end if;
-- liga bypass SOMENTE nesta transação
perform set_config('app.plan_migration_bypass', '1', true);
update public.plans
set target = p_new_target
where id = v_plan_id;
end
$$;
ALTER FUNCTION "public"."admin_fix_plan_target"("p_plan_key" "text", "p_new_target" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."agenda_cfg_sync"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
if new.agenda_view_mode = 'custom' then
new.usar_horario_admin_custom := true;
new.admin_inicio_visualizacao := new.agenda_custom_start;
new.admin_fim_visualizacao := new.agenda_custom_end;
else
new.usar_horario_admin_custom := false;
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."agenda_cfg_sync"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."agendador_dias_disponiveis"("p_slug" "text", "p_ano" integer, "p_mes" integer) RETURNS TABLE("data" "date", "tem_slots" boolean)
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
DECLARE
v_owner_id uuid;
v_antecedencia int;
v_agora timestamptz;
v_data date;
v_data_inicio date;
v_data_fim date;
v_db_dow int;
v_tem_slot boolean;
BEGIN
SELECT c.owner_id, c.antecedencia_minima_horas
INTO v_owner_id, v_antecedencia
FROM public.agendador_configuracoes c
WHERE c.link_slug = p_slug AND c.ativo = true
LIMIT 1;
IF v_owner_id IS NULL THEN RETURN; END IF;
v_agora := now();
v_data_inicio := make_date(p_ano, p_mes, 1);
v_data_fim := (v_data_inicio + interval '1 month' - interval '1 day')::date;
v_data := v_data_inicio;
WHILE v_data <= v_data_fim LOOP
v_db_dow := extract(dow from v_data::timestamp)::int;
SELECT EXISTS (
SELECT 1 FROM public.agenda_online_slots s
WHERE s.owner_id = v_owner_id
AND s.weekday = v_db_dow
AND s.enabled = true
AND (v_data::text || ' ' || s.time::text)::timestamp
AT TIME ZONE 'America/Sao_Paulo'
>= v_agora + (v_antecedencia || ' hours')::interval
) INTO v_tem_slot;
IF v_tem_slot THEN
data := v_data;
tem_slots := true;
RETURN NEXT;
END IF;
v_data := v_data + 1;
END LOOP;
END;
$$;
ALTER FUNCTION "public"."agendador_dias_disponiveis"("p_slug" "text", "p_ano" integer, "p_mes" integer) OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."agendador_gerar_slug"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
DECLARE
v_slug text;
v_exists boolean;
BEGIN
-- só gera se ativou e não tem slug ainda
IF NEW.ativo = true AND (NEW.link_slug IS NULL OR NEW.link_slug = '') THEN
LOOP
v_slug := lower(substring(replace(gen_random_uuid()::text, '-', ''), 1, 8));
SELECT EXISTS (
SELECT 1 FROM public.agendador_configuracoes
WHERE link_slug = v_slug AND owner_id <> NEW.owner_id
) INTO v_exists;
EXIT WHEN NOT v_exists;
END LOOP;
NEW.link_slug := v_slug;
END IF;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."agendador_gerar_slug"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."agendador_slots_disponiveis"("p_slug" "text", "p_data" "date") RETURNS TABLE("hora" time without time zone, "disponivel" boolean)
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
DECLARE
v_owner_id uuid;
v_duracao int;
v_antecedencia int;
v_agora timestamptz;
v_db_dow int;
v_slot time;
v_slot_fim time;
v_slot_ts timestamptz;
v_ocupado boolean;
-- loop de recorrências
v_rule RECORD;
v_rule_start_dow int;
v_first_occ date;
v_day_diff int;
v_ex_type text;
BEGIN
SELECT c.owner_id, c.duracao_sessao_min, c.antecedencia_minima_horas
INTO v_owner_id, v_duracao, v_antecedencia
FROM public.agendador_configuracoes c
WHERE c.link_slug = p_slug AND c.ativo = true
LIMIT 1;
IF v_owner_id IS NULL THEN RETURN; END IF;
v_agora := now();
v_db_dow := extract(dow from p_data::timestamp)::int;
FOR v_slot IN
SELECT s.time
FROM public.agenda_online_slots s
WHERE s.owner_id = v_owner_id
AND s.weekday = v_db_dow
AND s.enabled = true
ORDER BY s.time
LOOP
v_slot_fim := v_slot + (v_duracao || ' minutes')::interval;
v_ocupado := false;
-- ── Antecedência mínima ──────────────────────────────────────────────────
v_slot_ts := (p_data::text || ' ' || v_slot::text)::timestamp
AT TIME ZONE 'America/Sao_Paulo';
IF v_slot_ts < v_agora + (v_antecedencia || ' hours')::interval THEN
v_ocupado := true;
END IF;
-- ── Eventos avulsos internos (agenda_eventos) ────────────────────────────
IF NOT v_ocupado THEN
SELECT EXISTS (
SELECT 1 FROM public.agenda_eventos e
WHERE e.owner_id = v_owner_id
AND e.status::text NOT IN ('cancelado', 'faltou')
AND (e.inicio_em AT TIME ZONE 'America/Sao_Paulo')::date = p_data
AND (e.inicio_em AT TIME ZONE 'America/Sao_Paulo')::time < v_slot_fim
AND (e.fim_em AT TIME ZONE 'America/Sao_Paulo')::time > v_slot
) INTO v_ocupado;
END IF;
-- ── Recorrências ativas (recurrence_rules) ───────────────────────────────
-- Loop explícito para evitar erros de tipo no cálculo do ciclo semanal
IF NOT v_ocupado THEN
FOR v_rule IN
SELECT
r.id,
r.start_date::date AS start_date,
r.end_date::date AS end_date,
r.start_time::time AS start_time,
r.end_time::time AS end_time,
COALESCE(r.interval, 1)::int AS interval
FROM public.recurrence_rules r
WHERE r.owner_id = v_owner_id
AND r.status = 'ativo'
AND p_data >= r.start_date::date
AND (r.end_date IS NULL OR p_data <= r.end_date::date)
AND v_db_dow = ANY(r.weekdays)
AND r.start_time::time < v_slot_fim
AND r.end_time::time > v_slot
LOOP
-- Calcula a primeira ocorrência do dia-da-semana a partir do start_date
v_rule_start_dow := extract(dow from v_rule.start_date)::int;
v_first_occ := v_rule.start_date
+ (((v_db_dow - v_rule_start_dow + 7) % 7))::int;
v_day_diff := (p_data - v_first_occ)::int;
-- Ocorrência válida: diff >= 0 e divisível pelo ciclo semanal
IF v_day_diff >= 0 AND v_day_diff % (7 * v_rule.interval) = 0 THEN
-- Verifica se há exceção para esta data
v_ex_type := NULL;
SELECT ex.type INTO v_ex_type
FROM public.recurrence_exceptions ex
WHERE ex.recurrence_id = v_rule.id
AND ex.original_date = p_data
LIMIT 1;
-- Sem exceção, ou exceção que não cancela → bloqueia o slot
IF v_ex_type IS NULL OR v_ex_type NOT IN (
'cancel_session', 'patient_missed',
'therapist_canceled', 'holiday_block',
'reschedule_session'
) THEN
v_ocupado := true;
EXIT; -- já basta uma regra que conflite
END IF;
END IF;
END LOOP;
END IF;
-- ── Recorrências remarcadas para este dia (reschedule → new_date = p_data) ─
IF NOT v_ocupado THEN
SELECT EXISTS (
SELECT 1
FROM public.recurrence_exceptions ex
JOIN public.recurrence_rules r ON r.id = ex.recurrence_id
WHERE r.owner_id = v_owner_id
AND r.status = 'ativo'
AND ex.type = 'reschedule_session'
AND ex.new_date = p_data
AND COALESCE(ex.new_start_time, r.start_time)::time < v_slot_fim
AND COALESCE(ex.new_end_time, r.end_time)::time > v_slot
) INTO v_ocupado;
END IF;
-- ── Solicitações públicas pendentes ──────────────────────────────────────
IF NOT v_ocupado THEN
SELECT EXISTS (
SELECT 1 FROM public.agendador_solicitacoes sol
WHERE sol.owner_id = v_owner_id
AND sol.status = 'pendente'
AND sol.data_solicitada = p_data
AND sol.hora_solicitada = v_slot
AND (sol.reservado_ate IS NULL OR sol.reservado_ate > v_agora)
) INTO v_ocupado;
END IF;
hora := v_slot;
disponivel := NOT v_ocupado;
RETURN NEXT;
END LOOP;
END;
$$;
ALTER FUNCTION "public"."agendador_slots_disponiveis"("p_slug" "text", "p_data" "date") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."cancel_recurrence_from"("p_recurrence_id" "uuid", "p_from_date" "date") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
BEGIN
UPDATE public.recurrence_rules
SET
end_date = p_from_date - INTERVAL '1 day',
open_ended = false,
status = CASE
WHEN p_from_date <= start_date THEN 'cancelado'
ELSE status
END,
updated_at = now()
WHERE id = p_recurrence_id;
END;
$$;
ALTER FUNCTION "public"."cancel_recurrence_from"("p_recurrence_id" "uuid", "p_from_date" "date") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."cancel_subscription"("p_subscription_id" "uuid") RETURNS "public"."subscriptions"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_sub public.subscriptions;
v_owner_type text;
v_owner_ref uuid;
begin
select *
into v_sub
from public.subscriptions
where id = p_subscription_id
for update;
if not found then
raise exception 'Subscription não encontrada';
end if;
if v_sub.status = 'canceled' then
return v_sub;
end if;
if v_sub.tenant_id is not null then
v_owner_type := 'clinic';
v_owner_ref := v_sub.tenant_id;
elsif v_sub.user_id is not null then
v_owner_type := 'therapist';
v_owner_ref := v_sub.user_id;
else
v_owner_type := null;
v_owner_ref := null;
end if;
update public.subscriptions
set status = 'canceled',
cancel_at_period_end = false,
updated_at = now()
where id = p_subscription_id
returning * into v_sub;
insert into public.subscription_events(
subscription_id,
owner_id,
owner_type,
owner_ref,
event_type,
old_plan_id,
new_plan_id,
created_by,
reason,
source,
metadata
)
values (
v_sub.id,
v_owner_ref,
v_owner_type,
v_owner_ref,
'canceled',
v_sub.plan_id,
v_sub.plan_id,
auth.uid(),
'Cancelamento manual via admin',
'admin_panel',
jsonb_build_object('previous_status', 'active')
);
if v_owner_ref is not null then
insert into public.entitlements_invalidation(owner_id, changed_at)
values (v_owner_ref, now())
on conflict (owner_id)
do update set changed_at = excluded.changed_at;
end if;
return v_sub;
end;
$$;
ALTER FUNCTION "public"."cancel_subscription"("p_subscription_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."cancelar_eventos_serie"("p_serie_id" "uuid", "p_a_partir_de" timestamp with time zone DEFAULT "now"()) RETURNS integer
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
DECLARE
v_count integer;
BEGIN
UPDATE public.agenda_eventos
SET status = 'cancelado',
updated_at = now()
WHERE serie_id = p_serie_id
AND inicio_em >= p_a_partir_de
AND status NOT IN ('realizado', 'cancelado');
GET DIAGNOSTICS v_count = ROW_COUNT;
RETURN v_count;
END;
$$;
ALTER FUNCTION "public"."cancelar_eventos_serie"("p_serie_id" "uuid", "p_a_partir_de" timestamp with time zone) OWNER TO "supabase_admin";
COMMENT ON FUNCTION "public"."cancelar_eventos_serie"("p_serie_id" "uuid", "p_a_partir_de" timestamp with time zone) IS 'Cancela todos os eventos futuros de uma série a partir de p_a_partir_de (inclusive).
Não cancela eventos já realizados.';
CREATE OR REPLACE FUNCTION "public"."change_subscription_plan"("p_subscription_id" "uuid", "p_new_plan_id" "uuid") RETURNS "public"."subscriptions"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_sub public.subscriptions;
v_old_plan uuid;
v_new_key text;
v_owner_type text;
v_owner_ref uuid;
v_new_target text;
v_sub_target text;
begin
select *
into v_sub
from public.subscriptions
where id = p_subscription_id
for update;
if not found then
raise exception 'Subscription não encontrada';
end if;
v_old_plan := v_sub.plan_id;
if v_old_plan = p_new_plan_id then
return v_sub;
end if;
select key, target
into v_new_key, v_new_target
from public.plans
where id = p_new_plan_id;
if v_new_key is null then
raise exception 'Plano não encontrado';
end if;
v_new_target := lower(coalesce(v_new_target, ''));
v_sub_target := case
when v_sub.tenant_id is not null then 'clinic'
else 'therapist'
end;
if v_new_target <> v_sub_target then
raise exception 'Plano inválido para este tipo de assinatura. Assinatura é % e o plano é %.',
v_sub_target, v_new_target
using errcode = 'P0001';
end if;
if v_sub.tenant_id is not null then
v_owner_type := 'clinic';
v_owner_ref := v_sub.tenant_id;
elsif v_sub.user_id is not null then
v_owner_type := 'therapist';
v_owner_ref := v_sub.user_id;
else
v_owner_type := null;
v_owner_ref := null;
end if;
update public.subscriptions
set plan_id = p_new_plan_id,
plan_key = v_new_key,
updated_at = now()
where id = p_subscription_id
returning * into v_sub;
insert into public.subscription_events(
subscription_id,
owner_id,
owner_type,
owner_ref,
event_type,
old_plan_id,
new_plan_id,
created_by,
reason,
source,
metadata
)
values (
v_sub.id,
v_owner_ref,
v_owner_type,
v_owner_ref,
'plan_changed',
v_old_plan,
p_new_plan_id,
auth.uid(),
'Plan change via DEV menu',
'dev_menu',
jsonb_build_object(
'previous_plan', v_old_plan,
'new_plan', p_new_plan_id,
'new_plan_key', v_new_key,
'new_plan_target', v_new_target
)
);
if v_owner_ref is not null then
insert into public.entitlements_invalidation (owner_id, changed_at)
values (v_owner_ref, now())
on conflict (owner_id)
do update set changed_at = excluded.changed_at;
end if;
return v_sub;
end;
$$;
ALTER FUNCTION "public"."change_subscription_plan"("p_subscription_id" "uuid", "p_new_plan_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."create_clinic_tenant"("p_name" "text") RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_uid uuid;
v_tenant uuid;
v_name text;
begin
v_uid := auth.uid();
if v_uid is null then
raise exception 'Not authenticated';
end if;
v_name := nullif(trim(coalesce(p_name, '')), '');
if v_name is null then
v_name := 'Clínica';
end if;
insert into public.tenants (name, kind, created_at)
values (v_name, 'clinic', now())
returning id into v_tenant;
insert into public.tenant_members (tenant_id, user_id, role, status, created_at)
values (v_tenant, v_uid, 'tenant_admin', 'active', now());
return v_tenant;
end;
$$;
ALTER FUNCTION "public"."create_clinic_tenant"("p_name" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."create_patient_intake_request"("p_token" "text", "p_name" "text", "p_email" "text" DEFAULT NULL::"text", "p_phone" "text" DEFAULT NULL::"text", "p_notes" "text" DEFAULT NULL::"text", "p_consent" boolean DEFAULT false) RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
declare
v_owner uuid;
v_active boolean;
v_expires timestamptz;
v_max_uses int;
v_uses int;
v_id uuid;
begin
select owner_id, active, expires_at, max_uses, uses
into v_owner, v_active, v_expires, v_max_uses, v_uses
from public.patient_invites
where token = p_token
limit 1;
if v_owner is null then
raise exception 'Token inválido';
end if;
if v_active is not true then
raise exception 'Link desativado';
end if;
if v_expires is not null and now() > v_expires then
raise exception 'Link expirado';
end if;
if v_max_uses is not null and v_uses >= v_max_uses then
raise exception 'Limite de uso atingido';
end if;
if p_name is null or length(trim(p_name)) = 0 then
raise exception 'Nome é obrigatório';
end if;
insert into public.patient_intake_requests
(owner_id, token, name, email, phone, notes, consent, status)
values
(v_owner, p_token, trim(p_name),
nullif(lower(trim(p_email)), ''),
nullif(trim(p_phone), ''),
nullif(trim(p_notes), ''),
coalesce(p_consent, false),
'new')
returning id into v_id;
update public.patient_invites
set uses = uses + 1
where token = p_token;
return v_id;
end;
$$;
ALTER FUNCTION "public"."create_patient_intake_request"("p_token" "text", "p_name" "text", "p_email" "text", "p_phone" "text", "p_notes" "text", "p_consent" boolean) OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."create_patient_intake_request_v2"("p_token" "text", "p_payload" "jsonb") RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $_$
declare
v_owner_id uuid;
v_intake_id uuid;
v_birth_raw text;
v_birth date;
begin
select owner_id
into v_owner_id
from public.patient_invites
where token = p_token;
if v_owner_id is null then
raise exception 'Token inválido ou expirado';
end if;
v_birth_raw := nullif(trim(coalesce(
p_payload->>'data_nascimento',
''
)), '');
v_birth := case
when v_birth_raw is null then null
when v_birth_raw ~ '^\d{4}-\d{2}-\d{2}$' then v_birth_raw::date
when v_birth_raw ~ '^\d{2}-\d{2}-\d{4}$' then to_date(v_birth_raw, 'DD-MM-YYYY')
else null
end;
insert into public.patient_intake_requests (
owner_id,
token,
status,
consent,
nome_completo,
email_principal,
telefone,
avatar_url, -- 🔥 AQUI
data_nascimento,
cpf,
rg,
genero,
estado_civil,
profissao,
escolaridade,
nacionalidade,
naturalidade,
cep,
pais,
cidade,
estado,
endereco,
numero,
complemento,
bairro,
observacoes,
notas_internas,
encaminhado_por,
onde_nos_conheceu
)
values (
v_owner_id,
p_token,
'new',
coalesce((p_payload->>'consent')::boolean, false),
nullif(trim(p_payload->>'nome_completo'), ''),
nullif(trim(p_payload->>'email_principal'), ''),
nullif(regexp_replace(coalesce(p_payload->>'telefone',''), '\D', '', 'g'), ''),
nullif(trim(p_payload->>'avatar_url'), ''), -- 🔥 AQUI
v_birth,
nullif(regexp_replace(coalesce(p_payload->>'cpf',''), '\D', '', 'g'), ''),
nullif(trim(p_payload->>'rg'), ''),
nullif(trim(p_payload->>'genero'), ''),
nullif(trim(p_payload->>'estado_civil'), ''),
nullif(trim(p_payload->>'profissao'), ''),
nullif(trim(p_payload->>'escolaridade'), ''),
nullif(trim(p_payload->>'nacionalidade'), ''),
nullif(trim(p_payload->>'naturalidade'), ''),
nullif(regexp_replace(coalesce(p_payload->>'cep',''), '\D', '', 'g'), ''),
nullif(trim(p_payload->>'pais'), ''),
nullif(trim(p_payload->>'cidade'), ''),
nullif(trim(p_payload->>'estado'), ''),
nullif(trim(p_payload->>'endereco'), ''),
nullif(trim(p_payload->>'numero'), ''),
nullif(trim(p_payload->>'complemento'), ''),
nullif(trim(p_payload->>'bairro'), ''),
nullif(trim(p_payload->>'observacoes'), ''),
nullif(trim(p_payload->>'notas_internas'), ''),
nullif(trim(p_payload->>'encaminhado_por'), ''),
nullif(trim(p_payload->>'onde_nos_conheceu'), '')
)
returning id into v_intake_id;
return v_intake_id;
end;
$_$;
ALTER FUNCTION "public"."create_patient_intake_request_v2"("p_token" "text", "p_payload" "jsonb") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."current_member_id"("p_tenant_id" "uuid") RETURNS "uuid"
LANGUAGE "sql" STABLE
AS $$
select tm.id
from public.tenant_members tm
where tm.tenant_id = p_tenant_id
and tm.user_id = auth.uid()
limit 1
$$;
ALTER FUNCTION "public"."current_member_id"("p_tenant_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."current_member_role"("p_tenant_id" "uuid") RETURNS "text"
LANGUAGE "sql" STABLE
AS $$
select tm.role
from public.tenant_members tm
where tm.tenant_id = p_tenant_id
and tm.user_id = auth.uid()
limit 1
$$;
ALTER FUNCTION "public"."current_member_role"("p_tenant_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."delete_commitment_full"("p_tenant_id" "uuid", "p_commitment_id" "uuid") RETURNS "jsonb"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
declare
v_is_native boolean;
v_fields int := 0;
v_logs int := 0;
v_parent int := 0;
begin
if auth.uid() is null then
raise exception 'Not authenticated';
end if;
if not exists (
select 1
from public.tenant_members tm
where tm.tenant_id = p_tenant_id
and tm.user_id = auth.uid()
and tm.status = 'active'
) then
raise exception 'Not allowed';
end if;
select dc.is_native
into v_is_native
from public.determined_commitments dc
where dc.tenant_id = p_tenant_id
and dc.id = p_commitment_id;
if v_is_native is null then
raise exception 'Commitment not found';
end if;
if v_is_native = true then
raise exception 'Cannot delete native commitment';
end if;
delete from public.determined_commitment_fields
where tenant_id = p_tenant_id
and commitment_id = p_commitment_id;
get diagnostics v_fields = row_count;
delete from public.commitment_time_logs
where tenant_id = p_tenant_id
and commitment_id = p_commitment_id;
get diagnostics v_logs = row_count;
delete from public.determined_commitments
where tenant_id = p_tenant_id
and id = p_commitment_id;
get diagnostics v_parent = row_count;
if v_parent <> 1 then
raise exception 'Parent not deleted (RLS/owner issue).';
end if;
return jsonb_build_object(
'ok', true,
'deleted', jsonb_build_object(
'fields', v_fields,
'logs', v_logs,
'commitment', v_parent
)
);
end;
$$;
ALTER FUNCTION "public"."delete_commitment_full"("p_tenant_id" "uuid", "p_commitment_id" "uuid") OWNER TO "postgres";
CREATE OR REPLACE FUNCTION "public"."delete_determined_commitment"("p_tenant_id" "uuid", "p_commitment_id" "uuid") RETURNS "jsonb"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
declare
v_is_native boolean;
v_fields_deleted int := 0;
v_logs_deleted int := 0;
v_commitment_deleted int := 0;
begin
if auth.uid() is null then
raise exception 'Not authenticated';
end if;
if not exists (
select 1
from public.tenant_members tm
where tm.tenant_id = p_tenant_id
and tm.user_id = auth.uid()
and tm.status = 'active'
) then
raise exception 'Not allowed';
end if;
select dc.is_native
into v_is_native
from public.determined_commitments dc
where dc.tenant_id = p_tenant_id
and dc.id = p_commitment_id;
if v_is_native is null then
raise exception 'Commitment not found for tenant';
end if;
if v_is_native = true then
raise exception 'Cannot delete native commitment';
end if;
delete from public.determined_commitment_fields f
where f.tenant_id = p_tenant_id
and f.commitment_id = p_commitment_id;
get diagnostics v_fields_deleted = row_count;
delete from public.commitment_time_logs l
where l.tenant_id = p_tenant_id
and l.commitment_id = p_commitment_id;
get diagnostics v_logs_deleted = row_count;
delete from public.determined_commitments dc
where dc.tenant_id = p_tenant_id
and dc.id = p_commitment_id;
get diagnostics v_commitment_deleted = row_count;
if v_commitment_deleted <> 1 then
raise exception 'Delete did not remove the commitment (tenant mismatch?)';
end if;
return jsonb_build_object(
'ok', true,
'tenant_id', p_tenant_id,
'commitment_id', p_commitment_id,
'deleted', jsonb_build_object(
'fields', v_fields_deleted,
'logs', v_logs_deleted,
'commitment', v_commitment_deleted
)
);
end;
$$;
ALTER FUNCTION "public"."delete_determined_commitment"("p_tenant_id" "uuid", "p_commitment_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."dev_list_auth_users"("p_limit" integer DEFAULT 50) RETURNS TABLE("id" "uuid", "email" "text", "created_at" timestamp with time zone)
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public', 'auth'
AS $$
begin
-- só saas_admin pode ver
if not exists (
select 1
from public.profiles p
where p.id = auth.uid()
and p.role = 'saas_admin'
) then
return;
end if;
return query
select
u.id,
u.email,
u.created_at
from auth.users u
order by u.created_at desc
limit greatest(1, least(coalesce(p_limit, 50), 500));
end;
$$;
ALTER FUNCTION "public"."dev_list_auth_users"("p_limit" integer) OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."dev_list_custom_users"() RETURNS TABLE("user_id" "uuid", "email" "text", "created_at" timestamp with time zone, "global_role" "text", "tenant_role" "text", "tenant_id" "uuid", "password_dev" "text", "kind" "text")
LANGUAGE "sql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
with base as (
select
u.id as user_id,
lower(u.email) as email,
u.created_at
from auth.users u
where lower(u.email) not in (
'clinic@agenciapsi.com.br',
'therapist@agenciapsi.com.br',
'patient@agenciapsi.com.br',
'saas@agenciapsi.com.br'
)
),
prof as (
select p.id, p.role as global_role
from public.profiles p
),
last_membership as (
select distinct on (tm.user_id)
tm.user_id,
tm.tenant_id,
tm.role as tenant_role,
tm.created_at
from public.tenant_members tm
where tm.status = 'active'
order by tm.user_id, tm.created_at desc
)
select
b.user_id,
b.email,
b.created_at,
pr.global_role,
lm.tenant_role,
lm.tenant_id,
dc.password_dev,
dc.kind
from base b
left join prof pr on pr.id = b.user_id
left join last_membership lm on lm.user_id = b.user_id
left join public.dev_user_credentials dc on lower(dc.email) = b.email
order by b.created_at desc;
$$;
ALTER FUNCTION "public"."dev_list_custom_users"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."dev_list_intent_leads"() RETURNS TABLE("email" "text", "last_intent_at" timestamp with time zone, "plan_key" "text", "billing_interval" "text", "status" "text", "tenant_id" "uuid")
LANGUAGE "sql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
select
lower(si.email) as email,
max(si.created_at) as last_intent_at,
(array_agg(si.plan_key order by si.created_at desc))[1] as plan_key,
(array_agg(si.interval order by si.created_at desc))[1] as billing_interval,
(array_agg(si.status order by si.created_at desc))[1] as status,
(array_agg(si.tenant_id order by si.created_at desc))[1] as tenant_id
from public.subscription_intents si
where si.email is not null
and not exists (
select 1
from auth.users au
where lower(au.email) = lower(si.email)
)
group by lower(si.email)
order by max(si.created_at) desc;
$$;
ALTER FUNCTION "public"."dev_list_intent_leads"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."dev_public_debug_snapshot"() RETURNS TABLE("users_total" integer, "tenants_total" integer, "intents_new_total" integer, "latest_intents" "jsonb")
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $_$
declare
v_latest jsonb;
begin
select jsonb_agg(
jsonb_build_object(
'created_at', si.created_at,
'email_masked',
regexp_replace(lower(si.email), '(^.).*(@.*$)', '\1***\2'),
'plan_key', si.plan_key,
'status', si.status
)
order by si.created_at desc
)
into v_latest
from (
select si.*
from public.subscription_intents si
where si.email is not null
order by si.created_at desc
limit 5
) si;
return query
select
(select count(*)::int from auth.users) as users_total,
(select count(*)::int from public.tenants) as tenants_total,
(select count(*)::int from public.subscription_intents where status = 'new') as intents_new_total,
coalesce(v_latest, '[]'::jsonb) as latest_intents;
end;
$_$;
ALTER FUNCTION "public"."dev_public_debug_snapshot"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."ensure_personal_tenant"() RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
DECLARE
v_uid uuid;
v_existing uuid;
BEGIN
v_uid := auth.uid();
IF v_uid IS NULL THEN
RAISE EXCEPTION 'Not authenticated';
END IF;
SELECT tm.tenant_id INTO v_existing
FROM public.tenant_members tm
JOIN public.tenants t ON t.id = tm.tenant_id
WHERE tm.user_id = v_uid
AND tm.status = 'active'
AND t.kind IN ('therapist', 'saas')
ORDER BY tm.created_at DESC
LIMIT 1;
IF v_existing IS NOT NULL THEN
RETURN v_existing;
END IF;
RETURN public.provision_account_tenant(v_uid, 'therapist');
END;
$$;
ALTER FUNCTION "public"."ensure_personal_tenant"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."ensure_personal_tenant_for_user"("p_user_id" "uuid") RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_uid uuid;
v_existing uuid;
v_tenant uuid;
v_email text;
v_name text;
begin
v_uid := p_user_id;
if v_uid is null then
raise exception 'Missing user id';
end if;
-- só considera tenant pessoal (kind='saas')
select tm.tenant_id
into v_existing
from public.tenant_members tm
join public.tenants t on t.id = tm.tenant_id
where tm.user_id = v_uid
and tm.status = 'active'
and t.kind = 'saas'
order by tm.created_at desc
limit 1;
if v_existing is not null then
return v_existing;
end if;
select email into v_email
from auth.users
where id = v_uid;
v_name := coalesce(split_part(v_email, '@', 1), 'Conta');
insert into public.tenants (name, kind, created_at)
values (v_name || ' (Pessoal)', 'saas', now())
returning id into v_tenant;
insert into public.tenant_members (tenant_id, user_id, role, status, created_at)
values (v_tenant, v_uid, 'tenant_admin', 'active', now());
return v_tenant;
end;
$$;
ALTER FUNCTION "public"."ensure_personal_tenant_for_user"("p_user_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."faq_votar"("faq_id" "uuid") RETURNS "void"
LANGUAGE "sql" SECURITY DEFINER
AS $$
update public.saas_faq
set votos = votos + 1,
updated_at = now()
where id = faq_id
and ativo = true;
$$;
ALTER FUNCTION "public"."faq_votar"("faq_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."fix_all_subscription_mismatches"() RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
r record;
begin
for r in
select distinct s.user_id as owner_id
from public.subscriptions s
where s.status = 'active'
and s.user_id is not null
loop
perform public.rebuild_owner_entitlements(r.owner_id);
end loop;
end;
$$;
ALTER FUNCTION "public"."fix_all_subscription_mismatches"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."fn_agenda_regras_semanais_no_overlap"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
declare
v_count int;
begin
if new.ativo is false then
return new;
end if;
select count(*) into v_count
from public.agenda_regras_semanais r
where r.owner_id = new.owner_id
and r.dia_semana = new.dia_semana
and r.ativo is true
and (tg_op = 'INSERT' or r.id <> new.id)
and (new.hora_inicio < r.hora_fim and new.hora_fim > r.hora_inicio);
if v_count > 0 then
raise exception 'Janela sobreposta: já existe uma regra ativa nesse intervalo.';
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."fn_agenda_regras_semanais_no_overlap"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."get_my_email"() RETURNS "text"
LANGUAGE "sql" SECURITY DEFINER
SET "search_path" TO 'public', 'auth'
AS $$
select lower(email)
from auth.users
where id = auth.uid();
$$;
ALTER FUNCTION "public"."get_my_email"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."guard_account_type_immutable"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
BEGIN
IF OLD.account_type <> 'free' AND NEW.account_type IS DISTINCT FROM OLD.account_type THEN
RAISE EXCEPTION 'account_type é imutável após escolha (atual: "%" para tentativa: "%"). Para mudar de perfil, crie uma nova conta.', OLD.account_type, NEW.account_type
USING ERRCODE = 'P0001';
END IF;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."guard_account_type_immutable"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."guard_locked_commitment"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
if (old.is_locked = true) then
if (tg_op = 'DELETE') then
raise exception 'Compromisso bloqueado não pode ser excluído.';
end if;
if (tg_op = 'UPDATE') then
if (new.active = false) then
raise exception 'Compromisso bloqueado não pode ser desativado.';
end if;
-- trava renomear (mantém o "Sessão" sempre igual)
if (new.name is distinct from old.name) then
raise exception 'Compromisso bloqueado não pode ser renomeado.';
end if;
-- se quiser travar descrição também, descomente:
-- if (new.description is distinct from old.description) then
-- raise exception 'Compromisso bloqueado não pode alterar descrição.';
-- end if;
end if;
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."guard_locked_commitment"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."guard_no_change_core_plan_key"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
if old.key in ('clinic_free','clinic_pro','therapist_free','therapist_pro')
and new.key is distinct from old.key then
raise exception 'Não é permitido alterar a key do plano padrão (%).', old.key
using errcode = 'P0001';
end if;
return new;
end $$;
ALTER FUNCTION "public"."guard_no_change_core_plan_key"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."guard_no_change_plan_target"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
declare
v_bypass text;
begin
-- bypass controlado por sessão/transação:
-- só passa se app.plan_migration_bypass = '1'
v_bypass := current_setting('app.plan_migration_bypass', true);
if v_bypass = '1' then
return new;
end if;
-- comportamento original (bloqueia qualquer mudança)
if new.target is distinct from old.target then
raise exception 'Não é permitido alterar target do plano (%) de % para %.',
old.key, old.target, new.target
using errcode = 'P0001';
end if;
return new;
end
$$;
ALTER FUNCTION "public"."guard_no_change_plan_target"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."guard_no_delete_core_plans"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
if old.key in ('clinic_free','clinic_pro','therapist_free','therapist_pro') then
raise exception 'Plano padrão (%) não pode ser removido.', old.key
using errcode = 'P0001';
end if;
return old;
end $$;
ALTER FUNCTION "public"."guard_no_delete_core_plans"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."guard_patient_cannot_own_tenant"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
DECLARE
v_account_type text;
BEGIN
SELECT account_type INTO v_account_type
FROM public.profiles
WHERE id = NEW.user_id;
IF v_account_type = 'patient' AND NEW.role IN ('tenant_admin', 'therapist') THEN
RAISE EXCEPTION 'Usuário com perfil "patient" não pode ser proprietário ou terapeuta de um tenant. Se tornou profissional? Crie uma nova conta.'
USING ERRCODE = 'P0001';
END IF;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."guard_patient_cannot_own_tenant"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."guard_tenant_kind_immutable"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
BEGIN
IF NEW.kind IS DISTINCT FROM OLD.kind THEN
RAISE EXCEPTION 'tenants.kind é imutável após criação. Tentativa de alterar "%" para "%".', OLD.kind, NEW.kind
USING ERRCODE = 'P0001';
END IF;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."guard_tenant_kind_immutable"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."handle_new_user"() RETURNS "trigger"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
BEGIN
INSERT INTO public.profiles (id, role, account_type)
VALUES (NEW.id, 'portal_user', 'free')
ON CONFLICT (id) DO NOTHING;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."handle_new_user"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."handle_new_user_create_personal_tenant"() RETURNS "trigger"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
BEGIN
-- Desabilitado. Tenant criado no onboarding via provision_account_tenant().
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."handle_new_user_create_personal_tenant"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."has_feature"("p_owner_id" "uuid", "p_feature_key" "text") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
select exists (
select 1
from public.owner_feature_entitlements e
where e.owner_id = p_owner_id
and e.feature_key = p_feature_key
);
$$;
ALTER FUNCTION "public"."has_feature"("p_owner_id" "uuid", "p_feature_key" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."is_clinic_tenant"("_tenant_id" "uuid") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
SELECT EXISTS (
SELECT 1 FROM public.tenants t
WHERE t.id = _tenant_id
AND t.kind IN ('clinic', 'clinic_coworking', 'clinic_reception', 'clinic_full')
);
$$;
ALTER FUNCTION "public"."is_clinic_tenant"("_tenant_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."is_saas_admin"() RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
select exists (
select 1 from public.saas_admins sa
where sa.user_id = auth.uid()
);
$$;
ALTER FUNCTION "public"."is_saas_admin"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."is_tenant_admin"("p_tenant_id" "uuid") RETURNS boolean
LANGUAGE "sql" STABLE SECURITY DEFINER
SET "search_path" TO 'public'
SET "row_security" TO 'off'
AS $$
select exists (
select 1
from public.tenant_members tm
where tm.tenant_id = p_tenant_id
and tm.user_id = auth.uid()
and tm.role = 'tenant_admin'
and tm.status = 'active'
);
$$;
ALTER FUNCTION "public"."is_tenant_admin"("p_tenant_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."is_tenant_member"("_tenant_id" "uuid") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
select exists (
select 1
from public.tenant_members m
where m.tenant_id = _tenant_id
and m.user_id = auth.uid()
and m.status = 'active'
);
$$;
ALTER FUNCTION "public"."is_tenant_member"("_tenant_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."is_therapist_tenant"("_tenant_id" "uuid") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
SELECT EXISTS (
SELECT 1 FROM public.tenants t
WHERE t.id = _tenant_id AND t.kind = 'therapist'
);
$$;
ALTER FUNCTION "public"."is_therapist_tenant"("_tenant_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."jwt_email"() RETURNS "text"
LANGUAGE "sql" STABLE
AS $$
select nullif(lower(current_setting('request.jwt.claim.email', true)), '');
$$;
ALTER FUNCTION "public"."jwt_email"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."my_tenants"() RETURNS TABLE("tenant_id" "uuid", "role" "text", "status" "text", "kind" "text")
LANGUAGE "sql" STABLE
AS $$
select
tm.tenant_id,
tm.role,
tm.status,
t.kind
from public.tenant_members tm
join public.tenants t on t.id = tm.tenant_id
where tm.user_id = auth.uid();
$$;
ALTER FUNCTION "public"."my_tenants"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."on_new_user_seed_patient_groups"() RETURNS "trigger"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
BEGIN
PERFORM public.seed_default_patient_groups(NEW.id);
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."on_new_user_seed_patient_groups"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."patients_validate_member_consistency"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
DECLARE
v_tenant_responsible uuid;
v_tenant_therapist uuid;
BEGIN
-- responsible_member sempre deve existir e ser do tenant
SELECT tenant_id INTO v_tenant_responsible
FROM public.tenant_members
WHERE id = NEW.responsible_member_id;
IF v_tenant_responsible IS NULL THEN
RAISE EXCEPTION 'Responsible member not found';
END IF;
IF NEW.tenant_id IS NULL THEN
RAISE EXCEPTION 'tenant_id is required';
END IF;
IF v_tenant_responsible <> NEW.tenant_id THEN
RAISE EXCEPTION 'Responsible member must belong to the same tenant';
END IF;
-- therapist scope: therapist_member_id deve existir e ser do mesmo tenant
IF NEW.patient_scope = 'therapist' THEN
IF NEW.therapist_member_id IS NULL THEN
RAISE EXCEPTION 'therapist_member_id is required when patient_scope=therapist';
END IF;
SELECT tenant_id INTO v_tenant_therapist
FROM public.tenant_members
WHERE id = NEW.therapist_member_id;
IF v_tenant_therapist IS NULL THEN
RAISE EXCEPTION 'Therapist member not found';
END IF;
IF v_tenant_therapist <> NEW.tenant_id THEN
RAISE EXCEPTION 'Therapist member must belong to the same tenant';
END IF;
END IF;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."patients_validate_member_consistency"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."patients_validate_responsible_member_tenant"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
declare
m_tenant uuid;
begin
select tenant_id into m_tenant
from public.tenant_members
where id = new.responsible_member_id;
if m_tenant is null then
raise exception 'Responsible member not found';
end if;
if new.tenant_id is null then
raise exception 'tenant_id is required';
end if;
if m_tenant <> new.tenant_id then
raise exception 'Responsible member must belong to the same tenant';
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."patients_validate_responsible_member_tenant"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."prevent_promoting_to_system"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
if new.is_system = true and old.is_system is distinct from true then
raise exception 'Não é permitido transformar um grupo comum em grupo do sistema.';
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."prevent_promoting_to_system"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."prevent_saas_membership"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
BEGIN
IF EXISTS (
SELECT 1
FROM public.profiles
WHERE id = NEW.user_id
AND role = 'saas_admin'
) THEN
RAISE EXCEPTION 'SaaS admin cannot belong to tenant';
END IF;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."prevent_saas_membership"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."prevent_system_group_changes"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
-- Se for grupo do sistema, regras rígidas:
if old.is_system = true then
-- nunca pode deletar
if tg_op = 'DELETE' then
raise exception 'Grupos padrão do sistema não podem ser alterados ou excluídos.';
end if;
if tg_op = 'UPDATE' then
-- permite SOMENTE mudar tenant_id e/ou updated_at
-- qualquer mudança de conteúdo permanece proibida
if
new.nome is distinct from old.nome or
new.descricao is distinct from old.descricao or
new.cor is distinct from old.cor or
new.is_active is distinct from old.is_active or
new.is_system is distinct from old.is_system or
new.owner_id is distinct from old.owner_id or
new.therapist_id is distinct from old.therapist_id or
new.created_at is distinct from old.created_at
then
raise exception 'Grupos padrão do sistema não podem ser alterados ou excluídos.';
end if;
-- chegou aqui: só tenant_id/updated_at mudaram -> ok
return new;
end if;
end if;
-- não-system: deixa passar
if tg_op = 'DELETE' then
return old;
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."prevent_system_group_changes"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."provision_account_tenant"("p_user_id" "uuid", "p_kind" "text", "p_name" "text" DEFAULT NULL::"text") RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
DECLARE
v_tenant_id uuid;
v_account_type text;
v_name text;
BEGIN
IF p_kind NOT IN ('therapist', 'clinic_coworking', 'clinic_reception', 'clinic_full') THEN
RAISE EXCEPTION 'kind inválido: "%". Use: therapist, clinic_coworking, clinic_reception, clinic_full.', p_kind
USING ERRCODE = 'P0001';
END IF;
v_account_type := CASE WHEN p_kind = 'therapist' THEN 'therapist' ELSE 'clinic' END;
IF EXISTS (
SELECT 1
FROM public.tenant_members tm
JOIN public.tenants t ON t.id = tm.tenant_id
WHERE tm.user_id = p_user_id
AND tm.role = 'tenant_admin'
AND tm.status = 'active'
AND t.kind = p_kind
) THEN
RAISE EXCEPTION 'Usuário já possui um tenant do tipo "%".', p_kind
USING ERRCODE = 'P0001';
END IF;
v_name := COALESCE(
NULLIF(TRIM(p_name), ''),
(
SELECT COALESCE(NULLIF(TRIM(pr.full_name), ''), SPLIT_PART(au.email, '@', 1))
FROM public.profiles pr
JOIN auth.users au ON au.id = pr.id
WHERE pr.id = p_user_id
),
'Conta'
);
INSERT INTO public.tenants (name, kind, created_at)
VALUES (v_name, p_kind, now())
RETURNING id INTO v_tenant_id;
INSERT INTO public.tenant_members (tenant_id, user_id, role, status, created_at)
VALUES (v_tenant_id, p_user_id, 'tenant_admin', 'active', now());
UPDATE public.profiles
SET account_type = v_account_type
WHERE id = p_user_id;
PERFORM public.seed_determined_commitments(v_tenant_id);
RETURN v_tenant_id;
END;
$$;
ALTER FUNCTION "public"."provision_account_tenant"("p_user_id" "uuid", "p_kind" "text", "p_name" "text") OWNER TO "supabase_admin";
COMMENT ON FUNCTION "public"."provision_account_tenant"("p_user_id" "uuid", "p_kind" "text", "p_name" "text") IS 'Cria o tenant do tipo correto e atualiza account_type no profile. Chamar no onboarding após escolha/pagamento de plano therapist ou clinic. p_kind: therapist | clinic_coworking | clinic_reception | clinic_full';
CREATE OR REPLACE FUNCTION "public"."reactivate_subscription"("p_subscription_id" "uuid") RETURNS "public"."subscriptions"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_sub public.subscriptions;
v_owner_type text;
v_owner_ref uuid;
begin
select *
into v_sub
from public.subscriptions
where id = p_subscription_id
for update;
if not found then
raise exception 'Subscription não encontrada';
end if;
if v_sub.status = 'active' then
return v_sub;
end if;
if v_sub.tenant_id is not null then
v_owner_type := 'clinic';
v_owner_ref := v_sub.tenant_id;
elsif v_sub.user_id is not null then
v_owner_type := 'therapist';
v_owner_ref := v_sub.user_id;
else
v_owner_type := null;
v_owner_ref := null;
end if;
update public.subscriptions
set status = 'active',
cancel_at_period_end = false,
updated_at = now()
where id = p_subscription_id
returning * into v_sub;
insert into public.subscription_events(
subscription_id,
owner_id,
owner_type,
owner_ref,
event_type,
old_plan_id,
new_plan_id,
created_by,
reason,
source,
metadata
)
values (
v_sub.id,
v_owner_ref,
v_owner_type,
v_owner_ref,
'reactivated',
v_sub.plan_id,
v_sub.plan_id,
auth.uid(),
'Reativação manual via admin',
'admin_panel',
jsonb_build_object('previous_status', 'canceled')
);
if v_owner_ref is not null then
insert into public.entitlements_invalidation(owner_id, changed_at)
values (v_owner_ref, now())
on conflict (owner_id)
do update set changed_at = excluded.changed_at;
end if;
return v_sub;
end;
$$;
ALTER FUNCTION "public"."reactivate_subscription"("p_subscription_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."rebuild_owner_entitlements"("p_owner_id" "uuid") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_plan_id uuid;
begin
-- Plano ativo do owner (owner = subscriptions.user_id)
select s.plan_id
into v_plan_id
from public.subscriptions s
where s.user_id = p_owner_id
and s.status = 'active'
order by s.created_at desc
limit 1;
-- Sempre zera entitlements do owner (rebuild)
delete from public.owner_feature_entitlements e
where e.owner_id = p_owner_id;
-- Se não tem assinatura ativa, acabou
if v_plan_id is null then
return;
end if;
-- Recria entitlements esperados pelo plano
insert into public.owner_feature_entitlements (owner_id, feature_key, sources, limits_list)
select
p_owner_id as owner_id,
f.key as feature_key,
array['plan'::text] as sources,
'{}'::jsonb as limits_list
from public.plan_features pf
join public.features f on f.id = pf.feature_id
where pf.plan_id = v_plan_id;
end;
$$;
ALTER FUNCTION "public"."rebuild_owner_entitlements"("p_owner_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."rotate_patient_invite_token"("p_new_token" "text") RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
declare
v_uid uuid;
v_id uuid;
begin
-- pega o usuário logado
v_uid := auth.uid();
if v_uid is null then
raise exception 'Usuário não autenticado';
end if;
-- desativa tokens antigos ativos do usuário
update public.patient_invites
set active = false
where owner_id = v_uid
and active = true;
-- cria novo token
insert into public.patient_invites (owner_id, token, active)
values (v_uid, p_new_token, true)
returning id into v_id;
return v_id;
end;
$$;
ALTER FUNCTION "public"."rotate_patient_invite_token"("p_new_token" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."saas_votar_doc"("p_doc_id" "uuid", "p_util" boolean) RETURNS "jsonb"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_uid uuid := auth.uid();
v_voto_antigo boolean;
begin
if v_uid is null then
raise exception 'Não autenticado';
end if;
-- Verifica se já votou
select util into v_voto_antigo
from public.saas_doc_votos
where doc_id = p_doc_id and user_id = v_uid;
if found then
-- Já votou igual → cancela o voto (toggle)
if v_voto_antigo = p_util then
delete from public.saas_doc_votos
where doc_id = p_doc_id and user_id = v_uid;
update public.saas_docs set
votos_util = greatest(0, votos_util - (case when p_util then 1 else 0 end)),
votos_nao_util = greatest(0, votos_nao_util - (case when not p_util then 1 else 0 end)),
updated_at = now()
where id = p_doc_id;
return jsonb_build_object('acao', 'removido', 'util', null);
else
-- Mudou de voto
update public.saas_doc_votos set util = p_util, updated_at = now()
where doc_id = p_doc_id and user_id = v_uid;
update public.saas_docs set
votos_util = greatest(0, votos_util + (case when p_util then 1 else -1 end)),
votos_nao_util = greatest(0, votos_nao_util + (case when not p_util then 1 else -1 end)),
updated_at = now()
where id = p_doc_id;
return jsonb_build_object('acao', 'atualizado', 'util', p_util);
end if;
else
-- Primeiro voto
insert into public.saas_doc_votos (doc_id, user_id, util)
values (p_doc_id, v_uid, p_util);
update public.saas_docs set
votos_util = votos_util + (case when p_util then 1 else 0 end),
votos_nao_util = votos_nao_util + (case when not p_util then 1 else 0 end),
updated_at = now()
where id = p_doc_id;
return jsonb_build_object('acao', 'registrado', 'util', p_util);
end if;
end;
$$;
ALTER FUNCTION "public"."saas_votar_doc"("p_doc_id" "uuid", "p_util" boolean) OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."seed_determined_commitments"("p_tenant_id" "uuid") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_id uuid;
begin
-- Sessão (locked + sempre ativa)
if not exists (
select 1 from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'session'
) then
insert into public.determined_commitments
(tenant_id, is_native, native_key, is_locked, active, name, description)
values
(p_tenant_id, true, 'session', true, true, 'Sessão', 'Sessão com paciente');
end if;
-- Leitura
if not exists (
select 1 from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'reading'
) then
insert into public.determined_commitments
(tenant_id, is_native, native_key, is_locked, active, name, description)
values
(p_tenant_id, true, 'reading', false, true, 'Leitura', 'Praticar leitura');
end if;
-- Supervisão
if not exists (
select 1 from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'supervision'
) then
insert into public.determined_commitments
(tenant_id, is_native, native_key, is_locked, active, name, description)
values
(p_tenant_id, true, 'supervision', false, true, 'Supervisão', 'Supervisão');
end if;
-- Aula ✅ (corrigido)
if not exists (
select 1 from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'class'
) then
insert into public.determined_commitments
(tenant_id, is_native, native_key, is_locked, active, name, description)
values
(p_tenant_id, true, 'class', false, false, 'Aula', 'Dar aula');
end if;
-- Análise pessoal
if not exists (
select 1 from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'analysis'
) then
insert into public.determined_commitments
(tenant_id, is_native, native_key, is_locked, active, name, description)
values
(p_tenant_id, true, 'analysis', false, true, 'Análise Pessoal', 'Minha análise pessoal');
end if;
-- -------------------------------------------------------
-- Campos padrão (idempotentes por (commitment_id, key))
-- -------------------------------------------------------
-- Leitura
select id into v_id
from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'reading'
limit 1;
if v_id is not null then
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'book') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'book', 'Livro', 'text', false, 10);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'author') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'author', 'Autor', 'text', false, 20);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'notes') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'notes', 'Observação', 'textarea', false, 30);
end if;
end if;
-- Supervisão
select id into v_id
from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'supervision'
limit 1;
if v_id is not null then
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'supervisor') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'supervisor', 'Supervisor', 'text', false, 10);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'topic') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'topic', 'Assunto', 'text', false, 20);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'notes') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'notes', 'Observação', 'textarea', false, 30);
end if;
end if;
-- Aula
select id into v_id
from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'class'
limit 1;
if v_id is not null then
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'theme') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'theme', 'Tema', 'text', false, 10);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'group') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'group', 'Turma', 'text', false, 20);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'notes') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'notes', 'Observação', 'textarea', false, 30);
end if;
end if;
-- Análise
select id into v_id
from public.determined_commitments
where tenant_id = p_tenant_id and is_native = true and native_key = 'analysis'
limit 1;
if v_id is not null then
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'analyst') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'analyst', 'Analista', 'text', false, 10);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'focus') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'focus', 'Foco', 'text', false, 20);
end if;
if not exists (select 1 from public.determined_commitment_fields where commitment_id = v_id and key = 'notes') then
insert into public.determined_commitment_fields (tenant_id, commitment_id, key, label, field_type, required, sort_order)
values (p_tenant_id, v_id, 'notes', 'Observação', 'textarea', false, 30);
end if;
end if;
end;
$$;
ALTER FUNCTION "public"."seed_determined_commitments"("p_tenant_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."set_owner_id"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
if new.owner_id is null then
new.owner_id := auth.uid();
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."set_owner_id"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."set_tenant_feature_exception"("p_tenant_id" "uuid", "p_feature_key" "text", "p_enabled" boolean, "p_reason" "text" DEFAULT NULL::"text") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
begin
-- ✅ Só owner ou admin do tenant podem alterar features
if not exists (
select 1 from public.tenant_members
where tenant_id = p_tenant_id
and user_id = auth.uid()
and role in ('owner', 'admin')
and status = 'active'
) then
raise exception 'Acesso negado: apenas owner/admin pode alterar features do tenant.';
end if;
insert into public.tenant_features (tenant_id, feature_key, enabled)
values (p_tenant_id, p_feature_key, p_enabled)
on conflict (tenant_id, feature_key)
do update set enabled = excluded.enabled;
insert into public.tenant_feature_exceptions_log (
tenant_id, feature_key, enabled, reason, created_by
) values (
p_tenant_id, p_feature_key, p_enabled, p_reason, auth.uid()
);
end;
$$;
ALTER FUNCTION "public"."set_tenant_feature_exception"("p_tenant_id" "uuid", "p_feature_key" "text", "p_enabled" boolean, "p_reason" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."set_updated_at"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
begin
new.updated_at = now();
return new;
end;
$$;
ALTER FUNCTION "public"."set_updated_at"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."set_updated_at_recurrence"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
BEGIN NEW.updated_at = now(); RETURN NEW; END;
$$;
ALTER FUNCTION "public"."set_updated_at_recurrence"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."split_recurrence_at"("p_recurrence_id" "uuid", "p_from_date" "date") RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
DECLARE
v_old public.recurrence_rules;
v_new_id uuid;
BEGIN
-- busca a regra original
SELECT * INTO v_old
FROM public.recurrence_rules
WHERE id = p_recurrence_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'recurrence_rule % não encontrada', p_recurrence_id;
END IF;
-- encerra a regra antiga na data anterior
UPDATE public.recurrence_rules
SET
end_date = p_from_date - INTERVAL '1 day',
open_ended = false,
updated_at = now()
WHERE id = p_recurrence_id;
-- cria nova regra a partir de p_from_date
INSERT INTO public.recurrence_rules (
tenant_id, owner_id, therapist_id, patient_id,
determined_commitment_id, type, interval, weekdays,
start_time, end_time, timezone, duration_min,
start_date, end_date, max_occurrences, open_ended,
modalidade, titulo_custom, observacoes, extra_fields, status
)
SELECT
tenant_id, owner_id, therapist_id, patient_id,
determined_commitment_id, type, interval, weekdays,
start_time, end_time, timezone, duration_min,
p_from_date, v_old.end_date, v_old.max_occurrences, v_old.open_ended,
modalidade, titulo_custom, observacoes, extra_fields, status
FROM public.recurrence_rules
WHERE id = p_recurrence_id
RETURNING id INTO v_new_id;
RETURN v_new_id;
END;
$$;
ALTER FUNCTION "public"."split_recurrence_at"("p_recurrence_id" "uuid", "p_from_date" "date") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."subscription_intents_view_insert"() RETURNS "trigger"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_target text;
v_plan_id uuid;
begin
select p.id, p.target into v_plan_id, v_target
from public.plans p
where p.key = new.plan_key;
if v_plan_id is null then
raise exception 'Plano inválido: plan_key=%', new.plan_key;
end if;
if lower(v_target) = 'clinic' then
if new.tenant_id is null then
raise exception 'Intenção clinic exige tenant_id.';
end if;
insert into public.subscription_intents_tenant (
id, tenant_id, created_by_user_id, email,
plan_id, plan_key, interval, amount_cents, currency,
status, source, notes, created_at, paid_at
) values (
coalesce(new.id, gen_random_uuid()),
new.tenant_id, new.created_by_user_id, new.email,
v_plan_id, new.plan_key, coalesce(new.interval,'month'),
new.amount_cents, coalesce(new.currency,'BRL'),
coalesce(new.status,'pending'), coalesce(new.source,'manual'),
new.notes, coalesce(new.created_at, now()), new.paid_at
);
new.plan_target := 'clinic';
return new;
end if;
-- therapist ou supervisor → tabela personal
if lower(v_target) in ('therapist', 'supervisor') then
insert into public.subscription_intents_personal (
id, user_id, created_by_user_id, email,
plan_id, plan_key, interval, amount_cents, currency,
status, source, notes, created_at, paid_at
) values (
coalesce(new.id, gen_random_uuid()),
new.user_id, new.created_by_user_id, new.email,
v_plan_id, new.plan_key, coalesce(new.interval,'month'),
new.amount_cents, coalesce(new.currency,'BRL'),
coalesce(new.status,'pending'), coalesce(new.source,'manual'),
new.notes, coalesce(new.created_at, now()), new.paid_at
);
new.plan_target := lower(v_target); -- 'therapist' ou 'supervisor'
return new;
end if;
raise exception 'Target de plano não suportado: %', v_target;
end;
$$;
ALTER FUNCTION "public"."subscription_intents_view_insert"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."subscriptions_validate_scope"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
DECLARE
v_target text;
BEGIN
SELECT lower(p.target) INTO v_target
FROM public.plans p
WHERE p.id = NEW.plan_id;
IF v_target IS NULL THEN
RAISE EXCEPTION 'Plano inválido (target nulo).';
END IF;
IF v_target = 'clinic' THEN
IF NEW.tenant_id IS NULL THEN
RAISE EXCEPTION 'Assinatura clinic exige tenant_id.';
END IF;
IF NEW.user_id IS NOT NULL THEN
RAISE EXCEPTION 'Assinatura clinic não pode ter user_id (XOR).';
END IF;
ELSIF v_target IN ('therapist', 'supervisor') THEN
-- supervisor é pessoal como therapist
IF NEW.tenant_id IS NOT NULL THEN
RAISE EXCEPTION 'Assinatura % não deve ter tenant_id.', v_target;
END IF;
IF NEW.user_id IS NULL THEN
RAISE EXCEPTION 'Assinatura % exige user_id.', v_target;
END IF;
ELSIF v_target = 'patient' THEN
IF NEW.tenant_id IS NOT NULL THEN
RAISE EXCEPTION 'Assinatura patient não deve ter tenant_id.';
END IF;
IF NEW.user_id IS NULL THEN
RAISE EXCEPTION 'Assinatura patient exige user_id.';
END IF;
ELSE
RAISE EXCEPTION 'Target de plano inválido: %', v_target;
END IF;
RETURN NEW;
END;
$$;
ALTER FUNCTION "public"."subscriptions_validate_scope"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."sync_busy_mirror_agenda_eventos"() RETURNS "trigger"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
AS $$
declare
clinic_tenant uuid;
is_personal boolean;
should_mirror boolean;
begin
-- Anti-recursão: espelho não espelha
if (tg_op <> 'DELETE') then
if new.mirror_of_event_id is not null then
return new;
end if;
else
if old.mirror_of_event_id is not null then
return old;
end if;
end if;
-- Define se é pessoal e se deve espelhar
if (tg_op = 'DELETE') then
is_personal := (old.tenant_id = old.owner_id);
should_mirror := (old.visibility_scope in ('busy_only','private'));
else
is_personal := (new.tenant_id = new.owner_id);
should_mirror := (new.visibility_scope in ('busy_only','private'));
end if;
-- Se não é pessoal, não faz nada
if not is_personal then
if (tg_op = 'DELETE') then
return old;
end if;
return new;
end if;
-- DELETE: remove espelhos existentes
if (tg_op = 'DELETE') then
delete from public.agenda_eventos e
where e.mirror_of_event_id = old.id
and e.mirror_source = 'personal_busy_mirror';
return old;
end if;
-- INSERT/UPDATE:
-- Se não deve espelhar, remove espelhos e sai
if not should_mirror then
delete from public.agenda_eventos e
where e.mirror_of_event_id = new.id
and e.mirror_source = 'personal_busy_mirror';
return new;
end if;
-- Para cada clínica onde o usuário é therapist active, cria/atualiza o "Ocupado"
for clinic_tenant in
select tm.tenant_id
from public.tenant_members tm
where tm.user_id = new.owner_id
and tm.role = 'therapist'
and tm.status = 'active'
and tm.tenant_id <> new.owner_id
loop
insert into public.agenda_eventos (
tenant_id,
owner_id,
terapeuta_id,
paciente_id,
tipo,
status,
titulo,
observacoes,
inicio_em,
fim_em,
mirror_of_event_id,
mirror_source,
visibility_scope,
created_at,
updated_at
) values (
clinic_tenant,
new.owner_id,
new.owner_id,
null,
'bloqueio'::public.tipo_evento_agenda,
'agendado'::public.status_evento_agenda,
'Ocupado',
null,
new.inicio_em,
new.fim_em,
new.id,
'personal_busy_mirror',
'public',
now(),
now()
)
on conflict (tenant_id, mirror_of_event_id) where mirror_of_event_id is not null
do update set
owner_id = excluded.owner_id,
terapeuta_id = excluded.terapeuta_id,
tipo = excluded.tipo,
status = excluded.status,
titulo = excluded.titulo,
observacoes = excluded.observacoes,
inicio_em = excluded.inicio_em,
fim_em = excluded.fim_em,
updated_at = now();
end loop;
-- Limpa espelhos de clínicas onde o vínculo therapist active não existe mais
delete from public.agenda_eventos e
where e.mirror_of_event_id = new.id
and e.mirror_source = 'personal_busy_mirror'
and not exists (
select 1
from public.tenant_members tm
where tm.user_id = new.owner_id
and tm.role = 'therapist'
and tm.status = 'active'
and tm.tenant_id = e.tenant_id
);
return new;
end;
$$;
ALTER FUNCTION "public"."sync_busy_mirror_agenda_eventos"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_accept_invite"("p_token" "uuid") RETURNS "jsonb"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public', 'auth'
AS $$
declare
v_uid uuid;
v_email text;
v_invite public.tenant_invites%rowtype;
begin
-- 1) precisa estar autenticado
v_uid := auth.uid();
if v_uid is null then
raise exception 'not_authenticated' using errcode = 'P0001';
end if;
-- 2) pega email real do usuário logado sem depender do JWT claim
select u.email
into v_email
from auth.users u
where u.id = v_uid;
if v_email is null or length(trim(v_email)) = 0 then
raise exception 'missing_user_email' using errcode = 'P0001';
end if;
-- 3) carrega o invite e trava linha (evita 2 aceites concorrentes)
select *
into v_invite
from public.tenant_invites i
where i.token = p_token
for update;
if not found then
raise exception 'invite_not_found' using errcode = 'P0001';
end if;
-- 4) validações de estado
if v_invite.revoked_at is not null then
raise exception 'invite_revoked' using errcode = 'P0001';
end if;
if v_invite.accepted_at is not null then
raise exception 'invite_already_accepted' using errcode = 'P0001';
end if;
if v_invite.expires_at is not null and v_invite.expires_at <= now() then
raise exception 'invite_expired' using errcode = 'P0001';
end if;
-- 5) valida email (case-insensitive)
if lower(trim(v_invite.email)) <> lower(trim(v_email)) then
raise exception 'email_mismatch' using errcode = 'P0001';
end if;
-- 6) consome o invite
update public.tenant_invites
set accepted_at = now(),
accepted_by = v_uid
where id = v_invite.id;
-- 7) cria ou reativa o membership
insert into public.tenant_members (tenant_id, user_id, role, status, created_at)
values (v_invite.tenant_id, v_uid, v_invite.role, 'active', now())
on conflict (tenant_id, user_id)
do update set
role = excluded.role,
status = 'active';
-- 8) retorno útil pro front (você já tenta ler tenant_id no AcceptInvitePage)
return jsonb_build_object(
'ok', true,
'tenant_id', v_invite.tenant_id,
'role', v_invite.role
);
end;
$$;
ALTER FUNCTION "public"."tenant_accept_invite"("p_token" "uuid") OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."tenant_members" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
"user_id" "uuid" NOT NULL,
"role" "text" NOT NULL,
"status" "text" DEFAULT 'active'::"text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."tenant_members" OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_add_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text" DEFAULT 'therapist'::"text") RETURNS "public"."tenant_members"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public', 'auth'
AS $$
declare
v_target_uid uuid;
v_member public.tenant_members%rowtype;
v_is_admin boolean;
v_email text;
begin
if p_tenant_id is null then
raise exception 'tenant_id é obrigatório';
end if;
v_email := lower(trim(coalesce(p_email, '')));
if v_email = '' then
raise exception 'email é obrigatório';
end if;
-- valida role permitida
if p_role not in ('tenant_admin','therapist','secretary','patient') then
raise exception 'role inválida: %', p_role;
end if;
-- apenas admin do tenant (role real no banco)
select exists (
select 1
from public.tenant_members tm
where tm.tenant_id = p_tenant_id
and tm.user_id = auth.uid()
and tm.role = 'tenant_admin'
and coalesce(tm.status,'active') = 'active'
) into v_is_admin;
if not v_is_admin then
raise exception 'sem permissão: apenas admin da clínica pode adicionar membros';
end if;
-- acha usuário pelo e-mail no Supabase Auth
select u.id
into v_target_uid
from auth.users u
where lower(u.email) = v_email
limit 1;
if v_target_uid is null then
raise exception 'nenhum usuário encontrado com este e-mail';
end if;
-- cria ou reativa membro
insert into public.tenant_members (tenant_id, user_id, role, status)
values (p_tenant_id, v_target_uid, p_role, 'active')
on conflict (tenant_id, user_id)
do update set
role = excluded.role,
status = 'active'
returning * into v_member;
return v_member;
end;
$$;
ALTER FUNCTION "public"."tenant_add_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_feature_allowed"("p_tenant_id" "uuid", "p_feature_key" "text") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
select exists (
select 1
from public.v_tenant_entitlements v
where v.tenant_id = p_tenant_id
and v.feature_key = p_feature_key
and coalesce(v.allowed, false) = true
);
$$;
ALTER FUNCTION "public"."tenant_feature_allowed"("p_tenant_id" "uuid", "p_feature_key" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_feature_enabled"("p_tenant_id" "uuid", "p_feature_key" "text") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
select coalesce(
(select tf.enabled
from public.tenant_features tf
where tf.tenant_id = p_tenant_id and tf.feature_key = p_feature_key),
false
);
$$;
ALTER FUNCTION "public"."tenant_feature_enabled"("p_tenant_id" "uuid", "p_feature_key" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_features_guard_with_plan"() RETURNS "trigger"
LANGUAGE "plpgsql"
AS $$
declare
v_allowed boolean;
begin
-- só valida quando está habilitando
if new.enabled is distinct from true then
return new;
end if;
-- permitido pelo plano do tenant?
select exists (
select 1
from public.v_tenant_entitlements_full v
where v.tenant_id = new.tenant_id
and v.feature_key = new.feature_key
and v.allowed = true
)
into v_allowed;
if not v_allowed then
raise exception 'Feature % não permitida pelo plano atual do tenant %.',
new.feature_key, new.tenant_id
using errcode = 'P0001';
end if;
return new;
end;
$$;
ALTER FUNCTION "public"."tenant_features_guard_with_plan"() OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_has_feature"("_tenant_id" "uuid", "_feature" "text") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
select
exists (
select 1
from public.v_tenant_entitlements e
where e.tenant_id = _tenant_id
and e.feature_key = _feature
and e.allowed = true
)
or exists (
select 1
from public.tenant_features tf
where tf.tenant_id = _tenant_id
and tf.feature_key = _feature
and tf.enabled = true
);
$$;
ALTER FUNCTION "public"."tenant_has_feature"("_tenant_id" "uuid", "_feature" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_invite_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") RETURNS "uuid"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public', 'auth'
AS $$
declare
v_email text;
v_my_email text;
v_token uuid;
v_updated int;
begin
-- validações básicas
if p_tenant_id is null then
raise exception 'tenant_id inválido' using errcode = 'P0001';
end if;
v_email := lower(trim(coalesce(p_email, '')));
if v_email = '' then
raise exception 'Informe um email' using errcode = 'P0001';
end if;
-- role permitido (ajuste se quiser)
if p_role is null or p_role not in ('therapist', 'secretary') then
raise exception 'Role inválido (use therapist/secretary)' using errcode = 'P0001';
end if;
-- ✅ bloqueio: auto-convite
v_my_email := public.get_my_email();
if v_my_email is not null and v_email = v_my_email then
raise exception 'Você não pode convidar o seu próprio email.' using errcode = 'P0001';
end if;
-- ✅ bloqueio: já é membro ativo do tenant
if exists (
select 1
from tenant_members tm
join auth.users au on au.id = tm.user_id
where tm.tenant_id = p_tenant_id
and tm.status = 'active'
and lower(au.email) = v_email
) then
raise exception 'Este email já está vinculado a esta clínica.' using errcode = 'P0001';
end if;
-- ✅ permissão: só admin do tenant pode convidar
if not exists (
select 1
from tenant_members me
where me.tenant_id = p_tenant_id
and me.user_id = auth.uid()
and me.status = 'active'
and me.role in ('tenant_admin','clinic_admin')
) then
raise exception 'Sem permissão para convidar membros.' using errcode = 'P0001';
end if;
-- Gera token (reenvio simples / regeneração)
v_token := gen_random_uuid();
-- 1) tenta "regerar" um convite pendente existente (mesmo email)
update tenant_invites
set token = v_token,
role = p_role,
created_at = now(),
expires_at = now() + interval '7 days',
accepted_at = null,
revoked_at = null
where tenant_id = p_tenant_id
and lower(email) = v_email
and accepted_at is null
and revoked_at is null;
get diagnostics v_updated = row_count;
-- 2) se não atualizou nada, cria convite novo
if v_updated = 0 then
insert into tenant_invites (tenant_id, email, role, token, created_at, expires_at)
values (p_tenant_id, v_email, p_role, v_token, now(), now() + interval '7 days');
end if;
return v_token;
end;
$$;
ALTER FUNCTION "public"."tenant_invite_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_reactivate_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
SET "row_security" TO 'off'
AS $$
begin
if auth.uid() is null then
raise exception 'not_authenticated';
end if;
if not public.is_tenant_admin(p_tenant_id) then
raise exception 'not_allowed';
end if;
update public.tenant_members
set status = 'active'
where tenant_id = p_tenant_id
and user_id = p_member_user_id;
if not found then
raise exception 'membership_not_found';
end if;
end;
$$;
ALTER FUNCTION "public"."tenant_reactivate_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_remove_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
SET "row_security" TO 'off'
AS $$
declare
v_role text;
begin
if auth.uid() is null then
raise exception 'not_authenticated';
end if;
if not public.is_tenant_admin(p_tenant_id) then
raise exception 'not_allowed';
end if;
if p_member_user_id = auth.uid() then
raise exception 'cannot_remove_self';
end if;
-- pega role atual do membro (se não existir, erro)
select role into v_role
from public.tenant_members
where tenant_id = p_tenant_id
and user_id = p_member_user_id;
if v_role is null then
raise exception 'membership_not_found';
end if;
-- trava: se for therapist, não pode remover com eventos futuros
if v_role = 'therapist' then
if exists (
select 1
from public.agenda_eventos e
where e.owner_id = p_tenant_id
and e.terapeuta_id = p_member_user_id
and e.inicio_em >= now()
and e.status::text not in ('cancelado','cancelled','canceled')
limit 1
) then
raise exception 'cannot_remove_therapist_with_future_events';
end if;
end if;
update public.tenant_members
set status = 'inactive'
where tenant_id = p_tenant_id
and user_id = p_member_user_id;
if not found then
raise exception 'membership_not_found';
end if;
end;
$$;
ALTER FUNCTION "public"."tenant_remove_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_remove_member_soft"("p_tenant_id" "uuid", "p_member_user_id" "uuid") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
SET "row_security" TO 'off'
AS $$
begin
if auth.uid() is null then
raise exception 'not_authenticated';
end if;
if not public.is_tenant_admin(p_tenant_id) then
raise exception 'not_allowed';
end if;
if p_member_user_id = auth.uid() then
raise exception 'cannot_remove_self';
end if;
update public.tenant_members
set status = 'inactive'
where tenant_id = p_tenant_id
and user_id = p_member_user_id;
if not found then
raise exception 'membership_not_found';
end if;
end;
$$;
ALTER FUNCTION "public"."tenant_remove_member_soft"("p_tenant_id" "uuid", "p_member_user_id" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_revoke_invite"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
SET "row_security" TO 'off'
AS $$
declare
v_email text;
begin
if auth.uid() is null then
raise exception 'not_authenticated';
end if;
if not public.is_tenant_admin(p_tenant_id) then
raise exception 'not_allowed';
end if;
v_email := lower(trim(p_email));
update public.tenant_invites
set revoked_at = now(),
revoked_by = auth.uid()
where tenant_id = p_tenant_id
and lower(email) = v_email
and role = p_role
and accepted_at is null
and revoked_at is null;
if not found then
raise exception 'invite_not_found';
end if;
end;
$$;
ALTER FUNCTION "public"."tenant_revoke_invite"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_set_member_status"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_status" "text") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
SET "row_security" TO 'off'
AS $$
begin
if auth.uid() is null then
raise exception 'not_authenticated';
end if;
-- valida status (adapte aos seus valores reais)
if p_new_status not in ('active','inactive','suspended','invited') then
raise exception 'invalid_status: %', p_new_status;
end if;
if not public.is_tenant_admin(p_tenant_id) then
raise exception 'not_allowed';
end if;
-- evita desativar a si mesmo (opcional)
if p_member_user_id = auth.uid() and p_new_status <> 'active' then
raise exception 'cannot_disable_self';
end if;
update public.tenant_members
set status = p_new_status
where tenant_id = p_tenant_id
and user_id = p_member_user_id;
if not found then
raise exception 'membership_not_found';
end if;
end;
$$;
ALTER FUNCTION "public"."tenant_set_member_status"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_status" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."tenant_update_member_role"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_role" "text") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
SET "search_path" TO 'public'
SET "row_security" TO 'off'
AS $$
begin
-- exige auth
if auth.uid() is null then
raise exception 'not_authenticated';
end if;
-- valida role
if p_new_role not in ('tenant_admin','therapist','secretary','patient') then
raise exception 'invalid_role: %', p_new_role;
end if;
-- somente tenant_admin ativo pode alterar role
if not public.is_tenant_admin(p_tenant_id) then
raise exception 'not_allowed';
end if;
-- evita o admin remover o próprio admin sem querer (opcional mas recomendado)
if p_member_user_id = auth.uid() and p_new_role <> 'tenant_admin' then
raise exception 'cannot_demote_self';
end if;
update public.tenant_members
set role = p_new_role
where tenant_id = p_tenant_id
and user_id = p_member_user_id;
if not found then
raise exception 'membership_not_found';
end if;
end;
$$;
ALTER FUNCTION "public"."tenant_update_member_role"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_role" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."toggle_plan"("owner" "uuid") RETURNS "void"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
current_key text;
new_key text;
begin
select p.key into current_key
from subscriptions s
join plans p on p.id = s.plan_id
where s.owner_id = owner
and s.status = 'active';
new_key := case
when current_key = 'pro' then 'free'
else 'pro'
end;
update subscriptions s
set plan_id = p.id
from plans p
where p.key = new_key
and s.owner_id = owner
and s.status = 'active';
end;
$$;
ALTER FUNCTION "public"."toggle_plan"("owner" "uuid") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."transition_subscription"("p_subscription_id" "uuid", "p_to_status" "text", "p_reason" "text" DEFAULT NULL::"text", "p_metadata" "jsonb" DEFAULT NULL::"jsonb") RETURNS "public"."subscriptions"
LANGUAGE "plpgsql" SECURITY DEFINER
AS $$
declare
v_sub public.subscriptions;
v_uid uuid;
v_is_allowed boolean := false;
begin
v_uid := auth.uid();
select *
into v_sub
from public.subscriptions
where id = p_subscription_id;
if not found then
raise exception 'Assinatura não encontrada';
end if;
-- =====================================================
-- 🔐 BLOCO DE AUTORIZAÇÃO
-- =====================================================
-- 1) SaaS admin pode tudo
if is_saas_admin() then
v_is_allowed := true;
end if;
-- 2) Assinatura pessoal (therapist)
if not v_is_allowed
and v_sub.tenant_id is null
and v_sub.user_id = v_uid then
v_is_allowed := true;
end if;
-- 3) Assinatura de clinic (tenant)
if not v_is_allowed
and v_sub.tenant_id is not null then
if exists (
select 1
from public.tenant_members tm
where tm.tenant_id = v_sub.tenant_id
and tm.user_id = v_uid
and tm.status = 'active'
and tm.role = 'tenant_admin'
) then
v_is_allowed := true;
end if;
end if;
if not v_is_allowed then
raise exception 'Sem permissão para transicionar esta assinatura';
end if;
-- =====================================================
-- 🧠 TRANSIÇÃO
-- =====================================================
update public.subscriptions
set status = p_to_status,
updated_at = now(),
cancelled_at = case when p_to_status = 'cancelled' then now() else cancelled_at end,
suspended_at = case when p_to_status = 'suspended' then now() else suspended_at end,
past_due_since = case when p_to_status = 'past_due' then now() else past_due_since end,
expired_at = case when p_to_status = 'expired' then now() else expired_at end,
activated_at = case when p_to_status = 'active' then now() else activated_at end
where id = p_subscription_id
returning * into v_sub;
-- =====================================================
-- 🧾 EVENT LOG
-- =====================================================
insert into public.subscription_events (
subscription_id,
owner_id,
event_type,
created_at,
created_by,
source,
reason,
metadata,
owner_type,
owner_ref
)
values (
v_sub.id,
coalesce(v_sub.tenant_id, v_sub.user_id),
'status_changed',
now(),
v_uid,
'manual_transition',
p_reason,
p_metadata,
case when v_sub.tenant_id is not null then 'tenant' else 'personal' end,
coalesce(v_sub.tenant_id, v_sub.user_id)
);
return v_sub;
end;
$$;
ALTER FUNCTION "public"."transition_subscription"("p_subscription_id" "uuid", "p_to_status" "text", "p_reason" "text", "p_metadata" "jsonb") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."user_has_feature"("_user_id" "uuid", "_feature" "text") RETURNS boolean
LANGUAGE "sql" STABLE
AS $$
select exists (
select 1
from public.v_user_entitlements e
where e.user_id = _user_id
and e.feature_key = _feature
and e.allowed = true
);
$$;
ALTER FUNCTION "public"."user_has_feature"("_user_id" "uuid", "_feature" "text") OWNER TO "supabase_admin";
CREATE OR REPLACE FUNCTION "public"."whoami"() RETURNS TABLE("uid" "uuid", "role" "text")
LANGUAGE "sql" STABLE
AS $$
select auth.uid() as uid, auth.role() as role;
$$;
ALTER FUNCTION "public"."whoami"() OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agenda_bloqueios" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"tenant_id" "uuid",
"tipo" "text" NOT NULL,
"titulo" "text" NOT NULL,
"data_inicio" "date" NOT NULL,
"data_fim" "date",
"hora_inicio" time without time zone,
"hora_fim" time without time zone,
"recorrente" boolean DEFAULT false NOT NULL,
"dia_semana" smallint,
"observacao" "text",
"origem" "text" DEFAULT 'manual'::"text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
CONSTRAINT "agenda_bloqueios_tipo_check" CHECK (("tipo" = ANY (ARRAY['feriado_nacional'::"text", 'feriado_municipal'::"text", 'bloqueio'::"text"])))
);
ALTER TABLE "public"."agenda_bloqueios" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agenda_configuracoes" (
"owner_id" "uuid" NOT NULL,
"duracao_padrao_minutos" integer DEFAULT 50 NOT NULL,
"intervalo_padrao_minutos" integer DEFAULT 0 NOT NULL,
"timezone" "text" DEFAULT 'America/Sao_Paulo'::"text" NOT NULL,
"usar_horario_admin_custom" boolean DEFAULT false NOT NULL,
"admin_inicio_visualizacao" time without time zone,
"admin_fim_visualizacao" time without time zone,
"admin_slot_visual_minutos" integer DEFAULT 30 NOT NULL,
"online_ativo" boolean DEFAULT false NOT NULL,
"online_min_antecedencia_horas" integer DEFAULT 24 NOT NULL,
"online_max_dias_futuro" integer DEFAULT 60 NOT NULL,
"online_cancelar_ate_horas" integer DEFAULT 12 NOT NULL,
"online_reagendar_ate_horas" integer DEFAULT 12 NOT NULL,
"online_limite_agendamentos_futuros" integer DEFAULT 1 NOT NULL,
"online_modo" "text" DEFAULT 'automatico'::"text" NOT NULL,
"online_buffer_antes_min" integer DEFAULT 0 NOT NULL,
"online_buffer_depois_min" integer DEFAULT 0 NOT NULL,
"online_modalidade" "text" DEFAULT 'ambos'::"text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"usar_granularidade_custom" boolean DEFAULT false NOT NULL,
"granularidade_min" integer,
"setup_concluido" boolean DEFAULT false NOT NULL,
"setup_concluido_em" timestamp with time zone,
"agenda_view_mode" "text" DEFAULT 'full_24h'::"text" NOT NULL,
"agenda_custom_start" time without time zone,
"agenda_custom_end" time without time zone,
"session_duration_min" integer DEFAULT 50 NOT NULL,
"session_break_min" integer DEFAULT 10 NOT NULL,
"pausas_semanais" "jsonb" DEFAULT '[]'::"jsonb" NOT NULL,
"setup_clinica_concluido" boolean DEFAULT false NOT NULL,
"setup_clinica_concluido_em" timestamp with time zone,
"tenant_id" "uuid",
"jornada_igual_todos" boolean DEFAULT true,
CONSTRAINT "agenda_configuracoes_admin_slot_visual_minutos_check" CHECK (("admin_slot_visual_minutos" = ANY (ARRAY[5, 10, 15, 20, 30, 60]))),
CONSTRAINT "agenda_configuracoes_check" CHECK ((("usar_horario_admin_custom" = false) OR (("admin_inicio_visualizacao" IS NOT NULL) AND ("admin_fim_visualizacao" IS NOT NULL) AND ("admin_fim_visualizacao" > "admin_inicio_visualizacao")))),
CONSTRAINT "agenda_configuracoes_duracao_padrao_minutos_check" CHECK ((("duracao_padrao_minutos" >= 10) AND ("duracao_padrao_minutos" <= 240))),
CONSTRAINT "agenda_configuracoes_granularidade_min_check" CHECK ((("granularidade_min" IS NULL) OR ("granularidade_min" = ANY (ARRAY[5, 10, 15, 20, 30, 45, 50, 60])))),
CONSTRAINT "agenda_configuracoes_intervalo_padrao_minutos_check" CHECK ((("intervalo_padrao_minutos" >= 0) AND ("intervalo_padrao_minutos" <= 120))),
CONSTRAINT "agenda_configuracoes_online_buffer_antes_min_check" CHECK ((("online_buffer_antes_min" >= 0) AND ("online_buffer_antes_min" <= 120))),
CONSTRAINT "agenda_configuracoes_online_buffer_depois_min_check" CHECK ((("online_buffer_depois_min" >= 0) AND ("online_buffer_depois_min" <= 120))),
CONSTRAINT "agenda_configuracoes_online_cancelar_ate_horas_check" CHECK ((("online_cancelar_ate_horas" >= 0) AND ("online_cancelar_ate_horas" <= 720))),
CONSTRAINT "agenda_configuracoes_online_limite_agendamentos_futuros_check" CHECK ((("online_limite_agendamentos_futuros" >= 1) AND ("online_limite_agendamentos_futuros" <= 10))),
CONSTRAINT "agenda_configuracoes_online_max_dias_futuro_check" CHECK ((("online_max_dias_futuro" >= 1) AND ("online_max_dias_futuro" <= 365))),
CONSTRAINT "agenda_configuracoes_online_min_antecedencia_horas_check" CHECK ((("online_min_antecedencia_horas" >= 0) AND ("online_min_antecedencia_horas" <= 720))),
CONSTRAINT "agenda_configuracoes_online_modalidade_check" CHECK (("online_modalidade" = ANY (ARRAY['online'::"text", 'presencial'::"text", 'ambos'::"text"]))),
CONSTRAINT "agenda_configuracoes_online_modo_check" CHECK (("online_modo" = ANY (ARRAY['automatico'::"text", 'aprovacao'::"text"]))),
CONSTRAINT "agenda_configuracoes_online_reagendar_ate_horas_check" CHECK ((("online_reagendar_ate_horas" >= 0) AND ("online_reagendar_ate_horas" <= 720))),
CONSTRAINT "session_break_min_chk" CHECK ((("session_break_min" >= 0) AND ("session_break_min" <= 60))),
CONSTRAINT "session_duration_min_chk" CHECK ((("session_duration_min" >= 10) AND ("session_duration_min" <= 240)))
);
ALTER TABLE "public"."agenda_configuracoes" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agenda_eventos" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"paciente_id" "uuid",
"tipo" "public"."tipo_evento_agenda" DEFAULT 'sessao'::"public"."tipo_evento_agenda" NOT NULL,
"status" "public"."status_evento_agenda" DEFAULT 'agendado'::"public"."status_evento_agenda" NOT NULL,
"titulo" "text",
"observacoes" "text",
"inicio_em" timestamp with time zone NOT NULL,
"fim_em" timestamp with time zone NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"terapeuta_id" "uuid",
"tenant_id" "uuid" NOT NULL,
"visibility_scope" "text" DEFAULT 'public'::"text" NOT NULL,
"mirror_of_event_id" "uuid",
"mirror_source" "text",
"patient_id" "uuid",
"determined_commitment_id" "uuid",
"link_online" "text",
"titulo_custom" "text",
"extra_fields" "jsonb",
"recurrence_id" "uuid",
"recurrence_date" "date",
"modalidade" "text" DEFAULT 'presencial'::"text",
CONSTRAINT "agenda_eventos_check" CHECK (("fim_em" > "inicio_em"))
);
ALTER TABLE "public"."agenda_eventos" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agenda_excecoes" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"data" "date" NOT NULL,
"hora_inicio" time without time zone,
"hora_fim" time without time zone,
"tipo" "public"."tipo_excecao_agenda" NOT NULL,
"motivo" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"status" "public"."status_excecao_agenda" DEFAULT 'ativo'::"public"."status_excecao_agenda" NOT NULL,
"fonte" "text" DEFAULT 'manual'::"text" NOT NULL,
"aplicavel_online" boolean DEFAULT true NOT NULL,
"tenant_id" "uuid" NOT NULL,
CONSTRAINT "agenda_excecoes_check" CHECK (((("hora_inicio" IS NULL) AND ("hora_fim" IS NULL)) OR (("hora_inicio" IS NOT NULL) AND ("hora_fim" IS NOT NULL) AND ("hora_fim" > "hora_inicio")))),
CONSTRAINT "agenda_excecoes_fonte_check" CHECK (("fonte" = ANY (ARRAY['manual'::"text", 'feriado_google'::"text", 'sistema'::"text"])))
);
ALTER TABLE "public"."agenda_excecoes" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agenda_online_slots" (
"id" bigint NOT NULL,
"owner_id" "uuid" NOT NULL,
"weekday" integer NOT NULL,
"time" time without time zone NOT NULL,
"enabled" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
CONSTRAINT "agenda_online_slots_weekday_check" CHECK (("weekday" = ANY (ARRAY[0, 1, 2, 3, 4, 5, 6])))
);
ALTER TABLE "public"."agenda_online_slots" OWNER TO "supabase_admin";
CREATE SEQUENCE IF NOT EXISTS "public"."agenda_online_slots_id_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE "public"."agenda_online_slots_id_seq" OWNER TO "supabase_admin";
ALTER SEQUENCE "public"."agenda_online_slots_id_seq" OWNED BY "public"."agenda_online_slots"."id";
CREATE TABLE IF NOT EXISTS "public"."agenda_regras_semanais" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"dia_semana" smallint NOT NULL,
"hora_inicio" time without time zone NOT NULL,
"hora_fim" time without time zone NOT NULL,
"modalidade" "text" DEFAULT 'ambos'::"text" NOT NULL,
"ativo" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
CONSTRAINT "agenda_regras_semanais_check" CHECK (("hora_fim" > "hora_inicio")),
CONSTRAINT "agenda_regras_semanais_dia_semana_check" CHECK ((("dia_semana" >= 0) AND ("dia_semana" <= 6))),
CONSTRAINT "agenda_regras_semanais_modalidade_check" CHECK ((("modalidade" = ANY (ARRAY['online'::"text", 'presencial'::"text", 'ambos'::"text"])) OR ("modalidade" IS NULL)))
);
ALTER TABLE "public"."agenda_regras_semanais" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agenda_slots_bloqueados_semanais" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"dia_semana" smallint NOT NULL,
"hora_inicio" time without time zone NOT NULL,
"motivo" "text",
"ativo" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
CONSTRAINT "agenda_slots_bloqueados_semanais_dia_semana_check" CHECK ((("dia_semana" >= 0) AND ("dia_semana" <= 6)))
);
ALTER TABLE "public"."agenda_slots_bloqueados_semanais" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agenda_slots_regras" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"dia_semana" smallint NOT NULL,
"passo_minutos" integer NOT NULL,
"offset_minutos" integer DEFAULT 0 NOT NULL,
"buffer_antes_min" integer DEFAULT 0 NOT NULL,
"buffer_depois_min" integer DEFAULT 0 NOT NULL,
"min_antecedencia_horas" integer DEFAULT 0 NOT NULL,
"ativo" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
CONSTRAINT "agenda_slots_regras_buffer_antes_min_check" CHECK ((("buffer_antes_min" >= 0) AND ("buffer_antes_min" <= 240))),
CONSTRAINT "agenda_slots_regras_buffer_depois_min_check" CHECK ((("buffer_depois_min" >= 0) AND ("buffer_depois_min" <= 240))),
CONSTRAINT "agenda_slots_regras_dia_semana_check" CHECK ((("dia_semana" >= 0) AND ("dia_semana" <= 6))),
CONSTRAINT "agenda_slots_regras_min_antecedencia_horas_check" CHECK ((("min_antecedencia_horas" >= 0) AND ("min_antecedencia_horas" <= 720))),
CONSTRAINT "agenda_slots_regras_offset_minutos_check" CHECK ((("offset_minutos" >= 0) AND ("offset_minutos" <= 55))),
CONSTRAINT "agenda_slots_regras_passo_minutos_check" CHECK ((("passo_minutos" >= 5) AND ("passo_minutos" <= 240)))
);
ALTER TABLE "public"."agenda_slots_regras" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agendador_configuracoes" (
"owner_id" "uuid" NOT NULL,
"tenant_id" "uuid",
"ativo" boolean DEFAULT false NOT NULL,
"link_slug" "text",
"imagem_fundo_url" "text",
"imagem_header_url" "text",
"logomarca_url" "text",
"cor_primaria" "text" DEFAULT '#4b6bff'::"text",
"nome_exibicao" "text",
"endereco" "text",
"botao_como_chegar_ativo" boolean DEFAULT true NOT NULL,
"maps_url" "text",
"modo_aprovacao" "text" DEFAULT 'aprovacao'::"text" NOT NULL,
"modalidade" "text" DEFAULT 'presencial'::"text" NOT NULL,
"tipos_habilitados" "jsonb" DEFAULT '["primeira", "retorno"]'::"jsonb" NOT NULL,
"duracao_sessao_min" integer DEFAULT 50 NOT NULL,
"antecedencia_minima_horas" integer DEFAULT 24 NOT NULL,
"prazo_resposta_horas" integer DEFAULT 2 NOT NULL,
"reserva_horas" integer DEFAULT 2 NOT NULL,
"pagamento_obrigatorio" boolean DEFAULT false NOT NULL,
"pix_chave" "text",
"pix_countdown_minutos" integer DEFAULT 20 NOT NULL,
"triagem_motivo" boolean DEFAULT true NOT NULL,
"triagem_como_conheceu" boolean DEFAULT false NOT NULL,
"verificacao_email" boolean DEFAULT false NOT NULL,
"exigir_aceite_lgpd" boolean DEFAULT true NOT NULL,
"mensagem_boas_vindas" "text",
"texto_como_se_preparar" "text",
"texto_termos_lgpd" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
CONSTRAINT "agendador_configuracoes_antecedencia_check" CHECK ((("antecedencia_minima_horas" >= 0) AND ("antecedencia_minima_horas" <= 720))),
CONSTRAINT "agendador_configuracoes_duracao_check" CHECK ((("duracao_sessao_min" >= 10) AND ("duracao_sessao_min" <= 240))),
CONSTRAINT "agendador_configuracoes_modalidade_check" CHECK (("modalidade" = ANY (ARRAY['presencial'::"text", 'online'::"text", 'ambos'::"text"]))),
CONSTRAINT "agendador_configuracoes_modo_check" CHECK (("modo_aprovacao" = ANY (ARRAY['automatico'::"text", 'aprovacao'::"text"]))),
CONSTRAINT "agendador_configuracoes_pix_countdown_check" CHECK ((("pix_countdown_minutos" >= 5) AND ("pix_countdown_minutos" <= 120))),
CONSTRAINT "agendador_configuracoes_prazo_check" CHECK ((("prazo_resposta_horas" >= 1) AND ("prazo_resposta_horas" <= 72))),
CONSTRAINT "agendador_configuracoes_reserva_check" CHECK ((("reserva_horas" >= 1) AND ("reserva_horas" <= 48)))
);
ALTER TABLE "public"."agendador_configuracoes" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."agendador_solicitacoes" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"tenant_id" "uuid",
"paciente_nome" "text" NOT NULL,
"paciente_sobrenome" "text",
"paciente_email" "text" NOT NULL,
"paciente_celular" "text",
"paciente_cpf" "text",
"tipo" "text" NOT NULL,
"modalidade" "text" NOT NULL,
"data_solicitada" "date" NOT NULL,
"hora_solicitada" time without time zone NOT NULL,
"reservado_ate" timestamp with time zone,
"motivo" "text",
"como_conheceu" "text",
"pix_status" "text" DEFAULT 'pendente'::"text",
"pix_pago_em" timestamp with time zone,
"status" "text" DEFAULT 'pendente'::"text" NOT NULL,
"recusado_motivo" "text",
"autorizado_em" timestamp with time zone,
"autorizado_por" "uuid",
"user_id" "uuid",
"patient_id" "uuid",
"evento_id" "uuid",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
CONSTRAINT "agendador_sol_modalidade_check" CHECK (("modalidade" = ANY (ARRAY['presencial'::"text", 'online'::"text"]))),
CONSTRAINT "agendador_sol_pix_check" CHECK ((("pix_status" IS NULL) OR ("pix_status" = ANY (ARRAY['pendente'::"text", 'pago'::"text", 'expirado'::"text"])))),
CONSTRAINT "agendador_sol_status_check" CHECK (("status" = ANY (ARRAY['pendente'::"text", 'autorizado'::"text", 'recusado'::"text", 'expirado'::"text", 'convertido'::"text"]))),
CONSTRAINT "agendador_sol_tipo_check" CHECK (("tipo" = ANY (ARRAY['primeira'::"text", 'retorno'::"text", 'reagendar'::"text"])))
);
ALTER TABLE "public"."agendador_solicitacoes" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."commitment_time_logs" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
"commitment_id" "uuid" NOT NULL,
"calendar_event_id" "uuid",
"source" "public"."commitment_log_source" DEFAULT 'manual'::"public"."commitment_log_source" NOT NULL,
"started_at" timestamp with time zone NOT NULL,
"ended_at" timestamp with time zone NOT NULL,
"minutes" integer NOT NULL,
"created_by" "uuid",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."commitment_time_logs" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."current_tenant_id" AS
SELECT "current_setting"('request.jwt.claim.tenant_id'::"text", true) AS "current_setting";
ALTER VIEW "public"."current_tenant_id" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."determined_commitment_fields" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
"commitment_id" "uuid" NOT NULL,
"key" "text" NOT NULL,
"label" "text" NOT NULL,
"field_type" "public"."determined_field_type" DEFAULT 'text'::"public"."determined_field_type" NOT NULL,
"required" boolean DEFAULT false NOT NULL,
"sort_order" integer DEFAULT 0 NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."determined_commitment_fields" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."determined_commitments" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
"created_by" "uuid",
"is_native" boolean DEFAULT false NOT NULL,
"native_key" "text",
"is_locked" boolean DEFAULT false NOT NULL,
"active" boolean DEFAULT true NOT NULL,
"name" "text" NOT NULL,
"description" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"bg_color" "text",
"text_color" "text"
);
ALTER TABLE "public"."determined_commitments" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."dev_user_credentials" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"user_id" "uuid",
"email" "text" NOT NULL,
"password_dev" "text" NOT NULL,
"kind" "text" DEFAULT 'custom'::"text" NOT NULL,
"note" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."dev_user_credentials" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."entitlements_invalidation" (
"owner_id" "uuid" NOT NULL,
"changed_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."entitlements_invalidation" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."features" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"key" "text" NOT NULL,
"description" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"descricao" "text" DEFAULT ''::"text" NOT NULL,
"name" "text" DEFAULT ''::"text" NOT NULL
);
ALTER TABLE "public"."features" OWNER TO "supabase_admin";
COMMENT ON COLUMN "public"."features"."descricao" IS 'Descrição humana da feature (exibição no admin e documentação).';
CREATE TABLE IF NOT EXISTS "public"."feriados" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid",
"owner_id" "uuid",
"tipo" "text" DEFAULT 'municipal'::"text" NOT NULL,
"nome" "text" NOT NULL,
"data" "date" NOT NULL,
"cidade" "text",
"estado" "text",
"observacao" "text",
"bloqueia_sessoes" boolean DEFAULT false NOT NULL,
"criado_em" timestamp with time zone DEFAULT "now"() NOT NULL,
CONSTRAINT "feriados_tipo_check" CHECK (("tipo" = ANY (ARRAY['municipal'::"text", 'personalizado'::"text"])))
);
ALTER TABLE "public"."feriados" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."module_features" (
"module_id" "uuid" NOT NULL,
"feature_id" "uuid" NOT NULL,
"enabled" boolean DEFAULT true NOT NULL,
"limits" "jsonb",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."module_features" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."modules" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"key" "text" NOT NULL,
"name" "text" NOT NULL,
"description" "text",
"is_active" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."modules" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."plan_features" (
"plan_id" "uuid" NOT NULL,
"feature_id" "uuid" NOT NULL,
"enabled" boolean DEFAULT true NOT NULL,
"limits" "jsonb",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."plan_features" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."tenant_modules" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"module_id" "uuid" NOT NULL,
"status" "text" DEFAULT 'active'::"text" NOT NULL,
"settings" "jsonb",
"provider" "text" DEFAULT 'manual'::"text" NOT NULL,
"provider_item_id" "text",
"installed_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."tenant_modules" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."owner_feature_entitlements" AS
WITH "base" AS (
SELECT "s"."user_id" AS "owner_id",
"f"."key" AS "feature_key",
"pf"."limits",
'plan'::"text" AS "source"
FROM (("public"."subscriptions" "s"
JOIN "public"."plan_features" "pf" ON ((("pf"."plan_id" = "s"."plan_id") AND ("pf"."enabled" = true))))
JOIN "public"."features" "f" ON (("f"."id" = "pf"."feature_id")))
WHERE (("s"."status" = 'active'::"text") AND ("s"."user_id" IS NOT NULL))
UNION ALL
SELECT "tm"."owner_id",
"f"."key" AS "feature_key",
"mf"."limits",
'module'::"text" AS "source"
FROM ((("public"."tenant_modules" "tm"
JOIN "public"."modules" "m" ON ((("m"."id" = "tm"."module_id") AND ("m"."is_active" = true))))
JOIN "public"."module_features" "mf" ON ((("mf"."module_id" = "m"."id") AND ("mf"."enabled" = true))))
JOIN "public"."features" "f" ON (("f"."id" = "mf"."feature_id")))
WHERE (("tm"."status" = 'active'::"text") AND ("tm"."owner_id" IS NOT NULL))
)
SELECT "owner_id",
"feature_key",
"array_agg"(DISTINCT "source") AS "sources",
"jsonb_agg"("limits") FILTER (WHERE ("limits" IS NOT NULL)) AS "limits_list"
FROM "base"
GROUP BY "owner_id", "feature_key";
ALTER VIEW "public"."owner_feature_entitlements" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."owner_users" (
"owner_id" "uuid" NOT NULL,
"user_id" "uuid" NOT NULL,
"role" "text" DEFAULT 'admin'::"text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."owner_users" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."patient_group_patient" (
"patient_group_id" "uuid" NOT NULL,
"patient_id" "uuid" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"(),
"tenant_id" "uuid" NOT NULL
);
ALTER TABLE "public"."patient_group_patient" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."patient_groups" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"nome" "text" NOT NULL,
"descricao" "text",
"cor" "text",
"is_active" boolean DEFAULT true NOT NULL,
"is_system" boolean DEFAULT false NOT NULL,
"owner_id" "uuid" DEFAULT "auth"."uid"() NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"therapist_id" "uuid",
"tenant_id" "uuid" NOT NULL
);
ALTER TABLE "public"."patient_groups" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."patient_intake_requests" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"token" "text" NOT NULL,
"consent" boolean DEFAULT false NOT NULL,
"status" "text" DEFAULT 'new'::"text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"converted_patient_id" "uuid",
"rejected_reason" "text",
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"cpf" "text",
"rg" "text",
"cep" "text",
"nome_completo" "text",
"email_principal" "text",
"telefone" "text",
"pais" "text",
"cidade" "text",
"estado" "text",
"endereco" "text",
"numero" "text",
"bairro" "text",
"complemento" "text",
"data_nascimento" "date",
"naturalidade" "text",
"genero" "text",
"estado_civil" "text",
"onde_nos_conheceu" "text",
"encaminhado_por" "text",
"observacoes" "text",
"notas_internas" "text",
"email_alternativo" "text",
"telefone_alternativo" "text",
"profissao" "text",
"escolaridade" "text",
"nacionalidade" "text",
"avatar_url" "text",
"tenant_id" "uuid",
CONSTRAINT "chk_intakes_status" CHECK (("status" = ANY (ARRAY['new'::"text", 'converted'::"text", 'rejected'::"text"])))
);
ALTER TABLE "public"."patient_intake_requests" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."patient_invites" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"token" "text" NOT NULL,
"active" boolean DEFAULT true NOT NULL,
"expires_at" timestamp with time zone,
"max_uses" integer,
"uses" integer DEFAULT 0 NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"tenant_id" "uuid"
);
ALTER TABLE "public"."patient_invites" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."patient_patient_tag" (
"owner_id" "uuid" NOT NULL,
"patient_id" "uuid" NOT NULL,
"tag_id" "uuid" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"tenant_id" "uuid" NOT NULL
);
ALTER TABLE "public"."patient_patient_tag" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."patient_tags" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"owner_id" "uuid" NOT NULL,
"nome" "text" NOT NULL,
"cor" "text",
"is_padrao" boolean DEFAULT false NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone,
"tenant_id" "uuid" NOT NULL
);
ALTER TABLE "public"."patient_tags" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."patients" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"nome_completo" "text" NOT NULL,
"email_principal" "text",
"telefone" "text",
"created_at" timestamp with time zone DEFAULT "now"(),
"owner_id" "uuid",
"avatar_url" "text",
"status" "text" DEFAULT 'Ativo'::"text",
"last_attended_at" timestamp with time zone,
"is_native" boolean DEFAULT false,
"naturalidade" "text",
"data_nascimento" "date",
"rg" "text",
"cpf" "text",
"identification_color" "text",
"genero" "text",
"estado_civil" "text",
"email_alternativo" "text",
"pais" "text" DEFAULT 'Brasil'::"text",
"cep" "text",
"cidade" "text",
"estado" "text",
"endereco" "text",
"numero" "text",
"bairro" "text",
"complemento" "text",
"escolaridade" "text",
"profissao" "text",
"nome_parente" "text",
"grau_parentesco" "text",
"telefone_alternativo" "text",
"onde_nos_conheceu" "text",
"encaminhado_por" "text",
"nome_responsavel" "text",
"telefone_responsavel" "text",
"cpf_responsavel" "text",
"observacao_responsavel" "text",
"cobranca_no_responsavel" boolean DEFAULT false,
"observacoes" "text",
"notas_internas" "text",
"updated_at" timestamp with time zone DEFAULT "now"(),
"telefone_parente" "text",
"tenant_id" "uuid" NOT NULL,
"responsible_member_id" "uuid" NOT NULL,
"user_id" "uuid",
"patient_scope" "text" DEFAULT 'clinic'::"text" NOT NULL,
"therapist_member_id" "uuid",
CONSTRAINT "cpf_responsavel_format_check" CHECK ((("cpf_responsavel" IS NULL) OR ("cpf_responsavel" ~ '^\d{11}$'::"text"))),
CONSTRAINT "patients_cpf_format_check" CHECK ((("cpf" IS NULL) OR ("cpf" ~ '^\d{11}$'::"text"))),
CONSTRAINT "patients_patient_scope_check" CHECK (("patient_scope" = ANY (ARRAY['clinic'::"text", 'therapist'::"text"]))),
CONSTRAINT "patients_status_check" CHECK (("status" = ANY (ARRAY['Ativo'::"text", 'Inativo'::"text", 'Alta'::"text", 'Encaminhado'::"text"]))),
CONSTRAINT "patients_therapist_scope_consistency" CHECK (((("patient_scope" = 'clinic'::"text") AND ("therapist_member_id" IS NULL)) OR (("patient_scope" = 'therapist'::"text") AND ("therapist_member_id" IS NOT NULL))))
);
ALTER TABLE "public"."patients" OWNER TO "supabase_admin";
COMMENT ON COLUMN "public"."patients"."avatar_url" IS 'URL pública da imagem de avatar armazenada no Supabase Storage';
CREATE TABLE IF NOT EXISTS "public"."plan_prices" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"plan_id" "uuid" NOT NULL,
"currency" "text" DEFAULT 'BRL'::"text" NOT NULL,
"interval" "text" NOT NULL,
"amount_cents" integer NOT NULL,
"is_active" boolean DEFAULT true NOT NULL,
"active_from" timestamp with time zone DEFAULT "now"() NOT NULL,
"active_to" timestamp with time zone,
"source" "text" DEFAULT 'manual'::"text" NOT NULL,
"provider" "text",
"provider_price_id" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
CONSTRAINT "plan_prices_amount_cents_check" CHECK (("amount_cents" >= 0)),
CONSTRAINT "plan_prices_interval_check" CHECK (("interval" = ANY (ARRAY['month'::"text", 'year'::"text"])))
);
ALTER TABLE "public"."plan_prices" OWNER TO "supabase_admin";
COMMENT ON TABLE "public"."plan_prices" IS 'Histórico de preços por plano (fonte: manual/gateway).';
CREATE TABLE IF NOT EXISTS "public"."plan_public" (
"plan_id" "uuid" NOT NULL,
"public_name" "text" DEFAULT ''::"text" NOT NULL,
"public_description" "text" DEFAULT ''::"text" NOT NULL,
"badge" "text",
"is_featured" boolean DEFAULT false NOT NULL,
"is_visible" boolean DEFAULT true NOT NULL,
"sort_order" integer DEFAULT 0 NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."plan_public" OWNER TO "supabase_admin";
COMMENT ON TABLE "public"."plan_public" IS 'Configuração de vitrine (página pública) dos planos.';
CREATE TABLE IF NOT EXISTS "public"."plan_public_bullets" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"plan_id" "uuid" NOT NULL,
"text" "text" NOT NULL,
"sort_order" integer DEFAULT 0 NOT NULL,
"highlight" boolean DEFAULT false NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."plan_public_bullets" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."plans" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"key" "text" NOT NULL,
"name" "text" NOT NULL,
"description" "text",
"is_active" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"price_cents" integer DEFAULT 0 NOT NULL,
"currency" "text" DEFAULT 'BRL'::"text" NOT NULL,
"billing_interval" "text" DEFAULT 'month'::"text" NOT NULL,
"target" "text",
"max_supervisees" integer,
CONSTRAINT "plans_target_check" CHECK (("target" = ANY (ARRAY['patient'::"text", 'therapist'::"text", 'clinic'::"text", 'supervisor'::"text"])))
);
ALTER TABLE "public"."plans" OWNER TO "supabase_admin";
COMMENT ON COLUMN "public"."plans"."name" IS 'Nome interno do plano (admin). A key é técnica/imutável.';
COMMENT ON COLUMN "public"."plans"."target" IS 'Público-alvo do plano: patient, therapist ou clinic.';
COMMENT ON COLUMN "public"."plans"."max_supervisees" IS 'Limite de terapeutas que podem ser supervisionados. Apenas para planos target=supervisor. NULL = sem limite.';
CREATE TABLE IF NOT EXISTS "public"."profiles" (
"id" "uuid" NOT NULL,
"role" "text" DEFAULT 'tenant_member'::"text" NOT NULL,
"full_name" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"avatar_url" "text",
"phone" "text",
"bio" "text",
"language" "text" DEFAULT 'pt-BR'::"text" NOT NULL,
"timezone" "text" DEFAULT 'America/Sao_Paulo'::"text" NOT NULL,
"notify_system_email" boolean DEFAULT true NOT NULL,
"notify_reminders" boolean DEFAULT true NOT NULL,
"notify_news" boolean DEFAULT false NOT NULL,
"account_type" "text" DEFAULT 'free'::"text" NOT NULL,
"platform_roles" "text"[] DEFAULT '{}'::"text"[] NOT NULL,
CONSTRAINT "profiles_account_type_check" CHECK (("account_type" = ANY (ARRAY['free'::"text", 'patient'::"text", 'therapist'::"text", 'clinic'::"text"]))),
CONSTRAINT "profiles_role_check" CHECK (("role" = ANY (ARRAY['saas_admin'::"text", 'tenant_member'::"text", 'portal_user'::"text", 'patient'::"text"])))
);
ALTER TABLE "public"."profiles" OWNER TO "supabase_admin";
COMMENT ON COLUMN "public"."profiles"."account_type" IS 'Tipo de conta: free=sem perfil ainda, patient=paciente (imutável), therapist=terapeuta (imutável), clinic=clínica (imutável).';
COMMENT ON COLUMN "public"."profiles"."platform_roles" IS 'Papéis globais de plataforma, independentes de tenant. Ex: editor de microlearning. Atribuído pelo saas_admin.';
CREATE TABLE IF NOT EXISTS "public"."recurrence_exceptions" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"recurrence_id" "uuid" NOT NULL,
"tenant_id" "uuid" NOT NULL,
"original_date" "date" NOT NULL,
"type" "public"."recurrence_exception_type" NOT NULL,
"new_date" "date",
"new_start_time" time without time zone,
"new_end_time" time without time zone,
"modalidade" "text",
"observacoes" "text",
"titulo_custom" "text",
"extra_fields" "jsonb",
"reason" "text",
"agenda_evento_id" "uuid",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."recurrence_exceptions" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."recurrence_rules" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
"owner_id" "uuid" NOT NULL,
"therapist_id" "uuid",
"patient_id" "uuid",
"determined_commitment_id" "uuid",
"type" "public"."recurrence_type" DEFAULT 'weekly'::"public"."recurrence_type" NOT NULL,
"interval" smallint DEFAULT 1 NOT NULL,
"weekdays" smallint[] DEFAULT '{}'::smallint[] NOT NULL,
"start_time" time without time zone NOT NULL,
"end_time" time without time zone NOT NULL,
"timezone" "text" DEFAULT 'America/Sao_Paulo'::"text" NOT NULL,
"duration_min" smallint DEFAULT 50 NOT NULL,
"start_date" "date" NOT NULL,
"end_date" "date",
"max_occurrences" integer,
"open_ended" boolean DEFAULT true NOT NULL,
"modalidade" "text" DEFAULT 'presencial'::"text",
"titulo_custom" "text",
"observacoes" "text",
"extra_fields" "jsonb",
"status" "text" DEFAULT 'ativo'::"text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
CONSTRAINT "recurrence_rules_dates_chk" CHECK ((("end_date" IS NULL) OR ("end_date" >= "start_date"))),
CONSTRAINT "recurrence_rules_interval_chk" CHECK (("interval" >= 1)),
CONSTRAINT "recurrence_rules_status_check" CHECK (("status" = ANY (ARRAY['ativo'::"text", 'pausado'::"text", 'cancelado'::"text"]))),
CONSTRAINT "recurrence_rules_times_chk" CHECK (("end_time" > "start_time"))
);
ALTER TABLE "public"."recurrence_rules" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."saas_admins" (
"user_id" "uuid" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."saas_admins" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."saas_doc_votos" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"doc_id" "uuid" NOT NULL,
"user_id" "uuid" NOT NULL,
"util" boolean NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."saas_doc_votos" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."saas_docs" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"titulo" "text" NOT NULL,
"conteudo" "text" DEFAULT ''::"text" NOT NULL,
"medias" "jsonb" DEFAULT '[]'::"jsonb" NOT NULL,
"tipo_acesso" "text" DEFAULT 'usuario'::"text" NOT NULL,
"pagina_path" "text" NOT NULL,
"docs_relacionados" "uuid"[] DEFAULT '{}'::"uuid"[] NOT NULL,
"ativo" boolean DEFAULT true NOT NULL,
"ordem" integer DEFAULT 0 NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"categoria" "text",
"exibir_no_faq" boolean DEFAULT false NOT NULL,
"votos_util" integer DEFAULT 0 NOT NULL,
"votos_nao_util" integer DEFAULT 0 NOT NULL,
CONSTRAINT "saas_docs_tipo_acesso_check" CHECK (("tipo_acesso" = ANY (ARRAY['admin'::"text", 'usuario'::"text"])))
);
ALTER TABLE "public"."saas_docs" OWNER TO "supabase_admin";
COMMENT ON COLUMN "public"."saas_docs"."categoria" IS 'Agrupa docs no portal FAQ (ex: Conta, Agenda, Pagamentos)';
COMMENT ON COLUMN "public"."saas_docs"."exibir_no_faq" IS 'Se true, a doc e seus itens FAQ aparecem no portal de FAQ';
CREATE TABLE IF NOT EXISTS "public"."saas_faq" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"pergunta" "text" NOT NULL,
"categoria" "text",
"publico" boolean DEFAULT false NOT NULL,
"votos" integer DEFAULT 0 NOT NULL,
"titulo" "text",
"conteudo" "text",
"tipo_acesso" "text" DEFAULT 'usuario'::"text" NOT NULL,
"pagina_path" "text" NOT NULL,
"pagina_label" "text",
"medias" "jsonb" DEFAULT '[]'::"jsonb" NOT NULL,
"faqs_relacionados" "uuid"[] DEFAULT '{}'::"uuid"[] NOT NULL,
"ativo" boolean DEFAULT true NOT NULL,
"ordem" integer DEFAULT 0 NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."saas_faq" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."saas_faq_itens" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"doc_id" "uuid" NOT NULL,
"pergunta" "text" NOT NULL,
"resposta" "text",
"ordem" integer DEFAULT 0 NOT NULL,
"ativo" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."saas_faq_itens" OWNER TO "supabase_admin";
COMMENT ON TABLE "public"."saas_faq_itens" IS 'Pares pergunta/resposta vinculados a um documento de ajuda';
CREATE TABLE IF NOT EXISTS "public"."subscription_events" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"subscription_id" "uuid" NOT NULL,
"owner_id" "uuid" NOT NULL,
"event_type" "text" NOT NULL,
"old_plan_id" "uuid",
"new_plan_id" "uuid",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"created_by" "uuid",
"source" "text" DEFAULT 'admin_ui'::"text",
"reason" "text",
"metadata" "jsonb",
"owner_type" "text" NOT NULL,
"owner_ref" "uuid" NOT NULL,
CONSTRAINT "subscription_events_owner_ref_consistency_chk" CHECK (("owner_id" = "owner_ref")),
CONSTRAINT "subscription_events_owner_type_chk" CHECK ((("owner_type" IS NULL) OR ("owner_type" = ANY (ARRAY['clinic'::"text", 'therapist'::"text"]))))
);
ALTER TABLE "public"."subscription_events" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."subscription_intents_personal" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"user_id" "uuid" NOT NULL,
"created_by_user_id" "uuid",
"email" "text" NOT NULL,
"plan_id" "uuid" NOT NULL,
"plan_key" "text",
"interval" "text",
"amount_cents" integer,
"currency" "text",
"status" "text" DEFAULT 'new'::"text" NOT NULL,
"source" "text" DEFAULT 'manual'::"text" NOT NULL,
"notes" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"paid_at" timestamp with time zone,
"subscription_id" "uuid",
CONSTRAINT "sint_personal_interval_check" CHECK ((("interval" IS NULL) OR ("interval" = ANY (ARRAY['month'::"text", 'year'::"text"])))),
CONSTRAINT "sint_personal_status_check" CHECK (("status" = ANY (ARRAY['new'::"text", 'waiting_payment'::"text", 'paid'::"text", 'canceled'::"text"])))
);
ALTER TABLE "public"."subscription_intents_personal" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."subscription_intents_tenant" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"user_id" "uuid" NOT NULL,
"created_by_user_id" "uuid",
"email" "text" NOT NULL,
"plan_id" "uuid" NOT NULL,
"plan_key" "text",
"interval" "text",
"amount_cents" integer,
"currency" "text",
"status" "text" DEFAULT 'new'::"text" NOT NULL,
"source" "text" DEFAULT 'manual'::"text" NOT NULL,
"notes" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"paid_at" timestamp with time zone,
"tenant_id" "uuid" NOT NULL,
"subscription_id" "uuid",
CONSTRAINT "sint_tenant_interval_check" CHECK ((("interval" IS NULL) OR ("interval" = ANY (ARRAY['month'::"text", 'year'::"text"])))),
CONSTRAINT "sint_tenant_status_check" CHECK (("status" = ANY (ARRAY['new'::"text", 'waiting_payment'::"text", 'paid'::"text", 'canceled'::"text"])))
);
ALTER TABLE "public"."subscription_intents_tenant" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."subscription_intents" AS
SELECT "t"."id",
"t"."user_id",
"t"."created_by_user_id",
"t"."email",
"t"."plan_id",
"t"."plan_key",
"t"."interval",
"t"."amount_cents",
"t"."currency",
"t"."status",
"t"."source",
"t"."notes",
"t"."created_at",
"t"."paid_at",
"t"."tenant_id",
"t"."subscription_id",
'clinic'::"text" AS "plan_target"
FROM "public"."subscription_intents_tenant" "t"
UNION ALL
SELECT "p"."id",
"p"."user_id",
"p"."created_by_user_id",
"p"."email",
"p"."plan_id",
"p"."plan_key",
"p"."interval",
"p"."amount_cents",
"p"."currency",
"p"."status",
"p"."source",
"p"."notes",
"p"."created_at",
"p"."paid_at",
NULL::"uuid" AS "tenant_id",
"p"."subscription_id",
'therapist'::"text" AS "plan_target"
FROM "public"."subscription_intents_personal" "p";
ALTER VIEW "public"."subscription_intents" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."subscription_intents_legacy" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"user_id" "uuid",
"email" "text",
"plan_key" "text" NOT NULL,
"interval" "text" NOT NULL,
"amount_cents" integer NOT NULL,
"currency" "text" DEFAULT 'BRL'::"text" NOT NULL,
"status" "text" DEFAULT 'new'::"text" NOT NULL,
"source" "text" DEFAULT 'landing'::"text" NOT NULL,
"notes" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"paid_at" timestamp with time zone,
"tenant_id" "uuid" NOT NULL,
"created_by_user_id" "uuid",
CONSTRAINT "subscription_intents_interval_check" CHECK (("interval" = ANY (ARRAY['month'::"text", 'year'::"text"]))),
CONSTRAINT "subscription_intents_status_check" CHECK (("status" = ANY (ARRAY['new'::"text", 'waiting_payment'::"text", 'paid'::"text", 'canceled'::"text"])))
);
ALTER TABLE "public"."subscription_intents_legacy" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."tenant_feature_exceptions_log" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
"feature_key" "text" NOT NULL,
"enabled" boolean NOT NULL,
"reason" "text",
"created_by" "uuid",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."tenant_feature_exceptions_log" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."tenant_features" (
"tenant_id" "uuid" NOT NULL,
"feature_key" "text" NOT NULL,
"enabled" boolean DEFAULT false NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."tenant_features" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."tenant_invites" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"tenant_id" "uuid" NOT NULL,
"email" "text" NOT NULL,
"role" "text" NOT NULL,
"token" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"invited_by" "uuid",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"expires_at" timestamp with time zone DEFAULT ("now"() + '7 days'::interval) NOT NULL,
"accepted_at" timestamp with time zone,
"accepted_by" "uuid",
"revoked_at" timestamp with time zone,
"revoked_by" "uuid",
CONSTRAINT "tenant_invites_role_check" CHECK (("role" = ANY (ARRAY['therapist'::"text", 'secretary'::"text"])))
);
ALTER TABLE "public"."tenant_invites" OWNER TO "supabase_admin";
CREATE TABLE IF NOT EXISTS "public"."tenants" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"name" "text",
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"kind" "text" DEFAULT 'saas'::"text" NOT NULL,
CONSTRAINT "tenants_kind_check" CHECK (("kind" = ANY (ARRAY['therapist'::"text", 'clinic_coworking'::"text", 'clinic_reception'::"text", 'clinic_full'::"text", 'clinic'::"text", 'saas'::"text", 'supervisor'::"text"])))
);
ALTER TABLE "public"."tenants" OWNER TO "supabase_admin";
COMMENT ON COLUMN "public"."tenants"."kind" IS 'Tipo do tenant. Imutável após criação. therapist=terapeuta solo. clinic_coworking/clinic_reception/clinic_full=clínicas. clinic e saas são legados.';
CREATE TABLE IF NOT EXISTS "public"."user_settings" (
"user_id" "uuid" NOT NULL,
"theme_mode" "text" DEFAULT 'dark'::"text" NOT NULL,
"preset" "text" DEFAULT 'Aura'::"text" NOT NULL,
"primary_color" "text" DEFAULT 'noir'::"text" NOT NULL,
"surface_color" "text" DEFAULT 'slate'::"text" NOT NULL,
"menu_mode" "text" DEFAULT 'static'::"text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."user_settings" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_auth_users_public" AS
SELECT "id" AS "user_id",
"email",
"created_at",
"last_sign_in_at"
FROM "auth"."users" "u";
ALTER VIEW "public"."v_auth_users_public" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_commitment_totals" AS
SELECT "c"."tenant_id",
"c"."id" AS "commitment_id",
(COALESCE("sum"("l"."minutes"), (0)::bigint))::integer AS "total_minutes"
FROM ("public"."determined_commitments" "c"
LEFT JOIN "public"."commitment_time_logs" "l" ON (("l"."commitment_id" = "c"."id")))
GROUP BY "c"."tenant_id", "c"."id";
ALTER VIEW "public"."v_commitment_totals" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_patient_groups_with_counts" AS
SELECT "pg"."id",
"pg"."nome",
"pg"."cor",
"pg"."owner_id",
"pg"."is_system",
"pg"."is_active",
"pg"."created_at",
"pg"."updated_at",
(COALESCE("count"("pgp"."patient_id"), (0)::bigint))::integer AS "patients_count"
FROM ("public"."patient_groups" "pg"
LEFT JOIN "public"."patient_group_patient" "pgp" ON (("pgp"."patient_group_id" = "pg"."id")))
GROUP BY "pg"."id", "pg"."nome", "pg"."cor", "pg"."owner_id", "pg"."is_system", "pg"."is_active", "pg"."created_at", "pg"."updated_at";
ALTER VIEW "public"."v_patient_groups_with_counts" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_plan_active_prices" AS
SELECT "plan_id",
"max"(
CASE
WHEN (("interval" = 'month'::"text") AND "is_active") THEN "amount_cents"
ELSE NULL::integer
END) AS "monthly_cents",
"max"(
CASE
WHEN (("interval" = 'year'::"text") AND "is_active") THEN "amount_cents"
ELSE NULL::integer
END) AS "yearly_cents",
"max"(
CASE
WHEN (("interval" = 'month'::"text") AND "is_active") THEN "currency"
ELSE NULL::"text"
END) AS "monthly_currency",
"max"(
CASE
WHEN (("interval" = 'year'::"text") AND "is_active") THEN "currency"
ELSE NULL::"text"
END) AS "yearly_currency"
FROM "public"."plan_prices"
GROUP BY "plan_id";
ALTER VIEW "public"."v_plan_active_prices" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_public_pricing" AS
SELECT "p"."id" AS "plan_id",
"p"."key" AS "plan_key",
"p"."name" AS "plan_name",
COALESCE("pp"."public_name", ''::"text") AS "public_name",
COALESCE("pp"."public_description", ''::"text") AS "public_description",
"pp"."badge",
COALESCE("pp"."is_featured", false) AS "is_featured",
COALESCE("pp"."is_visible", true) AS "is_visible",
COALESCE("pp"."sort_order", 0) AS "sort_order",
"ap"."monthly_cents",
"ap"."yearly_cents",
"ap"."monthly_currency",
"ap"."yearly_currency",
COALESCE(( SELECT "jsonb_agg"("jsonb_build_object"('id', "b"."id", 'text', "b"."text", 'highlight', "b"."highlight", 'sort_order', "b"."sort_order") ORDER BY "b"."sort_order", "b"."created_at") AS "jsonb_agg"
FROM "public"."plan_public_bullets" "b"
WHERE ("b"."plan_id" = "p"."id")), '[]'::"jsonb") AS "bullets",
"p"."target" AS "plan_target"
FROM (("public"."plans" "p"
LEFT JOIN "public"."plan_public" "pp" ON (("pp"."plan_id" = "p"."id")))
LEFT JOIN "public"."v_plan_active_prices" "ap" ON (("ap"."plan_id" = "p"."id")))
ORDER BY COALESCE("pp"."sort_order", 0), "p"."key";
ALTER VIEW "public"."v_public_pricing" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_subscription_feature_mismatch" AS
WITH "expected" AS (
SELECT "s"."user_id" AS "owner_id",
"f"."key" AS "feature_key"
FROM (("public"."subscriptions" "s"
JOIN "public"."plan_features" "pf" ON ((("pf"."plan_id" = "s"."plan_id") AND ("pf"."enabled" = true))))
JOIN "public"."features" "f" ON (("f"."id" = "pf"."feature_id")))
WHERE (("s"."status" = 'active'::"text") AND ("s"."tenant_id" IS NULL) AND ("s"."user_id" IS NOT NULL))
), "actual" AS (
SELECT "e"."owner_id",
"e"."feature_key"
FROM "public"."owner_feature_entitlements" "e"
)
SELECT COALESCE("expected"."owner_id", "actual"."owner_id") AS "owner_id",
COALESCE("expected"."feature_key", "actual"."feature_key") AS "feature_key",
CASE
WHEN (("expected"."feature_key" IS NOT NULL) AND ("actual"."feature_key" IS NULL)) THEN 'missing_entitlement'::"text"
WHEN (("expected"."feature_key" IS NULL) AND ("actual"."feature_key" IS NOT NULL)) THEN 'unexpected_entitlement'::"text"
ELSE NULL::"text"
END AS "mismatch_type"
FROM ("expected"
FULL JOIN "actual" ON ((("expected"."owner_id" = "actual"."owner_id") AND ("expected"."feature_key" = "actual"."feature_key"))))
WHERE (("expected"."feature_key" IS NULL) OR ("actual"."feature_key" IS NULL));
ALTER VIEW "public"."v_subscription_feature_mismatch" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_subscription_health" AS
SELECT "s"."id" AS "subscription_id",
"s"."user_id" AS "owner_id",
"s"."status",
"s"."plan_id",
"p"."key" AS "plan_key",
"s"."current_period_start",
"s"."current_period_end",
"s"."updated_at",
CASE
WHEN ("s"."plan_id" IS NULL) THEN 'missing_plan'::"text"
WHEN ("p"."id" IS NULL) THEN 'invalid_plan'::"text"
WHEN (("s"."status" = 'active'::"text") AND ("s"."current_period_end" IS NOT NULL) AND ("s"."current_period_end" < "now"())) THEN 'expired_but_active'::"text"
WHEN (("s"."status" = 'canceled'::"text") AND ("s"."current_period_end" > "now"())) THEN 'canceled_but_still_in_period'::"text"
ELSE 'ok'::"text"
END AS "health_status",
CASE
WHEN ("s"."tenant_id" IS NOT NULL) THEN 'clinic'::"text"
ELSE 'therapist'::"text"
END AS "owner_type",
COALESCE("s"."tenant_id", "s"."user_id") AS "owner_ref"
FROM ("public"."subscriptions" "s"
LEFT JOIN "public"."plans" "p" ON (("p"."id" = "s"."plan_id")));
ALTER VIEW "public"."v_subscription_health" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_subscription_health_v2" AS
SELECT "s"."id" AS "subscription_id",
"s"."user_id" AS "owner_id",
CASE
WHEN ("s"."tenant_id" IS NOT NULL) THEN 'clinic'::"text"
ELSE 'therapist'::"text"
END AS "owner_type",
COALESCE("s"."tenant_id", "s"."user_id") AS "owner_ref",
"s"."status",
"s"."plan_id",
"p"."key" AS "plan_key",
"s"."current_period_start",
"s"."current_period_end",
"s"."updated_at",
CASE
WHEN ("s"."plan_id" IS NULL) THEN 'missing_plan'::"text"
WHEN ("p"."id" IS NULL) THEN 'invalid_plan'::"text"
WHEN (("s"."status" = 'active'::"text") AND ("s"."current_period_end" IS NOT NULL) AND ("s"."current_period_end" < "now"())) THEN 'expired_but_active'::"text"
WHEN (("s"."status" = 'canceled'::"text") AND ("s"."current_period_end" > "now"())) THEN 'canceled_but_still_in_period'::"text"
ELSE 'ok'::"text"
END AS "health_status"
FROM ("public"."subscriptions" "s"
LEFT JOIN "public"."plans" "p" ON (("p"."id" = "s"."plan_id")));
ALTER VIEW "public"."v_subscription_health_v2" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tag_patient_counts" AS
SELECT "t"."id",
"t"."owner_id",
"t"."nome",
"t"."cor",
"t"."is_padrao",
"t"."created_at",
"t"."updated_at",
(COALESCE("count"("ppt"."patient_id"), (0)::bigint))::integer AS "pacientes_count",
(COALESCE("count"("ppt"."patient_id"), (0)::bigint))::integer AS "patient_count"
FROM ("public"."patient_tags" "t"
LEFT JOIN "public"."patient_patient_tag" "ppt" ON ((("ppt"."tag_id" = "t"."id") AND ("ppt"."owner_id" = "t"."owner_id"))))
GROUP BY "t"."id", "t"."owner_id", "t"."nome", "t"."cor", "t"."is_padrao", "t"."created_at", "t"."updated_at";
ALTER VIEW "public"."v_tag_patient_counts" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_active_subscription" AS
SELECT DISTINCT ON ("tenant_id") "tenant_id",
"plan_id",
"plan_key",
"interval",
"status",
"current_period_start",
"current_period_end",
"created_at"
FROM "public"."subscriptions" "s"
WHERE (("tenant_id" IS NOT NULL) AND ("status" = 'active'::"text") AND (("current_period_end" IS NULL) OR ("current_period_end" > "now"())))
ORDER BY "tenant_id", "created_at" DESC;
ALTER VIEW "public"."v_tenant_active_subscription" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_entitlements" AS
SELECT "a"."tenant_id",
"f"."key" AS "feature_key",
true AS "allowed"
FROM (("public"."v_tenant_active_subscription" "a"
JOIN "public"."plan_features" "pf" ON ((("pf"."plan_id" = "a"."plan_id") AND ("pf"."enabled" = true))))
JOIN "public"."features" "f" ON (("f"."id" = "pf"."feature_id")));
ALTER VIEW "public"."v_tenant_entitlements" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_entitlements_full" AS
SELECT "a"."tenant_id",
"f"."key" AS "feature_key",
("pf"."enabled" = true) AS "allowed",
"pf"."limits",
"a"."plan_id",
"p"."key" AS "plan_key"
FROM ((("public"."v_tenant_active_subscription" "a"
JOIN "public"."plan_features" "pf" ON (("pf"."plan_id" = "a"."plan_id")))
JOIN "public"."features" "f" ON (("f"."id" = "pf"."feature_id")))
JOIN "public"."plans" "p" ON (("p"."id" = "a"."plan_id")));
ALTER VIEW "public"."v_tenant_entitlements_full" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_entitlements_json" AS
SELECT "tenant_id",
"max"("plan_key") AS "plan_key",
"jsonb_object_agg"("feature_key", "jsonb_build_object"('allowed', "allowed", 'limits', COALESCE("limits", '{}'::"jsonb")) ORDER BY "feature_key") AS "entitlements"
FROM "public"."v_tenant_entitlements_full"
GROUP BY "tenant_id";
ALTER VIEW "public"."v_tenant_entitlements_json" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_feature_exceptions" AS
SELECT "tf"."tenant_id",
"a"."plan_key",
"tf"."feature_key",
'commercial_exception'::"text" AS "exception_type"
FROM (("public"."tenant_features" "tf"
JOIN "public"."v_tenant_active_subscription" "a" ON (("a"."tenant_id" = "tf"."tenant_id")))
LEFT JOIN "public"."v_tenant_entitlements_full" "v" ON ((("v"."tenant_id" = "tf"."tenant_id") AND ("v"."feature_key" = "tf"."feature_key"))))
WHERE (("tf"."enabled" = true) AND (COALESCE("v"."allowed", false) = false));
ALTER VIEW "public"."v_tenant_feature_exceptions" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_feature_mismatch" AS
WITH "plan_allowed" AS (
SELECT "v"."tenant_id",
"v"."feature_key",
"v"."allowed"
FROM "public"."v_tenant_entitlements_full" "v"
), "overrides" AS (
SELECT "tf"."tenant_id",
"tf"."feature_key",
"tf"."enabled"
FROM "public"."tenant_features" "tf"
)
SELECT "o"."tenant_id",
"o"."feature_key",
CASE
WHEN (("o"."enabled" = true) AND (COALESCE("p"."allowed", false) = false)) THEN 'unexpected_override'::"text"
ELSE NULL::"text"
END AS "mismatch_type"
FROM ("overrides" "o"
LEFT JOIN "plan_allowed" "p" ON ((("p"."tenant_id" = "o"."tenant_id") AND ("p"."feature_key" = "o"."feature_key"))))
WHERE (("o"."enabled" = true) AND (COALESCE("p"."allowed", false) = false));
ALTER VIEW "public"."v_tenant_feature_mismatch" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_members_with_profiles" AS
SELECT "tm"."id" AS "tenant_member_id",
"tm"."tenant_id",
"tm"."user_id",
"tm"."role",
"tm"."status",
"tm"."created_at",
"p"."full_name",
"au"."email"
FROM (("public"."tenant_members" "tm"
LEFT JOIN "public"."profiles" "p" ON (("p"."id" = "tm"."user_id")))
LEFT JOIN "auth"."users" "au" ON (("au"."id" = "tm"."user_id")));
ALTER VIEW "public"."v_tenant_members_with_profiles" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_people" AS
SELECT 'member'::"text" AS "type",
"m"."tenant_id",
"m"."user_id",
"u"."email",
"m"."role",
"m"."status",
NULL::"uuid" AS "invite_token",
NULL::timestamp with time zone AS "expires_at"
FROM ("public"."tenant_members" "m"
JOIN "auth"."users" "u" ON (("u"."id" = "m"."user_id")))
UNION ALL
SELECT 'invite'::"text" AS "type",
"i"."tenant_id",
NULL::"uuid" AS "user_id",
"i"."email",
"i"."role",
'invited'::"text" AS "status",
"i"."token" AS "invite_token",
"i"."expires_at"
FROM "public"."tenant_invites" "i"
WHERE (("i"."accepted_at" IS NULL) AND ("i"."revoked_at" IS NULL));
ALTER VIEW "public"."v_tenant_people" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_tenant_staff" AS
SELECT ('m_'::"text" || ("tm"."id")::"text") AS "row_id",
"tm"."tenant_id",
"tm"."user_id",
"tm"."role",
"tm"."status",
"tm"."created_at",
"p"."full_name",
"au"."email",
NULL::"uuid" AS "invite_token"
FROM (("public"."tenant_members" "tm"
LEFT JOIN "public"."profiles" "p" ON (("p"."id" = "tm"."user_id")))
LEFT JOIN "auth"."users" "au" ON (("au"."id" = "tm"."user_id")))
UNION ALL
SELECT ('i_'::"text" || ("ti"."id")::"text") AS "row_id",
"ti"."tenant_id",
NULL::"uuid" AS "user_id",
"ti"."role",
'invited'::"text" AS "status",
"ti"."created_at",
NULL::"text" AS "full_name",
"ti"."email",
"ti"."token" AS "invite_token"
FROM "public"."tenant_invites" "ti"
WHERE (("ti"."accepted_at" IS NULL) AND ("ti"."revoked_at" IS NULL) AND ("ti"."expires_at" > "now"()));
ALTER VIEW "public"."v_tenant_staff" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_user_active_subscription" AS
SELECT DISTINCT ON ("user_id") "user_id",
"plan_id",
"plan_key",
"interval",
"status",
"current_period_start",
"current_period_end",
"created_at"
FROM "public"."subscriptions" "s"
WHERE (("tenant_id" IS NULL) AND ("user_id" IS NOT NULL) AND ("status" = 'active'::"text") AND (("current_period_end" IS NULL) OR ("current_period_end" > "now"())))
ORDER BY "user_id", "created_at" DESC;
ALTER VIEW "public"."v_user_active_subscription" OWNER TO "supabase_admin";
CREATE OR REPLACE VIEW "public"."v_user_entitlements" AS
SELECT "a"."user_id",
"f"."key" AS "feature_key",
true AS "allowed"
FROM (("public"."v_user_active_subscription" "a"
JOIN "public"."plan_features" "pf" ON ((("pf"."plan_id" = "a"."plan_id") AND ("pf"."enabled" = true))))
JOIN "public"."features" "f" ON (("f"."id" = "pf"."feature_id")));
ALTER VIEW "public"."v_user_entitlements" OWNER TO "supabase_admin";
ALTER TABLE ONLY "public"."agenda_online_slots" ALTER COLUMN "id" SET DEFAULT "nextval"('"public"."agenda_online_slots_id_seq"'::"regclass");
ALTER TABLE ONLY "public"."agenda_bloqueios"
ADD CONSTRAINT "agenda_bloqueios_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."agenda_configuracoes"
ADD CONSTRAINT "agenda_configuracoes_pkey" PRIMARY KEY ("owner_id");
ALTER TABLE ONLY "public"."agenda_eventos"
ADD CONSTRAINT "agenda_eventos_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."agenda_eventos"
ADD CONSTRAINT "agenda_eventos_sem_sobreposicao" EXCLUDE USING "gist" ("owner_id" WITH =, "tstzrange"("inicio_em", "fim_em", '[)'::"text") WITH &&);
ALTER TABLE ONLY "public"."agenda_excecoes"
ADD CONSTRAINT "agenda_excecoes_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."agenda_online_slots"
ADD CONSTRAINT "agenda_online_slots_owner_id_weekday_time_key" UNIQUE ("owner_id", "weekday", "time");
ALTER TABLE ONLY "public"."agenda_online_slots"
ADD CONSTRAINT "agenda_online_slots_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."agenda_regras_semanais"
ADD CONSTRAINT "agenda_regras_semanais_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."agenda_regras_semanais"
ADD CONSTRAINT "agenda_regras_semanais_unique" UNIQUE ("owner_id", "dia_semana", "hora_inicio", "hora_fim", "modalidade");
ALTER TABLE ONLY "public"."agenda_slots_bloqueados_semanais"
ADD CONSTRAINT "agenda_slots_bloqueados_seman_owner_id_dia_semana_hora_inic_key" UNIQUE ("owner_id", "dia_semana", "hora_inicio");
ALTER TABLE ONLY "public"."agenda_slots_bloqueados_semanais"
ADD CONSTRAINT "agenda_slots_bloqueados_semanais_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."agenda_slots_regras"
ADD CONSTRAINT "agenda_slots_regras_owner_id_dia_semana_key" UNIQUE ("owner_id", "dia_semana");
ALTER TABLE ONLY "public"."agenda_slots_regras"
ADD CONSTRAINT "agenda_slots_regras_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."agendador_configuracoes"
ADD CONSTRAINT "agendador_configuracoes_pkey" PRIMARY KEY ("owner_id");
ALTER TABLE ONLY "public"."agendador_solicitacoes"
ADD CONSTRAINT "agendador_solicitacoes_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."commitment_time_logs"
ADD CONSTRAINT "commitment_time_logs_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."determined_commitment_fields"
ADD CONSTRAINT "determined_commitment_fields_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."determined_commitments"
ADD CONSTRAINT "determined_commitments_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."determined_commitments"
ADD CONSTRAINT "determined_commitments_tenant_native_key_uq" UNIQUE ("tenant_id", "native_key");
ALTER TABLE ONLY "public"."dev_user_credentials"
ADD CONSTRAINT "dev_user_credentials_email_key" UNIQUE ("email");
ALTER TABLE ONLY "public"."dev_user_credentials"
ADD CONSTRAINT "dev_user_credentials_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."entitlements_invalidation"
ADD CONSTRAINT "entitlements_invalidation_pkey" PRIMARY KEY ("owner_id");
ALTER TABLE ONLY "public"."features"
ADD CONSTRAINT "features_key_key" UNIQUE ("key");
ALTER TABLE ONLY "public"."features"
ADD CONSTRAINT "features_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."feriados"
ADD CONSTRAINT "feriados_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."feriados"
ADD CONSTRAINT "feriados_tenant_id_data_nome_key" UNIQUE ("tenant_id", "data", "nome");
ALTER TABLE ONLY "public"."module_features"
ADD CONSTRAINT "module_features_pkey" PRIMARY KEY ("module_id", "feature_id");
ALTER TABLE ONLY "public"."modules"
ADD CONSTRAINT "modules_key_key" UNIQUE ("key");
ALTER TABLE ONLY "public"."modules"
ADD CONSTRAINT "modules_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."owner_users"
ADD CONSTRAINT "owner_users_pkey" PRIMARY KEY ("owner_id", "user_id");
ALTER TABLE ONLY "public"."patient_group_patient"
ADD CONSTRAINT "patient_group_patient_pkey" PRIMARY KEY ("patient_group_id", "patient_id");
ALTER TABLE ONLY "public"."patient_groups"
ADD CONSTRAINT "patient_groups_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."patient_intake_requests"
ADD CONSTRAINT "patient_intake_requests_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."patient_invites"
ADD CONSTRAINT "patient_invites_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."patient_invites"
ADD CONSTRAINT "patient_invites_token_key" UNIQUE ("token");
ALTER TABLE ONLY "public"."patient_patient_tag"
ADD CONSTRAINT "patient_patient_tag_pkey" PRIMARY KEY ("patient_id", "tag_id");
ALTER TABLE ONLY "public"."patient_tags"
ADD CONSTRAINT "patient_tags_owner_name_uniq" UNIQUE ("owner_id", "nome");
ALTER TABLE ONLY "public"."patient_tags"
ADD CONSTRAINT "patient_tags_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."patients"
ADD CONSTRAINT "patients_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."plan_features"
ADD CONSTRAINT "plan_features_pkey" PRIMARY KEY ("plan_id", "feature_id");
ALTER TABLE ONLY "public"."plan_prices"
ADD CONSTRAINT "plan_prices_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."plan_public_bullets"
ADD CONSTRAINT "plan_public_bullets_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."plan_public"
ADD CONSTRAINT "plan_public_pkey" PRIMARY KEY ("plan_id");
ALTER TABLE ONLY "public"."plans"
ADD CONSTRAINT "plans_key_key" UNIQUE ("key");
ALTER TABLE ONLY "public"."plans"
ADD CONSTRAINT "plans_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."profiles"
ADD CONSTRAINT "profiles_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."recurrence_exceptions"
ADD CONSTRAINT "recurrence_exceptions_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."recurrence_exceptions"
ADD CONSTRAINT "recurrence_exceptions_unique" UNIQUE ("recurrence_id", "original_date");
ALTER TABLE ONLY "public"."recurrence_rules"
ADD CONSTRAINT "recurrence_rules_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."saas_admins"
ADD CONSTRAINT "saas_admins_pkey" PRIMARY KEY ("user_id");
ALTER TABLE ONLY "public"."saas_doc_votos"
ADD CONSTRAINT "saas_doc_votos_doc_id_user_id_key" UNIQUE ("doc_id", "user_id");
ALTER TABLE ONLY "public"."saas_doc_votos"
ADD CONSTRAINT "saas_doc_votos_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."saas_docs"
ADD CONSTRAINT "saas_docs_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."saas_faq_itens"
ADD CONSTRAINT "saas_faq_itens_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."saas_faq"
ADD CONSTRAINT "saas_faq_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."subscription_events"
ADD CONSTRAINT "subscription_events_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."subscription_intents_personal"
ADD CONSTRAINT "subscription_intents_personal_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."subscription_intents_legacy"
ADD CONSTRAINT "subscription_intents_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."subscription_intents_tenant"
ADD CONSTRAINT "subscription_intents_tenant_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."subscriptions"
ADD CONSTRAINT "subscriptions_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."tenant_feature_exceptions_log"
ADD CONSTRAINT "tenant_feature_exceptions_log_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."tenant_features"
ADD CONSTRAINT "tenant_features_pkey" PRIMARY KEY ("tenant_id", "feature_key");
ALTER TABLE ONLY "public"."tenant_invites"
ADD CONSTRAINT "tenant_invites_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."tenant_members"
ADD CONSTRAINT "tenant_members_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."tenant_members"
ADD CONSTRAINT "tenant_members_tenant_id_user_id_key" UNIQUE ("tenant_id", "user_id");
ALTER TABLE ONLY "public"."tenant_modules"
ADD CONSTRAINT "tenant_modules_owner_id_module_id_key" UNIQUE ("owner_id", "module_id");
ALTER TABLE ONLY "public"."tenant_modules"
ADD CONSTRAINT "tenant_modules_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."tenants"
ADD CONSTRAINT "tenants_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."user_settings"
ADD CONSTRAINT "user_settings_pkey" PRIMARY KEY ("user_id");
CREATE INDEX "agenda_bloqueios_owner_data_idx" ON "public"."agenda_bloqueios" USING "btree" ("owner_id", "data_inicio", "data_fim");
CREATE INDEX "agenda_bloqueios_owner_id_idx" ON "public"."agenda_bloqueios" USING "btree" ("owner_id");
CREATE INDEX "agenda_bloqueios_recorrente_idx" ON "public"."agenda_bloqueios" USING "btree" ("owner_id", "dia_semana") WHERE ("recorrente" = true);
CREATE INDEX "agenda_bloqueios_tenant_id_idx" ON "public"."agenda_bloqueios" USING "btree" ("tenant_id");
CREATE INDEX "agenda_configuracoes_tenant_idx" ON "public"."agenda_configuracoes" USING "btree" ("tenant_id");
CREATE INDEX "agenda_configuracoes_tenant_owner_idx" ON "public"."agenda_configuracoes" USING "btree" ("tenant_id", "owner_id");
CREATE INDEX "agenda_eventos_owner_inicio_idx" ON "public"."agenda_eventos" USING "btree" ("owner_id", "inicio_em");
CREATE INDEX "agenda_eventos_owner_paciente_idx" ON "public"."agenda_eventos" USING "btree" ("owner_id", "paciente_id");
CREATE INDEX "agenda_eventos_owner_terapeuta_inicio_idx" ON "public"."agenda_eventos" USING "btree" ("owner_id", "terapeuta_id", "inicio_em");
CREATE INDEX "agenda_eventos_recurrence_idx" ON "public"."agenda_eventos" USING "btree" ("recurrence_id") WHERE ("recurrence_id" IS NOT NULL);
CREATE INDEX "agenda_eventos_tenant_inicio_idx" ON "public"."agenda_eventos" USING "btree" ("tenant_id", "inicio_em");
CREATE INDEX "agenda_eventos_tenant_owner_inicio_idx" ON "public"."agenda_eventos" USING "btree" ("tenant_id", "owner_id", "inicio_em");
CREATE INDEX "agenda_excecoes_owner_data_idx" ON "public"."agenda_excecoes" USING "btree" ("owner_id", "data");
CREATE INDEX "agenda_excecoes_tenant_idx" ON "public"."agenda_excecoes" USING "btree" ("tenant_id");
CREATE INDEX "agenda_excecoes_tenant_owner_idx" ON "public"."agenda_excecoes" USING "btree" ("tenant_id", "owner_id");
CREATE INDEX "agenda_online_slots_owner_weekday_idx" ON "public"."agenda_online_slots" USING "btree" ("owner_id", "weekday");
CREATE INDEX "agenda_online_slots_tenant_idx" ON "public"."agenda_online_slots" USING "btree" ("tenant_id");
CREATE INDEX "agenda_online_slots_tenant_owner_idx" ON "public"."agenda_online_slots" USING "btree" ("tenant_id", "owner_id");
CREATE INDEX "agenda_regras_semanais_owner_dia_idx" ON "public"."agenda_regras_semanais" USING "btree" ("owner_id", "dia_semana");
CREATE INDEX "agenda_regras_semanais_tenant_idx" ON "public"."agenda_regras_semanais" USING "btree" ("tenant_id");
CREATE INDEX "agenda_regras_semanais_tenant_owner_idx" ON "public"."agenda_regras_semanais" USING "btree" ("tenant_id", "owner_id");
CREATE INDEX "agenda_slots_bloqueados_semanais_tenant_idx" ON "public"."agenda_slots_bloqueados_semanais" USING "btree" ("tenant_id");
CREATE INDEX "agenda_slots_bloqueados_semanais_tenant_owner_idx" ON "public"."agenda_slots_bloqueados_semanais" USING "btree" ("tenant_id", "owner_id");
CREATE INDEX "agenda_slots_regras_tenant_idx" ON "public"."agenda_slots_regras" USING "btree" ("tenant_id");
CREATE INDEX "agenda_slots_regras_tenant_owner_idx" ON "public"."agenda_slots_regras" USING "btree" ("tenant_id", "owner_id");
CREATE INDEX "agendador_cfg_tenant_idx" ON "public"."agendador_configuracoes" USING "btree" ("tenant_id");
CREATE INDEX "agendador_sol_data_idx" ON "public"."agendador_solicitacoes" USING "btree" ("data_solicitada", "hora_solicitada");
CREATE INDEX "agendador_sol_owner_idx" ON "public"."agendador_solicitacoes" USING "btree" ("owner_id", "status");
CREATE INDEX "agendador_sol_tenant_idx" ON "public"."agendador_solicitacoes" USING "btree" ("tenant_id");
CREATE INDEX "commitment_time_logs_calendar_event_idx" ON "public"."commitment_time_logs" USING "btree" ("calendar_event_id");
CREATE INDEX "commitment_time_logs_commitment_idx" ON "public"."commitment_time_logs" USING "btree" ("commitment_id", "created_at" DESC);
CREATE INDEX "commitment_time_logs_tenant_idx" ON "public"."commitment_time_logs" USING "btree" ("tenant_id", "created_at" DESC);
CREATE INDEX "determined_commitment_fields_commitment_idx" ON "public"."determined_commitment_fields" USING "btree" ("commitment_id", "sort_order");
CREATE UNIQUE INDEX "determined_commitment_fields_key_uniq" ON "public"."determined_commitment_fields" USING "btree" ("commitment_id", "key");
CREATE INDEX "determined_commitment_fields_tenant_idx" ON "public"."determined_commitment_fields" USING "btree" ("tenant_id");
CREATE INDEX "determined_commitments_active_idx" ON "public"."determined_commitments" USING "btree" ("tenant_id", "active");
CREATE INDEX "determined_commitments_tenant_idx" ON "public"."determined_commitments" USING "btree" ("tenant_id");
CREATE UNIQUE INDEX "determined_commitments_tenant_name_uniq" ON "public"."determined_commitments" USING "btree" ("tenant_id", "lower"("name"));
CREATE UNIQUE INDEX "feriados_global_unique" ON "public"."feriados" USING "btree" ("data", "nome") WHERE ("tenant_id" IS NULL);
CREATE INDEX "idx_agenda_eventos_determined_commitment_id" ON "public"."agenda_eventos" USING "btree" ("determined_commitment_id");
CREATE INDEX "idx_agenda_excecoes_owner_data" ON "public"."agenda_excecoes" USING "btree" ("owner_id", "data");
CREATE INDEX "idx_agenda_slots_regras_owner_dia" ON "public"."agenda_slots_regras" USING "btree" ("owner_id", "dia_semana");
CREATE INDEX "idx_intakes_converted_patient_id" ON "public"."patient_intake_requests" USING "btree" ("converted_patient_id");
CREATE INDEX "idx_intakes_owner_cpf" ON "public"."patient_intake_requests" USING "btree" ("owner_id", "cpf");
CREATE INDEX "idx_intakes_owner_created" ON "public"."patient_intake_requests" USING "btree" ("owner_id", "created_at" DESC);
CREATE INDEX "idx_intakes_owner_status_created" ON "public"."patient_intake_requests" USING "btree" ("owner_id", "status", "created_at" DESC);
CREATE INDEX "idx_intakes_status_created" ON "public"."patient_intake_requests" USING "btree" ("status", "created_at" DESC);
CREATE INDEX "idx_patient_group_patient_group_id" ON "public"."patient_group_patient" USING "btree" ("patient_group_id");
CREATE INDEX "idx_patient_groups_owner" ON "public"."patient_groups" USING "btree" ("owner_id");
CREATE INDEX "idx_patient_groups_owner_system_nome" ON "public"."patient_groups" USING "btree" ("owner_id", "is_system", "nome");
CREATE INDEX "idx_patient_tags_owner" ON "public"."patient_tags" USING "btree" ("owner_id");
CREATE INDEX "idx_patients_created_at" ON "public"."patients" USING "btree" ("created_at" DESC);
CREATE INDEX "idx_patients_last_attended" ON "public"."patients" USING "btree" ("last_attended_at" DESC);
CREATE INDEX "idx_patients_owner_email_principal" ON "public"."patients" USING "btree" ("owner_id", "email_principal");
CREATE INDEX "idx_patients_owner_id" ON "public"."patients" USING "btree" ("owner_id");
CREATE INDEX "idx_patients_owner_nome" ON "public"."patients" USING "btree" ("owner_id", "nome_completo");
CREATE INDEX "idx_patients_responsible_member" ON "public"."patients" USING "btree" ("responsible_member_id");
CREATE INDEX "idx_patients_status" ON "public"."patients" USING "btree" ("status");
CREATE INDEX "idx_patients_tenant" ON "public"."patients" USING "btree" ("tenant_id");
CREATE INDEX "idx_patients_tenant_email_norm" ON "public"."patients" USING "btree" ("tenant_id", "lower"(TRIM(BOTH FROM "email_principal")));
CREATE INDEX "idx_pgp_group" ON "public"."patient_group_patient" USING "btree" ("patient_group_id");
CREATE INDEX "idx_pgp_patient" ON "public"."patient_group_patient" USING "btree" ("patient_id");
CREATE INDEX "idx_ppt_patient" ON "public"."patient_patient_tag" USING "btree" ("patient_id");
CREATE INDEX "idx_ppt_tag" ON "public"."patient_patient_tag" USING "btree" ("tag_id");
CREATE INDEX "idx_slots_bloq_owner_dia" ON "public"."agenda_slots_bloqueados_semanais" USING "btree" ("owner_id", "dia_semana");
CREATE INDEX "idx_subscription_intents_plan_interval" ON "public"."subscription_intents_legacy" USING "btree" ("plan_key", "interval");
CREATE INDEX "idx_subscription_intents_status" ON "public"."subscription_intents_legacy" USING "btree" ("status");
CREATE INDEX "idx_subscription_intents_user_id" ON "public"."subscription_intents_legacy" USING "btree" ("user_id");
CREATE INDEX "idx_tenant_features_tenant" ON "public"."tenant_features" USING "btree" ("tenant_id");
CREATE INDEX "idx_tenant_invites_tenant" ON "public"."tenant_invites" USING "btree" ("tenant_id");
CREATE INDEX "idx_tenant_invites_token" ON "public"."tenant_invites" USING "btree" ("token");
CREATE INDEX "ix_plan_prices_plan" ON "public"."plan_prices" USING "btree" ("plan_id");
CREATE INDEX "ix_plan_public_bullets_plan" ON "public"."plan_public_bullets" USING "btree" ("plan_id");
CREATE INDEX "ix_plan_public_sort" ON "public"."plan_public" USING "btree" ("sort_order");
CREATE INDEX "patient_group_patient_tenant_idx" ON "public"."patient_group_patient" USING "btree" ("tenant_id");
CREATE UNIQUE INDEX "patient_groups_owner_nome_uniq" ON "public"."patient_groups" USING "btree" ("owner_id", "nome");
CREATE INDEX "patient_groups_tenant_idx" ON "public"."patient_groups" USING "btree" ("tenant_id");
CREATE INDEX "patient_intake_owner_id_idx" ON "public"."patient_intake_requests" USING "btree" ("owner_id");
CREATE INDEX "patient_intake_requests_tenant_idx" ON "public"."patient_intake_requests" USING "btree" ("tenant_id");
CREATE INDEX "patient_intake_status_idx" ON "public"."patient_intake_requests" USING "btree" ("status");
CREATE INDEX "patient_intake_token_idx" ON "public"."patient_intake_requests" USING "btree" ("token");
CREATE UNIQUE INDEX "patient_invites_one_active_per_owner" ON "public"."patient_invites" USING "btree" ("owner_id") WHERE ("active" = true);
CREATE INDEX "patient_invites_owner_id_idx" ON "public"."patient_invites" USING "btree" ("owner_id");
CREATE INDEX "patient_invites_tenant_idx" ON "public"."patient_invites" USING "btree" ("tenant_id");
CREATE INDEX "patient_invites_token_idx" ON "public"."patient_invites" USING "btree" ("token");
CREATE INDEX "patient_patient_tag_tenant_idx" ON "public"."patient_patient_tag" USING "btree" ("tenant_id");
CREATE UNIQUE INDEX "patient_tags_owner_name_uq" ON "public"."patient_tags" USING "btree" ("owner_id", "lower"("nome"));
CREATE INDEX "patient_tags_tenant_idx" ON "public"."patient_tags" USING "btree" ("tenant_id");
CREATE INDEX "ppt_owner_idx" ON "public"."patient_patient_tag" USING "btree" ("owner_id");
CREATE INDEX "ppt_patient_idx" ON "public"."patient_patient_tag" USING "btree" ("patient_id");
CREATE INDEX "ppt_tag_idx" ON "public"."patient_patient_tag" USING "btree" ("tag_id");
CREATE INDEX "recurrence_exceptions_rule_idx" ON "public"."recurrence_exceptions" USING "btree" ("recurrence_id");
CREATE INDEX "recurrence_exceptions_tenant_idx" ON "public"."recurrence_exceptions" USING "btree" ("tenant_id");
CREATE INDEX "recurrence_rules_active_idx" ON "public"."recurrence_rules" USING "btree" ("owner_id", "status") WHERE ("status" = 'ativo'::"text");
CREATE INDEX "recurrence_rules_owner_idx" ON "public"."recurrence_rules" USING "btree" ("owner_id");
CREATE INDEX "recurrence_rules_patient_idx" ON "public"."recurrence_rules" USING "btree" ("patient_id");
CREATE INDEX "recurrence_rules_tenant_idx" ON "public"."recurrence_rules" USING "btree" ("tenant_id");
CREATE INDEX "saas_doc_votos_doc_id_idx" ON "public"."saas_doc_votos" USING "btree" ("doc_id");
CREATE INDEX "saas_doc_votos_user_id_idx" ON "public"."saas_doc_votos" USING "btree" ("user_id");
CREATE INDEX "saas_docs_categoria_idx" ON "public"."saas_docs" USING "btree" ("categoria");
CREATE INDEX "saas_docs_exibir_no_faq_idx" ON "public"."saas_docs" USING "btree" ("exibir_no_faq") WHERE ("exibir_no_faq" = true);
CREATE INDEX "saas_docs_path_ativo_idx" ON "public"."saas_docs" USING "btree" ("pagina_path", "ativo");
CREATE INDEX "saas_faq_ativo_idx" ON "public"."saas_faq" USING "btree" ("ativo");
CREATE INDEX "saas_faq_categoria_idx" ON "public"."saas_faq" USING "btree" ("categoria");
CREATE INDEX "saas_faq_fts_idx" ON "public"."saas_faq" USING "gin" ("to_tsvector"('"portuguese"'::"regconfig", ((COALESCE("pergunta", ''::"text") || ' '::"text") || COALESCE("conteudo", ''::"text"))));
CREATE INDEX "saas_faq_itens_ativo_idx" ON "public"."saas_faq_itens" USING "btree" ("ativo");
CREATE INDEX "saas_faq_itens_doc_id_idx" ON "public"."saas_faq_itens" USING "btree" ("doc_id");
CREATE INDEX "saas_faq_pagina_path_idx" ON "public"."saas_faq" USING "btree" ("pagina_path");
CREATE INDEX "saas_faq_publico_idx" ON "public"."saas_faq" USING "btree" ("publico");
CREATE INDEX "saas_faq_votos_idx" ON "public"."saas_faq" USING "btree" ("votos" DESC);
CREATE INDEX "sint_personal_created_idx" ON "public"."subscription_intents_personal" USING "btree" ("created_at" DESC);
CREATE INDEX "sint_personal_status_idx" ON "public"."subscription_intents_personal" USING "btree" ("status");
CREATE INDEX "sint_tenant_created_idx" ON "public"."subscription_intents_tenant" USING "btree" ("created_at" DESC);
CREATE INDEX "sint_tenant_status_idx" ON "public"."subscription_intents_tenant" USING "btree" ("status");
CREATE INDEX "sint_tenant_tenant_idx" ON "public"."subscription_intents_tenant" USING "btree" ("tenant_id");
CREATE INDEX "subscription_events_created_at_idx" ON "public"."subscription_events" USING "btree" ("created_at" DESC);
CREATE INDEX "subscription_events_owner_ref_idx" ON "public"."subscription_events" USING "btree" ("owner_type", "owner_ref");
CREATE INDEX "subscription_events_sub_created_idx" ON "public"."subscription_events" USING "btree" ("subscription_id", "created_at" DESC);
CREATE INDEX "subscription_events_subscription_id_idx" ON "public"."subscription_events" USING "btree" ("subscription_id");
CREATE UNIQUE INDEX "subscriptions_one_active_per_tenant" ON "public"."subscriptions" USING "btree" ("tenant_id") WHERE ("status" = 'active'::"text");
CREATE UNIQUE INDEX "subscriptions_one_active_per_user" ON "public"."subscriptions" USING "btree" ("user_id") WHERE ("status" = 'active'::"text");
CREATE UNIQUE INDEX "subscriptions_one_active_per_user_personal" ON "public"."subscriptions" USING "btree" ("user_id") WHERE (("tenant_id" IS NULL) AND ("status" = 'active'::"text"));
CREATE INDEX "subscriptions_owner_idx" ON "public"."subscriptions" USING "btree" ("user_id");
CREATE INDEX "subscriptions_plan_key_idx" ON "public"."subscriptions" USING "btree" ("plan_key");
CREATE INDEX "subscriptions_status_idx" ON "public"."subscriptions" USING "btree" ("status");
CREATE INDEX "subscriptions_tenant_id_idx" ON "public"."subscriptions" USING "btree" ("tenant_id");
CREATE INDEX "subscriptions_tenant_period_end_idx" ON "public"."subscriptions" USING "btree" ("tenant_id", "current_period_end");
CREATE INDEX "subscriptions_tenant_status_idx" ON "public"."subscriptions" USING "btree" ("tenant_id", "status");
CREATE INDEX "subscriptions_user_status_idx" ON "public"."subscriptions" USING "btree" ("user_id", "status", "created_at" DESC);
CREATE INDEX "tenant_members_tenant_idx" ON "public"."tenant_members" USING "btree" ("tenant_id");
CREATE INDEX "tenant_members_user_idx" ON "public"."tenant_members" USING "btree" ("user_id");
CREATE INDEX "tenant_modules_owner_idx" ON "public"."tenant_modules" USING "btree" ("owner_id");
CREATE UNIQUE INDEX "unique_member_per_tenant" ON "public"."tenant_members" USING "btree" ("tenant_id", "user_id");
CREATE UNIQUE INDEX "uq_patients_tenant_user" ON "public"."patients" USING "btree" ("tenant_id", "user_id") WHERE ("user_id" IS NOT NULL);
CREATE UNIQUE INDEX "uq_plan_price_active" ON "public"."plan_prices" USING "btree" ("plan_id", "interval", "currency") WHERE (("is_active" = true) AND ("active_to" IS NULL));
CREATE UNIQUE INDEX "uq_plan_prices_active" ON "public"."plan_prices" USING "btree" ("plan_id", "interval") WHERE ("is_active" = true);
CREATE UNIQUE INDEX "uq_subscriptions_active_by_tenant" ON "public"."subscriptions" USING "btree" ("tenant_id") WHERE (("tenant_id" IS NOT NULL) AND ("status" = 'active'::"text"));
CREATE UNIQUE INDEX "uq_subscriptions_active_personal_by_user" ON "public"."subscriptions" USING "btree" ("user_id") WHERE (("tenant_id" IS NULL) AND ("status" = 'active'::"text"));
CREATE UNIQUE INDEX "uq_tenant_invites_pending" ON "public"."tenant_invites" USING "btree" ("tenant_id", "lower"("email"), "role") WHERE (("accepted_at" IS NULL) AND ("revoked_at" IS NULL));
CREATE UNIQUE INDEX "uq_tenant_members_tenant_user" ON "public"."tenant_members" USING "btree" ("tenant_id", "user_id");
CREATE UNIQUE INDEX "ux_subscriptions_active_per_personal_user" ON "public"."subscriptions" USING "btree" ("user_id") WHERE (("status" = 'active'::"text") AND ("tenant_id" IS NULL));
CREATE UNIQUE INDEX "ux_subscriptions_active_per_tenant" ON "public"."subscriptions" USING "btree" ("tenant_id") WHERE (("status" = 'active'::"text") AND ("tenant_id" IS NOT NULL));
CREATE OR REPLACE TRIGGER "agenda_bloqueios_updated_at" BEFORE UPDATE ON "public"."agenda_bloqueios" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "agendador_slug_trigger" BEFORE INSERT OR UPDATE ON "public"."agendador_configuracoes" FOR EACH ROW EXECUTE FUNCTION "public"."agendador_gerar_slug"();
CREATE OR REPLACE TRIGGER "prevent_saas_membership_trigger" BEFORE INSERT ON "public"."tenant_members" FOR EACH ROW EXECUTE FUNCTION "public"."prevent_saas_membership"();
CREATE OR REPLACE TRIGGER "tg_agenda_configuracoes_updated_at" BEFORE UPDATE ON "public"."agenda_configuracoes" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "tg_agenda_eventos_updated_at" BEFORE UPDATE ON "public"."agenda_eventos" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "tg_agenda_excecoes_updated_at" BEFORE UPDATE ON "public"."agenda_excecoes" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "tg_agenda_regras_semanais_updated_at" BEFORE UPDATE ON "public"."agenda_regras_semanais" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "tg_recurrence_rules_updated_at" BEFORE UPDATE ON "public"."recurrence_rules" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at_recurrence"();
CREATE OR REPLACE TRIGGER "tr_plan_public_updated_at" BEFORE UPDATE ON "public"."plan_public" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_account_type_immutable" BEFORE UPDATE OF "account_type" ON "public"."profiles" FOR EACH ROW EXECUTE FUNCTION "public"."guard_account_type_immutable"();
CREATE OR REPLACE TRIGGER "trg_agenda_cfg_sync" BEFORE INSERT OR UPDATE ON "public"."agenda_configuracoes" FOR EACH ROW EXECUTE FUNCTION "public"."agenda_cfg_sync"();
CREATE OR REPLACE TRIGGER "trg_agenda_eventos_busy_mirror_del" AFTER DELETE ON "public"."agenda_eventos" FOR EACH ROW WHEN ((("old"."mirror_of_event_id" IS NULL) AND ("old"."tenant_id" = "old"."owner_id"))) EXECUTE FUNCTION "public"."sync_busy_mirror_agenda_eventos"();
CREATE OR REPLACE TRIGGER "trg_agenda_eventos_busy_mirror_ins" AFTER INSERT ON "public"."agenda_eventos" FOR EACH ROW WHEN ((("new"."mirror_of_event_id" IS NULL) AND ("new"."tenant_id" = "new"."owner_id") AND ("new"."visibility_scope" = ANY (ARRAY['busy_only'::"text", 'private'::"text"])))) EXECUTE FUNCTION "public"."sync_busy_mirror_agenda_eventos"();
CREATE OR REPLACE TRIGGER "trg_agenda_eventos_busy_mirror_upd" AFTER UPDATE ON "public"."agenda_eventos" FOR EACH ROW WHEN ((("new"."mirror_of_event_id" IS NULL) AND ("new"."tenant_id" = "new"."owner_id") AND (("new"."visibility_scope" IS DISTINCT FROM "old"."visibility_scope") OR ("new"."inicio_em" IS DISTINCT FROM "old"."inicio_em") OR ("new"."fim_em" IS DISTINCT FROM "old"."fim_em") OR ("new"."owner_id" IS DISTINCT FROM "old"."owner_id") OR ("new"."tenant_id" IS DISTINCT FROM "old"."tenant_id")))) EXECUTE FUNCTION "public"."sync_busy_mirror_agenda_eventos"();
CREATE OR REPLACE TRIGGER "trg_agenda_regras_semanais_no_overlap" BEFORE INSERT OR UPDATE ON "public"."agenda_regras_semanais" FOR EACH ROW EXECUTE FUNCTION "public"."fn_agenda_regras_semanais_no_overlap"();
CREATE OR REPLACE TRIGGER "trg_determined_commitment_fields_updated_at" BEFORE UPDATE ON "public"."determined_commitment_fields" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_determined_commitments_updated_at" BEFORE UPDATE ON "public"."determined_commitments" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_no_change_core_plan_key" BEFORE UPDATE ON "public"."plans" FOR EACH ROW EXECUTE FUNCTION "public"."guard_no_change_core_plan_key"();
CREATE OR REPLACE TRIGGER "trg_no_change_plan_target" BEFORE UPDATE ON "public"."plans" FOR EACH ROW EXECUTE FUNCTION "public"."guard_no_change_plan_target"();
CREATE OR REPLACE TRIGGER "trg_no_delete_core_plans" BEFORE DELETE ON "public"."plans" FOR EACH ROW EXECUTE FUNCTION "public"."guard_no_delete_core_plans"();
CREATE OR REPLACE TRIGGER "trg_patient_cannot_own_tenant" BEFORE INSERT OR UPDATE ON "public"."tenant_members" FOR EACH ROW EXECUTE FUNCTION "public"."guard_patient_cannot_own_tenant"();
CREATE OR REPLACE TRIGGER "trg_patient_groups_set_updated_at" BEFORE UPDATE ON "public"."patient_groups" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_patient_intake_requests_updated_at" BEFORE UPDATE ON "public"."patient_intake_requests" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_patient_tags_set_updated_at" BEFORE UPDATE ON "public"."patient_tags" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_patients_updated_at" BEFORE UPDATE ON "public"."patients" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_patients_validate_members" BEFORE INSERT OR UPDATE OF "tenant_id", "responsible_member_id", "patient_scope", "therapist_member_id" ON "public"."patients" FOR EACH ROW EXECUTE FUNCTION "public"."patients_validate_member_consistency"();
CREATE OR REPLACE TRIGGER "trg_prevent_promoting_to_system" BEFORE UPDATE ON "public"."patient_groups" FOR EACH ROW EXECUTE FUNCTION "public"."prevent_promoting_to_system"();
CREATE OR REPLACE TRIGGER "trg_prevent_system_group_changes" BEFORE DELETE OR UPDATE ON "public"."patient_groups" FOR EACH ROW EXECUTE FUNCTION "public"."prevent_system_group_changes"();
CREATE OR REPLACE TRIGGER "trg_profiles_updated_at" BEFORE UPDATE ON "public"."profiles" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_subscription_intents_view_insert" INSTEAD OF INSERT ON "public"."subscription_intents" FOR EACH ROW EXECUTE FUNCTION "public"."subscription_intents_view_insert"();
CREATE OR REPLACE TRIGGER "trg_subscriptions_validate_scope" BEFORE INSERT OR UPDATE ON "public"."subscriptions" FOR EACH ROW EXECUTE FUNCTION "public"."subscriptions_validate_scope"();
CREATE OR REPLACE TRIGGER "trg_tenant_features_guard_with_plan" BEFORE INSERT OR UPDATE ON "public"."tenant_features" FOR EACH ROW EXECUTE FUNCTION "public"."tenant_features_guard_with_plan"();
CREATE OR REPLACE TRIGGER "trg_tenant_features_updated_at" BEFORE UPDATE ON "public"."tenant_features" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
CREATE OR REPLACE TRIGGER "trg_tenant_kind_immutable" BEFORE UPDATE OF "kind" ON "public"."tenants" FOR EACH ROW EXECUTE FUNCTION "public"."guard_tenant_kind_immutable"();
CREATE OR REPLACE TRIGGER "trg_user_settings_updated_at" BEFORE UPDATE ON "public"."user_settings" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"();
ALTER TABLE ONLY "public"."agenda_bloqueios"
ADD CONSTRAINT "agenda_bloqueios_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agenda_bloqueios"
ADD CONSTRAINT "agenda_bloqueios_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."agenda_configuracoes"
ADD CONSTRAINT "agenda_configuracoes_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agenda_eventos"
ADD CONSTRAINT "agenda_eventos_determined_commitment_fk" FOREIGN KEY ("determined_commitment_id") REFERENCES "public"."determined_commitments"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."agenda_eventos"
ADD CONSTRAINT "agenda_eventos_patient_id_fkey" FOREIGN KEY ("patient_id") REFERENCES "public"."patients"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."agenda_eventos"
ADD CONSTRAINT "agenda_eventos_recurrence_id_fkey" FOREIGN KEY ("recurrence_id") REFERENCES "public"."recurrence_rules"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."agenda_eventos"
ADD CONSTRAINT "agenda_eventos_terapeuta_fk" FOREIGN KEY ("terapeuta_id") REFERENCES "auth"."users"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."agenda_excecoes"
ADD CONSTRAINT "agenda_excecoes_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agenda_online_slots"
ADD CONSTRAINT "agenda_online_slots_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agenda_online_slots"
ADD CONSTRAINT "agenda_online_slots_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agenda_regras_semanais"
ADD CONSTRAINT "agenda_regras_semanais_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agenda_slots_bloqueados_semanais"
ADD CONSTRAINT "agenda_slots_bloqueados_semanais_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agenda_slots_regras"
ADD CONSTRAINT "agenda_slots_regras_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agendador_configuracoes"
ADD CONSTRAINT "agendador_configuracoes_owner_fk" FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agendador_configuracoes"
ADD CONSTRAINT "agendador_configuracoes_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agendador_solicitacoes"
ADD CONSTRAINT "agendador_sol_owner_fk" FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."agendador_solicitacoes"
ADD CONSTRAINT "agendador_sol_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."commitment_time_logs"
ADD CONSTRAINT "commitment_time_logs_calendar_event_id_fkey" FOREIGN KEY ("calendar_event_id") REFERENCES "public"."agenda_eventos"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."commitment_time_logs"
ADD CONSTRAINT "commitment_time_logs_commitment_id_fkey" FOREIGN KEY ("commitment_id") REFERENCES "public"."determined_commitments"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."commitment_time_logs"
ADD CONSTRAINT "commitment_time_logs_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."determined_commitment_fields"
ADD CONSTRAINT "determined_commitment_fields_commitment_id_fkey" FOREIGN KEY ("commitment_id") REFERENCES "public"."determined_commitments"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."determined_commitment_fields"
ADD CONSTRAINT "determined_commitment_fields_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."determined_commitments"
ADD CONSTRAINT "determined_commitments_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."feriados"
ADD CONSTRAINT "feriados_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."feriados"
ADD CONSTRAINT "feriados_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."module_features"
ADD CONSTRAINT "module_features_feature_id_fkey" FOREIGN KEY ("feature_id") REFERENCES "public"."features"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."module_features"
ADD CONSTRAINT "module_features_module_id_fkey" FOREIGN KEY ("module_id") REFERENCES "public"."modules"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_group_patient"
ADD CONSTRAINT "patient_group_patient_patient_id_fkey" FOREIGN KEY ("patient_id") REFERENCES "public"."patients"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_group_patient"
ADD CONSTRAINT "patient_group_patient_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_groups"
ADD CONSTRAINT "patient_groups_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_intake_requests"
ADD CONSTRAINT "patient_intake_requests_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_invites"
ADD CONSTRAINT "patient_invites_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_patient_tag"
ADD CONSTRAINT "patient_patient_tag_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "public"."patient_tags"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_patient_tag"
ADD CONSTRAINT "patient_patient_tag_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_tags"
ADD CONSTRAINT "patient_tags_tenant_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patients"
ADD CONSTRAINT "patients_responsible_member_id_fkey" FOREIGN KEY ("responsible_member_id") REFERENCES "public"."tenant_members"("id") ON DELETE RESTRICT;
ALTER TABLE ONLY "public"."patients"
ADD CONSTRAINT "patients_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patients"
ADD CONSTRAINT "patients_therapist_member_id_fkey" FOREIGN KEY ("therapist_member_id") REFERENCES "public"."tenant_members"("id");
ALTER TABLE ONLY "public"."patients"
ADD CONSTRAINT "patients_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."plan_features"
ADD CONSTRAINT "plan_features_feature_id_fkey" FOREIGN KEY ("feature_id") REFERENCES "public"."features"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."plan_features"
ADD CONSTRAINT "plan_features_plan_id_fkey" FOREIGN KEY ("plan_id") REFERENCES "public"."plans"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."plan_prices"
ADD CONSTRAINT "plan_prices_plan_id_fkey" FOREIGN KEY ("plan_id") REFERENCES "public"."plans"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."plan_public_bullets"
ADD CONSTRAINT "plan_public_bullets_plan_id_fkey" FOREIGN KEY ("plan_id") REFERENCES "public"."plans"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."plan_public"
ADD CONSTRAINT "plan_public_plan_id_fkey" FOREIGN KEY ("plan_id") REFERENCES "public"."plans"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_patient_tag"
ADD CONSTRAINT "ppt_patient_fk" FOREIGN KEY ("patient_id") REFERENCES "public"."patients"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."patient_patient_tag"
ADD CONSTRAINT "ppt_tag_fk" FOREIGN KEY ("tag_id") REFERENCES "public"."patient_tags"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."profiles"
ADD CONSTRAINT "profiles_id_fkey" FOREIGN KEY ("id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."recurrence_exceptions"
ADD CONSTRAINT "recurrence_exceptions_agenda_evento_id_fkey" FOREIGN KEY ("agenda_evento_id") REFERENCES "public"."agenda_eventos"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."recurrence_exceptions"
ADD CONSTRAINT "recurrence_exceptions_recurrence_id_fkey" FOREIGN KEY ("recurrence_id") REFERENCES "public"."recurrence_rules"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."saas_admins"
ADD CONSTRAINT "saas_admins_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."saas_doc_votos"
ADD CONSTRAINT "saas_doc_votos_doc_id_fkey" FOREIGN KEY ("doc_id") REFERENCES "public"."saas_docs"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."saas_doc_votos"
ADD CONSTRAINT "saas_doc_votos_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."saas_faq_itens"
ADD CONSTRAINT "saas_faq_itens_doc_id_fkey" FOREIGN KEY ("doc_id") REFERENCES "public"."saas_docs"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."subscription_intents_personal"
ADD CONSTRAINT "sint_personal_subscription_id_fkey" FOREIGN KEY ("subscription_id") REFERENCES "public"."subscriptions"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."subscription_intents_tenant"
ADD CONSTRAINT "sint_tenant_subscription_id_fkey" FOREIGN KEY ("subscription_id") REFERENCES "public"."subscriptions"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."subscription_events"
ADD CONSTRAINT "subscription_events_subscription_id_fkey" FOREIGN KEY ("subscription_id") REFERENCES "public"."subscriptions"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."subscription_intents_personal"
ADD CONSTRAINT "subscription_intents_personal_plan_id_fkey" FOREIGN KEY ("plan_id") REFERENCES "public"."plans"("id") ON DELETE RESTRICT;
ALTER TABLE ONLY "public"."subscription_intents_tenant"
ADD CONSTRAINT "subscription_intents_tenant_plan_id_fkey" FOREIGN KEY ("plan_id") REFERENCES "public"."plans"("id") ON DELETE RESTRICT;
ALTER TABLE ONLY "public"."subscription_intents_legacy"
ADD CONSTRAINT "subscription_intents_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."subscriptions"
ADD CONSTRAINT "subscriptions_owner_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."subscriptions"
ADD CONSTRAINT "subscriptions_plan_id_fkey" FOREIGN KEY ("plan_id") REFERENCES "public"."plans"("id") ON DELETE RESTRICT;
ALTER TABLE ONLY "public"."tenant_features"
ADD CONSTRAINT "tenant_features_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."tenant_invites"
ADD CONSTRAINT "tenant_invites_accepted_by_fkey" FOREIGN KEY ("accepted_by") REFERENCES "auth"."users"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."tenant_invites"
ADD CONSTRAINT "tenant_invites_invited_by_fkey" FOREIGN KEY ("invited_by") REFERENCES "auth"."users"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."tenant_invites"
ADD CONSTRAINT "tenant_invites_revoked_by_fkey" FOREIGN KEY ("revoked_by") REFERENCES "auth"."users"("id") ON DELETE SET NULL;
ALTER TABLE ONLY "public"."tenant_invites"
ADD CONSTRAINT "tenant_invites_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."tenant_members"
ADD CONSTRAINT "tenant_members_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."tenant_members"
ADD CONSTRAINT "tenant_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."tenant_modules"
ADD CONSTRAINT "tenant_modules_module_id_fkey" FOREIGN KEY ("module_id") REFERENCES "public"."modules"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."tenant_modules"
ADD CONSTRAINT "tenant_modules_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."user_settings"
ADD CONSTRAINT "user_settings_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
ALTER TABLE "public"."agenda_bloqueios" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."agenda_configuracoes" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agenda_configuracoes_clinic_read" ON "public"."agenda_configuracoes" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "agenda_configuracoes_clinic_write" ON "public"."agenda_configuracoes" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
CREATE POLICY "agenda_configuracoes_owner" ON "public"."agenda_configuracoes" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
ALTER TABLE "public"."agenda_eventos" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agenda_eventos_delete" ON "public"."agenda_eventos" FOR DELETE USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.delete'::"text")));
CREATE POLICY "agenda_eventos_insert" ON "public"."agenda_eventos" FOR INSERT WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.create'::"text")));
CREATE POLICY "agenda_eventos_owner_all" ON "public"."agenda_eventos" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "agenda_eventos_select" ON "public"."agenda_eventos" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "agenda_eventos_update" ON "public"."agenda_eventos" FOR UPDATE USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
ALTER TABLE "public"."agenda_excecoes" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agenda_excecoes_owner" ON "public"."agenda_excecoes" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "agenda_excecoes_select" ON "public"."agenda_excecoes" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "agenda_excecoes_write" ON "public"."agenda_excecoes" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
ALTER TABLE "public"."agenda_online_slots" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agenda_online_slots_owner" ON "public"."agenda_online_slots" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "agenda_online_slots_select" ON "public"."agenda_online_slots" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "agenda_online_slots_write" ON "public"."agenda_online_slots" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
ALTER TABLE "public"."agenda_regras_semanais" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agenda_regras_semanais_owner" ON "public"."agenda_regras_semanais" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "agenda_regras_semanais_select" ON "public"."agenda_regras_semanais" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "agenda_regras_semanais_write" ON "public"."agenda_regras_semanais" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
ALTER TABLE "public"."agenda_slots_bloqueados_semanais" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agenda_slots_bloqueados_semanais_select" ON "public"."agenda_slots_bloqueados_semanais" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "agenda_slots_bloqueados_semanais_write" ON "public"."agenda_slots_bloqueados_semanais" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
ALTER TABLE "public"."agenda_slots_regras" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agenda_slots_regras_select" ON "public"."agenda_slots_regras" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "agenda_slots_regras_write" ON "public"."agenda_slots_regras" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
CREATE POLICY "agendador_cfg_public_read" ON "public"."agendador_configuracoes" FOR SELECT TO "anon" USING ((("ativo" = true) AND ("link_slug" IS NOT NULL)));
CREATE POLICY "agendador_cfg_select" ON "public"."agendador_configuracoes" FOR SELECT USING (("auth"."uid"() = "owner_id"));
CREATE POLICY "agendador_cfg_write" ON "public"."agendador_configuracoes" USING (("auth"."uid"() = "owner_id")) WITH CHECK (("auth"."uid"() = "owner_id"));
ALTER TABLE "public"."agendador_configuracoes" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "agendador_sol_owner_select" ON "public"."agendador_solicitacoes" FOR SELECT USING (("auth"."uid"() = "owner_id"));
CREATE POLICY "agendador_sol_owner_write" ON "public"."agendador_solicitacoes" USING (("auth"."uid"() = "owner_id")) WITH CHECK (("auth"."uid"() = "owner_id"));
CREATE POLICY "agendador_sol_patient_read" ON "public"."agendador_solicitacoes" FOR SELECT TO "authenticated" USING ((("auth"."uid"() = "user_id") OR ("auth"."uid"() = "owner_id")));
CREATE POLICY "agendador_sol_public_insert" ON "public"."agendador_solicitacoes" FOR INSERT TO "anon" WITH CHECK (true);
ALTER TABLE "public"."agendador_solicitacoes" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "bloqueios_delete" ON "public"."agenda_bloqueios" FOR DELETE TO "authenticated" USING (("owner_id" = "auth"."uid"()));
CREATE POLICY "bloqueios_insert" ON "public"."agenda_bloqueios" FOR INSERT TO "authenticated" WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "bloqueios_select_clinic" ON "public"."agenda_bloqueios" FOR SELECT TO "authenticated" USING (("tenant_id" IN ( SELECT "tenant_members"."tenant_id"
FROM "public"."tenant_members"
WHERE (("tenant_members"."user_id" = "auth"."uid"()) AND ("tenant_members"."role" = ANY (ARRAY['admin'::"text", 'clinic_admin'::"text", 'tenant_admin'::"text", 'secretary'::"text"]))))));
CREATE POLICY "bloqueios_select_own" ON "public"."agenda_bloqueios" FOR SELECT TO "authenticated" USING (("owner_id" = "auth"."uid"()));
CREATE POLICY "bloqueios_update" ON "public"."agenda_bloqueios" FOR UPDATE TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "clinic_admin_read_all_docs" ON "public"."saas_docs" FOR SELECT TO "authenticated" USING ((("ativo" = true) AND (EXISTS ( SELECT 1
FROM "public"."profiles"
WHERE (("profiles"."id" = "auth"."uid"()) AND ("profiles"."role" = ANY (ARRAY['clinic_admin'::"text", 'tenant_admin'::"text"])))))));
ALTER TABLE "public"."commitment_time_logs" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "ctl_delete_for_active_member" ON "public"."commitment_time_logs" FOR DELETE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "commitment_time_logs"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "ctl_insert_for_active_member" ON "public"."commitment_time_logs" FOR INSERT TO "authenticated" WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "commitment_time_logs"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "ctl_select_for_active_member" ON "public"."commitment_time_logs" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "commitment_time_logs"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "ctl_update_for_active_member" ON "public"."commitment_time_logs" FOR UPDATE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "commitment_time_logs"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text"))))) WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "commitment_time_logs"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "dc_delete_custom_for_active_member" ON "public"."determined_commitments" FOR DELETE TO "authenticated" USING ((("is_native" = false) AND (EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitments"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text"))))));
CREATE POLICY "dc_insert_for_active_member" ON "public"."determined_commitments" FOR INSERT TO "authenticated" WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitments"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "dc_select_for_active_member" ON "public"."determined_commitments" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitments"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "dc_update_for_active_member" ON "public"."determined_commitments" FOR UPDATE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitments"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text"))))) WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitments"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "dcf_delete_for_active_member" ON "public"."determined_commitment_fields" FOR DELETE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitment_fields"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "dcf_insert_for_active_member" ON "public"."determined_commitment_fields" FOR INSERT TO "authenticated" WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitment_fields"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "dcf_select_for_active_member" ON "public"."determined_commitment_fields" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitment_fields"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "dcf_update_for_active_member" ON "public"."determined_commitment_fields" FOR UPDATE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitment_fields"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text"))))) WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "determined_commitment_fields"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text")))));
CREATE POLICY "delete own" ON "public"."agenda_bloqueios" FOR DELETE USING (("owner_id" = "auth"."uid"()));
ALTER TABLE "public"."determined_commitment_fields" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."determined_commitments" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "dev_creds_select_saas_admin" ON "public"."dev_user_credentials" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."profiles" "p"
WHERE (("p"."id" = "auth"."uid"()) AND ("p"."role" = 'saas_admin'::"text")))));
CREATE POLICY "dev_creds_write_saas_admin" ON "public"."dev_user_credentials" TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."profiles" "p"
WHERE (("p"."id" = "auth"."uid"()) AND ("p"."role" = 'saas_admin'::"text"))))) WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."profiles" "p"
WHERE (("p"."id" = "auth"."uid"()) AND ("p"."role" = 'saas_admin'::"text")))));
ALTER TABLE "public"."dev_user_credentials" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "ent_inv_select_own" ON "public"."entitlements_invalidation" FOR SELECT USING ((("owner_id" = "auth"."uid"()) OR "public"."is_saas_admin"()));
CREATE POLICY "ent_inv_update_saas" ON "public"."entitlements_invalidation" FOR UPDATE USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
CREATE POLICY "ent_inv_write_saas" ON "public"."entitlements_invalidation" FOR INSERT WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."entitlements_invalidation" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "faq_admin_write" ON "public"."saas_faq" TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."profiles"
WHERE (("profiles"."id" = "auth"."uid"()) AND ("profiles"."role" = ANY (ARRAY['saas_admin'::"text", 'tenant_admin'::"text", 'clinic_admin'::"text"]))))));
CREATE POLICY "faq_auth_read" ON "public"."saas_faq" FOR SELECT TO "authenticated" USING (("ativo" = true));
CREATE POLICY "faq_itens_admin_write" ON "public"."saas_faq_itens" TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."profiles"
WHERE (("profiles"."id" = "auth"."uid"()) AND ("profiles"."role" = ANY (ARRAY['saas_admin'::"text", 'tenant_admin'::"text", 'clinic_admin'::"text"]))))));
CREATE POLICY "faq_itens_auth_read" ON "public"."saas_faq_itens" FOR SELECT TO "authenticated" USING ((("ativo" = true) AND (EXISTS ( SELECT 1
FROM "public"."saas_docs" "d"
WHERE (("d"."id" = "saas_faq_itens"."doc_id") AND ("d"."ativo" = true))))));
CREATE POLICY "faq_public_read" ON "public"."saas_faq" FOR SELECT USING ((("publico" = true) AND ("ativo" = true)));
ALTER TABLE "public"."features" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "features_read_authenticated" ON "public"."features" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "features_write_saas_admin" ON "public"."features" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."feriados" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "feriados_delete" ON "public"."feriados" FOR DELETE USING (("owner_id" = "auth"."uid"()));
CREATE POLICY "feriados_global_select" ON "public"."feriados" FOR SELECT USING (("tenant_id" IS NULL));
CREATE POLICY "feriados_insert" ON "public"."feriados" FOR INSERT WITH CHECK (("tenant_id" IN ( SELECT "tenant_members"."tenant_id"
FROM "public"."tenant_members"
WHERE ("tenant_members"."user_id" = "auth"."uid"()))));
CREATE POLICY "feriados_saas_delete" ON "public"."feriados" FOR DELETE USING ((EXISTS ( SELECT 1
FROM "public"."saas_admins"
WHERE ("saas_admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "feriados_saas_insert" ON "public"."feriados" FOR INSERT WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."saas_admins"
WHERE ("saas_admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "feriados_saas_select" ON "public"."feriados" FOR SELECT USING ((EXISTS ( SELECT 1
FROM "public"."saas_admins"
WHERE ("saas_admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "feriados_select" ON "public"."feriados" FOR SELECT USING (("tenant_id" IN ( SELECT "tenant_members"."tenant_id"
FROM "public"."tenant_members"
WHERE ("tenant_members"."user_id" = "auth"."uid"()))));
CREATE POLICY "insert own" ON "public"."agenda_bloqueios" FOR INSERT WITH CHECK (("owner_id" = "auth"."uid"()));
ALTER TABLE "public"."module_features" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "module_features_read_authenticated" ON "public"."module_features" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "module_features_write_saas_admin" ON "public"."module_features" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."modules" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "modules_read_authenticated" ON "public"."modules" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "modules_write_saas_admin" ON "public"."modules" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."owner_users" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "owner_users: user can read own links" ON "public"."owner_users" FOR SELECT TO "authenticated" USING (("user_id" = "auth"."uid"()));
ALTER TABLE "public"."patient_group_patient" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "patient_group_patient_owner_all" ON "public"."patient_group_patient" TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."patients" "p"
WHERE (("p"."id" = "patient_group_patient"."patient_id") AND ("p"."owner_id" = "auth"."uid"()))))) WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."patients" "p"
WHERE (("p"."id" = "patient_group_patient"."patient_id") AND ("p"."owner_id" = "auth"."uid"())))));
CREATE POLICY "patient_group_patient_select" ON "public"."patient_group_patient" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.view'::"text")));
CREATE POLICY "patient_group_patient_write" ON "public"."patient_group_patient" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text")));
ALTER TABLE "public"."patient_groups" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "patient_groups_owner_all" ON "public"."patient_groups" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "patient_groups_select" ON "public"."patient_groups" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.view'::"text")));
CREATE POLICY "patient_groups_write" ON "public"."patient_groups" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text")));
ALTER TABLE "public"."patient_intake_requests" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "patient_intake_requests_owner_all" ON "public"."patient_intake_requests" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "patient_intake_requests_select" ON "public"."patient_intake_requests" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.view'::"text")));
CREATE POLICY "patient_intake_requests_write" ON "public"."patient_intake_requests" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text")));
ALTER TABLE "public"."patient_invites" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "patient_invites_owner_all" ON "public"."patient_invites" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "patient_invites_select" ON "public"."patient_invites" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.view'::"text")));
CREATE POLICY "patient_invites_write" ON "public"."patient_invites" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text")));
ALTER TABLE "public"."patient_patient_tag" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "patient_patient_tag_owner_all" ON "public"."patient_patient_tag" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "patient_patient_tag_select" ON "public"."patient_patient_tag" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.view'::"text")));
CREATE POLICY "patient_patient_tag_write" ON "public"."patient_patient_tag" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text")));
ALTER TABLE "public"."patient_tags" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "patient_tags_owner_all" ON "public"."patient_tags" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "patient_tags_select" ON "public"."patient_tags" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.view'::"text")));
CREATE POLICY "patient_tags_write" ON "public"."patient_tags" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text")));
ALTER TABLE "public"."patients" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "patients_delete" ON "public"."patients" FOR DELETE USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.delete'::"text")));
CREATE POLICY "patients_insert" ON "public"."patients" FOR INSERT WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.create'::"text")));
CREATE POLICY "patients_owner_all" ON "public"."patients" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "patients_select" ON "public"."patients" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.view'::"text")));
CREATE POLICY "patients_update" ON "public"."patients" FOR UPDATE USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'patients.edit'::"text")));
ALTER TABLE "public"."plan_features" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "plan_features_read_authenticated" ON "public"."plan_features" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "plan_features_write_saas_admin" ON "public"."plan_features" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."plans" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "plans_read_authenticated" ON "public"."plans" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "plans_write_saas_admin" ON "public"."plans" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."profiles" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "profiles_insert_own" ON "public"."profiles" FOR INSERT WITH CHECK (("id" = "auth"."uid"()));
CREATE POLICY "profiles_read_saas_admin" ON "public"."profiles" FOR SELECT USING ("public"."is_saas_admin"());
CREATE POLICY "profiles_select_own" ON "public"."profiles" FOR SELECT USING (("id" = "auth"."uid"()));
CREATE POLICY "profiles_update_own" ON "public"."profiles" FOR UPDATE USING (("id" = "auth"."uid"())) WITH CHECK (("id" = "auth"."uid"()));
CREATE POLICY "read features (auth)" ON "public"."features" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "read plan_features (auth)" ON "public"."plan_features" FOR SELECT TO "authenticated" USING (true);
CREATE POLICY "read plans (auth)" ON "public"."plans" FOR SELECT TO "authenticated" USING (true);
ALTER TABLE "public"."recurrence_exceptions" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "recurrence_exceptions_tenant" ON "public"."recurrence_exceptions" TO "authenticated" USING (("tenant_id" IN ( SELECT "tenant_members"."tenant_id"
FROM "public"."tenant_members"
WHERE ("tenant_members"."user_id" = "auth"."uid"())))) WITH CHECK (("tenant_id" IN ( SELECT "tenant_members"."tenant_id"
FROM "public"."tenant_members"
WHERE ("tenant_members"."user_id" = "auth"."uid"()))));
ALTER TABLE "public"."recurrence_rules" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "recurrence_rules_clinic_read" ON "public"."recurrence_rules" FOR SELECT USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.view'::"text")));
CREATE POLICY "recurrence_rules_clinic_write" ON "public"."recurrence_rules" USING (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text"))) WITH CHECK (("public"."is_clinic_tenant"("tenant_id") AND "public"."is_tenant_member"("tenant_id") AND "public"."tenant_has_feature"("tenant_id", 'agenda.edit'::"text")));
CREATE POLICY "recurrence_rules_owner" ON "public"."recurrence_rules" TO "authenticated" USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"()));
CREATE POLICY "saas_admin can read subscription_intents" ON "public"."subscription_intents_legacy" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."saas_admins" "a"
WHERE ("a"."user_id" = "auth"."uid"()))));
CREATE POLICY "saas_admin can update subscription_intents" ON "public"."subscription_intents_legacy" FOR UPDATE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."saas_admins" "a"
WHERE ("a"."user_id" = "auth"."uid"())))) WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."saas_admins" "a"
WHERE ("a"."user_id" = "auth"."uid"()))));
CREATE POLICY "saas_admin_full_access" ON "public"."saas_docs" TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."saas_admins"
WHERE ("saas_admins"."user_id" = "auth"."uid"())))) WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."saas_admins"
WHERE ("saas_admins"."user_id" = "auth"."uid"()))));
ALTER TABLE "public"."saas_admins" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "saas_admins_select_self" ON "public"."saas_admins" FOR SELECT TO "authenticated" USING (("user_id" = "auth"."uid"()));
ALTER TABLE "public"."saas_doc_votos" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."saas_docs" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."saas_faq" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."saas_faq_itens" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "select own" ON "public"."agenda_bloqueios" FOR SELECT USING (("owner_id" = "auth"."uid"()));
ALTER TABLE "public"."subscription_events" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "subscription_events_read_saas" ON "public"."subscription_events" FOR SELECT USING ("public"."is_saas_admin"());
CREATE POLICY "subscription_events_write_saas" ON "public"."subscription_events" FOR INSERT WITH CHECK ("public"."is_saas_admin"());
CREATE POLICY "subscription_intents_insert_own" ON "public"."subscription_intents_legacy" FOR INSERT TO "authenticated" WITH CHECK (("user_id" = "auth"."uid"()));
ALTER TABLE "public"."subscription_intents_legacy" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "subscription_intents_select_own" ON "public"."subscription_intents_legacy" FOR SELECT TO "authenticated" USING (("user_id" = "auth"."uid"()));
ALTER TABLE "public"."subscriptions" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "subscriptions read own" ON "public"."subscriptions" FOR SELECT TO "authenticated" USING (("user_id" = "auth"."uid"()));
CREATE POLICY "subscriptions: read if linked owner_users" ON "public"."subscriptions" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."owner_users" "ou"
WHERE (("ou"."owner_id" = "subscriptions"."user_id") AND ("ou"."user_id" = "auth"."uid"())))));
CREATE POLICY "subscriptions_insert_own_personal" ON "public"."subscriptions" FOR INSERT TO "authenticated" WITH CHECK ((("user_id" = "auth"."uid"()) AND ("tenant_id" IS NULL)));
CREATE POLICY "subscriptions_no_direct_update" ON "public"."subscriptions" FOR UPDATE TO "authenticated" USING (false) WITH CHECK (false);
CREATE POLICY "subscriptions_read_own" ON "public"."subscriptions" FOR SELECT TO "authenticated" USING ((("user_id" = "auth"."uid"()) OR "public"."is_saas_admin"()));
CREATE POLICY "subscriptions_select_for_tenant_members" ON "public"."subscriptions" FOR SELECT TO "authenticated" USING ((("tenant_id" IS NOT NULL) AND (EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "subscriptions"."tenant_id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text"))))));
CREATE POLICY "subscriptions_select_own_personal" ON "public"."subscriptions" FOR SELECT TO "authenticated" USING ((("user_id" = "auth"."uid"()) AND ("tenant_id" IS NULL)));
CREATE POLICY "subscriptions_update_only_saas_admin" ON "public"."subscriptions" FOR UPDATE TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."tenant_members" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "tenant_members_write_saas" ON "public"."tenant_members" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."tenant_modules" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "tenant_modules_read_own" ON "public"."tenant_modules" FOR SELECT TO "authenticated" USING ((("owner_id" = "auth"."uid"()) OR "public"."is_saas_admin"()));
CREATE POLICY "tenant_modules_write_saas" ON "public"."tenant_modules" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
ALTER TABLE "public"."tenants" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "tenants_read_members" ON "public"."tenants" FOR SELECT TO "authenticated" USING (("public"."is_saas_admin"() OR (EXISTS ( SELECT 1
FROM "public"."tenant_members" "tm"
WHERE (("tm"."tenant_id" = "tenants"."id") AND ("tm"."user_id" = "auth"."uid"()) AND ("tm"."status" = 'active'::"text"))))));
CREATE POLICY "tenants_write_saas" ON "public"."tenants" TO "authenticated" USING ("public"."is_saas_admin"()) WITH CHECK ("public"."is_saas_admin"());
CREATE POLICY "tm_select_admin_all_members" ON "public"."tenant_members" FOR SELECT TO "authenticated" USING ("public"."is_tenant_admin"("tenant_id"));
CREATE POLICY "tm_select_own_membership" ON "public"."tenant_members" FOR SELECT TO "authenticated" USING (("user_id" = "auth"."uid"()));
CREATE POLICY "update own" ON "public"."agenda_bloqueios" FOR UPDATE USING (("owner_id" = "auth"."uid"()));
ALTER TABLE "public"."user_settings" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "user_settings_insert_own" ON "public"."user_settings" FOR INSERT WITH CHECK (("user_id" = "auth"."uid"()));
CREATE POLICY "user_settings_select_own" ON "public"."user_settings" FOR SELECT USING (("user_id" = "auth"."uid"()));
CREATE POLICY "user_settings_update_own" ON "public"."user_settings" FOR UPDATE USING (("user_id" = "auth"."uid"())) WITH CHECK (("user_id" = "auth"."uid"()));
CREATE POLICY "users_read_usuario_docs" ON "public"."saas_docs" FOR SELECT TO "authenticated" USING ((("ativo" = true) AND ("tipo_acesso" = 'usuario'::"text")));
CREATE POLICY "votos_select_own" ON "public"."saas_doc_votos" FOR SELECT TO "authenticated" USING (("user_id" = "auth"."uid"()));
CREATE POLICY "votos_upsert_own" ON "public"."saas_doc_votos" TO "authenticated" USING (("user_id" = "auth"."uid"())) WITH CHECK (("user_id" = "auth"."uid"()));
ALTER PUBLICATION "supabase_realtime" OWNER TO "postgres";
GRANT USAGE ON SCHEMA "public" TO "postgres";
GRANT USAGE ON SCHEMA "public" TO "anon";
GRANT USAGE ON SCHEMA "public" TO "authenticated";
GRANT USAGE ON SCHEMA "public" TO "service_role";
GRANT ALL ON FUNCTION "public"."citextin"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."citextin"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."citextin"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citextin"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."citextout"("public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citextout"("public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citextout"("public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citextout"("public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citextrecv"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."citextrecv"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."citextrecv"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citextrecv"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."citextsend"("public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citextsend"("public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citextsend"("public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citextsend"("public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey16_in"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey16_in"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey16_in"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey16_in"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey16_out"("public"."gbtreekey16") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey16_out"("public"."gbtreekey16") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey16_out"("public"."gbtreekey16") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey16_out"("public"."gbtreekey16") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey2_in"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey2_in"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey2_in"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey2_in"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey2_out"("public"."gbtreekey2") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey2_out"("public"."gbtreekey2") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey2_out"("public"."gbtreekey2") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey2_out"("public"."gbtreekey2") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey32_in"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey32_in"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey32_in"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey32_in"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey32_out"("public"."gbtreekey32") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey32_out"("public"."gbtreekey32") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey32_out"("public"."gbtreekey32") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey32_out"("public"."gbtreekey32") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey4_in"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey4_in"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey4_in"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey4_in"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey4_out"("public"."gbtreekey4") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey4_out"("public"."gbtreekey4") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey4_out"("public"."gbtreekey4") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey4_out"("public"."gbtreekey4") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey8_in"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey8_in"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey8_in"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey8_in"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey8_out"("public"."gbtreekey8") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey8_out"("public"."gbtreekey8") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey8_out"("public"."gbtreekey8") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey8_out"("public"."gbtreekey8") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_in"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_in"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_in"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_in"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_out"("public"."gbtreekey_var") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_out"("public"."gbtreekey_var") TO "anon";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_out"("public"."gbtreekey_var") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbtreekey_var_out"("public"."gbtreekey_var") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_in"("cstring") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_in"("cstring") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_in"("cstring") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_in"("cstring") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_out"("public"."gtrgm") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_out"("public"."gtrgm") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_out"("public"."gtrgm") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_out"("public"."gtrgm") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext"(boolean) TO "postgres";
GRANT ALL ON FUNCTION "public"."citext"(boolean) TO "anon";
GRANT ALL ON FUNCTION "public"."citext"(boolean) TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext"(boolean) TO "service_role";
GRANT ALL ON FUNCTION "public"."citext"(character) TO "postgres";
GRANT ALL ON FUNCTION "public"."citext"(character) TO "anon";
GRANT ALL ON FUNCTION "public"."citext"(character) TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext"(character) TO "service_role";
GRANT ALL ON FUNCTION "public"."citext"("inet") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext"("inet") TO "anon";
GRANT ALL ON FUNCTION "public"."citext"("inet") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext"("inet") TO "service_role";
GRANT ALL ON FUNCTION "public"."__rls_ping"() TO "postgres";
GRANT ALL ON FUNCTION "public"."__rls_ping"() TO "anon";
GRANT ALL ON FUNCTION "public"."__rls_ping"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."__rls_ping"() TO "service_role";
GRANT ALL ON TABLE "public"."subscriptions" TO "postgres";
GRANT ALL ON TABLE "public"."subscriptions" TO "anon";
GRANT ALL ON TABLE "public"."subscriptions" TO "authenticated";
GRANT ALL ON TABLE "public"."subscriptions" TO "service_role";
GRANT ALL ON FUNCTION "public"."activate_subscription_from_intent"("p_intent_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."activate_subscription_from_intent"("p_intent_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."activate_subscription_from_intent"("p_intent_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."activate_subscription_from_intent"("p_intent_id" "uuid") TO "service_role";
REVOKE ALL ON FUNCTION "public"."admin_fix_plan_target"("p_plan_key" "text", "p_new_target" "text") FROM PUBLIC;
GRANT ALL ON FUNCTION "public"."admin_fix_plan_target"("p_plan_key" "text", "p_new_target" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."admin_fix_plan_target"("p_plan_key" "text", "p_new_target" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."admin_fix_plan_target"("p_plan_key" "text", "p_new_target" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."admin_fix_plan_target"("p_plan_key" "text", "p_new_target" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."agenda_cfg_sync"() TO "postgres";
GRANT ALL ON FUNCTION "public"."agenda_cfg_sync"() TO "anon";
GRANT ALL ON FUNCTION "public"."agenda_cfg_sync"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."agenda_cfg_sync"() TO "service_role";
GRANT ALL ON FUNCTION "public"."agendador_dias_disponiveis"("p_slug" "text", "p_ano" integer, "p_mes" integer) TO "postgres";
GRANT ALL ON FUNCTION "public"."agendador_dias_disponiveis"("p_slug" "text", "p_ano" integer, "p_mes" integer) TO "anon";
GRANT ALL ON FUNCTION "public"."agendador_dias_disponiveis"("p_slug" "text", "p_ano" integer, "p_mes" integer) TO "authenticated";
GRANT ALL ON FUNCTION "public"."agendador_dias_disponiveis"("p_slug" "text", "p_ano" integer, "p_mes" integer) TO "service_role";
GRANT ALL ON FUNCTION "public"."agendador_gerar_slug"() TO "postgres";
GRANT ALL ON FUNCTION "public"."agendador_gerar_slug"() TO "anon";
GRANT ALL ON FUNCTION "public"."agendador_gerar_slug"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."agendador_gerar_slug"() TO "service_role";
GRANT ALL ON FUNCTION "public"."agendador_slots_disponiveis"("p_slug" "text", "p_data" "date") TO "postgres";
GRANT ALL ON FUNCTION "public"."agendador_slots_disponiveis"("p_slug" "text", "p_data" "date") TO "anon";
GRANT ALL ON FUNCTION "public"."agendador_slots_disponiveis"("p_slug" "text", "p_data" "date") TO "authenticated";
GRANT ALL ON FUNCTION "public"."agendador_slots_disponiveis"("p_slug" "text", "p_data" "date") TO "service_role";
GRANT ALL ON FUNCTION "public"."cancel_recurrence_from"("p_recurrence_id" "uuid", "p_from_date" "date") TO "postgres";
GRANT ALL ON FUNCTION "public"."cancel_recurrence_from"("p_recurrence_id" "uuid", "p_from_date" "date") TO "anon";
GRANT ALL ON FUNCTION "public"."cancel_recurrence_from"("p_recurrence_id" "uuid", "p_from_date" "date") TO "authenticated";
GRANT ALL ON FUNCTION "public"."cancel_recurrence_from"("p_recurrence_id" "uuid", "p_from_date" "date") TO "service_role";
GRANT ALL ON FUNCTION "public"."cancel_subscription"("p_subscription_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."cancel_subscription"("p_subscription_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."cancel_subscription"("p_subscription_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."cancel_subscription"("p_subscription_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."cancelar_eventos_serie"("p_serie_id" "uuid", "p_a_partir_de" timestamp with time zone) TO "postgres";
GRANT ALL ON FUNCTION "public"."cancelar_eventos_serie"("p_serie_id" "uuid", "p_a_partir_de" timestamp with time zone) TO "anon";
GRANT ALL ON FUNCTION "public"."cancelar_eventos_serie"("p_serie_id" "uuid", "p_a_partir_de" timestamp with time zone) TO "authenticated";
GRANT ALL ON FUNCTION "public"."cancelar_eventos_serie"("p_serie_id" "uuid", "p_a_partir_de" timestamp with time zone) TO "service_role";
GRANT ALL ON FUNCTION "public"."cash_dist"("money", "money") TO "postgres";
GRANT ALL ON FUNCTION "public"."cash_dist"("money", "money") TO "anon";
GRANT ALL ON FUNCTION "public"."cash_dist"("money", "money") TO "authenticated";
GRANT ALL ON FUNCTION "public"."cash_dist"("money", "money") TO "service_role";
GRANT ALL ON FUNCTION "public"."change_subscription_plan"("p_subscription_id" "uuid", "p_new_plan_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."change_subscription_plan"("p_subscription_id" "uuid", "p_new_plan_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."change_subscription_plan"("p_subscription_id" "uuid", "p_new_plan_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."change_subscription_plan"("p_subscription_id" "uuid", "p_new_plan_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_cmp"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_cmp"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_cmp"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_cmp"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_eq"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_eq"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_eq"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_eq"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_ge"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_ge"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_ge"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_ge"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_gt"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_gt"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_gt"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_gt"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_hash"("public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_hash"("public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_hash"("public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_hash"("public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_hash_extended"("public"."citext", bigint) TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_hash_extended"("public"."citext", bigint) TO "anon";
GRANT ALL ON FUNCTION "public"."citext_hash_extended"("public"."citext", bigint) TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_hash_extended"("public"."citext", bigint) TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_larger"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_larger"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_larger"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_larger"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_le"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_le"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_le"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_le"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_lt"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_lt"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_lt"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_lt"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_ne"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_ne"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_ne"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_ne"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_pattern_cmp"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_pattern_cmp"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_pattern_cmp"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_pattern_cmp"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_pattern_ge"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_pattern_ge"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_pattern_ge"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_pattern_ge"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_pattern_gt"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_pattern_gt"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_pattern_gt"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_pattern_gt"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_pattern_le"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_pattern_le"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_pattern_le"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_pattern_le"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_pattern_lt"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_pattern_lt"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_pattern_lt"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_pattern_lt"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."citext_smaller"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."citext_smaller"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."citext_smaller"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."citext_smaller"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."create_clinic_tenant"("p_name" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."create_clinic_tenant"("p_name" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."create_clinic_tenant"("p_name" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."create_clinic_tenant"("p_name" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."create_patient_intake_request"("p_token" "text", "p_name" "text", "p_email" "text", "p_phone" "text", "p_notes" "text", "p_consent" boolean) TO "postgres";
GRANT ALL ON FUNCTION "public"."create_patient_intake_request"("p_token" "text", "p_name" "text", "p_email" "text", "p_phone" "text", "p_notes" "text", "p_consent" boolean) TO "anon";
GRANT ALL ON FUNCTION "public"."create_patient_intake_request"("p_token" "text", "p_name" "text", "p_email" "text", "p_phone" "text", "p_notes" "text", "p_consent" boolean) TO "authenticated";
GRANT ALL ON FUNCTION "public"."create_patient_intake_request"("p_token" "text", "p_name" "text", "p_email" "text", "p_phone" "text", "p_notes" "text", "p_consent" boolean) TO "service_role";
REVOKE ALL ON FUNCTION "public"."create_patient_intake_request_v2"("p_token" "text", "p_payload" "jsonb") FROM PUBLIC;
GRANT ALL ON FUNCTION "public"."create_patient_intake_request_v2"("p_token" "text", "p_payload" "jsonb") TO "postgres";
GRANT ALL ON FUNCTION "public"."create_patient_intake_request_v2"("p_token" "text", "p_payload" "jsonb") TO "anon";
GRANT ALL ON FUNCTION "public"."create_patient_intake_request_v2"("p_token" "text", "p_payload" "jsonb") TO "authenticated";
GRANT ALL ON FUNCTION "public"."create_patient_intake_request_v2"("p_token" "text", "p_payload" "jsonb") TO "service_role";
GRANT ALL ON FUNCTION "public"."current_member_id"("p_tenant_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."current_member_id"("p_tenant_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."current_member_id"("p_tenant_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."current_member_id"("p_tenant_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."current_member_role"("p_tenant_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."current_member_role"("p_tenant_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."current_member_role"("p_tenant_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."current_member_role"("p_tenant_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."date_dist"("date", "date") TO "postgres";
GRANT ALL ON FUNCTION "public"."date_dist"("date", "date") TO "anon";
GRANT ALL ON FUNCTION "public"."date_dist"("date", "date") TO "authenticated";
GRANT ALL ON FUNCTION "public"."date_dist"("date", "date") TO "service_role";
GRANT ALL ON FUNCTION "public"."delete_commitment_full"("p_tenant_id" "uuid", "p_commitment_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."delete_commitment_full"("p_tenant_id" "uuid", "p_commitment_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."delete_commitment_full"("p_tenant_id" "uuid", "p_commitment_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."delete_determined_commitment"("p_tenant_id" "uuid", "p_commitment_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."delete_determined_commitment"("p_tenant_id" "uuid", "p_commitment_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."delete_determined_commitment"("p_tenant_id" "uuid", "p_commitment_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."delete_determined_commitment"("p_tenant_id" "uuid", "p_commitment_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."dev_list_auth_users"("p_limit" integer) TO "postgres";
GRANT ALL ON FUNCTION "public"."dev_list_auth_users"("p_limit" integer) TO "anon";
GRANT ALL ON FUNCTION "public"."dev_list_auth_users"("p_limit" integer) TO "authenticated";
GRANT ALL ON FUNCTION "public"."dev_list_auth_users"("p_limit" integer) TO "service_role";
REVOKE ALL ON FUNCTION "public"."dev_list_custom_users"() FROM PUBLIC;
GRANT ALL ON FUNCTION "public"."dev_list_custom_users"() TO "postgres";
GRANT ALL ON FUNCTION "public"."dev_list_custom_users"() TO "anon";
GRANT ALL ON FUNCTION "public"."dev_list_custom_users"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."dev_list_custom_users"() TO "service_role";
REVOKE ALL ON FUNCTION "public"."dev_list_intent_leads"() FROM PUBLIC;
GRANT ALL ON FUNCTION "public"."dev_list_intent_leads"() TO "postgres";
GRANT ALL ON FUNCTION "public"."dev_list_intent_leads"() TO "anon";
GRANT ALL ON FUNCTION "public"."dev_list_intent_leads"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."dev_list_intent_leads"() TO "service_role";
GRANT ALL ON FUNCTION "public"."dev_public_debug_snapshot"() TO "postgres";
GRANT ALL ON FUNCTION "public"."dev_public_debug_snapshot"() TO "anon";
GRANT ALL ON FUNCTION "public"."dev_public_debug_snapshot"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."dev_public_debug_snapshot"() TO "service_role";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant"() TO "postgres";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant"() TO "anon";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant"() TO "service_role";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant_for_user"("p_user_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant_for_user"("p_user_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant_for_user"("p_user_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."ensure_personal_tenant_for_user"("p_user_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."faq_votar"("faq_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."faq_votar"("faq_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."faq_votar"("faq_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."faq_votar"("faq_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."fix_all_subscription_mismatches"() TO "postgres";
GRANT ALL ON FUNCTION "public"."fix_all_subscription_mismatches"() TO "anon";
GRANT ALL ON FUNCTION "public"."fix_all_subscription_mismatches"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."fix_all_subscription_mismatches"() TO "service_role";
GRANT ALL ON FUNCTION "public"."float4_dist"(real, real) TO "postgres";
GRANT ALL ON FUNCTION "public"."float4_dist"(real, real) TO "anon";
GRANT ALL ON FUNCTION "public"."float4_dist"(real, real) TO "authenticated";
GRANT ALL ON FUNCTION "public"."float4_dist"(real, real) TO "service_role";
GRANT ALL ON FUNCTION "public"."float8_dist"(double precision, double precision) TO "postgres";
GRANT ALL ON FUNCTION "public"."float8_dist"(double precision, double precision) TO "anon";
GRANT ALL ON FUNCTION "public"."float8_dist"(double precision, double precision) TO "authenticated";
GRANT ALL ON FUNCTION "public"."float8_dist"(double precision, double precision) TO "service_role";
GRANT ALL ON FUNCTION "public"."fn_agenda_regras_semanais_no_overlap"() TO "postgres";
GRANT ALL ON FUNCTION "public"."fn_agenda_regras_semanais_no_overlap"() TO "anon";
GRANT ALL ON FUNCTION "public"."fn_agenda_regras_semanais_no_overlap"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."fn_agenda_regras_semanais_no_overlap"() TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bit_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bit_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bit_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bit_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bit_consistent"("internal", bit, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bit_consistent"("internal", bit, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bit_consistent"("internal", bit, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bit_consistent"("internal", bit, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bit_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bit_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bit_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bit_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bit_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bit_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bit_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bit_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bit_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bit_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bit_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bit_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bit_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bit_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bit_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bit_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bool_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bool_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bool_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bool_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bool_consistent"("internal", boolean, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bool_consistent"("internal", boolean, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bool_consistent"("internal", boolean, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bool_consistent"("internal", boolean, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bool_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bool_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bool_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bool_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bool_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bool_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bool_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bool_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bool_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bool_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bool_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bool_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bool_same"("public"."gbtreekey2", "public"."gbtreekey2", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bool_same"("public"."gbtreekey2", "public"."gbtreekey2", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bool_same"("public"."gbtreekey2", "public"."gbtreekey2", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bool_same"("public"."gbtreekey2", "public"."gbtreekey2", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bool_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bool_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bool_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bool_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_consistent"("internal", character, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_consistent"("internal", character, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_consistent"("internal", character, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bpchar_consistent"("internal", character, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bytea_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bytea_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bytea_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bytea_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bytea_consistent"("internal", "bytea", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bytea_consistent"("internal", "bytea", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bytea_consistent"("internal", "bytea", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bytea_consistent"("internal", "bytea", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bytea_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bytea_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bytea_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bytea_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bytea_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bytea_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bytea_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bytea_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bytea_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bytea_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bytea_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bytea_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_bytea_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_bytea_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_bytea_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_bytea_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_consistent"("internal", "money", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_consistent"("internal", "money", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_consistent"("internal", "money", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_consistent"("internal", "money", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_distance"("internal", "money", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_distance"("internal", "money", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_distance"("internal", "money", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_distance"("internal", "money", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_cash_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_cash_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_cash_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_cash_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_consistent"("internal", "date", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_consistent"("internal", "date", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_consistent"("internal", "date", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_consistent"("internal", "date", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_distance"("internal", "date", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_distance"("internal", "date", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_distance"("internal", "date", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_distance"("internal", "date", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_date_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_date_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_date_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_date_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_decompress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_decompress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_decompress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_decompress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_enum_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_enum_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_enum_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_enum_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_enum_consistent"("internal", "anyenum", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_enum_consistent"("internal", "anyenum", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_enum_consistent"("internal", "anyenum", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_enum_consistent"("internal", "anyenum", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_enum_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_enum_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_enum_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_enum_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_enum_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_enum_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_enum_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_enum_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_enum_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_enum_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_enum_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_enum_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_enum_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_enum_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_enum_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_enum_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_enum_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_enum_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_enum_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_enum_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_consistent"("internal", real, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_consistent"("internal", real, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_consistent"("internal", real, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_consistent"("internal", real, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_distance"("internal", real, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_distance"("internal", real, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_distance"("internal", real, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_distance"("internal", real, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float4_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float4_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float4_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float4_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_consistent"("internal", double precision, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_consistent"("internal", double precision, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_consistent"("internal", double precision, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_consistent"("internal", double precision, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_distance"("internal", double precision, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_distance"("internal", double precision, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_distance"("internal", double precision, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_distance"("internal", double precision, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_float8_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_float8_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_float8_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_float8_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_inet_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_inet_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_inet_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_inet_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_inet_consistent"("internal", "inet", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_inet_consistent"("internal", "inet", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_inet_consistent"("internal", "inet", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_inet_consistent"("internal", "inet", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_inet_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_inet_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_inet_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_inet_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_inet_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_inet_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_inet_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_inet_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_inet_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_inet_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_inet_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_inet_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_inet_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_inet_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_inet_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_inet_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_consistent"("internal", smallint, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_consistent"("internal", smallint, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_consistent"("internal", smallint, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_consistent"("internal", smallint, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_distance"("internal", smallint, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_distance"("internal", smallint, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_distance"("internal", smallint, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_distance"("internal", smallint, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_same"("public"."gbtreekey4", "public"."gbtreekey4", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_same"("public"."gbtreekey4", "public"."gbtreekey4", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_same"("public"."gbtreekey4", "public"."gbtreekey4", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_same"("public"."gbtreekey4", "public"."gbtreekey4", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int2_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int2_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int2_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int2_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_consistent"("internal", integer, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_consistent"("internal", integer, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_consistent"("internal", integer, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_consistent"("internal", integer, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_distance"("internal", integer, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_distance"("internal", integer, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_distance"("internal", integer, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_distance"("internal", integer, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int4_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int4_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int4_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int4_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_consistent"("internal", bigint, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_consistent"("internal", bigint, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_consistent"("internal", bigint, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_consistent"("internal", bigint, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_distance"("internal", bigint, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_distance"("internal", bigint, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_distance"("internal", bigint, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_distance"("internal", bigint, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_int8_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_int8_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_int8_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_int8_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_consistent"("internal", interval, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_consistent"("internal", interval, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_consistent"("internal", interval, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_consistent"("internal", interval, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_decompress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_decompress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_decompress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_decompress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_distance"("internal", interval, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_distance"("internal", interval, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_distance"("internal", interval, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_distance"("internal", interval, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_intv_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_intv_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_intv_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_intv_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad8_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad8_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad8_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad8_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad8_consistent"("internal", "macaddr8", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad8_consistent"("internal", "macaddr8", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad8_consistent"("internal", "macaddr8", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad8_consistent"("internal", "macaddr8", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad8_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad8_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad8_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad8_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad8_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad8_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad8_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad8_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad8_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad8_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad8_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad8_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad8_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad8_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad8_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad8_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad8_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad_consistent"("internal", "macaddr", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad_consistent"("internal", "macaddr", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad_consistent"("internal", "macaddr", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad_consistent"("internal", "macaddr", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_macad_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_macad_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_macad_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_macad_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_numeric_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_numeric_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_numeric_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_numeric_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_numeric_consistent"("internal", numeric, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_numeric_consistent"("internal", numeric, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_numeric_consistent"("internal", numeric, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_numeric_consistent"("internal", numeric, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_numeric_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_numeric_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_numeric_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_numeric_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_numeric_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_numeric_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_numeric_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_numeric_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_numeric_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_numeric_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_numeric_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_numeric_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_numeric_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_numeric_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_numeric_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_numeric_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_consistent"("internal", "oid", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_consistent"("internal", "oid", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_consistent"("internal", "oid", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_consistent"("internal", "oid", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_distance"("internal", "oid", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_distance"("internal", "oid", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_distance"("internal", "oid", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_distance"("internal", "oid", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_same"("public"."gbtreekey8", "public"."gbtreekey8", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_oid_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_oid_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_oid_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_oid_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_text_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_text_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_text_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_text_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_text_consistent"("internal", "text", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_text_consistent"("internal", "text", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_text_consistent"("internal", "text", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_text_consistent"("internal", "text", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_text_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_text_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_text_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_text_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_text_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_text_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_text_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_text_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_text_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_text_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_text_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_text_same"("public"."gbtreekey_var", "public"."gbtreekey_var", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_text_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_text_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_text_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_text_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_consistent"("internal", time without time zone, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_consistent"("internal", time without time zone, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_consistent"("internal", time without time zone, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_consistent"("internal", time without time zone, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_distance"("internal", time without time zone, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_distance"("internal", time without time zone, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_distance"("internal", time without time zone, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_distance"("internal", time without time zone, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_time_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_time_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_time_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_time_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_timetz_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_timetz_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_timetz_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_timetz_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_timetz_consistent"("internal", time with time zone, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_timetz_consistent"("internal", time with time zone, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_timetz_consistent"("internal", time with time zone, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_timetz_consistent"("internal", time with time zone, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_consistent"("internal", timestamp without time zone, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_consistent"("internal", timestamp without time zone, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_consistent"("internal", timestamp without time zone, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_consistent"("internal", timestamp without time zone, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_distance"("internal", timestamp without time zone, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_distance"("internal", timestamp without time zone, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_distance"("internal", timestamp without time zone, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_distance"("internal", timestamp without time zone, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_same"("public"."gbtreekey16", "public"."gbtreekey16", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_ts_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_ts_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_ts_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_ts_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_tstz_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_tstz_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_tstz_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_tstz_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_tstz_consistent"("internal", timestamp with time zone, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_tstz_consistent"("internal", timestamp with time zone, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_tstz_consistent"("internal", timestamp with time zone, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_tstz_consistent"("internal", timestamp with time zone, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_tstz_distance"("internal", timestamp with time zone, smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_tstz_distance"("internal", timestamp with time zone, smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_tstz_distance"("internal", timestamp with time zone, smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_tstz_distance"("internal", timestamp with time zone, smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_uuid_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_uuid_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_uuid_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_uuid_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_uuid_consistent"("internal", "uuid", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_uuid_consistent"("internal", "uuid", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_uuid_consistent"("internal", "uuid", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_uuid_consistent"("internal", "uuid", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_uuid_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_uuid_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_uuid_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_uuid_fetch"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_uuid_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_uuid_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_uuid_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_uuid_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_uuid_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_uuid_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_uuid_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_uuid_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_uuid_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_uuid_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_uuid_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_uuid_same"("public"."gbtreekey32", "public"."gbtreekey32", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_uuid_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_uuid_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_uuid_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_uuid_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_var_decompress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_var_decompress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_var_decompress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_var_decompress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gbt_var_fetch"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gbt_var_fetch"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gbt_var_fetch"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gbt_var_fetch"("internal") TO "service_role";
REVOKE ALL ON FUNCTION "public"."get_my_email"() FROM PUBLIC;
GRANT ALL ON FUNCTION "public"."get_my_email"() TO "postgres";
GRANT ALL ON FUNCTION "public"."get_my_email"() TO "anon";
GRANT ALL ON FUNCTION "public"."get_my_email"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."get_my_email"() TO "service_role";
GRANT ALL ON FUNCTION "public"."gin_extract_query_trgm"("text", "internal", smallint, "internal", "internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gin_extract_query_trgm"("text", "internal", smallint, "internal", "internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gin_extract_query_trgm"("text", "internal", smallint, "internal", "internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gin_extract_query_trgm"("text", "internal", smallint, "internal", "internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gin_extract_value_trgm"("text", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gin_extract_value_trgm"("text", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gin_extract_value_trgm"("text", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gin_extract_value_trgm"("text", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gin_trgm_consistent"("internal", smallint, "text", integer, "internal", "internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gin_trgm_consistent"("internal", smallint, "text", integer, "internal", "internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gin_trgm_consistent"("internal", smallint, "text", integer, "internal", "internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gin_trgm_consistent"("internal", smallint, "text", integer, "internal", "internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gin_trgm_triconsistent"("internal", smallint, "text", integer, "internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gin_trgm_triconsistent"("internal", smallint, "text", integer, "internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gin_trgm_triconsistent"("internal", smallint, "text", integer, "internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gin_trgm_triconsistent"("internal", smallint, "text", integer, "internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_compress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_compress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_compress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_compress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_consistent"("internal", "text", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_consistent"("internal", "text", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_consistent"("internal", "text", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_consistent"("internal", "text", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_decompress"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_decompress"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_decompress"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_decompress"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_distance"("internal", "text", smallint, "oid", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_distance"("internal", "text", smallint, "oid", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_distance"("internal", "text", smallint, "oid", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_distance"("internal", "text", smallint, "oid", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_options"("internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_options"("internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_options"("internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_options"("internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_penalty"("internal", "internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_penalty"("internal", "internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_penalty"("internal", "internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_penalty"("internal", "internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_picksplit"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_picksplit"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_picksplit"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_picksplit"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_same"("public"."gtrgm", "public"."gtrgm", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_same"("public"."gtrgm", "public"."gtrgm", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_same"("public"."gtrgm", "public"."gtrgm", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_same"("public"."gtrgm", "public"."gtrgm", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."gtrgm_union"("internal", "internal") TO "postgres";
GRANT ALL ON FUNCTION "public"."gtrgm_union"("internal", "internal") TO "anon";
GRANT ALL ON FUNCTION "public"."gtrgm_union"("internal", "internal") TO "authenticated";
GRANT ALL ON FUNCTION "public"."gtrgm_union"("internal", "internal") TO "service_role";
GRANT ALL ON FUNCTION "public"."guard_account_type_immutable"() TO "postgres";
GRANT ALL ON FUNCTION "public"."guard_account_type_immutable"() TO "anon";
GRANT ALL ON FUNCTION "public"."guard_account_type_immutable"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."guard_account_type_immutable"() TO "service_role";
GRANT ALL ON FUNCTION "public"."guard_locked_commitment"() TO "postgres";
GRANT ALL ON FUNCTION "public"."guard_locked_commitment"() TO "anon";
GRANT ALL ON FUNCTION "public"."guard_locked_commitment"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."guard_locked_commitment"() TO "service_role";
GRANT ALL ON FUNCTION "public"."guard_no_change_core_plan_key"() TO "postgres";
GRANT ALL ON FUNCTION "public"."guard_no_change_core_plan_key"() TO "anon";
GRANT ALL ON FUNCTION "public"."guard_no_change_core_plan_key"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."guard_no_change_core_plan_key"() TO "service_role";
GRANT ALL ON FUNCTION "public"."guard_no_change_plan_target"() TO "postgres";
GRANT ALL ON FUNCTION "public"."guard_no_change_plan_target"() TO "anon";
GRANT ALL ON FUNCTION "public"."guard_no_change_plan_target"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."guard_no_change_plan_target"() TO "service_role";
GRANT ALL ON FUNCTION "public"."guard_no_delete_core_plans"() TO "postgres";
GRANT ALL ON FUNCTION "public"."guard_no_delete_core_plans"() TO "anon";
GRANT ALL ON FUNCTION "public"."guard_no_delete_core_plans"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."guard_no_delete_core_plans"() TO "service_role";
GRANT ALL ON FUNCTION "public"."guard_patient_cannot_own_tenant"() TO "postgres";
GRANT ALL ON FUNCTION "public"."guard_patient_cannot_own_tenant"() TO "anon";
GRANT ALL ON FUNCTION "public"."guard_patient_cannot_own_tenant"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."guard_patient_cannot_own_tenant"() TO "service_role";
GRANT ALL ON FUNCTION "public"."guard_tenant_kind_immutable"() TO "postgres";
GRANT ALL ON FUNCTION "public"."guard_tenant_kind_immutable"() TO "anon";
GRANT ALL ON FUNCTION "public"."guard_tenant_kind_immutable"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."guard_tenant_kind_immutable"() TO "service_role";
GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "postgres";
GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "anon";
GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "service_role";
GRANT ALL ON FUNCTION "public"."handle_new_user_create_personal_tenant"() TO "postgres";
GRANT ALL ON FUNCTION "public"."handle_new_user_create_personal_tenant"() TO "anon";
GRANT ALL ON FUNCTION "public"."handle_new_user_create_personal_tenant"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."handle_new_user_create_personal_tenant"() TO "service_role";
GRANT ALL ON FUNCTION "public"."has_feature"("p_owner_id" "uuid", "p_feature_key" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."has_feature"("p_owner_id" "uuid", "p_feature_key" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."has_feature"("p_owner_id" "uuid", "p_feature_key" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."has_feature"("p_owner_id" "uuid", "p_feature_key" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."int2_dist"(smallint, smallint) TO "postgres";
GRANT ALL ON FUNCTION "public"."int2_dist"(smallint, smallint) TO "anon";
GRANT ALL ON FUNCTION "public"."int2_dist"(smallint, smallint) TO "authenticated";
GRANT ALL ON FUNCTION "public"."int2_dist"(smallint, smallint) TO "service_role";
GRANT ALL ON FUNCTION "public"."int4_dist"(integer, integer) TO "postgres";
GRANT ALL ON FUNCTION "public"."int4_dist"(integer, integer) TO "anon";
GRANT ALL ON FUNCTION "public"."int4_dist"(integer, integer) TO "authenticated";
GRANT ALL ON FUNCTION "public"."int4_dist"(integer, integer) TO "service_role";
GRANT ALL ON FUNCTION "public"."int8_dist"(bigint, bigint) TO "postgres";
GRANT ALL ON FUNCTION "public"."int8_dist"(bigint, bigint) TO "anon";
GRANT ALL ON FUNCTION "public"."int8_dist"(bigint, bigint) TO "authenticated";
GRANT ALL ON FUNCTION "public"."int8_dist"(bigint, bigint) TO "service_role";
GRANT ALL ON FUNCTION "public"."interval_dist"(interval, interval) TO "postgres";
GRANT ALL ON FUNCTION "public"."interval_dist"(interval, interval) TO "anon";
GRANT ALL ON FUNCTION "public"."interval_dist"(interval, interval) TO "authenticated";
GRANT ALL ON FUNCTION "public"."interval_dist"(interval, interval) TO "service_role";
GRANT ALL ON FUNCTION "public"."is_clinic_tenant"("_tenant_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."is_clinic_tenant"("_tenant_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."is_clinic_tenant"("_tenant_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."is_clinic_tenant"("_tenant_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."is_saas_admin"() TO "postgres";
GRANT ALL ON FUNCTION "public"."is_saas_admin"() TO "anon";
GRANT ALL ON FUNCTION "public"."is_saas_admin"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."is_saas_admin"() TO "service_role";
GRANT ALL ON FUNCTION "public"."is_tenant_admin"("p_tenant_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."is_tenant_admin"("p_tenant_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."is_tenant_admin"("p_tenant_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."is_tenant_admin"("p_tenant_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."is_tenant_member"("_tenant_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."is_tenant_member"("_tenant_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."is_tenant_member"("_tenant_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."is_tenant_member"("_tenant_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."is_therapist_tenant"("_tenant_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."is_therapist_tenant"("_tenant_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."is_therapist_tenant"("_tenant_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."is_therapist_tenant"("_tenant_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."jwt_email"() TO "postgres";
GRANT ALL ON FUNCTION "public"."jwt_email"() TO "anon";
GRANT ALL ON FUNCTION "public"."jwt_email"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."jwt_email"() TO "service_role";
GRANT ALL ON FUNCTION "public"."my_tenants"() TO "postgres";
GRANT ALL ON FUNCTION "public"."my_tenants"() TO "anon";
GRANT ALL ON FUNCTION "public"."my_tenants"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."my_tenants"() TO "service_role";
GRANT ALL ON FUNCTION "public"."oid_dist"("oid", "oid") TO "postgres";
GRANT ALL ON FUNCTION "public"."oid_dist"("oid", "oid") TO "anon";
GRANT ALL ON FUNCTION "public"."oid_dist"("oid", "oid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."oid_dist"("oid", "oid") TO "service_role";
GRANT ALL ON FUNCTION "public"."on_new_user_seed_patient_groups"() TO "postgres";
GRANT ALL ON FUNCTION "public"."on_new_user_seed_patient_groups"() TO "anon";
GRANT ALL ON FUNCTION "public"."on_new_user_seed_patient_groups"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."on_new_user_seed_patient_groups"() TO "service_role";
GRANT ALL ON FUNCTION "public"."patients_validate_member_consistency"() TO "postgres";
GRANT ALL ON FUNCTION "public"."patients_validate_member_consistency"() TO "anon";
GRANT ALL ON FUNCTION "public"."patients_validate_member_consistency"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."patients_validate_member_consistency"() TO "service_role";
GRANT ALL ON FUNCTION "public"."patients_validate_responsible_member_tenant"() TO "postgres";
GRANT ALL ON FUNCTION "public"."patients_validate_responsible_member_tenant"() TO "anon";
GRANT ALL ON FUNCTION "public"."patients_validate_responsible_member_tenant"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."patients_validate_responsible_member_tenant"() TO "service_role";
GRANT ALL ON FUNCTION "public"."prevent_promoting_to_system"() TO "postgres";
GRANT ALL ON FUNCTION "public"."prevent_promoting_to_system"() TO "anon";
GRANT ALL ON FUNCTION "public"."prevent_promoting_to_system"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."prevent_promoting_to_system"() TO "service_role";
GRANT ALL ON FUNCTION "public"."prevent_saas_membership"() TO "postgres";
GRANT ALL ON FUNCTION "public"."prevent_saas_membership"() TO "anon";
GRANT ALL ON FUNCTION "public"."prevent_saas_membership"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."prevent_saas_membership"() TO "service_role";
GRANT ALL ON FUNCTION "public"."prevent_system_group_changes"() TO "postgres";
GRANT ALL ON FUNCTION "public"."prevent_system_group_changes"() TO "anon";
GRANT ALL ON FUNCTION "public"."prevent_system_group_changes"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."prevent_system_group_changes"() TO "service_role";
GRANT ALL ON FUNCTION "public"."provision_account_tenant"("p_user_id" "uuid", "p_kind" "text", "p_name" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."provision_account_tenant"("p_user_id" "uuid", "p_kind" "text", "p_name" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."provision_account_tenant"("p_user_id" "uuid", "p_kind" "text", "p_name" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."provision_account_tenant"("p_user_id" "uuid", "p_kind" "text", "p_name" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."reactivate_subscription"("p_subscription_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."reactivate_subscription"("p_subscription_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."reactivate_subscription"("p_subscription_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."reactivate_subscription"("p_subscription_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."rebuild_owner_entitlements"("p_owner_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."rebuild_owner_entitlements"("p_owner_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."rebuild_owner_entitlements"("p_owner_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."rebuild_owner_entitlements"("p_owner_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_match"("public"."citext", "public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_matches"("public"."citext", "public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_replace"("public"."citext", "public"."citext", "text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_split_to_array"("public"."citext", "public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."regexp_split_to_table"("public"."citext", "public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."replace"("public"."citext", "public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."replace"("public"."citext", "public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."replace"("public"."citext", "public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."replace"("public"."citext", "public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."rotate_patient_invite_token"("p_new_token" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."rotate_patient_invite_token"("p_new_token" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."rotate_patient_invite_token"("p_new_token" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."rotate_patient_invite_token"("p_new_token" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."saas_votar_doc"("p_doc_id" "uuid", "p_util" boolean) TO "postgres";
GRANT ALL ON FUNCTION "public"."saas_votar_doc"("p_doc_id" "uuid", "p_util" boolean) TO "anon";
GRANT ALL ON FUNCTION "public"."saas_votar_doc"("p_doc_id" "uuid", "p_util" boolean) TO "authenticated";
GRANT ALL ON FUNCTION "public"."saas_votar_doc"("p_doc_id" "uuid", "p_util" boolean) TO "service_role";
GRANT ALL ON FUNCTION "public"."seed_determined_commitments"("p_tenant_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."seed_determined_commitments"("p_tenant_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."seed_determined_commitments"("p_tenant_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."seed_determined_commitments"("p_tenant_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."set_limit"(real) TO "postgres";
GRANT ALL ON FUNCTION "public"."set_limit"(real) TO "anon";
GRANT ALL ON FUNCTION "public"."set_limit"(real) TO "authenticated";
GRANT ALL ON FUNCTION "public"."set_limit"(real) TO "service_role";
GRANT ALL ON FUNCTION "public"."set_owner_id"() TO "postgres";
GRANT ALL ON FUNCTION "public"."set_owner_id"() TO "anon";
GRANT ALL ON FUNCTION "public"."set_owner_id"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."set_owner_id"() TO "service_role";
GRANT ALL ON FUNCTION "public"."set_tenant_feature_exception"("p_tenant_id" "uuid", "p_feature_key" "text", "p_enabled" boolean, "p_reason" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."set_tenant_feature_exception"("p_tenant_id" "uuid", "p_feature_key" "text", "p_enabled" boolean, "p_reason" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."set_tenant_feature_exception"("p_tenant_id" "uuid", "p_feature_key" "text", "p_enabled" boolean, "p_reason" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."set_tenant_feature_exception"("p_tenant_id" "uuid", "p_feature_key" "text", "p_enabled" boolean, "p_reason" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."set_updated_at"() TO "postgres";
GRANT ALL ON FUNCTION "public"."set_updated_at"() TO "anon";
GRANT ALL ON FUNCTION "public"."set_updated_at"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."set_updated_at"() TO "service_role";
GRANT ALL ON FUNCTION "public"."set_updated_at_recurrence"() TO "postgres";
GRANT ALL ON FUNCTION "public"."set_updated_at_recurrence"() TO "anon";
GRANT ALL ON FUNCTION "public"."set_updated_at_recurrence"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."set_updated_at_recurrence"() TO "service_role";
GRANT ALL ON FUNCTION "public"."show_limit"() TO "postgres";
GRANT ALL ON FUNCTION "public"."show_limit"() TO "anon";
GRANT ALL ON FUNCTION "public"."show_limit"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."show_limit"() TO "service_role";
GRANT ALL ON FUNCTION "public"."show_trgm"("text") TO "postgres";
GRANT ALL ON FUNCTION "public"."show_trgm"("text") TO "anon";
GRANT ALL ON FUNCTION "public"."show_trgm"("text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."show_trgm"("text") TO "service_role";
GRANT ALL ON FUNCTION "public"."similarity"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."similarity"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."similarity"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."similarity"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."similarity_dist"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."similarity_dist"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."similarity_dist"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."similarity_dist"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."similarity_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."similarity_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."similarity_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."similarity_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."split_part"("public"."citext", "public"."citext", integer) TO "postgres";
GRANT ALL ON FUNCTION "public"."split_part"("public"."citext", "public"."citext", integer) TO "anon";
GRANT ALL ON FUNCTION "public"."split_part"("public"."citext", "public"."citext", integer) TO "authenticated";
GRANT ALL ON FUNCTION "public"."split_part"("public"."citext", "public"."citext", integer) TO "service_role";
GRANT ALL ON FUNCTION "public"."split_recurrence_at"("p_recurrence_id" "uuid", "p_from_date" "date") TO "postgres";
GRANT ALL ON FUNCTION "public"."split_recurrence_at"("p_recurrence_id" "uuid", "p_from_date" "date") TO "anon";
GRANT ALL ON FUNCTION "public"."split_recurrence_at"("p_recurrence_id" "uuid", "p_from_date" "date") TO "authenticated";
GRANT ALL ON FUNCTION "public"."split_recurrence_at"("p_recurrence_id" "uuid", "p_from_date" "date") TO "service_role";
GRANT ALL ON FUNCTION "public"."strict_word_similarity"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."strict_word_similarity"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."strict_word_similarity"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."strict_word_similarity"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_commutator_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_commutator_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_commutator_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_commutator_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_commutator_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_commutator_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_commutator_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_commutator_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_dist_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."strict_word_similarity_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."strpos"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."strpos"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."strpos"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."strpos"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."subscription_intents_view_insert"() TO "postgres";
GRANT ALL ON FUNCTION "public"."subscription_intents_view_insert"() TO "anon";
GRANT ALL ON FUNCTION "public"."subscription_intents_view_insert"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."subscription_intents_view_insert"() TO "service_role";
GRANT ALL ON FUNCTION "public"."subscriptions_validate_scope"() TO "postgres";
GRANT ALL ON FUNCTION "public"."subscriptions_validate_scope"() TO "anon";
GRANT ALL ON FUNCTION "public"."subscriptions_validate_scope"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."subscriptions_validate_scope"() TO "service_role";
GRANT ALL ON FUNCTION "public"."sync_busy_mirror_agenda_eventos"() TO "postgres";
GRANT ALL ON FUNCTION "public"."sync_busy_mirror_agenda_eventos"() TO "anon";
GRANT ALL ON FUNCTION "public"."sync_busy_mirror_agenda_eventos"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."sync_busy_mirror_agenda_eventos"() TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_accept_invite"("p_token" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_accept_invite"("p_token" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_accept_invite"("p_token" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_accept_invite"("p_token" "uuid") TO "service_role";
GRANT ALL ON TABLE "public"."tenant_members" TO "postgres";
GRANT SELECT,REFERENCES,TRIGGER,TRUNCATE,MAINTAIN ON TABLE "public"."tenant_members" TO "authenticated";
GRANT ALL ON TABLE "public"."tenant_members" TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_add_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_add_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_add_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_add_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_feature_allowed"("p_tenant_id" "uuid", "p_feature_key" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_feature_allowed"("p_tenant_id" "uuid", "p_feature_key" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_feature_allowed"("p_tenant_id" "uuid", "p_feature_key" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_feature_allowed"("p_tenant_id" "uuid", "p_feature_key" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_feature_enabled"("p_tenant_id" "uuid", "p_feature_key" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_feature_enabled"("p_tenant_id" "uuid", "p_feature_key" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_feature_enabled"("p_tenant_id" "uuid", "p_feature_key" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_feature_enabled"("p_tenant_id" "uuid", "p_feature_key" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_features_guard_with_plan"() TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_features_guard_with_plan"() TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_features_guard_with_plan"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_features_guard_with_plan"() TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_has_feature"("_tenant_id" "uuid", "_feature" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_has_feature"("_tenant_id" "uuid", "_feature" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_has_feature"("_tenant_id" "uuid", "_feature" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_has_feature"("_tenant_id" "uuid", "_feature" "text") TO "service_role";
REVOKE ALL ON FUNCTION "public"."tenant_invite_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") FROM PUBLIC;
GRANT ALL ON FUNCTION "public"."tenant_invite_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_invite_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_invite_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_invite_member_by_email"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_reactivate_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_reactivate_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_reactivate_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_reactivate_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_remove_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_remove_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_remove_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_remove_member"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_remove_member_soft"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_remove_member_soft"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_remove_member_soft"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_remove_member_soft"("p_tenant_id" "uuid", "p_member_user_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_revoke_invite"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_revoke_invite"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_revoke_invite"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_revoke_invite"("p_tenant_id" "uuid", "p_email" "text", "p_role" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_set_member_status"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_status" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_set_member_status"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_status" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_set_member_status"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_status" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_set_member_status"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_status" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."tenant_update_member_role"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_role" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."tenant_update_member_role"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_role" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."tenant_update_member_role"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_role" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."tenant_update_member_role"("p_tenant_id" "uuid", "p_member_user_id" "uuid", "p_new_role" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticlike"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticnlike"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticregexeq"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."texticregexne"("public"."citext", "public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."time_dist"(time without time zone, time without time zone) TO "postgres";
GRANT ALL ON FUNCTION "public"."time_dist"(time without time zone, time without time zone) TO "anon";
GRANT ALL ON FUNCTION "public"."time_dist"(time without time zone, time without time zone) TO "authenticated";
GRANT ALL ON FUNCTION "public"."time_dist"(time without time zone, time without time zone) TO "service_role";
GRANT ALL ON FUNCTION "public"."toggle_plan"("owner" "uuid") TO "postgres";
GRANT ALL ON FUNCTION "public"."toggle_plan"("owner" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."toggle_plan"("owner" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."toggle_plan"("owner" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."transition_subscription"("p_subscription_id" "uuid", "p_to_status" "text", "p_reason" "text", "p_metadata" "jsonb") TO "postgres";
GRANT ALL ON FUNCTION "public"."transition_subscription"("p_subscription_id" "uuid", "p_to_status" "text", "p_reason" "text", "p_metadata" "jsonb") TO "anon";
GRANT ALL ON FUNCTION "public"."transition_subscription"("p_subscription_id" "uuid", "p_to_status" "text", "p_reason" "text", "p_metadata" "jsonb") TO "authenticated";
GRANT ALL ON FUNCTION "public"."transition_subscription"("p_subscription_id" "uuid", "p_to_status" "text", "p_reason" "text", "p_metadata" "jsonb") TO "service_role";
GRANT ALL ON FUNCTION "public"."translate"("public"."citext", "public"."citext", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."translate"("public"."citext", "public"."citext", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."translate"("public"."citext", "public"."citext", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."translate"("public"."citext", "public"."citext", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."ts_dist"(timestamp without time zone, timestamp without time zone) TO "postgres";
GRANT ALL ON FUNCTION "public"."ts_dist"(timestamp without time zone, timestamp without time zone) TO "anon";
GRANT ALL ON FUNCTION "public"."ts_dist"(timestamp without time zone, timestamp without time zone) TO "authenticated";
GRANT ALL ON FUNCTION "public"."ts_dist"(timestamp without time zone, timestamp without time zone) TO "service_role";
GRANT ALL ON FUNCTION "public"."tstz_dist"(timestamp with time zone, timestamp with time zone) TO "postgres";
GRANT ALL ON FUNCTION "public"."tstz_dist"(timestamp with time zone, timestamp with time zone) TO "anon";
GRANT ALL ON FUNCTION "public"."tstz_dist"(timestamp with time zone, timestamp with time zone) TO "authenticated";
GRANT ALL ON FUNCTION "public"."tstz_dist"(timestamp with time zone, timestamp with time zone) TO "service_role";
GRANT ALL ON FUNCTION "public"."user_has_feature"("_user_id" "uuid", "_feature" "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."user_has_feature"("_user_id" "uuid", "_feature" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."user_has_feature"("_user_id" "uuid", "_feature" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."user_has_feature"("_user_id" "uuid", "_feature" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."whoami"() TO "postgres";
GRANT ALL ON FUNCTION "public"."whoami"() TO "anon";
GRANT ALL ON FUNCTION "public"."whoami"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."whoami"() TO "service_role";
GRANT ALL ON FUNCTION "public"."word_similarity"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."word_similarity"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."word_similarity"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."word_similarity"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."word_similarity_commutator_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."word_similarity_commutator_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."word_similarity_commutator_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."word_similarity_commutator_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_commutator_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_commutator_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_commutator_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_commutator_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."word_similarity_dist_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."word_similarity_op"("text", "text") TO "postgres";
GRANT ALL ON FUNCTION "public"."word_similarity_op"("text", "text") TO "anon";
GRANT ALL ON FUNCTION "public"."word_similarity_op"("text", "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."word_similarity_op"("text", "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."max"("public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."max"("public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."max"("public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."max"("public"."citext") TO "service_role";
GRANT ALL ON FUNCTION "public"."min"("public"."citext") TO "postgres";
GRANT ALL ON FUNCTION "public"."min"("public"."citext") TO "anon";
GRANT ALL ON FUNCTION "public"."min"("public"."citext") TO "authenticated";
GRANT ALL ON FUNCTION "public"."min"("public"."citext") TO "service_role";
GRANT ALL ON TABLE "public"."agenda_bloqueios" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_bloqueios" TO "anon";
GRANT ALL ON TABLE "public"."agenda_bloqueios" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_bloqueios" TO "service_role";
GRANT ALL ON TABLE "public"."agenda_configuracoes" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_configuracoes" TO "anon";
GRANT ALL ON TABLE "public"."agenda_configuracoes" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_configuracoes" TO "service_role";
GRANT ALL ON TABLE "public"."agenda_eventos" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_eventos" TO "anon";
GRANT ALL ON TABLE "public"."agenda_eventos" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_eventos" TO "service_role";
GRANT ALL ON TABLE "public"."agenda_excecoes" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_excecoes" TO "anon";
GRANT ALL ON TABLE "public"."agenda_excecoes" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_excecoes" TO "service_role";
GRANT ALL ON TABLE "public"."agenda_online_slots" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_online_slots" TO "anon";
GRANT ALL ON TABLE "public"."agenda_online_slots" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_online_slots" TO "service_role";
GRANT ALL ON SEQUENCE "public"."agenda_online_slots_id_seq" TO "postgres";
GRANT ALL ON SEQUENCE "public"."agenda_online_slots_id_seq" TO "anon";
GRANT ALL ON SEQUENCE "public"."agenda_online_slots_id_seq" TO "authenticated";
GRANT ALL ON SEQUENCE "public"."agenda_online_slots_id_seq" TO "service_role";
GRANT ALL ON TABLE "public"."agenda_regras_semanais" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_regras_semanais" TO "anon";
GRANT ALL ON TABLE "public"."agenda_regras_semanais" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_regras_semanais" TO "service_role";
GRANT ALL ON TABLE "public"."agenda_slots_bloqueados_semanais" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_slots_bloqueados_semanais" TO "anon";
GRANT ALL ON TABLE "public"."agenda_slots_bloqueados_semanais" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_slots_bloqueados_semanais" TO "service_role";
GRANT ALL ON TABLE "public"."agenda_slots_regras" TO "postgres";
GRANT ALL ON TABLE "public"."agenda_slots_regras" TO "anon";
GRANT ALL ON TABLE "public"."agenda_slots_regras" TO "authenticated";
GRANT ALL ON TABLE "public"."agenda_slots_regras" TO "service_role";
GRANT ALL ON TABLE "public"."agendador_configuracoes" TO "postgres";
GRANT ALL ON TABLE "public"."agendador_configuracoes" TO "anon";
GRANT ALL ON TABLE "public"."agendador_configuracoes" TO "authenticated";
GRANT ALL ON TABLE "public"."agendador_configuracoes" TO "service_role";
GRANT ALL ON TABLE "public"."agendador_solicitacoes" TO "postgres";
GRANT ALL ON TABLE "public"."agendador_solicitacoes" TO "anon";
GRANT ALL ON TABLE "public"."agendador_solicitacoes" TO "authenticated";
GRANT ALL ON TABLE "public"."agendador_solicitacoes" TO "service_role";
GRANT ALL ON TABLE "public"."commitment_time_logs" TO "postgres";
GRANT ALL ON TABLE "public"."commitment_time_logs" TO "anon";
GRANT ALL ON TABLE "public"."commitment_time_logs" TO "authenticated";
GRANT ALL ON TABLE "public"."commitment_time_logs" TO "service_role";
GRANT ALL ON TABLE "public"."current_tenant_id" TO "postgres";
GRANT ALL ON TABLE "public"."current_tenant_id" TO "anon";
GRANT ALL ON TABLE "public"."current_tenant_id" TO "authenticated";
GRANT ALL ON TABLE "public"."current_tenant_id" TO "service_role";
GRANT ALL ON TABLE "public"."determined_commitment_fields" TO "postgres";
GRANT ALL ON TABLE "public"."determined_commitment_fields" TO "anon";
GRANT ALL ON TABLE "public"."determined_commitment_fields" TO "authenticated";
GRANT ALL ON TABLE "public"."determined_commitment_fields" TO "service_role";
GRANT ALL ON TABLE "public"."determined_commitments" TO "postgres";
GRANT ALL ON TABLE "public"."determined_commitments" TO "anon";
GRANT ALL ON TABLE "public"."determined_commitments" TO "authenticated";
GRANT ALL ON TABLE "public"."determined_commitments" TO "service_role";
GRANT ALL ON TABLE "public"."dev_user_credentials" TO "postgres";
GRANT ALL ON TABLE "public"."dev_user_credentials" TO "anon";
GRANT ALL ON TABLE "public"."dev_user_credentials" TO "authenticated";
GRANT ALL ON TABLE "public"."dev_user_credentials" TO "service_role";
GRANT ALL ON TABLE "public"."entitlements_invalidation" TO "postgres";
GRANT ALL ON TABLE "public"."entitlements_invalidation" TO "anon";
GRANT ALL ON TABLE "public"."entitlements_invalidation" TO "authenticated";
GRANT ALL ON TABLE "public"."entitlements_invalidation" TO "service_role";
GRANT ALL ON TABLE "public"."features" TO "postgres";
GRANT ALL ON TABLE "public"."features" TO "anon";
GRANT ALL ON TABLE "public"."features" TO "authenticated";
GRANT ALL ON TABLE "public"."features" TO "service_role";
GRANT ALL ON TABLE "public"."feriados" TO "postgres";
GRANT ALL ON TABLE "public"."feriados" TO "anon";
GRANT ALL ON TABLE "public"."feriados" TO "authenticated";
GRANT ALL ON TABLE "public"."feriados" TO "service_role";
GRANT ALL ON TABLE "public"."module_features" TO "postgres";
GRANT ALL ON TABLE "public"."module_features" TO "anon";
GRANT ALL ON TABLE "public"."module_features" TO "authenticated";
GRANT ALL ON TABLE "public"."module_features" TO "service_role";
GRANT ALL ON TABLE "public"."modules" TO "postgres";
GRANT ALL ON TABLE "public"."modules" TO "anon";
GRANT ALL ON TABLE "public"."modules" TO "authenticated";
GRANT ALL ON TABLE "public"."modules" TO "service_role";
GRANT ALL ON TABLE "public"."plan_features" TO "postgres";
GRANT ALL ON TABLE "public"."plan_features" TO "anon";
GRANT ALL ON TABLE "public"."plan_features" TO "authenticated";
GRANT ALL ON TABLE "public"."plan_features" TO "service_role";
GRANT ALL ON TABLE "public"."tenant_modules" TO "postgres";
GRANT ALL ON TABLE "public"."tenant_modules" TO "anon";
GRANT ALL ON TABLE "public"."tenant_modules" TO "authenticated";
GRANT ALL ON TABLE "public"."tenant_modules" TO "service_role";
GRANT ALL ON TABLE "public"."owner_feature_entitlements" TO "postgres";
GRANT ALL ON TABLE "public"."owner_feature_entitlements" TO "anon";
GRANT ALL ON TABLE "public"."owner_feature_entitlements" TO "authenticated";
GRANT ALL ON TABLE "public"."owner_feature_entitlements" TO "service_role";
GRANT ALL ON TABLE "public"."owner_users" TO "postgres";
GRANT ALL ON TABLE "public"."owner_users" TO "anon";
GRANT ALL ON TABLE "public"."owner_users" TO "authenticated";
GRANT ALL ON TABLE "public"."owner_users" TO "service_role";
GRANT ALL ON TABLE "public"."patient_group_patient" TO "postgres";
GRANT ALL ON TABLE "public"."patient_group_patient" TO "anon";
GRANT ALL ON TABLE "public"."patient_group_patient" TO "authenticated";
GRANT ALL ON TABLE "public"."patient_group_patient" TO "service_role";
GRANT ALL ON TABLE "public"."patient_groups" TO "postgres";
GRANT ALL ON TABLE "public"."patient_groups" TO "anon";
GRANT ALL ON TABLE "public"."patient_groups" TO "authenticated";
GRANT ALL ON TABLE "public"."patient_groups" TO "service_role";
GRANT ALL ON TABLE "public"."patient_intake_requests" TO "postgres";
GRANT ALL ON TABLE "public"."patient_intake_requests" TO "authenticated";
GRANT ALL ON TABLE "public"."patient_intake_requests" TO "service_role";
GRANT ALL ON TABLE "public"."patient_invites" TO "postgres";
GRANT ALL ON TABLE "public"."patient_invites" TO "authenticated";
GRANT ALL ON TABLE "public"."patient_invites" TO "service_role";
GRANT ALL ON TABLE "public"."patient_patient_tag" TO "postgres";
GRANT ALL ON TABLE "public"."patient_patient_tag" TO "anon";
GRANT ALL ON TABLE "public"."patient_patient_tag" TO "authenticated";
GRANT ALL ON TABLE "public"."patient_patient_tag" TO "service_role";
GRANT ALL ON TABLE "public"."patient_tags" TO "postgres";
GRANT ALL ON TABLE "public"."patient_tags" TO "anon";
GRANT ALL ON TABLE "public"."patient_tags" TO "authenticated";
GRANT ALL ON TABLE "public"."patient_tags" TO "service_role";
GRANT ALL ON TABLE "public"."patients" TO "postgres";
GRANT ALL ON TABLE "public"."patients" TO "anon";
GRANT ALL ON TABLE "public"."patients" TO "authenticated";
GRANT ALL ON TABLE "public"."patients" TO "service_role";
GRANT ALL ON TABLE "public"."plan_prices" TO "postgres";
GRANT ALL ON TABLE "public"."plan_prices" TO "anon";
GRANT ALL ON TABLE "public"."plan_prices" TO "authenticated";
GRANT ALL ON TABLE "public"."plan_prices" TO "service_role";
GRANT ALL ON TABLE "public"."plan_public" TO "postgres";
GRANT ALL ON TABLE "public"."plan_public" TO "anon";
GRANT ALL ON TABLE "public"."plan_public" TO "authenticated";
GRANT ALL ON TABLE "public"."plan_public" TO "service_role";
GRANT ALL ON TABLE "public"."plan_public_bullets" TO "postgres";
GRANT ALL ON TABLE "public"."plan_public_bullets" TO "anon";
GRANT ALL ON TABLE "public"."plan_public_bullets" TO "authenticated";
GRANT ALL ON TABLE "public"."plan_public_bullets" TO "service_role";
GRANT ALL ON TABLE "public"."plans" TO "postgres";
GRANT ALL ON TABLE "public"."plans" TO "anon";
GRANT ALL ON TABLE "public"."plans" TO "authenticated";
GRANT ALL ON TABLE "public"."plans" TO "service_role";
GRANT ALL ON TABLE "public"."profiles" TO "postgres";
GRANT ALL ON TABLE "public"."profiles" TO "anon";
GRANT ALL ON TABLE "public"."profiles" TO "authenticated";
GRANT ALL ON TABLE "public"."profiles" TO "service_role";
GRANT ALL ON TABLE "public"."recurrence_exceptions" TO "postgres";
GRANT ALL ON TABLE "public"."recurrence_exceptions" TO "anon";
GRANT ALL ON TABLE "public"."recurrence_exceptions" TO "authenticated";
GRANT ALL ON TABLE "public"."recurrence_exceptions" TO "service_role";
GRANT ALL ON TABLE "public"."recurrence_rules" TO "postgres";
GRANT ALL ON TABLE "public"."recurrence_rules" TO "anon";
GRANT ALL ON TABLE "public"."recurrence_rules" TO "authenticated";
GRANT ALL ON TABLE "public"."recurrence_rules" TO "service_role";
GRANT ALL ON TABLE "public"."saas_admins" TO "postgres";
GRANT ALL ON TABLE "public"."saas_admins" TO "anon";
GRANT ALL ON TABLE "public"."saas_admins" TO "authenticated";
GRANT ALL ON TABLE "public"."saas_admins" TO "service_role";
GRANT ALL ON TABLE "public"."saas_doc_votos" TO "postgres";
GRANT ALL ON TABLE "public"."saas_doc_votos" TO "anon";
GRANT ALL ON TABLE "public"."saas_doc_votos" TO "authenticated";
GRANT ALL ON TABLE "public"."saas_doc_votos" TO "service_role";
GRANT ALL ON TABLE "public"."saas_docs" TO "postgres";
GRANT ALL ON TABLE "public"."saas_docs" TO "anon";
GRANT ALL ON TABLE "public"."saas_docs" TO "authenticated";
GRANT ALL ON TABLE "public"."saas_docs" TO "service_role";
GRANT ALL ON TABLE "public"."saas_faq" TO "postgres";
GRANT ALL ON TABLE "public"."saas_faq" TO "anon";
GRANT ALL ON TABLE "public"."saas_faq" TO "authenticated";
GRANT ALL ON TABLE "public"."saas_faq" TO "service_role";
GRANT ALL ON TABLE "public"."saas_faq_itens" TO "postgres";
GRANT ALL ON TABLE "public"."saas_faq_itens" TO "anon";
GRANT ALL ON TABLE "public"."saas_faq_itens" TO "authenticated";
GRANT ALL ON TABLE "public"."saas_faq_itens" TO "service_role";
GRANT ALL ON TABLE "public"."subscription_events" TO "postgres";
GRANT ALL ON TABLE "public"."subscription_events" TO "anon";
GRANT ALL ON TABLE "public"."subscription_events" TO "authenticated";
GRANT ALL ON TABLE "public"."subscription_events" TO "service_role";
GRANT ALL ON TABLE "public"."subscription_intents_personal" TO "postgres";
GRANT ALL ON TABLE "public"."subscription_intents_personal" TO "anon";
GRANT ALL ON TABLE "public"."subscription_intents_personal" TO "authenticated";
GRANT ALL ON TABLE "public"."subscription_intents_personal" TO "service_role";
GRANT ALL ON TABLE "public"."subscription_intents_tenant" TO "postgres";
GRANT ALL ON TABLE "public"."subscription_intents_tenant" TO "anon";
GRANT ALL ON TABLE "public"."subscription_intents_tenant" TO "authenticated";
GRANT ALL ON TABLE "public"."subscription_intents_tenant" TO "service_role";
GRANT ALL ON TABLE "public"."subscription_intents" TO "postgres";
GRANT ALL ON TABLE "public"."subscription_intents" TO "anon";
GRANT ALL ON TABLE "public"."subscription_intents" TO "authenticated";
GRANT ALL ON TABLE "public"."subscription_intents" TO "service_role";
GRANT ALL ON TABLE "public"."subscription_intents_legacy" TO "postgres";
GRANT ALL ON TABLE "public"."subscription_intents_legacy" TO "anon";
GRANT ALL ON TABLE "public"."subscription_intents_legacy" TO "authenticated";
GRANT ALL ON TABLE "public"."subscription_intents_legacy" TO "service_role";
GRANT ALL ON TABLE "public"."tenant_feature_exceptions_log" TO "postgres";
GRANT ALL ON TABLE "public"."tenant_feature_exceptions_log" TO "anon";
GRANT ALL ON TABLE "public"."tenant_feature_exceptions_log" TO "authenticated";
GRANT ALL ON TABLE "public"."tenant_feature_exceptions_log" TO "service_role";
GRANT ALL ON TABLE "public"."tenant_features" TO "postgres";
GRANT ALL ON TABLE "public"."tenant_features" TO "anon";
GRANT ALL ON TABLE "public"."tenant_features" TO "authenticated";
GRANT ALL ON TABLE "public"."tenant_features" TO "service_role";
GRANT ALL ON TABLE "public"."tenant_invites" TO "postgres";
GRANT ALL ON TABLE "public"."tenant_invites" TO "authenticated";
GRANT ALL ON TABLE "public"."tenant_invites" TO "service_role";
GRANT ALL ON TABLE "public"."tenants" TO "postgres";
GRANT ALL ON TABLE "public"."tenants" TO "anon";
GRANT ALL ON TABLE "public"."tenants" TO "authenticated";
GRANT ALL ON TABLE "public"."tenants" TO "service_role";
GRANT ALL ON TABLE "public"."user_settings" TO "postgres";
GRANT ALL ON TABLE "public"."user_settings" TO "anon";
GRANT ALL ON TABLE "public"."user_settings" TO "authenticated";
GRANT ALL ON TABLE "public"."user_settings" TO "service_role";
GRANT ALL ON TABLE "public"."v_auth_users_public" TO "postgres";
GRANT ALL ON TABLE "public"."v_auth_users_public" TO "anon";
GRANT ALL ON TABLE "public"."v_auth_users_public" TO "authenticated";
GRANT ALL ON TABLE "public"."v_auth_users_public" TO "service_role";
GRANT ALL ON TABLE "public"."v_commitment_totals" TO "postgres";
GRANT ALL ON TABLE "public"."v_commitment_totals" TO "anon";
GRANT ALL ON TABLE "public"."v_commitment_totals" TO "authenticated";
GRANT ALL ON TABLE "public"."v_commitment_totals" TO "service_role";
GRANT ALL ON TABLE "public"."v_patient_groups_with_counts" TO "postgres";
GRANT ALL ON TABLE "public"."v_patient_groups_with_counts" TO "anon";
GRANT ALL ON TABLE "public"."v_patient_groups_with_counts" TO "authenticated";
GRANT ALL ON TABLE "public"."v_patient_groups_with_counts" TO "service_role";
GRANT ALL ON TABLE "public"."v_plan_active_prices" TO "postgres";
GRANT ALL ON TABLE "public"."v_plan_active_prices" TO "anon";
GRANT ALL ON TABLE "public"."v_plan_active_prices" TO "authenticated";
GRANT ALL ON TABLE "public"."v_plan_active_prices" TO "service_role";
GRANT ALL ON TABLE "public"."v_public_pricing" TO "postgres";
GRANT ALL ON TABLE "public"."v_public_pricing" TO "anon";
GRANT ALL ON TABLE "public"."v_public_pricing" TO "authenticated";
GRANT ALL ON TABLE "public"."v_public_pricing" TO "service_role";
GRANT ALL ON TABLE "public"."v_subscription_feature_mismatch" TO "postgres";
GRANT ALL ON TABLE "public"."v_subscription_feature_mismatch" TO "anon";
GRANT ALL ON TABLE "public"."v_subscription_feature_mismatch" TO "authenticated";
GRANT ALL ON TABLE "public"."v_subscription_feature_mismatch" TO "service_role";
GRANT ALL ON TABLE "public"."v_subscription_health" TO "postgres";
GRANT ALL ON TABLE "public"."v_subscription_health" TO "anon";
GRANT ALL ON TABLE "public"."v_subscription_health" TO "authenticated";
GRANT ALL ON TABLE "public"."v_subscription_health" TO "service_role";
GRANT ALL ON TABLE "public"."v_subscription_health_v2" TO "postgres";
GRANT ALL ON TABLE "public"."v_subscription_health_v2" TO "anon";
GRANT ALL ON TABLE "public"."v_subscription_health_v2" TO "authenticated";
GRANT ALL ON TABLE "public"."v_subscription_health_v2" TO "service_role";
GRANT ALL ON TABLE "public"."v_tag_patient_counts" TO "postgres";
GRANT ALL ON TABLE "public"."v_tag_patient_counts" TO "anon";
GRANT ALL ON TABLE "public"."v_tag_patient_counts" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tag_patient_counts" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_active_subscription" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_active_subscription" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_active_subscription" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_active_subscription" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_entitlements" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_entitlements" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_entitlements" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_entitlements" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_full" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_full" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_full" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_full" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_json" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_json" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_json" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_entitlements_json" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_feature_exceptions" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_feature_exceptions" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_feature_exceptions" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_feature_exceptions" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_feature_mismatch" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_feature_mismatch" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_feature_mismatch" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_feature_mismatch" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_members_with_profiles" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_members_with_profiles" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_members_with_profiles" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_members_with_profiles" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_people" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_people" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_people" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_people" TO "service_role";
GRANT ALL ON TABLE "public"."v_tenant_staff" TO "postgres";
GRANT ALL ON TABLE "public"."v_tenant_staff" TO "anon";
GRANT ALL ON TABLE "public"."v_tenant_staff" TO "authenticated";
GRANT ALL ON TABLE "public"."v_tenant_staff" TO "service_role";
GRANT ALL ON TABLE "public"."v_user_active_subscription" TO "postgres";
GRANT ALL ON TABLE "public"."v_user_active_subscription" TO "anon";
GRANT ALL ON TABLE "public"."v_user_active_subscription" TO "authenticated";
GRANT ALL ON TABLE "public"."v_user_active_subscription" TO "service_role";
GRANT ALL ON TABLE "public"."v_user_entitlements" TO "postgres";
GRANT ALL ON TABLE "public"."v_user_entitlements" TO "anon";
GRANT ALL ON TABLE "public"."v_user_entitlements" TO "authenticated";
GRANT ALL ON TABLE "public"."v_user_entitlements" TO "service_role";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "postgres";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "anon";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "authenticated";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "service_role";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "postgres";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "anon";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "authenticated";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "service_role";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "postgres";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "anon";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "authenticated";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "service_role";