Agenda, Agendador, Configurações
This commit is contained in:
170
DBS/2026-03-11/migrations/agendador_online.sql
Normal file
170
DBS/2026-03-11/migrations/agendador_online.sql
Normal file
@@ -0,0 +1,170 @@
|
||||
-- ═══════════════════════════════════════════════════════════════════════════
|
||||
-- Agendador Online — tabelas de configuração e solicitações
|
||||
-- ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
-- ── 1. agendador_configuracoes ──────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS "public"."agendador_configuracoes" (
|
||||
"owner_id" "uuid" NOT NULL,
|
||||
"tenant_id" "uuid",
|
||||
|
||||
-- PRO / Ativação
|
||||
"ativo" boolean DEFAULT false NOT NULL,
|
||||
"link_slug" "text",
|
||||
|
||||
-- Identidade Visual
|
||||
"imagem_fundo_url" "text",
|
||||
"imagem_header_url" "text",
|
||||
"logomarca_url" "text",
|
||||
"cor_primaria" "text" DEFAULT '#4b6bff',
|
||||
|
||||
-- Perfil Público
|
||||
"nome_exibicao" "text",
|
||||
"endereco" "text",
|
||||
"botao_como_chegar_ativo" boolean DEFAULT true NOT NULL,
|
||||
"maps_url" "text",
|
||||
|
||||
-- Fluxo de Agendamento
|
||||
"modo_aprovacao" "text" DEFAULT 'aprovacao' NOT NULL,
|
||||
"modalidade" "text" DEFAULT 'presencial' NOT NULL,
|
||||
"tipos_habilitados" "jsonb" DEFAULT '["primeira","retorno"]'::jsonb NOT NULL,
|
||||
"duracao_sessao_min" integer DEFAULT 50 NOT NULL,
|
||||
"antecedencia_minima_horas" integer DEFAULT 24 NOT NULL,
|
||||
"prazo_resposta_horas" integer DEFAULT 2 NOT NULL,
|
||||
"reserva_horas" integer DEFAULT 2 NOT NULL,
|
||||
|
||||
-- Pagamento
|
||||
"pagamento_obrigatorio" boolean DEFAULT false NOT NULL,
|
||||
"pix_chave" "text",
|
||||
"pix_countdown_minutos" integer DEFAULT 20 NOT NULL,
|
||||
|
||||
-- Triagem & Conformidade
|
||||
"triagem_motivo" boolean DEFAULT true NOT NULL,
|
||||
"triagem_como_conheceu" boolean DEFAULT false NOT NULL,
|
||||
"verificacao_email" boolean DEFAULT false NOT NULL,
|
||||
"exigir_aceite_lgpd" boolean DEFAULT true NOT NULL,
|
||||
|
||||
-- Textos
|
||||
"mensagem_boas_vindas" "text",
|
||||
"texto_como_se_preparar" "text",
|
||||
"texto_termos_lgpd" "text",
|
||||
|
||||
-- Timestamps
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
|
||||
CONSTRAINT "agendador_configuracoes_pkey" PRIMARY KEY ("owner_id"),
|
||||
CONSTRAINT "agendador_configuracoes_owner_fk"
|
||||
FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "agendador_configuracoes_tenant_fk"
|
||||
FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "agendador_configuracoes_modo_check"
|
||||
CHECK ("modo_aprovacao" = ANY (ARRAY['automatico','aprovacao'])),
|
||||
CONSTRAINT "agendador_configuracoes_modalidade_check"
|
||||
CHECK ("modalidade" = ANY (ARRAY['presencial','online','ambos'])),
|
||||
CONSTRAINT "agendador_configuracoes_duracao_check"
|
||||
CHECK ("duracao_sessao_min" >= 10 AND "duracao_sessao_min" <= 240),
|
||||
CONSTRAINT "agendador_configuracoes_antecedencia_check"
|
||||
CHECK ("antecedencia_minima_horas" >= 0 AND "antecedencia_minima_horas" <= 720),
|
||||
CONSTRAINT "agendador_configuracoes_reserva_check"
|
||||
CHECK ("reserva_horas" >= 1 AND "reserva_horas" <= 48),
|
||||
CONSTRAINT "agendador_configuracoes_pix_countdown_check"
|
||||
CHECK ("pix_countdown_minutos" >= 5 AND "pix_countdown_minutos" <= 120),
|
||||
CONSTRAINT "agendador_configuracoes_prazo_check"
|
||||
CHECK ("prazo_resposta_horas" >= 1 AND "prazo_resposta_horas" <= 72)
|
||||
);
|
||||
|
||||
ALTER TABLE "public"."agendador_configuracoes" ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
DROP POLICY IF EXISTS "agendador_cfg_select" ON "public"."agendador_configuracoes";
|
||||
CREATE POLICY "agendador_cfg_select" ON "public"."agendador_configuracoes"
|
||||
FOR SELECT USING (auth.uid() = owner_id);
|
||||
|
||||
DROP POLICY IF EXISTS "agendador_cfg_write" ON "public"."agendador_configuracoes";
|
||||
CREATE POLICY "agendador_cfg_write" ON "public"."agendador_configuracoes"
|
||||
USING (auth.uid() = owner_id)
|
||||
WITH CHECK (auth.uid() = owner_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "agendador_cfg_tenant_idx"
|
||||
ON "public"."agendador_configuracoes" ("tenant_id");
|
||||
|
||||
-- ── 2. agendador_solicitacoes ───────────────────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS "public"."agendador_solicitacoes" (
|
||||
"id" "uuid" DEFAULT gen_random_uuid() NOT NULL,
|
||||
"owner_id" "uuid" NOT NULL,
|
||||
"tenant_id" "uuid",
|
||||
|
||||
-- Dados do paciente
|
||||
"paciente_nome" "text" NOT NULL,
|
||||
"paciente_sobrenome" "text",
|
||||
"paciente_email" "text" NOT NULL,
|
||||
"paciente_celular" "text",
|
||||
"paciente_cpf" "text",
|
||||
|
||||
-- Agendamento solicitado
|
||||
"tipo" "text" NOT NULL,
|
||||
"modalidade" "text" NOT NULL,
|
||||
"data_solicitada" date NOT NULL,
|
||||
"hora_solicitada" time NOT NULL,
|
||||
|
||||
-- Reserva temporária
|
||||
"reservado_ate" timestamp with time zone,
|
||||
|
||||
-- Triagem
|
||||
"motivo" "text",
|
||||
"como_conheceu" "text",
|
||||
|
||||
-- Pagamento
|
||||
"pix_status" "text" DEFAULT 'pendente',
|
||||
"pix_pago_em" timestamp with time zone,
|
||||
|
||||
-- Status geral
|
||||
"status" "text" DEFAULT 'pendente' NOT NULL,
|
||||
"recusado_motivo" "text",
|
||||
|
||||
-- Autorização
|
||||
"autorizado_em" timestamp with time zone,
|
||||
"autorizado_por" "uuid",
|
||||
|
||||
-- Vínculos internos
|
||||
"user_id" "uuid",
|
||||
"patient_id" "uuid",
|
||||
"evento_id" "uuid",
|
||||
|
||||
-- Timestamps
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
|
||||
CONSTRAINT "agendador_solicitacoes_pkey" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "agendador_sol_owner_fk"
|
||||
FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "agendador_sol_tenant_fk"
|
||||
FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "agendador_sol_status_check"
|
||||
CHECK ("status" = ANY (ARRAY['pendente','autorizado','recusado','expirado'])),
|
||||
CONSTRAINT "agendador_sol_tipo_check"
|
||||
CHECK ("tipo" = ANY (ARRAY['primeira','retorno','reagendar'])),
|
||||
CONSTRAINT "agendador_sol_modalidade_check"
|
||||
CHECK ("modalidade" = ANY (ARRAY['presencial','online'])),
|
||||
CONSTRAINT "agendador_sol_pix_check"
|
||||
CHECK ("pix_status" IS NULL OR "pix_status" = ANY (ARRAY['pendente','pago','expirado']))
|
||||
);
|
||||
|
||||
ALTER TABLE "public"."agendador_solicitacoes" ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
DROP POLICY IF EXISTS "agendador_sol_owner_select" ON "public"."agendador_solicitacoes";
|
||||
CREATE POLICY "agendador_sol_owner_select" ON "public"."agendador_solicitacoes"
|
||||
FOR SELECT USING (auth.uid() = owner_id);
|
||||
|
||||
DROP POLICY IF EXISTS "agendador_sol_owner_write" ON "public"."agendador_solicitacoes";
|
||||
CREATE POLICY "agendador_sol_owner_write" ON "public"."agendador_solicitacoes"
|
||||
USING (auth.uid() = owner_id)
|
||||
WITH CHECK (auth.uid() = owner_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "agendador_sol_owner_idx"
|
||||
ON "public"."agendador_solicitacoes" ("owner_id", "status");
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "agendador_sol_tenant_idx"
|
||||
ON "public"."agendador_solicitacoes" ("tenant_id");
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "agendador_sol_data_idx"
|
||||
ON "public"."agendador_solicitacoes" ("data_solicitada", "hora_solicitada");
|
||||
Reference in New Issue
Block a user