Correcao Sidebar Classico e Rail, Correcao Layout, Ajuste de Breakpoint para Tailwind, Ajuste AppTopbar, Ajuste Menu PopOver, Recriado Paleta de Cores, Inserido algumas animações leves, Reajuste Cor items NOVOS da tabela, Drawer Ajuda Corrigido no Logout, Whatsapp, sms, email, recursos extras

This commit is contained in:
Leonardo
2026-03-24 21:26:58 -03:00
parent a89d1f5560
commit 53a4980396
453 changed files with 121427 additions and 174407 deletions

View File

@@ -0,0 +1,776 @@
-- =============================================================================
-- AgenciaPsi — Functions — Compromissos, Suporte, SaaS
-- =============================================================================
-- seed_determined_commitments, delete_commitment_full,
-- delete_determined_commitment, guard_locked_commitment,
-- create_support_session, revoke_support_session, validate_support_session,
-- saas_votar_doc, faq_votar, notice_track_click/view,
-- sanitize_phone_br, create_clinic_tenant
-- =============================================================================
CREATE 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;
--
-- Name: financial_records; Type: TABLE; Schema: public; Owner: supabase_admin
--
CREATE TABLE public.financial_records (
id uuid DEFAULT gen_random_uuid() NOT NULL,
owner_id uuid NOT NULL,
tenant_id uuid,
type public.financial_record_type DEFAULT 'receita'::public.financial_record_type NOT NULL,
amount numeric(10,2) NOT NULL,
description text,
category text,
payment_method text,
paid_at timestamp with time zone,
due_date date,
installments smallint DEFAULT 1,
installment_number smallint DEFAULT 1,
installment_group uuid,
agenda_evento_id uuid,
patient_id uuid,
clinic_fee_pct numeric(5,2) DEFAULT 0,
clinic_fee_amount numeric(10,2) DEFAULT 0,
net_amount numeric(10,2) GENERATED ALWAYS AS ((amount - clinic_fee_amount)) STORED,
insurance_plan_id uuid,
notes text,
tags text[],
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
deleted_at timestamp with time zone,
discount_amount numeric(10,2) DEFAULT 0 NOT NULL,
final_amount numeric(10,2) DEFAULT 0 NOT NULL,
status text DEFAULT 'pending'::text NOT NULL,
category_id uuid,
CONSTRAINT financial_records_amount_check CHECK ((amount >= (0)::numeric)),
CONSTRAINT financial_records_clinic_fee_amount_check CHECK ((clinic_fee_amount >= (0)::numeric)),
CONSTRAINT financial_records_clinic_fee_pct_check CHECK (((clinic_fee_pct >= (0)::numeric) AND (clinic_fee_pct <= (100)::numeric))),
CONSTRAINT financial_records_discount_amount_check CHECK ((discount_amount >= (0)::numeric)),
CONSTRAINT financial_records_final_amount_check CHECK ((final_amount >= (0)::numeric)),
CONSTRAINT financial_records_installments_check CHECK ((installments >= 1)),
CONSTRAINT financial_records_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'paid'::text, 'partial'::text, 'overdue'::text, 'cancelled'::text, 'refunded'::text])))
);
ALTER TABLE public.financial_records OWNER TO supabase_admin;
--
-- Name: create_financial_record_for_session(uuid, uuid, uuid, uuid, numeric, date); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.create_financial_record_for_session(p_tenant_id uuid, p_owner_id uuid, p_patient_id uuid, p_agenda_evento_id uuid, p_amount numeric, p_due_date date) RETURNS SETOF public.financial_records
CREATE FUNCTION public.create_support_session(p_tenant_id uuid, p_ttl_minutes integer DEFAULT 60) RETURNS json
LANGUAGE plpgsql SECURITY DEFINER
SET search_path TO 'public'
AS $$
DECLARE
v_admin_id uuid;
v_role text;
v_token text;
v_expires timestamp with time zone;
v_session support_sessions;
BEGIN
-- Verifica autenticação
v_admin_id := auth.uid();
IF v_admin_id IS NULL THEN
RAISE EXCEPTION 'Não autenticado.' USING ERRCODE = 'P0001';
END IF;
-- Verifica role saas_admin
SELECT role INTO v_role
FROM public.profiles
WHERE id = v_admin_id;
IF v_role <> 'saas_admin' THEN
RAISE EXCEPTION 'Acesso negado. Somente saas_admin pode criar sessões de suporte.'
USING ERRCODE = 'P0002';
END IF;
-- Valida TTL (1 a 120 minutos)
IF p_ttl_minutes < 1 OR p_ttl_minutes > 120 THEN
RAISE EXCEPTION 'TTL inválido. Use entre 1 e 120 minutos.'
USING ERRCODE = 'P0003';
END IF;
-- Valida tenant
IF NOT EXISTS (SELECT 1 FROM public.tenants WHERE id = p_tenant_id) THEN
RAISE EXCEPTION 'Tenant não encontrado.'
USING ERRCODE = 'P0004';
END IF;
-- Gera token único (64 chars hex, sem pgcrypto)
v_token := replace(gen_random_uuid()::text, '-', '') || replace(gen_random_uuid()::text, '-', '');
v_expires := now() + (p_ttl_minutes || ' minutes')::interval;
-- Insere sessão
INSERT INTO public.support_sessions (tenant_id, admin_id, token, expires_at)
VALUES (p_tenant_id, v_admin_id, v_token, v_expires)
RETURNING * INTO v_session;
RETURN json_build_object(
'token', v_session.token,
'expires_at', v_session.expires_at,
'session_id', v_session.id
);
END;
$$;
ALTER FUNCTION public.create_support_session(p_tenant_id uuid, p_ttl_minutes integer) OWNER TO supabase_admin;
--
-- Name: therapist_payouts; Type: TABLE; Schema: public; Owner: supabase_admin
--
CREATE TABLE public.therapist_payouts (
id uuid DEFAULT gen_random_uuid() NOT NULL,
owner_id uuid NOT NULL,
tenant_id uuid NOT NULL,
period_start date NOT NULL,
period_end date NOT NULL,
total_sessions integer DEFAULT 0 NOT NULL,
gross_amount numeric(10,2) DEFAULT 0 NOT NULL,
clinic_fee_total numeric(10,2) DEFAULT 0 NOT NULL,
net_amount numeric(10,2) DEFAULT 0 NOT NULL,
status text DEFAULT 'pending'::text NOT NULL,
paid_at timestamp with time zone,
notes text,
created_at timestamp with time zone DEFAULT now() NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT therapist_payouts_clinic_fee_total_check CHECK ((clinic_fee_total >= (0)::numeric)),
CONSTRAINT therapist_payouts_gross_amount_check CHECK ((gross_amount >= (0)::numeric)),
CONSTRAINT therapist_payouts_net_amount_check CHECK ((net_amount >= (0)::numeric)),
CONSTRAINT therapist_payouts_period_chk CHECK ((period_end >= period_start)),
CONSTRAINT therapist_payouts_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'paid'::text, 'cancelled'::text])))
);
ALTER TABLE public.therapist_payouts OWNER TO supabase_admin;
--
-- Name: create_therapist_payout(uuid, uuid, date, date); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.create_therapist_payout(p_tenant_id uuid, p_therapist_id uuid, p_period_start date, p_period_end date) RETURNS public.therapist_payouts
CREATE 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;
--
-- Name: delete_determined_commitment(uuid, uuid); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE 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;
--
-- Name: dev_list_auth_users(integer); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.dev_list_auth_users(p_limit integer DEFAULT 50) RETURNS TABLE(id uuid, email text, created_at timestamp with time zone)
CREATE FUNCTION public.faq_votar(faq_id uuid) RETURNS void
LANGUAGE sql SECURITY DEFINER
AS $$
update public.saas_faq
set votos = votos + 1,
updated_at = now()
where id = faq_id
and ativo = true;
$$;
ALTER FUNCTION public.faq_votar(faq_id uuid) OWNER TO supabase_admin;
--
-- Name: fix_all_subscription_mismatches(); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE 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;
--
-- Name: fn_agenda_regras_semanais_no_overlap(); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.fn_agenda_regras_semanais_no_overlap() RETURNS trigger
CREATE 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;
--
-- Name: guard_no_change_core_plan_key(); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.guard_no_change_core_plan_key() RETURNS trigger
CREATE FUNCTION public.notice_track_click(p_notice_id uuid) RETURNS void
LANGUAGE plpgsql SECURITY DEFINER
AS $$
begin
update public.global_notices
set clicks_count = clicks_count + 1
where id = p_notice_id;
end;
$$;
ALTER FUNCTION public.notice_track_click(p_notice_id uuid) OWNER TO supabase_admin;
--
-- Name: notice_track_view(uuid); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.notice_track_view(p_notice_id uuid) RETURNS void
LANGUAGE plpgsql SECURITY DEFINER
AS $$
begin
update public.global_notices
set views_count = views_count + 1
where id = p_notice_id;
end;
$$;
ALTER FUNCTION public.notice_track_view(p_notice_id uuid) OWNER TO supabase_admin;
--
-- Name: notify_on_intake(); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.notify_on_intake() RETURNS trigger
CREATE FUNCTION public.revoke_support_session(p_token text) RETURNS boolean
LANGUAGE plpgsql SECURITY DEFINER
SET search_path TO 'public'
AS $$
DECLARE
v_admin_id uuid;
v_role text;
BEGIN
v_admin_id := auth.uid();
IF v_admin_id IS NULL THEN
RAISE EXCEPTION 'Não autenticado.' USING ERRCODE = 'P0001';
END IF;
SELECT role INTO v_role FROM public.profiles WHERE id = v_admin_id;
IF v_role <> 'saas_admin' THEN
RAISE EXCEPTION 'Acesso negado.' USING ERRCODE = 'P0002';
END IF;
DELETE FROM public.support_sessions
WHERE token = p_token
AND admin_id = v_admin_id;
RETURN FOUND;
END;
$$;
ALTER FUNCTION public.revoke_support_session(p_token text) OWNER TO supabase_admin;
--
-- Name: rotate_patient_invite_token(text); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.rotate_patient_invite_token(p_new_token text) RETURNS uuid
CREATE FUNCTION public.saas_votar_doc(p_doc_id uuid, p_util boolean) RETURNS jsonb
LANGUAGE plpgsql SECURITY DEFINER
AS $$
declare
v_uid uuid := auth.uid();
v_voto_antigo boolean;
begin
if v_uid is null then
raise exception 'Não autenticado';
end if;
-- Verifica se já votou
select util into v_voto_antigo
from public.saas_doc_votos
where doc_id = p_doc_id and user_id = v_uid;
if found then
-- Já votou igual → cancela o voto (toggle)
if v_voto_antigo = p_util then
delete from public.saas_doc_votos
where doc_id = p_doc_id and user_id = v_uid;
update public.saas_docs set
votos_util = greatest(0, votos_util - (case when p_util then 1 else 0 end)),
votos_nao_util = greatest(0, votos_nao_util - (case when not p_util then 1 else 0 end)),
updated_at = now()
where id = p_doc_id;
return jsonb_build_object('acao', 'removido', 'util', null);
else
-- Mudou de voto
update public.saas_doc_votos set util = p_util, updated_at = now()
where doc_id = p_doc_id and user_id = v_uid;
update public.saas_docs set
votos_util = greatest(0, votos_util + (case when p_util then 1 else -1 end)),
votos_nao_util = greatest(0, votos_nao_util + (case when not p_util then 1 else -1 end)),
updated_at = now()
where id = p_doc_id;
return jsonb_build_object('acao', 'atualizado', 'util', p_util);
end if;
else
-- Primeiro voto
insert into public.saas_doc_votos (doc_id, user_id, util)
values (p_doc_id, v_uid, p_util);
update public.saas_docs set
votos_util = votos_util + (case when p_util then 1 else 0 end),
votos_nao_util = votos_nao_util + (case when not p_util then 1 else 0 end),
updated_at = now()
where id = p_doc_id;
return jsonb_build_object('acao', 'registrado', 'util', p_util);
end if;
end;
$$;
ALTER FUNCTION public.saas_votar_doc(p_doc_id uuid, p_util boolean) OWNER TO supabase_admin;
--
-- Name: safe_delete_patient(uuid); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.safe_delete_patient(p_patient_id uuid) RETURNS jsonb
CREATE FUNCTION public.sanitize_phone_br(raw_phone text) RETURNS text
LANGUAGE plpgsql IMMUTABLE
AS $$ DECLARE digits text;
BEGIN
digits := regexp_replace(COALESCE(raw_phone, ''), '[^0-9]', '', 'g');
IF digits = '' THEN RETURN ''; END IF;
IF length(digits) = 10 OR length(digits) = 11 THEN
digits := '55' || digits;
END IF;
RETURN digits;
END; $$;
ALTER FUNCTION public.sanitize_phone_br(raw_phone text) OWNER TO supabase_admin;
--
-- Name: seed_default_financial_categories(uuid); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.seed_default_financial_categories(p_user_id uuid) RETURNS void
CREATE 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;
--
-- Name: set_insurance_plans_updated_at(); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.set_insurance_plans_updated_at() RETURNS trigger
CREATE FUNCTION public.validate_support_session(p_token text) RETURNS json
LANGUAGE plpgsql SECURITY DEFINER
SET search_path TO 'public'
AS $$
DECLARE
v_session support_sessions;
BEGIN
IF p_token IS NULL OR length(trim(p_token)) < 32 THEN
RETURN json_build_object('valid', false, 'tenant_id', null);
END IF;
SELECT * INTO v_session
FROM public.support_sessions
WHERE token = p_token
AND expires_at > now()
LIMIT 1;
IF NOT FOUND THEN
RETURN json_build_object('valid', false, 'tenant_id', null);
END IF;
RETURN json_build_object(
'valid', true,
'tenant_id', v_session.tenant_id
);
END;
$$;
ALTER FUNCTION public.validate_support_session(p_token text) OWNER TO supabase_admin;
--
-- Name: whoami(); Type: FUNCTION; Schema: public; Owner: supabase_admin
--
CREATE FUNCTION public.whoami() RETURNS TABLE(uid uuid, role text)