Pular para o conteúdo

0010 — Marketplace de Consultores Credenciados + Pacotes Avulsos

Status

Accepted · 2026-04-26 · Autor: Alexandre + Claude.

Contexto

Modelo de Revenue Share (ADR 0008) precisa de marketplace pra:

  1. Clínicas órfãs (sem consultor) descobrirem consultores credenciados
  2. Consultores ganharem visibilidade pública (SEO)
  3. Plataforma curar quem entra (qualidade)

Sem marketplace, plataforma fica refém de “consultor que conhecemos”. Com marketplace mal-feito, vira lugar de spam onde consultores assediam clínicas.

Decisão

1. Curadoria por convite (sem auto-cadastro)

Consultor não pode “se cadastrar” na plataforma. Apenas Alexandre (platform_admin) convida.

Status do credenciamento (consultancies.credentialed_status):

  • pending_invitation — Alexandre cadastrou mas não enviou convite ainda
  • invited — convite enviado por email; consultor recebeu link mas não aceitou
  • pending_approval — consultor aceitou e completou perfil; aguarda aprovação final
  • credentialed — aprovado e ativo no marketplace
  • suspended — temporariamente fora (dispute, não cumprimento de SLA, etc)
  • revoked — descredenciado permanentemente

Razão: qualidade do marketplace > volume. Cliente final (clínica) confia em ClinicGestor pela curadoria.

2. Marketplace público SEO-indexed

Rota /consultores (no domínio clinicgestor.com):

  • Listagem pública de todos credentialed_status = 'credentialed' AND accepts_new_clinics = true
  • Filtros: especialidade, região, idiomas
  • Sem autenticação (público pra SEO)
  • Branding: plataforma (não consultor)

Rota /consultores/<slug>:

  • Perfil individual do consultor
  • Branding: do consultor (logo + 2 cores próprios)
  • Mostra: bio, casos, depoimentos, pacotes avulsos oferecidos, promoção opcional (“Primeira sessão grátis”)
  • CTA: “Quero ser cliente” (redireciona pra /signup se não logado, ou direto pra “tornar X minha consultoria” se logado e órfã)

Ambas indexadas pelo Google. Captura busca SEO orgânica.

3. Princípio “no-spam B2B” (busca unidirecional)

Regra inviolável: clínica busca consultor; consultor nunca busca clínica.

  • Não existe rota tipo /consultancy/marketplace-clinicas
  • Não existe filtro/listing de clínicas órfãs disponível ao consultor
  • RLS bloqueia: consultancy_can_view_clinic(consultancy_id, clinic_id) retorna false se clínica não está em current_consultancy_id ou attribution_consultancy_id
  • Lint custom lint:no-spam-b2b proíbe rotas com pattern /consultancy/(marketplace|search|browse)-clinic*

Razão: B2B SaaS sem essa regra vira “garimpagem” — consultor caça clínicas, marketplace vira spam, plataforma perde reputação.

4. Marketplace só pra órfãs com plano ativo

Helper:

CREATE OR REPLACE FUNCTION public.clinic_can_browse_marketplace(p_clinic_id UUID)
RETURNS BOOLEAN
LANGUAGE SQL STABLE SECURITY DEFINER SET search_path = public AS $$
SELECT EXISTS (
SELECT 1 FROM public.clinics c
WHERE c.id = p_clinic_id
AND c.deleted_at IS NULL
AND c.current_consultancy_id IS NULL
AND c.platform_subscription_state = 'active'
);
$$;

UI esconde rota /clinic/escolher-consultor se helper retornar false. API rejeita com 403.

Razão: clínica em contrato não vê marketplace pra evitar “garimpagem inversa” (outros consultores assediarem).

5. Vitrine futura curada pela plataforma (F2+)

Pra dar visibilidade controlada aos consultores credenciados (sem permitir que eles façam outreach proativo):

  • Blog clinicgestor.com/blog com artigos de gestão clínica (consultor pode ser convidado como autor)
  • Podcasts da plataforma com consultores como entrevistados
  • Banner no marketplace “Consultor do Mês” (curado por Alexandre)
  • Lives mensais da plataforma com 1 consultor convidado

Schema dormente em F1 (platform_blog_posts, platform_podcast_episodes, marketplace_featured_consultancies); ativação F2+.

6. Pacotes Avulsos (F1.5) — degrau 2 da escada de aquisição

Escada de aquisição:

Degrau 1: 1h GRÁTIS (promoção opcional do consultor — campo em consultancies.promotional_offer)
Degrau 2: PACOTE PAGO 1-10h (essa subseção — F1.5)
Degrau 3: CONTRATO FIXO mensal (Ideia 1 base — Revenue Share)

6.1 Tabelas (F1)

-- Pacotes oferecidos pelo consultor (F1 prepara, F1.5 ativa UI)
CREATE TABLE public.consultancy_session_packages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
consultancy_id UUID NOT NULL REFERENCES public.consultancies(id),
name TEXT NOT NULL, -- "Mentoria Pontual 1h"
description TEXT,
hours_count INT NOT NULL CHECK (hours_count > 0),
price_brl_cents INT NOT NULL CHECK (price_brl_cents >= 0),
validity_days INT NOT NULL DEFAULT 90,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Compra de pacote (F1.5)
CREATE TABLE public.session_package_purchases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
package_id UUID NOT NULL REFERENCES public.consultancy_session_packages(id),
clinic_id UUID NOT NULL REFERENCES public.clinics(id),
consultancy_id UUID NOT NULL REFERENCES public.consultancies(id),
purchased_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL,
hours_total INT NOT NULL,
hours_used NUMERIC(5,2) DEFAULT 0,
status TEXT NOT NULL DEFAULT 'active'
CHECK (status IN ('active', 'consumed', 'expired', 'refunded')),
asaas_payment_id TEXT,
data_access_consent_until TIMESTAMPTZ NOT NULL, -- consent escopado pelo pacote
refunded_at TIMESTAMPTZ,
refund_reason TEXT
);
-- Sessões agendadas (F1.5)
CREATE TABLE public.session_appointments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
purchase_id UUID NOT NULL REFERENCES public.session_package_purchases(id),
scheduled_for TIMESTAMPTZ NOT NULL,
duration_minutes INT DEFAULT 60,
status TEXT NOT NULL DEFAULT 'scheduled'
CHECK (status IN ('scheduled', 'completed', 'cancelled', 'no_show')),
consultant_notes TEXT,
clinic_rating INT CHECK (clinic_rating BETWEEN 1 AND 5),
clinic_feedback TEXT,
meeting_url TEXT, -- preenchido manualmente pelo consultor (F1.5; integração com Cal.com em F2+)
cancelled_at TIMESTAMPTZ,
cancelled_by TEXT CHECK (cancelled_by IN ('clinic', 'consultancy', 'platform')),
cancellation_reason TEXT
);
-- Slots de disponibilidade (F1.5 simples; F2+ com Google Calendar)
CREATE TABLE public.consultancy_availability_slots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
consultancy_id UUID NOT NULL REFERENCES public.consultancies(id),
start_at TIMESTAMPTZ NOT NULL,
duration_minutes INT DEFAULT 60,
status TEXT NOT NULL DEFAULT 'available'
CHECK (status IN ('available', 'reserved', 'completed', 'cancelled')),
reserved_by_appointment_id UUID REFERENCES public.session_appointments(id)
);

6.2 Regras

  • 0% comissão da plataforma — coerência com modelo “só cobramos plano”. 100% pro consultor.
  • Pacote NÃO muda current_consultancy_id da clínica (transação efêmera, sem vínculo formal)
  • Só pra clínica com plano ativo (regra 5.7.4)
  • Consent escopado por pacote: ao comprar, clínica autoriza acesso aos dados pelo período do pacote + 30 dias após última sessão. Expira automaticamente. Helper consultancy_has_data_access_to trata.
  • SLA do consultor: 7 dias pra publicar slots ou agendar 1ª sessão. Refund integral até 1ª sessão. 3 ocorrências em 90 dias = revisão de credenciamento.

6.3 Edge functions (F1.5)

  • purchase-session-package — clínica compra; integra Asaas do consultor
  • schedule-session-appointment — clínica agenda dentro do pacote
  • complete-session-appointment — consultor marca concluída + adiciona notas
  • expire-session-packages-cron — job diário detecta pacotes expirados; libera consent
  • consultancy-sla-monitor-cron — monitora SLA de 7 dias; alerta clínica + escala consultor

6.4 UI (F1.5)

  • /consultancy/configuracoes/pacotes — consultor cria/edita
  • /consultancy/agenda — sessões agendadas + slots
  • /consultores/<slug> (revisado) — mostra pacotes oferecidos
  • /clinic/comprar-consultoria — clínica órfã navega + compra
  • /clinic/agenda — clínica vê sessões compradas

7. Promoção opcional (Ideia 1.H)

Cada consultor pode publicar promoção no perfil público:

ALTER TABLE public.consultancies
ADD COLUMN promotional_offer_text TEXT,
ADD COLUMN promotional_offer_active BOOLEAN DEFAULT FALSE,
ADD COLUMN promotional_offer_updated_at TIMESTAMPTZ;

Exemplos:

  • “Primeira sessão de consultoria gratuita”
  • “Mentoria mensal grátis nos primeiros 90 dias”
  • “Análise de fluxo de caixa sem custo”

Plataforma não monitora cumprimento (compromisso bilateral consultor↔clínica). Mas vira diferencial comercial.

Consequências

Positivas

  • Marketplace orgânico atrai clínicas órfãs via SEO
  • Curadoria por convite mantém qualidade
  • No-spam B2B protege experiência de consultor (não é assediado) e clínica (não tem consultor caça-níqueis)
  • Pacotes Avulsos criam degrau de baixa fricção — clínica experimenta antes de fechar contrato
  • Promoção opcional dá flexibilidade comercial pro consultor

Negativas

  • Curadoria escala lentamente — Alexandre precisa convidar consultor a consultor
  • Marketplace começa vazio — 1 consultor (Karla) na F1 não enche

Riscos

  • Marketplace fraco em F1 afeta atração de clínicas órfãs
    • Mitigação: foco em F1 é canal direto (lead via consultor existente). Marketplace vira diferencial em F1.5+ quando 5+ consultores credenciados
  • Pacote sem cumprimento vira disputa
    • Mitigação: SLA de 7 dias + auditoria via tickets; refund automático se SLA falha

Alternativas consideradas

1. Auto-cadastro de consultor

  • Prós: escala mais rápido
  • Contras: qualidade impossível de garantir; vai gerar reputação ruim. Rejeitado.

2. Marketplace mostra clínicas órfãs pra consultor escolher

  • Prós: aceleração de match
  • Contras: viola “no-spam B2B”; gera assédio. Rejeitado.
  • Prós: simplicidade
  • Contras: viola LGPD (consultor que só fez 1 sessão tem acesso pra sempre)
  • Rejeitado — consent escopado é regra inviolável.

4. Cobrar comissão sobre pacote avulso

  • Prós: receita extra
  • Contras: contradiz princípio “só cobramos plano”; complexidade fiscal. Rejeitado.

Atualizações de documentos

  • AGENTS.md §5.15 (Marketplace), §5.7.4 (pacote sem comissão)
  • BLUEPRINT.md §6 (princípios)
  • docs/consultancy/perfil-publico.md
  • docs/consultancy/configuracoes-pacotes.md

Referências

  • ADR 0001 (multi-consultancy)
  • ADR 0008 (modelo financeiro)
  • ADR 0009 (consent escopado por pacote)
  • ADR 0011 (cancelamento bilateral)