Ir para o conteúdo

Schema & Constraints

Todos os dados da Brandvelia vivem no schema brandvelia do projeto Supabase compartilhado panoptes. O app não toca nada fora desse schema. Nomes de tabela usam o prefixo bv_ e o domínio é codificado no ID nominal TypeScript (BV_Campaign, etc.).


Modelo de acesso

O acesso é controlado em três camadas (veja INFRA.md para as regras operacionais):

  1. RLS — toda tabela brandvelia tem Row-Level Security ligada; o isolamento é por workspace_id via workspace_members. As tabelas do motor de decisão usam ainda forced RLS.
  2. Views auto-atualizáveis public.bv_* — a API REST lê views com security_invoker = true, então o RLS das tabelas base se aplica transparentemente (views "congelam" a lista de colunas).
  3. Wrappers SQL — funções públicas como bv_create_workspace, bv_get_dashboard_summary, bv_create_product_score e, no motor de decisão, pontes estreitas service/admin (bv_materialize_capital_snapshot, bv_evaluate_recommendation, etc.).

Papéis

Papel Escopo
anon Apenas landing pages published (policy específica).
authenticated Dados dos workspaces em que o usuário é membro (leitura no motor de decisão).
service_role Endpoints públicos server-side (/api/track, /api/leads) + ingestão e syncs.

Inventário de tabelas

Tabela bv_* Domínio Estado
bv_workspaces Workspaces (raiz da multi-tenancy). ✅ DDL
bv_workspace_members Membership; alimenta o isolamento RLS por workspace_id. ✅ DDL
bv_offers Catálogo de produtos (redes + produtos próprios). ✅ DDL
bv_marketplace_snapshots Snapshots de oportunidade do Radar. ✅ DDL
bv_marketplace_sync_runs Runs de sincronização do Radar. ✅ DDL
bv_ai_models Registro de modelos de IA. ✅ DDL
bv_visits Visitas atribuídas (click_id → landing page). ✅ DDL
bv_transactions Ledger (pedidos, reembolsos, chargebacks, taxas). ✅ DDL
bv_campaigns Campanhas de tráfego. ✅ DDL
bv_creatives Criativos gerados por IA. ✅ DDL
bv_landing_pages Landings próprias do operador. ✅ DDL
bv_leads / bv_lead_events Captura CRM + pipeline. ✅ DDL
bv_experiments Testes A/B + quebra de métricas. ✅ DDL
bv_ai_runs, bv_ai_usage Logs de chamadas de IA + uso agregado. ✅ DDL
bv_workspaces_api_credentials Credenciais de API geradas (Vision Board). 📋 planejado, sem DDL
bv_marketplaces Feed inbound de produtos de marketplace. 📋 planejado, sem DDL
bv_finance Ledger consolidado / P&L (ver get_finance_report). 📋 view lógica, sem tabela própria
bv_vision_board Ideias de produto + planilhas de oferta. 📋 planejado, sem DDL
bv_integrations Apps conectados, webhooks, triggers, refresh. 📋 planejado, sem DDL
bv_settings Settings do workspace + operador. 📋 planejado, sem DDL

Motor de decisão (novo)

Tabela Domínio
evidence_envelopes Evidência imutável com hash SQL e supersession.
capital_calculation_snapshots Snapshots imutáveis S0/Cp/L/Ca (capital/v1).
scenario_sets / scenario_variants / scenario_variant_inputs Cenários LOW/BASE/HIGH com lifecycle e maker-checker.
recommendation_snapshots Recomendações TEST/HOLD/BLOCK determinísticas (recommendation/v1).
human_decisions Decisões ACCEPT/REJECT/DEFER imutáveis.
campaign_phase_history Histórico append-only de fases de campanha.
decision_alerts Alertas determinísticos replay-safe.
opportunity_score_snapshots Score v2 em shadow, somente cohorts maduras.

Consulte o Data Contract para colunas, enums e invariantes completos.


Constraints-chave

  • Idempotência (replay-safe). Eventos ClickBank usam dedup_key único; raw v2 é imutável e conflitos são auditados sem sobrescrever evidência.
  • Normalização de valores. Valores normalizados para USD; dinheiro cruza fronteiras como decimal exato (numeric(20,6) / strings decimais).
  • Integridade. Fallbacks garantem currency sensato (padrão USD), rank ordenável e status obrigatórios.
  • Append-only. Evidência, snapshots de capital, recomendações, decisões humanas, histórico de fases, alertas e scores têm triggers que rejeitam UPDATE/DELETE.

Migrations pendentes de aplicação (Fases 1–5, 2026-08-24)

Atenção: as migrations abaixo estão no repositório mas ainda não foram aplicadas ao Supabase remoto (supabase db push é manual e o banco panoptes é compartilhado). Todas são additive-only no schema brandvelia + views public.bv_* correspondentes.

Migration Conteúdo
20260824000000_brandvelia_capture_provenance.sql Proveniência da captura em marketplace_snapshots (vendor_domain, source_url, capture_status, capture_meta) + status partial em marketplace_sync_runs; refresh das views.
20260824010000_brandvelia_offer_enrichment.sql Oferta enriquecida: jv_page_url, affiliate_terms_url, official_domain, sales_page_url, tracking_link_template, avatar, core_mechanism, main_promise, angles, compliance_restrictions, trilha enrichment_*; refresh de bv_offers.
20260824020000_brandvelia_competitor_diagnostic.sql Evolução de offer_ai_analyses: analysis_type, input_hash (índice único parcial para dedup), status, sources_count; refresh de bv_offer_ai_analyses.
20260824030000_brandvelia_google_campaign_creative_rpc.sql RPC transacional public.bv_create_campaign_with_creative (campanha draft + pack versionado + criativo vinculado em uma transação, workspace-scoped, idempotência opcional via campaign_creation_idempotency).

Contratos novos suportados por essas colunas

  • Captura: envelope com hash canônico recalculado no servidor; capturas parciais ficam marcadas (capture_status='partial') e exigem confirmação na UI.
  • Enriquecimento IA: enrichment_status segue none → pending → completed | failed; falha nunca desfaz a oferta.
  • Diagnóstico competitivo: dedup por (workspace_id, analysis_type, input_hash) — reanálise do mesmo material atualiza em vez de duplicar.
  • Criação integrada Google: a RPC valida membership (brandvelia.is_member), fixa search_path = '', usa advisory lock, revoga acesso de public/anon e só concede execute a authenticated.