UNO Data Lake
Documentação das Tabelas
Este repositório contém os modelos de dados utilizados no Uno Data Lake, um sistema para gestão e armazenamento de dados de franquias e seus negócios relacionados. Esta documentação explica a estrutura de cada tabela e seus campos.
Bem-vindo(a) à documentação do UNO Data Lake. Este ambiente concentra os dados operacionais de cada franqueadora e suas unidades (franquias/empresas) em um banco PostgreSQL, permitindo a construção de dashboards, relatórios e análises de BI sobre uma base unificada.
Esta documentação descreve o que cada tabela representa, quais colunas existem, como elas se relacionam e como consultá-las corretamente. Foi escrita para um público misto: analistas de BI (com SQL básico) e engenheiros de dados.
Índice
- UNO Data Lake
- Índice
- Visão geral
- Como acessar o Data Lake
- Convenções importantes
- Multi-tenant: a coluna
schemae ofranchisor_id - Sempre filtre por
schema. - Regra de ouro dos JOINs
- Chaves: não existe
idtécnico - Índices e desempenho no Postgres
- Datas, fuso horário e tipos
- Dinheiro e números
- Textos truncados
- Nomes mascarados
- Atualização e frescor dos dados
- Exclusões e regras de inclusão
- Multi-tenant: a coluna
- Mapa de relacionamentos
- Catálogo de tabelas
- Tabelas — Estrutura organizacional
- Tabelas — CRM e funil comercial
- Tabelas — Vendas (orders e itens)
- Tabelas — Financeiro
- Tabelas — Catálogo (produtos, serviços, planos, cursos)
- Tabelas — Operação clínica/atendimento
- Tabelas — Metas e desempenho
- Tabelas — Royalties e taxas da franqueadora
- Tabelas — Marketing (Facebook Ads)
- Tabelas — Sistema
- Enums e dicionários de valores
- Exemplos de queries para BI
- 1. Faturamento mensal (vendas faturadas)
- 2. Recebíveis pendentes (a vencer e vencidos)
- 3. Ranking de vendedores no mês
- 4. Conversão do funil de CRM
- 5. Vendas com seus pagamentos (uso correto do JOIN)
- 6. Ocupação de agenda por profissional
- 7. Custo por lead (Facebook Ads × Deals)
- 8. Consolidado da rede (todas as unidades da franqueadora)
- 9. Frescor dos dados por unidade
- Boas práticas de desempenho no Postgres
Visão geral
O Data Lake recebe réplicas dos dados transacionais das aplicações operacionais (Vendas, CRM, Atendimento, Financeiro, Marketing) e os organiza em tabelas analíticas amplas, denormalizadas (com nomes já materializados em colunas *_name) para facilitar a leitura por ferramentas de BI.
Características principais:
- Banco: PostgreSQL (Amazon RDS), com SSL obrigatório.
- Um schema por franqueadora: os dados de cada rede ficam em um schema próprio, chamado
frq<ID>(ex.:frq4163). O seu login enxerga apenas o schema da sua franqueadora; não há como consultar outra rede. - Modelo: estrela "achatada" — cada tabela já contém o nome (denormalizado) das principais entidades relacionadas, evitando a maior parte dos JOINs em consultas típicas.
- Multi-tenant dentro do schema: todas as tabelas operacionais possuem a coluna
schema, que identifica a unidade (franquia/empresa) dona do registro. Toda consulta deve filtrar porschema. - Carga direta: as tabelas são projetadas diretamente da base de origem, sem camada intermediária. As tabelas de vendas são atualizadas a cada 30 minutos; as demais, diariamente (ver Atualização e frescor).
- Histórico: as tabelas refletem o estado atual da operação. Para análises temporais, use as colunas de data (
created_at,updated_at,due_date,liquidation_date, etc.).
Como acessar o Data Lake
O acesso é feito com um login individual (por pessoa ou por ferramenta de BI), criado pelo operador do Data Lake no painel de operação, na aba Acesso BI da franqueadora.
| Item | Detalhe |
|---|---|
| Login | bi_frq<ID>_<login> (ex.: bi_frq4163_powerbi). A senha é exibida uma única vez, na criação. Se for perdida, o operador rotaciona a senha pelo painel. |
| Permissões | Somente leitura (SELECT) nas tabelas do schema da franqueadora. Nenhum acesso a outros schemas nem às tabelas internas do pipeline. |
| Schema padrão | O search_path do login já aponta para frq<ID>: as tabelas aparecem sem prefixo (orders, e não frq4163.orders). |
| SSL | Obrigatório (sslmode=require). Sem SSL o servidor recusa a conexão. |
| Liberação de IP | O IP de saída da sua rede/ferramenta precisa estar liberado pelo operador (tela Acesso ao banco do painel). |
| Limites | Até 10 conexões simultâneas por login (configure pool na ferramenta de BI) e 15 minutos por consulta (statement_timeout; uma sessão pode subir o próprio limite com SET statement_timeout). |
Exemplo de string de conexão (host, porta e nome do banco são informados pelo operador ao criar o login):
postgres://bi_frq<ID>_<login>:<senha>@<host>:5432/<database>?sslmode=require
Se uma ferramenta exigir o schema explicitamente, informe frq<ID>.
Convenções importantes
Multi-tenant: a coluna schema e o franchisor_id
schema e o franchisor_idQuase todas as tabelas possuem duas colunas de contexto:
| Coluna | Descrição |
|---|---|
schema | Identificador (texto) da unidade (franquia/empresa) dona do registro. Funciona como o "tenant" dentro do schema da franqueadora e é a primeira coluna de todo índice. |
franchisor_id | Identificador da franqueadora (rede/marca). Como cada franqueadora tem seu próprio schema Postgres, esse valor é o mesmo em todas as linhas que você enxerga; ele existe por compatibilidade e não precisa entrar em filtros. As tabelas de royalties e taxas (franchise_*) não o possuem. |
Por que isso importa? Os IDs de negócio (como order_id, customer_id, appointment_id) são gerados por unidade — ou seja, não são únicos dentro do schema da franqueadora. Duas unidades diferentes podem ter um order_id = 1234 apontando para vendas completamente distintas.
Regra de ouro dos JOINs
Toda relação entre tabelas deve ser feita pela combinação
schema+<id_de_negócio>— nunca apenas pelo ID.
Exemplos corretos:
-- ✅ CORRETO: JOIN por schema + order_id
SELECT *
FROM orders o
JOIN payments p
ON p.schema = o.schema
AND p.order_id = o.order_id
WHERE o.schema = 'minha_unidade';
-- ❌ INCORRETO: JOIN apenas por order_id
SELECT *
FROM orders o
JOIN payments p ON p.order_id = o.order_id; -- vai cruzar dados de unidades diferentes!Para análises da rede inteira (todas as unidades da franqueadora), basta não filtrar schema no WHERE — mas mantenha o schema em todos os JOINs:
SELECT o.schema, SUM(p.value) AS recebido
FROM orders o
JOIN payments p
ON p.schema = o.schema
AND p.order_id = o.order_id
GROUP BY o.schema;Chaves: não existe id técnico
id técnicoA chave primária de cada tabela é composta: (schema, <entidade>_id) — por exemplo (schema, order_id) em orders. Não há coluna id técnica.
Use sempre as colunas com sufixo _id (order_id, customer_id, appointment_id, …) — são essas que vêm dos sistemas operacionais e que devem ser usadas em filtros e JOINs (sempre combinadas com schema).
Única exceção:
franchise_category_typestem uma colunaid(bigint) gerada pelo Data Lake, porque a origem não tem identificador próprio para essa junção.
Índices e desempenho no Postgres
Toda tabela tem a chave primária (schema, <id>) e, quando a consulta típica pede, índices adicionais que também começam por schema:
| Tabela | Índices além da chave primária |
|---|---|
orders | (schema, created_at), (schema, customer_id), (schema, status) |
order_products, order_services, order_plans, order_courses | (schema, order_id) |
payments | (schema, order_id), (schema, created_at), (schema, liquidation_date) |
budgets | (schema, created_at) |
customers | (schema, created_at) |
appointments | (schema, start_date), (schema, customer_id) |
order_lessons | (schema, customer_id) |
deals | (schema, created_at) |
accounts_payable | (schema, due_date) |
measures | (schema, customer_id) |
facebook_campaign_data | (schema, date) |
Implicação prática: uma consulta que não filtra por schema não consegue usar nenhum desses índices e varre a tabela inteira. Com o filtro, um recorte por período (created_at, due_date, start_date, date) ou por cliente usa o índice e responde rápido.
Datas, fuso horário e tipos
- Todas as colunas de data/hora usam
timestamptz(UTC). Converta para o fuso local da empresa (a colunacompanies.timezoneindica o fuso, ex.:America/Sao_Paulo) quando for exibir para o usuário final:created_at AT TIME ZONE 'America/Sao_Paulo'. facebook_campaign_data.dateé do tipodate(dia da métrica, sem hora).- Textos são
text(sem limite de tamanho declarado); inteiros sãointeger; flags sãoboolean. - A moeda padrão de cada empresa está em
companies.currency.
Dinheiro e números
- Valores monetários são
numeric(14,2)— exatos, sem erro de arredondamento de ponto flutuante.SUM/AVGsobre eles devolvemnumeric. - Percentuais e taxas ficam em
numeric(14,4):facebook_campaign_data.frequency,franchise_royalties.percentage,franchise_advertising_fees.percentage. - Número de parcela é
numeric(6,1)empayments.installmenteaccounts_payable.installment. - Guarda de faixa: se um valor na origem for impossível (não cabe em 14 dígitos, infinito ou inválido), a coluna chega como
NULL— nunca como um número inventado. Nas colunas de total deorders,budgetse dos itens de venda, que sãoNOT NULL DEFAULT 0, esse caso vira0. - A mesma guarda vale para colunas inteiras vindas de campos numéricos da origem (ex.:
room_time_slots.start_time,goals.indication): fora da faixa,NULL.
Textos truncados
Alguns nomes e observações são cortados na carga para manter compatibilidade com dashboards existentes:
| Coluna(s) | Tamanho máximo |
|---|---|
orders.customer_name, deals.name | 149 |
budgets.customer_name, budgets.employee_name, budgets.observation, budgets.observation_discarded | 220 |
services.name, appointments.service_name | 199 |
accounts_payable.description, accounts_payable.supplier_name, facebook_campaign_data.ad_name | 200 |
accounts_payable.chart_account_name, accounts_payable.cost_center_name | 254 |
Nomes mascarados
O banco é compartilhado entre franqueadoras, então nomes de empresas e franquias nunca chegam ao Data Lake:
companies.nameecompanies.legal_nametrazem o alias cadastrado no painel para a unidade (padrãofrq<ID>-u<company_id>). Uma unidade sem alias cadastrado não aparece emcompanies.franchises.nametraz o alias da franquia ou, na ausência dele,franquia-<franchise_id>.- As demais tabelas (
customers,employees,deals, …) não são mascaradas.
Se precisar exibir o nome comercial da unidade num dashboard, mantenha um de-para schema → nome na própria ferramenta de BI.
Atualização e frescor dos dados
As tabelas são carregadas em cadências (grupos), configuradas por franqueadora no painel de operação. Valores padrão:
| Cadência | Tabelas | Intervalo padrão |
|---|---|---|
| Vendas | orders, order_products, order_services, order_plans, order_courses, payments, budgets | 30 min |
| Diário | companies, customers, employees, catálogo, agenda, CRM, metas, financeiro, Facebook Ads | 24 h |
| Royalties e taxas | franchises, franchise_categories, franchise_category_types, franchise_royalties, franchise_royalty_periods, franchise_advertising_fees, franchise_advertising_fee_periods — dados da unidade franqueadora | 24 h |
| Verificação de exclusões | todas as tabelas — remove linhas que deixaram de existir na origem | 24 h |
A carga é incremental: só as linhas cujas tabelas de origem mudaram são recalculadas. A coluna updated_at de cada linha é o maior updated_at entre as tabelas de origem que a compõem — por exemplo, orders.updated_at avança quando um pagamento da venda é liquidado, mesmo sem alteração no pedido.
Para saber até quando os dados de uma unidade estão atualizados, consulte a view metadata: ela informa, por unidade e tabela, o dado mais novo já carregado. Atenção: isso não é atraso do pipeline — uma unidade sem venda nova terá last_updated antigo em orders e estará em dia.
Exclusões e regras de inclusão
- Uma linha apagada na origem (ou que deixou de atender à regra de inclusão da tabela) é removida do Data Lake pela verificação de exclusões (diária) ou por uma carga completa. Entre uma coisa e outra, ela pode aparecer por até 24 h.
- Regras de inclusão aplicadas na carga:
| Tabela | Só entram linhas que… |
|---|---|
orders, budgets | têm total_price > 0 |
appointments | não foram excluídas, têm cliente e não estão com status_id = 7 (Bloqueio) |
payments, accounts_payable | não foram excluídas na origem |
companies | são unidades operacionais (a empresa-franqueadora não entra) e têm alias cadastrado no painel |
franchise_* | pertencem à unidade franqueadora (o schema dessas tabelas é o da própria franqueadora) |
Mapa de relacionamentos
franchises (1) ──< companies (N)
│
└──< franchise_royalties ──< franchise_royalty_periods
└──< franchise_advertising_fees ──< franchise_advertising_fee_periods
└──< franchise_category_types >── franchise_categories
customers ──┐
├──< deals
├──< budgets ──> orders
├──< orders ──< order_services ──> services
│ ──< order_products ──> products
│ ──< order_plans ──> plans
│ ──< order_courses ──> courses ──< classes
│ ──< order_lessons
│ ──< payments
├──< appointments ──> rooms ──< room_time_slots
├──< measures
└──< slimming_goals
employees ──< employee_goals >── goals
accounts_payable (financeiro – contas a pagar)
facebook_accounts ──< facebook_campaign_data
Todos os JOINs implícitos acima usam
schema + <id>.
Catálogo de tabelas
| Tabela | Domínio | Cadência | Descrição rápida |
|---|---|---|---|
franchises | Organização | Royalties e taxas | Franquias (unidades) cadastradas. |
companies | Organização | Diário | Dados cadastrais e de endereço das empresas. |
employees | Organização | Diário | Funcionários (vendedores, atendentes, etc.). |
customers | Organização | Diário | Clientes finais (PF/PJ). |
deals | CRM | Diário | Negociações/oportunidades do funil comercial. |
budgets | CRM | Vendas | Orçamentos gerados para clientes. |
orders | Vendas | Vendas | Vendas (pedidos) consolidadas. |
order_services | Vendas | Vendas | Itens de serviço dentro de uma venda. |
order_products | Vendas | Vendas | Itens de produto dentro de uma venda. |
order_plans | Vendas | Vendas | Planos contratados em uma venda. |
order_courses | Vendas | Vendas | Cursos contratados em uma venda. |
order_lessons | Vendas | Diário | Aulas individuais relacionadas a order_courses. |
payments | Financeiro | Vendas | Recebíveis (parcelas) gerados por vendas. |
accounts_payable | Financeiro | Diário | Contas a pagar da empresa. |
services | Catálogo | Diário | Serviços oferecidos. |
products | Catálogo | Diário | Produtos oferecidos. |
plans | Catálogo | Diário | Planos comercializados. |
courses | Catálogo | Diário | Cursos oferecidos. |
classes | Catálogo | Diário | Turmas de cursos. |
appointments | Atendimento | Diário | Agendamentos de serviços. |
rooms | Atendimento | Diário | Salas de atendimento. |
room_time_slots | Atendimento | Diário | Janelas de funcionamento das salas. |
measures | Atendimento | Diário | Medidas corporais coletadas (ramo estética/saúde). |
slimming_goals | Atendimento | Diário | Metas de emagrecimento por cliente. |
goals | Metas | Diário | Metas globais da empresa por período. |
employee_goals | Metas | Diário | Metas individualizadas por funcionário. |
franchise_royalties | Franqueadora | Royalties e taxas | Regras de cobrança de royalties por franquia. |
franchise_royalty_periods | Franqueadora | Royalties e taxas | Valores apurados de royalties por período. |
franchise_advertising_fees | Franqueadora | Royalties e taxas | Regras de taxa de publicidade. |
franchise_advertising_fee_periods | Franqueadora | Royalties e taxas | Valores apurados de publicidade por período. |
franchise_categories | Franqueadora | Royalties e taxas | Categorias de classificação de franquias. |
franchise_category_types | Franqueadora | Royalties e taxas | Vínculo entre franquia e categoria. |
facebook_accounts | Marketing | Diário | Contas de anúncio do Facebook integradas. |
facebook_campaign_data | Marketing | Diário | Métricas diárias por campanha/anúncio. |
metadata | Sistema | — | View: dado mais novo carregado por tabela/unidade. |
Tabelas — Estrutura organizacional
franchises
franchisesFranquias (unidades operacionais) cadastradas. Carregada a partir da unidade franqueadora; o schema aqui é o da própria franqueadora. Não possui franchisor_id.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema | text | não | Unidade franqueadora. |
franchise_id | integer | não | ID da franquia (chave de negócio). |
name | text | sim | Mascarado: alias da franquia ou franquia-<franchise_id>. |
status | text | sim | Ver Status de franquia. |
created_at | timestamptz | sim | Criação. |
updated_at | timestamptz | sim | Última atualização. |
Chave primária: (schema, franchise_id).
companies
companiesEmpresas (CNPJs) operadas pelas unidades. Existe uma company por schema; a empresa-franqueadora não entra. Os nomes são mascarados.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema | text | não | Unidade. |
franchisor_id | integer | sim | Franqueadora. |
company_id | integer | não | ID da empresa. |
name | text | sim | Mascarado: alias da unidade (ex.: frq4163-u123). |
legal_name | text | sim | Mascarado: mesmo alias. |
status | text | sim | Ver Status de empresa. |
street, neighborhood, number, zip_code | text | sim | Endereço (primeiro endereço cadastrado). |
city_name, city_identifier | text | sim | Cidade e código IBGE. |
state_name, state_initials | text | sim | Estado. |
country_name | text | sim | País. |
timezone | text | sim | Fuso horário (ex.: America/Sao_Paulo). |
locale | text | sim | Locale (ex.: pt-BR). |
currency | text | sim | Moeda (ex.: BRL). |
cnpj | text | sim | CNPJ (documento mais recente). |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, company_id).
employees
employeesFuncionários das empresas (vendedores, atendentes, profissionais, etc.).
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
employee_id | integer | não | ID do funcionário. |
name | text | sim | Nome. |
active | boolean | sim | Está ativo? |
employee_type_id | integer | sim | ID do tipo (cargo/função). |
employee_type_name | text | sim | Nome do tipo. |
employee_type_franchise_identifier | integer | sim | ID do tipo no escopo da franquia. |
employee_type_franchisor | boolean | sim | Se o tipo é definido pela franqueadora. |
expected_merit_level | text | sim | Nível de mérito esperado. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, employee_id).
customers
customersClientes finais (PF e PJ).
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
customer_id | integer | não | ID do cliente. |
type | text | sim | Tipo: pessoa física, jurídica, etc. |
name | text | sim | Nome (PF) ou nome fantasia (PJ). |
legal_name | text | sim | Razão social (PJ). |
cpf / cnpj | text | sim | Documento (mais recente de cada tipo). |
cellphone, email, phone | text | sim | Contatos. |
gender | text | sim | Gênero. |
occupation_id, occupation_name | integer / text | sim | Ocupação/profissão. |
birthday | timestamptz | sim | Data de nascimento. |
street, neighborhood, number, zip_code | text | sim | Endereço. |
city_id, city_name, state_id, state_name, country_id, country_name | integer / text | sim | Localização. |
franchise_id | integer | sim | Franquia de origem. |
active | boolean | não | Ativo? (default true). |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, customer_id). Índice: (schema, created_at).
Tabelas — CRM e funil comercial
deals
dealsNegociações/oportunidades do funil comercial. Um deal pode (ou não) ser convertido em uma order. Quando o deal tem mais de um agendamento, a linha reflete o mais recente (customer_appointment_*).
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
deal_id | integer | não | ID do deal. |
name | text | sim | Nome do contato/lead. |
converted_at | timestamptz | sim | Quando foi convertido em venda. |
discarded_at | timestamptz | sim | Quando foi descartado. |
rating | integer | sim | Pontuação/qualificação. |
order_id | integer | sim | Venda gerada (JOIN com orders por schema + order_id). |
deal_origin_id, deal_origin_name | integer / text | sim | Origem do lead. |
deal_stage_id, deal_stage_name | integer / text | sim | Estágio atual no funil. |
deal_campaign_id, deal_campaign_name, deal_campaign_slug | integer / text / text | sim | Campanha de CRM associada. |
ad_campaign_name, ad_set_name, ad_name | text | sim | Hierarquia do anúncio que originou o lead. |
facebook_source_id, facebook_wacl_id | text | sim | Rastreio de origem do Facebook Ads. |
employee_id, employee_name | integer / text | sim | Responsável. |
customer_id | integer | sim | Cliente (da venda vinculada). |
seller_id, seller_name | integer / text | sim | Vendedor (da venda vinculada). |
aux_id, aux_name | integer / text | sim | Auxiliar (da venda vinculada). |
total_price | numeric(14,2) | sim | Valor da venda vinculada. |
customer_appointment_date | timestamptz | sim | Data do agendamento mais recente. |
customer_appointment_status_id | integer | sim | Status desse agendamento. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, deal_id). Índice: (schema, created_at).
Para taxa de conversão:
dealscomconverted_at IS NOT NULLou comorder_idpreenchido.
budgets
budgetsOrçamentos elaborados para clientes. Só entram orçamentos com total_price > 0.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
budget_id | integer | não | ID do orçamento. |
status | text | sim | Ver Status de orçamento. |
customer_id, customer_name | integer / text | sim | Cliente. |
employee_id, employee_name | integer / text | sim | Funcionário responsável. |
service_total_price, product_total_price, plan_total_price, course_total_price | numeric(14,2) | não | Subtotais por categoria (default 0). |
total_price | numeric(14,2) | não | Valor total. |
total_discount | numeric(14,2) | não | Desconto aplicado. |
installment | integer | sim | Nº de parcelas previsto. |
expiration_at | timestamptz | sim | Validade do orçamento. |
discarded_at | timestamptz | sim | Descartado em. |
converted_at | timestamptz | sim | Convertido em venda em. |
observation | text | sim | Observação livre. |
observation_discarded | text | sim | Motivo do descarte (texto). |
transformation | boolean | sim | Indica orçamento de transformação (renegociação). |
order_service_id | integer | sim | Item de venda originado (quando aplicável). |
order_id | integer | sim | Venda originada deste orçamento. |
budget_discard_reason_id | integer | sim | ID do motivo de descarte. |
created_at / updated_at | timestamptz | não | Auditoria. |
Chave primária: (schema, budget_id). Índice: (schema, created_at).
Tabelas — Vendas (orders e itens)
orders
ordersCabeçalho da venda. Os itens estão nas tabelas order_services, order_products, order_plans, order_courses. Só entram vendas com total_price > 0.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
order_id | integer | não | ID da venda. |
status | text | não | Ver Status de venda. |
customer_id, customer_name | integer / text | não / sim | Cliente. |
seller_id, seller_name | integer / text | não / sim | Vendedor. |
aux_id, aux_name | integer / text | sim | Vendedor auxiliar. |
service_total_price, product_total_price, plan_total_price, course_total_price | numeric(14,2) | não | Subtotais por categoria (default 0). |
total_price | numeric(14,2) | não | Valor total da venda. |
total_discount | numeric(14,2) | não | Desconto total. |
total_paid | numeric(14,2) | não | Total já pago (conforme a origem). |
total_liquidated | numeric(14,2) | não | Soma das parcelas liquidadas (payment_status_id = 4) da venda. |
is_accounting | boolean | não | Se entra em contabilidade/relatórios financeiros (default true). |
order_cancellation_reason_id, order_cancellation_name | integer / text | sim | Motivo do cancelamento. |
order_abandonment_name | text | sim | Motivo de abandono. |
created_at | timestamptz | não | Criação. |
updated_at | timestamptz | não | Última alteração da venda ou de um pagamento dela. |
canceled_at | timestamptz | sim | Data de cancelamento. |
Chave primária: (schema, order_id). Índices: (schema, created_at), (schema, customer_id), (schema, status).
order_services
order_servicesItens de serviço de uma venda.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
order_service_id | integer | não | ID do item. |
service_id | integer | sim | Serviço do catálogo (JOIN schema + service_id). |
order_id | integer | não | Venda (JOIN schema + order_id). |
order_plan_id | integer | sim | Se o serviço veio incluído num plano. |
quantity | integer | não | Quantidade (default 1). |
price | numeric(14,2) | não | Preço unitário. |
discount | numeric(14,2) | não | Desconto. |
additional_value | numeric(14,2) | não | Acréscimo. |
created_at / updated_at | timestamptz | não | Auditoria. |
Chave primária: (schema, order_service_id). Índice: (schema, order_id).
order_products
order_productsItens de produto de uma venda.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
order_product_id | integer | não | ID do item. |
product_id | integer | sim | Produto (JOIN schema + product_id). |
order_id | integer | não | Venda. |
order_plan_id | integer | sim | Se incluso em plano. |
quantity | integer | não | Quantidade (default 1). |
price, discount, additional_value | numeric(14,2) | não | Valores (default 0). |
created_at / updated_at | timestamptz | não | Auditoria. |
Chave primária: (schema, order_product_id). Índice: (schema, order_id).
order_plans
order_plansPlanos contratados em uma venda.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
order_plan_id | integer | não | ID do item. |
plan_id | integer | sim | Plano (JOIN schema + plan_id). |
order_id | integer | não | Venda. |
price, discount, additional_value | numeric(14,2) | não | Valores (default 0). |
created_at / updated_at | timestamptz | não | Auditoria. |
Chave primária: (schema, order_plan_id). Índice: (schema, order_id).
order_courses
order_coursesCursos contratados em uma venda.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
order_course_id | integer | não | ID do item. |
course_id | integer | sim | Curso (JOIN schema + course_id). |
order_id | integer | não | Venda. |
status | text | sim | Status do curso contratado. |
price, discount, additional_value | numeric(14,2) | não | Valores (default 0). |
created_at / updated_at | timestamptz | não | Auditoria. |
Chave primária: (schema, order_course_id). Índice: (schema, order_id).
order_lessons
order_lessonsAulas individuais associadas a order_courses (controle de presença).
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
order_lesson_id | integer | não | ID da aula contratada. |
attendance | boolean | sim | Presença. |
start_date, end_date | timestamptz | sim | Janela da aula. |
order_course_id | integer | sim | Vínculo com o curso comprado. |
class_id, class_name | integer / text | sim | Turma. |
lesson_id, lesson_name | integer / text | sim | Aula. |
course_id, course_name | integer / text | sim | Curso. |
customer_id, customer_name | integer / text | sim | Aluno. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, order_lesson_id). Índice: (schema, customer_id).
Tabelas — Financeiro
payments
paymentsRecebíveis (parcelas a receber) gerados pelas vendas. Parcelas excluídas na origem não entram.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
payment_id | integer | não | ID do recebível. |
value | numeric(14,2) | não | Valor da parcela. |
original_due_date | timestamptz | sim | Vencimento original. |
due_date | timestamptz | sim | Vencimento atual. |
liquidation_date | timestamptz | sim | Data de liquidação (compensação). |
billed_date | timestamptz | sim | Data de faturamento. |
interest_value | numeric(14,2) | sim | Juros. |
fee_value | numeric(14,2) | sim | Tarifa. |
discount_value | numeric(14,2) | sim | Desconto concedido. |
installment | numeric(6,1) | sim | Número da parcela. |
store | boolean | não | Recebido no balcão (loja)? (default false). |
customer_id, customer_name | integer / text | sim | Cliente. |
order_id | integer | sim | Venda originadora (JOIN schema + order_id). |
employee_id, employee_name | integer / text | sim | Funcionário responsável (vendedor/financeiro). |
payment_status_id, payment_status_name | integer / text | sim | Status. Ver Status de pagamento. |
payment_type_id, payment_type_name | integer / text | sim | Forma/tipo de pagamento. |
payment_brand_id, payment_brand_name | integer / text | sim | Bandeira (cartão, boleto, etc.). |
chart_account_id, chart_account_name | integer / text | sim | Plano de contas. |
created_at / updated_at | timestamptz | não | Auditoria. |
credit_card_brand | text | sim | Bandeira do cartão (integrações). |
last_credit_card_number | text | sim | Últimos 4 dígitos. |
Chave primária: (schema, payment_id). Índices: (schema, order_id), (schema, created_at), (schema, liquidation_date).
accounts_payable
accounts_payableContas a pagar da empresa (despesas, fornecedores, etc.). Contas excluídas na origem não entram.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
account_payable_id | integer | não | ID da conta. |
description | text | sim | Descrição. |
installment | numeric(6,1) | sim | Parcela. |
value | numeric(14,2) | sim | Valor. |
fees | numeric(14,2) | sim | Juros. |
fine | numeric(14,2) | sim | Multa. |
due_date | timestamptz | sim | Vencimento. |
payment_date | timestamptz | sim | Data do pagamento. |
competence_date | timestamptz | sim | Competência contábil. |
type | text | sim | Tipo. |
supplier_id, supplier_name | integer / text | sim | Fornecedor. |
payment_brand_id, payment_brand_name | integer / text | sim | Forma de pagamento. |
chart_account_id, chart_account_name | integer / text | sim | Plano de contas. |
cost_center_id, cost_center_name | integer / text | sim | Centro de custo. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, account_payable_id). Índice: (schema, due_date).
Tabelas — Catálogo (produtos, serviços, planos, cursos)
Todas as tabelas de catálogo seguem o mesmo padrão:
schema,franchisor_id,<item>_id(integer, não nulo),franchise_identifier(integer — id no escopo da franquia),name(text),price(numeric(14,2)),active(boolean),created_at,updated_at(timestamptz). Chave primária(schema, <item>_id). Todas as colunas além deschemae do id são nullable.
services
servicesServiços oferecidos pela unidade.
| Coluna extra | Tipo | Descrição |
|---|---|---|
is_budget | boolean | Se o serviço só pode ser vendido via orçamento. |
Chave: service_id.
products
productsProdutos comercializados. Sem colunas adicionais além do padrão. Chave: product_id.
plans
plansPlanos comercializados. Sem colunas adicionais além do padrão. Chave: plan_id.
courses
coursesCursos oferecidos. Sem colunas adicionais além do padrão. Chave: course_id.
classes
classesTurmas de cursos.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
class_id | integer | não | ID da turma. |
name | text | sim | Nome da turma. |
start_date, end_date | timestamptz | sim | Período da turma. |
is_cyclic | boolean | sim | Turma cíclica? |
class_limit | numeric(14,2) | sim | Limite de alunos. |
minimum_frequency | numeric(14,2) | sim | Frequência mínima exigida. |
class_status_id, class_status_name | integer / text | sim | Status da turma. |
course_id, course_name | integer / text | sim | Curso. |
employee_id, employee_name | integer / text | sim | Professor responsável. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, class_id).
Tabelas — Operação clínica/atendimento
appointments
appointmentsAgendamentos de serviços para clientes. Não entram agendamentos excluídos, sem cliente ou com status_id = 7 (Bloqueio de agenda).
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
appointment_id | integer | não | ID do agendamento. |
order_id | integer | sim | Venda relacionada. |
customer_id, customer_name | integer / text | sim | Cliente. |
employee_id, employee_name | integer / text | sim | Profissional. |
service_id, service_franchise_identifier, service_name | integer / integer / text | sim | Serviço. |
service_budget | boolean | sim | É serviço de orçamento? |
status_id | integer | sim | Status. Ver Status de agendamento. |
start_date, end_date | timestamptz | sim | Janela do atendimento. |
service_session | integer | sim | Nº da sessão. |
rating | integer | sim | Avaliação do cliente. |
rescheduled | integer | sim | Quantidade de reagendamentos. |
created_at / updated_at | timestamptz | sim | Auditoria. |
room_id, room_name | integer / text | sim | Sala (JOIN schema + room_id). |
Chave primária: (schema, appointment_id). Índices: (schema, start_date), (schema, customer_id).
rooms
roomsSalas de atendimento.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
room_id | integer | não | ID da sala. |
name | text | sim | Nome. |
customer_limits | integer | sim | Capacidade simultânea. |
status | text | sim | Status (ativa/inativa, etc.). |
employee_id | integer | sim | Funcionário responsável. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, room_id).
room_time_slots
room_time_slotsJanelas de funcionamento das salas (por dia da semana).
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
room_time_slot_id | integer | não | ID. |
day_of_week | text | sim | Dia da semana (ex.: MONDAY). |
start_time | integer | sim | Início (em minutos a partir de 00:00). |
end_time | integer | sim | Fim (em minutos a partir de 00:00). |
room_id | integer | sim | Sala. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, room_time_slot_id).
measures
measuresMedidas corporais coletadas (típico de redes de estética/saúde). Medidas fora da faixa numérica chegam como NULL.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
measure_id | integer | não | ID da medição. |
customer_id | integer | sim | Cliente. |
date | timestamptz | sim | Data da medição. |
weight, height | numeric(14,2) | sim | Peso e altura. |
hip, waist, high_waist, low_waist | numeric(14,2) | sim | Quadril e cinturas. |
left_arm, right_arm | numeric(14,2) | sim | Braços. |
left_thigh_high, left_thigh_low, right_thigh_high, right_thigh_low | numeric(14,2) | sim | Coxas. |
calf | numeric(14,2) | sim | Panturrilha. |
baseline_measure | numeric(14,2) | sim | Linha de base. |
abdominal_circumference | numeric(14,2) | sim | Circunferência abdominal. |
fat_percentage | numeric(14,2) | sim | % de gordura. |
blood_pressure_max, blood_pressure_min | numeric(14,2) | sim | Pressão arterial. |
first_measure | boolean | sim | É a primeira medição? |
order_service_id | integer | sim | Item de venda associado. |
observation | text | sim | Observação. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, measure_id). Índice: (schema, customer_id).
slimming_goals
slimming_goalsMetas de emagrecimento por cliente.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
slimming_goal_id | integer | não | ID. |
customer_id | integer | sim | Cliente. |
start_date, end_date | timestamptz | sim | Período da meta. |
finished_at | timestamptz | sim | Quando concluída. |
weight, height, hip, waist, high_waist, low_waist, left_arm, right_arm, left_thigh_high, left_thigh_low, right_thigh_high, right_thigh_low, calf | numeric(14,2) | sim | Medidas-alvo. |
observation | text | sim | Observação. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, slimming_goal_id).
Tabelas — Metas e desempenho
goals
goalsMetas globais da empresa por período.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
goal_id | integer | não | ID. |
initial_date, end_date | timestamptz | sim | Período da meta. |
indication | integer | sim | Meta de indicações. |
product, service, plan, course | numeric(14,2) | sim | Metas por categoria. |
ticket | numeric(14,2) | sim | Meta de ticket médio. |
efficiency | numeric(14,2) | sim | Meta de eficiência. |
transformation | numeric(14,2) | sim | Meta de transformação. |
total | numeric(14,2) | sim | Meta total (R$). |
count_days, count_past_days | integer | sim | Dias úteis no período / já transcorridos. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, goal_id).
employee_goals
employee_goalsMetas individuais por funcionário.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
employee_goal_id | integer | não | ID. |
employee_id | integer | sim | Funcionário. |
goal_id | integer | sim | Meta global associada. |
initial_date, end_date | timestamptz | sim | Período. |
indication | integer | sim | Meta de indicações. |
product, service, plan, course, transformation, total | numeric(14,2) | sim | Metas por categoria e total. |
count_days, count_past_days | integer | sim | Dias do período / dias passados. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, employee_goal_id).
Tabelas — Royalties e taxas da franqueadora
As tabelas deste grupo vêm da unidade franqueadora: o
schemaé o da própria franqueadora e não há colunafranchisor_id.
franchise_royalties
franchise_royaltiesRegras de cobrança de royalties por franquia.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema | text | não | Unidade franqueadora. |
franchise_royalty_id | integer | não | ID da regra. |
start_at, end_at | timestamptz | sim | Vigência. |
due_day | integer | sim | Dia de vencimento. |
type | text | sim | Tipo de cobrança. |
min_value | numeric(14,2) | sim | Valor mínimo. |
percentage | numeric(14,4) | sim | Percentual. |
calculation_type | text | sim | Forma de cálculo (sobre faturamento, etc.). |
payment_brand_id, payment_brand_name | integer / text | sim | Forma de pagamento. |
franchise_id | integer | sim | Franquia. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, franchise_royalty_id).
franchise_royalty_periods
franchise_royalty_periodsValores apurados de royalties por período.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema | text | não | Unidade franqueadora. |
franchise_royalty_period_id | integer | não | ID. |
start_at, end_at | timestamptz | sim | Período de apuração. |
value | numeric(14,2) | sim | Valor apurado. |
franchise_royalty_id | integer | sim | Regra associada. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, franchise_royalty_period_id).
franchise_advertising_fees
franchise_advertising_feesRegras de taxa de publicidade. Mesma estrutura de franchise_royalties, trocando franchise_royalty_id por franchise_advertising_fee_id. Chave primária: (schema, franchise_advertising_fee_id).
franchise_advertising_fee_periods
franchise_advertising_fee_periodsValores apurados de taxa de publicidade. Mesma estrutura de franchise_royalty_periods, com franchise_advertising_fee_period_id (chave) e franchise_advertising_fee_id (regra associada).
franchise_categories
franchise_categoriesCategorias para classificar franquias.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema | text | não | Unidade franqueadora. |
franchise_category_id | integer | não | ID. |
name | text | sim | Nome da categoria. |
active | boolean | sim | Ativa? |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, franchise_category_id).
franchise_category_types
franchise_category_typesTabela de junção entre franquia e categoria.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema | text | não | Unidade franqueadora. |
id | bigint | não | Identificador gerado pelo Data Lake: (franchise_category_id << 32) + franchise_id. A origem não tem id para esta junção. |
franchise_category_id | integer | sim | Categoria. |
franchise_id | integer | sim | Franquia. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, id).
Tabelas — Marketing (Facebook Ads)
facebook_accounts
facebook_accountsContas de anúncio do Facebook integradas.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
facebook_account_id | integer | não | ID. |
name | text | sim | Nome da conta. |
account_status | integer | sim | Status (códigos do Facebook). |
currency | text | sim | Moeda. |
amount_spent | text | sim | Total gasto (acumulado, como texto). |
spend_cap | text | sim | Limite de gasto (como texto). |
business_id | text | sim | Business Manager. |
created_time | timestamptz | sim | Quando a conta foi criada no Facebook. |
bm_id | text | sim | ID do BM. |
last_campaign_sync | timestamptz | sim | Última sincronização. |
active | boolean | sim | Está ativa no nosso sistema? |
business_name | text | sim | Nome do Business Manager. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, facebook_account_id).
facebook_campaign_data
facebook_campaign_dataMétricas diárias por anúncio.
| Coluna | Tipo | Nullable | Descrição |
|---|---|---|---|
schema / franchisor_id | text / integer | não / sim | Unidade / rede. |
facebook_campaign_data_id | integer | não | ID. |
account_id | text | sim | Conta de anúncio. |
identifier | text | sim | Identificador do registro. |
date | date | sim | Dia da métrica. |
source_id | text | sim | ID de origem (anúncio). |
total_spent | numeric(14,2) | sim | Gasto. |
ad_campaign_name, ad_set_name, ad_name | text | sim | Hierarquia do anúncio. |
impressions, link_clicks, reach | integer | sim | Métricas de entrega. |
frequency | numeric(14,4) | sim | Frequência. |
started_messages | integer | sim | Conversas iniciadas. |
video_view_25_count, video_view_50_count, video_view_75_count, video_view_95_count | integer | sim | Visualizações de vídeo por % assistido. |
created_at / updated_at | timestamptz | sim | Auditoria. |
Chave primária: (schema, facebook_campaign_data_id). Índice: (schema, date).
Para atribuir leads/vendas a campanhas, cruze com
deals.facebook_source_idou comdeals.ad_campaign_name/ad_set_name/ad_name.
Tabelas — Sistema
metadata
metadataView (somente leitura) que informa, para cada par (schema, table), o dado mais novo já carregado no Data Lake.
| Coluna | Tipo | Descrição |
|---|---|---|
schema | text | Unidade. |
table | text | Nome da tabela final (ex.: orders). |
last_updated | timestamptz | Maior updated_at da origem já carregado para essa tabela/unidade. |
Use para verificar até quando os dados de uma unidade estão atualizados:
SELECT "table", last_updated
FROM metadata
WHERE schema = 'minha_unidade'
ORDER BY "table";
last_updatedé a idade do dado, não do pipeline: uma unidade sem movimentação recente terá valores antigos e estará em dia. A verificação de exclusões não altera esta view.
Enums e dicionários de valores
franchises.status
franchises.status| Valor | Significado |
|---|---|
IN_IMPLEMENTATION | Em implementação. |
ACTIVE | Ativa. |
TERMINATION_REQUEST | Solicitação de encerramento. |
TERMINATION | Em encerramento. |
CANCELED | Cancelada. |
LEGAL | Em situação jurídica. |
companies.status
companies.status| Valor | Significado |
|---|---|
ACTIVE | Ativa. |
INACTIVE | Inativa. |
IMPLANTATION | Em implantação. |
BLOCKED | Bloqueada. |
orders.status
orders.status| Valor | Significado |
|---|---|
BILLED | Faturada. |
CLOSED | Fechada. |
CANCELED | Cancelada. |
ABANDONMENT | Abandono. |
PENDING_BALANCE | Saldo pendente. |
budgets.status
budgets.status| Valor | Significado |
|---|---|
PENDING | Aguardando. |
ACCOMPLISHED | Realizada. |
CONVERTED | Convertida em venda. |
DISCARDED | Descartada. |
payments.payment_status_id
payments.payment_status_id| ID | Nome |
|---|---|
| 0 | Cancelado |
| 1 | Pendente |
| 2 | Conciliação |
| 3 | Vencido |
| 4 | Liquidado |
appointments.status_id
appointments.status_id| ID | Nome | Observação |
|---|---|---|
| 1 | Agendado | |
| 2 | Confirmado | |
| 3 | Em espera | |
| 4 | Em andamento | |
| 5 | Realizado | |
| 6 | Falta | |
| 7 | Bloqueio | Não é carregado em appointments. |
Exemplos de queries para BI
Em todos os exemplos, troque
'minha_unidade'peloschemadesejado.
1. Faturamento mensal (vendas faturadas)
SELECT date_trunc('month', created_at) AS mes,
SUM(total_price) AS faturamento,
COUNT(*) AS qtd_vendas
FROM orders
WHERE schema = 'minha_unidade'
AND status = 'BILLED'
AND created_at >= '2025-01-01'
GROUP BY 1
ORDER BY 1;2. Recebíveis pendentes (a vencer e vencidos)
SELECT payment_status_name,
COUNT(*) AS qtd,
SUM(value) AS total
FROM payments
WHERE schema = 'minha_unidade'
AND payment_status_id IN (1, 3) -- Pendente, Vencido
GROUP BY 1;3. Ranking de vendedores no mês
SELECT seller_id,
seller_name,
COUNT(*) AS qtd_vendas,
SUM(total_price) AS receita,
SUM(total_paid) AS recebido
FROM orders
WHERE schema = 'minha_unidade'
AND status = 'BILLED'
AND created_at >= date_trunc('month', current_date)
GROUP BY 1, 2
ORDER BY receita DESC;4. Conversão do funil de CRM
SELECT COUNT(*) AS leads,
COUNT(converted_at) AS convertidos,
COUNT(discarded_at) AS descartados,
ROUND(100.0 * COUNT(converted_at) / NULLIF(COUNT(*),0), 2) AS taxa_conversao_pct
FROM deals
WHERE schema = 'minha_unidade'
AND created_at >= current_date - INTERVAL '90 days';5. Vendas com seus pagamentos (uso correto do JOIN)
SELECT o.order_id,
o.customer_name,
o.total_price,
o.total_paid,
p.payment_id,
p.value,
p.due_date,
p.payment_status_name
FROM orders o
JOIN payments p
ON p.schema = o.schema -- ✅ obrigatório
AND p.order_id = o.order_id
WHERE o.schema = 'minha_unidade'
AND o.created_at >= current_date - INTERVAL '30 days';6. Ocupação de agenda por profissional
SELECT employee_id,
employee_name,
COUNT(*) FILTER (WHERE status_id = 5) AS realizados,
COUNT(*) FILTER (WHERE status_id = 6) AS faltas,
COUNT(*) AS total_agendamentos
FROM appointments
WHERE schema = 'minha_unidade'
AND start_date >= date_trunc('month', current_date)
GROUP BY 1, 2
ORDER BY total_agendamentos DESC;7. Custo por lead (Facebook Ads × Deals)
WITH gasto AS (
SELECT date, SUM(total_spent) AS spent
FROM facebook_campaign_data
WHERE schema = 'minha_unidade'
AND date >= current_date - INTERVAL '30 days'
GROUP BY 1
),
leads AS (
SELECT created_at::date AS date, COUNT(*) AS qtd
FROM deals
WHERE schema = 'minha_unidade'
AND facebook_source_id IS NOT NULL
AND created_at >= current_date - INTERVAL '30 days'
GROUP BY 1
)
SELECT g.date,
g.spent,
l.qtd AS leads,
ROUND(g.spent / NULLIF(l.qtd, 0), 2) AS cpl
FROM gasto g
LEFT JOIN leads l ON l.date = g.date
ORDER BY g.date;8. Consolidado da rede (todas as unidades da franqueadora)
Como o schema Postgres já é o da franqueadora, basta agrupar por schema sem filtrá-lo. Para exibir o nome da unidade, cruze com companies (o name é o alias cadastrado no painel).
SELECT o.schema,
c.name AS unidade,
SUM(o.total_price) AS faturamento
FROM orders o
LEFT JOIN companies c
ON c.schema = o.schema
WHERE o.status = 'BILLED'
AND o.created_at >= date_trunc('month', current_date)
GROUP BY o.schema, c.name
ORDER BY faturamento DESC;9. Frescor dos dados por unidade
SELECT schema,
MAX(last_updated) FILTER (WHERE "table" = 'orders') AS ultima_venda_vista,
MAX(last_updated) FILTER (WHERE "table" = 'payments') AS ultimo_pagamento_visto
FROM metadata
GROUP BY schema
ORDER BY schema;Boas práticas de desempenho no Postgres
- Sempre filtre por
schema. Todo índice começa por essa coluna; sem o filtro, a consulta varre a tabela inteira. - Faça JOINs por
schema + <id>. Além de correto, é o que permite usar a chave primária composta dos dois lados. - Use os campos
*_namedenormalizados sempre que possível, em vez de fazer JOIN com tabelas-mestras (customers,services, etc.). Eles existem justamente para evitar JOINs em queries comuns de BI. - Filtre por colunas indexadas junto com
schema:created_at(vendas, pagamentos, clientes, orçamentos, deals),due_date(contas a pagar),start_date(agendamentos),date(Facebook Ads),liquidation_date(pagamentos),customer_id,order_id,status(vendas). - Janelas curtas de data (ex.: últimos 90 dias) reduzem muito o volume lido.
- Selecione só as colunas necessárias — menos dados trafegando para a ferramenta de BI.
- Prefira agregações
GROUP BYem colunas de baixa cardinalidade (status,employee_id,schema) e dimensões temporais (date_trunc(...)). - Use
WITH(CTEs) para deixar a query legível; o planejador do Postgres as otimiza normalmente. - Confira com
EXPLAINse a consulta usa índice (Index Scan/Bitmap Index Scan) em vez deSeq Scanquando ela estiver lenta. - Lembre dos limites do login: 15 minutos por consulta e 10 conexões simultâneas. Configure pool e cache na ferramenta de BI em vez de abrir uma conexão por painel.
- Para saber até onde o Data Lake está atualizado, consulte a view
metadata.
Em caso de dúvidas sobre o significado de um campo ou enum específico, consulte o time de dados — esta documentação é viva e será atualizada conforme novas tabelas e colunas forem adicionadas ao Data Lake.
Updated 1 day ago