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"."status_evento_agenda" AS ENUM ( 'agendado', 'realizado', 'faltou', 'cancelado' ); 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 (agora ela tem plan_target e plan_id) select * into v_intent from public.subscription_intents where id = p_intent_id; if not found then raise exception 'Intent não encontrada'; 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, '')); if v_target not in ('clinic','therapist') 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 if v_intent.tenant_id is not null then raise exception 'Intent therapist não deve ter tenant_id'; end if; end if; v_days := case when v_intent.interval = 'year' then 365 else 30 end; -- define user_id (compat com schema legado) v_user_id := coalesce(v_intent.created_by_user_id, v_intent.user_id); -- fallback só faz sentido para therapist/personal (porque clinic NÃO usa user_id no XOR) -- Se você quiser manter um "responsável" da clínica, faça isso em outra coluna/tabela/evento, -- mas NÃO em subscriptions.user_id, pois quebra o XOR. if v_target = 'therapist' and v_user_id is null then raise exception 'Não foi possível determinar user_id para assinatura therapist.'; end if; -- cancela assinatura ativa anterior if v_target = 'clinic' then -- para clinic: uma assinatura ativa por tenant update public.subscriptions set status = 'cancelled', cancelled_at = now(), updated_at = now() where tenant_id = v_intent.tenant_id and status = 'active'; else -- para therapist: uma assinatura ativa por user (escopo pessoal) update public.subscriptions set status = 'cancelled', cancelled_at = now(), updated_at = now() where user_id = v_user_id and tenant_id is null and status = 'active'; end if; -- cria nova assinatura ativa (✅ respeita XOR) insert into public.subscriptions ( user_id, plan_id, status, current_period_start, current_period_end, cancel_at_period_end, provider, provider_customer_id, provider_subscription_id, created_at, updated_at, tenant_id, plan_key, interval, source, started_at, canceled_at, cancelled_at, activated_at ) values ( case when v_target = 'clinic' then null else v_user_id end, -- ✅ XOR v_plan_id, 'active', now(), now() + make_interval(days => v_days), false, 'manual', null, null, now(), now(), case when v_target = 'clinic' then v_intent.tenant_id else null end, -- ✅ XOR v_intent.plan_key, v_intent.interval, 'manual', now(), null, null, now() ) returning * into v_sub; -- ✅ grava o vínculo intent → subscription (para rastreio e UI) 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"."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"."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"."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"."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"."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"."subscription_intents_view_insert"() RETURNS "trigger" LANGUAGE "plpgsql" SECURITY DEFINER AS $$ declare v_target text; v_plan_id uuid; begin -- descobre o plano pelo plan_key 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; -- clinic → tabela tenant (tenant_id obrigatório) 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, user_id, created_by_user_id, email, plan_id, plan_key, interval, amount_cents, currency, status, source, notes, created_at, paid_at, tenant_id ) values ( coalesce(new.id, gen_random_uuid()), new.user_id, new.created_by_user_id, new.email, v_plan_id, new.plan_key, new.interval, new.amount_cents, new.currency, coalesce(new.status, 'new'), coalesce(new.source, 'manual'), new.notes, coalesce(new.created_at, now()), new.paid_at, new.tenant_id ) returning id, user_id, created_by_user_id, email, plan_id, plan_key, interval, amount_cents, currency, status, source, notes, created_at, paid_at, tenant_id, 'clinic'::text into new.id, new.user_id, new.created_by_user_id, new.email, new.plan_id, new.plan_key, new.interval, new.amount_cents, new.currency, new.status, new.source, new.notes, new.created_at, new.paid_at, new.tenant_id, new.plan_target; return new; end if; -- therapist → tabela personal (sem tenant_id) if lower(v_target) = 'therapist' 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, new.interval, new.amount_cents, new.currency, coalesce(new.status, 'new'), coalesce(new.source, 'manual'), new.notes, coalesce(new.created_at, now()), new.paid_at ) returning id, user_id, created_by_user_id, email, plan_id, plan_key, interval, amount_cents, currency, status, source, notes, created_at, paid_at into new.id, new.user_id, new.created_by_user_id, new.email, new.plan_id, new.plan_key, new.interval, new.amount_cents, new.currency, new.status, new.source, new.notes, new.created_at, new.paid_at; new.tenant_id := null; new.plan_target := 'therapist'; 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 = 'therapist' THEN IF NEW.tenant_id IS NOT NULL THEN RAISE EXCEPTION 'Assinatura therapist não deve ter tenant_id.'; END IF; IF NEW.user_id IS NULL THEN RAISE EXCEPTION 'Assinatura therapist exige user_id.'; 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_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, "session_start_offset_min" integer DEFAULT 0 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, "jornada_igual_todos" boolean DEFAULT true, "tenant_id" "uuid", 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))), CONSTRAINT "session_start_offset_min_chk" CHECK (("session_start_offset_min" = ANY (ARRAY[0, 15, 30, 45]))) ); 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", 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"."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 ); 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"."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", CONSTRAINT "plans_target_check" CHECK (("target" = ANY (ARRAY['patient'::"text", 'therapist'::"text", 'clinic'::"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.'; 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, 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).'; 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"."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_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"."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"."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"."saas_admins" ADD CONSTRAINT "saas_admins_pkey" PRIMARY KEY ("user_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_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_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 "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 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 "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 "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 "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_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_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"."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"."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"."saas_admins" ADD CONSTRAINT "saas_admins_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("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_configuracoes" ENABLE ROW LEVEL SECURITY; CREATE POLICY "agenda_configuracoes_owner" ON "public"."agenda_configuracoes" FOR ALL USING (("owner_id" = "auth"."uid"())) WITH CHECK (("owner_id" = "auth"."uid"())); 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" FOR ALL 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_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_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"))); -- Permite que o terapeuta/owner gerencie seus próprios eventos de agenda CREATE POLICY "agenda_eventos_owner_all" ON "public"."agenda_eventos" FOR ALL TO authenticated USING ("owner_id" = "auth"."uid"()) WITH CHECK ("owner_id" = "auth"."uid"()); ALTER TABLE "public"."agenda_excecoes" ENABLE ROW LEVEL SECURITY; 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_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_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"))); 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"))))); 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; 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"."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_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"))); -- Permite que o terapeuta/owner gerencie os grupos dos seus próprios pacientes CREATE POLICY "patient_group_patient_owner_all" ON "public"."patient_group_patient" FOR ALL TO authenticated USING ( EXISTS ( SELECT 1 FROM "public"."patients" p WHERE p.id = "patient_id" AND p.owner_id = "auth"."uid"() ) ) WITH CHECK ( EXISTS ( SELECT 1 FROM "public"."patients" p WHERE p.id = "patient_id" AND p.owner_id = "auth"."uid"() ) ); ALTER TABLE "public"."patient_groups" ENABLE ROW LEVEL SECURITY; 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"))); -- Permite que o terapeuta/owner acesse seus próprios grupos (incluindo via onboarding individual) CREATE POLICY "patient_groups_owner_all" ON "public"."patient_groups" FOR ALL TO authenticated USING ("owner_id" = "auth"."uid"()) WITH CHECK ("owner_id" = "auth"."uid"()); ALTER TABLE "public"."patient_intake_requests" ENABLE ROW LEVEL SECURITY; 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"))); -- Permite que o terapeuta/owner veja e gerencie os cadastros recebidos dos seus links CREATE POLICY "patient_intake_requests_owner_all" ON "public"."patient_intake_requests" FOR ALL TO authenticated USING ("owner_id" = "auth"."uid"()) WITH CHECK ("owner_id" = "auth"."uid"()); ALTER TABLE "public"."patient_invites" ENABLE ROW LEVEL SECURITY; 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"))); -- Permite que o terapeuta/owner gerencie seus próprios convites de cadastro externo CREATE POLICY "patient_invites_owner_all" ON "public"."patient_invites" FOR ALL TO authenticated USING ("owner_id" = "auth"."uid"()) WITH CHECK ("owner_id" = "auth"."uid"()); ALTER TABLE "public"."patient_patient_tag" ENABLE ROW LEVEL SECURITY; 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"))); -- Permite que o terapeuta/owner gerencie a pivot tag<->paciente pelos seus próprios registros CREATE POLICY "patient_patient_tag_owner_all" ON "public"."patient_patient_tag" FOR ALL TO authenticated USING ("owner_id" = "auth"."uid"()) WITH CHECK ("owner_id" = "auth"."uid"()); ALTER TABLE "public"."patient_tags" ENABLE ROW LEVEL SECURITY; 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"))); -- Permite que o terapeuta/owner acesse suas próprias tags CREATE POLICY "patient_tags_owner_all" ON "public"."patient_tags" FOR ALL TO authenticated USING ("owner_id" = "auth"."uid"()) WITH CHECK ("owner_id" = "auth"."uid"()); 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_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); 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"())))); 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"."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"())); 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"())); 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"."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"."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"."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"."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"."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"."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"."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_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"."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"."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"."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"."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"; -- ============================================================= -- MIGRATIONS APLICADAS MANUALMENTE (post-dump) -- ============================================================= -- [2025-03] Coluna jornada_igual_todos em agenda_configuracoes -- Já incluída na definição da tabela acima. -- Para aplicar em ambiente existente: -- ALTER TABLE public.agenda_configuracoes -- ADD COLUMN IF NOT EXISTS jornada_igual_todos boolean DEFAULT true; -- [2025-03] RLS: terapeuta acessa seus próprios grupos de pacientes -- Já incluída na seção de policies acima (patient_groups_owner_all). -- Para aplicar em ambiente existente: -- CREATE POLICY "patient_groups_owner_all" ON public.patient_groups -- FOR ALL TO authenticated -- USING (owner_id = auth.uid()) -- WITH CHECK (owner_id = auth.uid()); -- [2025-03] RLS: terapeuta gerencia pivot grupo<->paciente dos seus pacientes -- Já incluída na seção de policies acima (patient_group_patient_owner_all). -- Para aplicar em ambiente existente: -- CREATE POLICY "patient_group_patient_owner_all" ON public.patient_group_patient -- FOR ALL TO authenticated -- USING (EXISTS (SELECT 1 FROM public.patients p WHERE p.id = patient_id AND p.owner_id = auth.uid())) -- WITH CHECK (EXISTS (SELECT 1 FROM public.patients p WHERE p.id = patient_id AND p.owner_id = auth.uid())); -- ============================================================= -- SEEDER: Grupos padrão do sistema por owner/tenant -- ============================================================= -- Grupos criados como is_system=true por owner+tenant. -- Devem ser semeados no onboarding de cada novo usuário. -- Execute este bloco para popular usuários já existentes. -- ============================================================= CREATE OR REPLACE FUNCTION public.seed_system_groups_for_member( p_owner_id uuid, p_tenant_id uuid ) RETURNS void LANGUAGE plpgsql SECURITY DEFINER AS $$ DECLARE v_groups text[][] := ARRAY[ ARRAY['Ativo', '#22c55e'], ARRAY['Em Avaliação', '#3b82f6'], ARRAY['Lista de Espera', '#f59e0b'], ARRAY['Alta', '#8b5cf6'], ARRAY['Inativo', '#6b7280'] ]; v_entry text[]; BEGIN FOREACH v_entry SLICE 1 IN ARRAY v_groups LOOP INSERT INTO public.patient_groups ( owner_id, tenant_id, nome, cor, is_system, is_active ) VALUES ( p_owner_id, p_tenant_id, v_entry[1], v_entry[2], true, true ) ON CONFLICT (owner_id, nome) DO NOTHING; END LOOP; END; $$; -- Semeia para todos os membros ativos que ainda não têm grupos do sistema DO $$ DECLARE r record; BEGIN FOR r IN SELECT DISTINCT tm.user_id, tm.tenant_id FROM public.tenant_members tm WHERE tm.status = 'active' AND NOT EXISTS ( SELECT 1 FROM public.patient_groups pg WHERE pg.owner_id = tm.user_id AND pg.is_system = true ) LOOP PERFORM public.seed_system_groups_for_member(r.user_id, r.tenant_id); END LOOP; END; $$; -- ============================================================= -- TRIGGER: semeia grupos padrão ao ativar novo membro de tenant -- ============================================================= CREATE OR REPLACE FUNCTION public.trg_seed_system_groups_on_member_active() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER AS $$ BEGIN -- só age quando status muda para 'active' (insert ou update) IF NEW.status = 'active' THEN PERFORM public.seed_system_groups_for_member(NEW.user_id, NEW.tenant_id); END IF; RETURN NEW; END; $$; DROP TRIGGER IF EXISTS trg_seed_system_groups ON public.tenant_members; CREATE TRIGGER trg_seed_system_groups AFTER INSERT OR UPDATE OF status ON public.tenant_members FOR EACH ROW EXECUTE FUNCTION public.trg_seed_system_groups_on_member_active(); 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";