DATABASE.md 25 KB

Documentação do Banco de Dados

Este documento descreve o schema PostgreSQL definido em migrations/migrations_v1.sql para o projeto php_api.

Visão geral

O banco foi modelado para suportar uma operação multiempresa, com as seguintes áreas principais:

  • Entidades centrais: company, user, operator, sku, integration.
  • Operação de atendimento: client, conversation, message, message_attachment, message_reaction, conversation_participant, webhook_event.
  • Análise e inteligência: conversation_analysis, aspect_feedback, emotion_snapshot, public_opinion, ai_action.
  • Estratégia e gestão: persona, client_persona, best_action.
  • Métricas e snapshots: volume_snapshot, sentiment_evolution, playbooks_monitor, operator_daily_stats, kpi_snapshot.

Convenções do schema

  • Todas as tabelas usam SERIAL PRIMARY KEY para o identificador principal.
  • Todas as colunas relevantes estão marcadas como NOT NULL.
  • Colunas de exclusão lógica usam o padrão:
    • TIMESTAMP NOT NULL DEFAULT 'infinity'
  • O valor 'infinity' indica que o registro está ativo.
  • A tabela user é criada entre aspas ("user") porque o nome é reservado em PostgreSQL.
  • As chaves estrangeiras foram declaradas com CONSTRAINT em linha única.
  • Alguns relacionamentos possuem UNIQUE para impedir duplicidade por empresa ou por data.

Tabelas

1. company

Tabela principal de empresas atendidas pelo sistema.

Coluna Tipo Descrição
company_id SERIAL Identificador da empresa.
company_name VARCHAR(100) Nome da empresa.
company_cnpj VARCHAR(14) CNPJ da empresa. Único.
company_logo TEXT Logo da empresa.
company_hmac_secret VARCHAR(64) Segredo HMAC próprio da empresa, usado para validar os webhooks de CRM. Default vazio (tratado como "não configurado").
company_created_at TIMESTAMP Data de criação.
company_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

2. user

Usuários do sistema vinculados a uma empresa.

Coluna Tipo Descrição
user_id SERIAL Identificador do usuário.
company_id INT FK para company.company_id.
user_name VARCHAR(100) Nome do usuário.
user_phone VARCHAR(20) Telefone.
user_email VARCHAR(100) E-mail. Único.
user_role VARCHAR(10) Papel/perfil do usuário.
user_password VARCHAR(255) Senha criptografada.
user_created_at TIMESTAMP Data de criação.
user_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

3. operator

Operadores/atendentes vinculados à empresa.

Coluna Tipo Descrição
operator_id SERIAL Identificador do operador.
company_id INT FK para company.
operator_name VARCHAR(100) Nome do operador.
operator_initials VARCHAR(5) Iniciais do operador.
operator_email VARCHAR(100) E-mail do operador.
operator_phone VARCHAR(20) Telefone.
operator_department VARCHAR(20) Departamento.
operator_status VARCHAR(30) Status atual. Default: 'Disponível'.
operator_available_for_escalation BOOLEAN Indica disponibilidade para escalonamento.
operator_created_at TIMESTAMP Data de criação.
operator_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

4. operator_channel

Canais vinculados a cada operador.

Coluna Tipo Descrição
operator_channel_id SERIAL Identificador do registro.
operator_id INT FK para operator.
operator_channel VARCHAR(20) Nome do canal.
operator_channel_created_at TIMESTAMP Data de criação.
operator_channel_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

5. sla_config

Configuração de SLA por empresa e departamento.

Coluna Tipo Descrição
sla_config_id SERIAL Identificador.
company_id INT FK para company.
sla_config_department VARCHAR(20) Departamento.
sla_config_response_hours INT Tempo de resposta em horas. Default: 2.
sla_config_resolution_hours INT Tempo de resolução em horas. Default: 24.
sla_config_updated_at TIMESTAMP Data de atualização.
sla_config_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

Restrição:

  • UNIQUE (company_id, sla_config_department)

6. sku

Cadastro de produtos/serviços da empresa.

Coluna Tipo Descrição
sku_id SERIAL Identificador.
company_id INT FK para company.
sku_name VARCHAR(100) Nome do item.
sku_value DECIMAL(12,2) Valor.
sku_sold INT Quantidade vendida. Default: 0.
sku_line VARCHAR(50) Linha/categoria.
sku_created_at TIMESTAMP Data de criação.
sku_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

7. integration

Integrações externas da empresa.

Coluna Tipo Descrição
integration_id SERIAL Identificador.
company_id INT FK para company.
integration_provider VARCHAR(30) Provedor da integração.
integration_account_id TEXT ID da conta.
integration_external_account_id TEXT ID externo da conta.
integration_account_name VARCHAR(100) Nome da conta.
integration_status VARCHAR(20) Status da integração.
integration_access_token TEXT Token de acesso.
integration_refresh_token TEXT Refresh token.
integration_is_connected BOOLEAN Indica se está conectada. Default: TRUE.
integration_last_sync_at TIMESTAMP Última sincronização.
integration_last_error TEXT Último erro.
integration_created_at TIMESTAMP Data de criação.
integration_updated_at TIMESTAMP Data de atualização.
integration_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

8. client

Clientes que interagem com a empresa.

Coluna Tipo Descrição
client_id SERIAL Identificador.
company_id INT FK para company.
client_provider_id TEXT ID do cliente no provedor.
client_phone VARCHAR(20) Telefone.
client_name VARCHAR(100) Nome.
client_email VARCHAR(100) E-mail.
client_segment VARCHAR(100) Segmento.
client_is_registered BOOLEAN Indica se o cliente está cadastrado. Default: FALSE.
client_created_at TIMESTAMP Data de criação.
client_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

Restrição:

  • UNIQUE (company_id, client_phone)

9. conversation

Conversas entre clientes e operadores/integrações.

Coluna Tipo Descrição
conversation_id SERIAL Identificador.
company_id INT FK para company.
integration_id INT FK para integration.
operator_id INT FK para operator.
client_id INT FK para client.
conversation_external_id TEXT ID externo da conversa.
conversation_provider_id TEXT ID no provedor.
conversation_channel VARCHAR(20) Canal.
conversation_status VARCHAR(20) Status da conversa. Default: 'open'.
conversation_is_automated BOOLEAN Indica automação. Default: FALSE.
conversation_started_at TIMESTAMP Início.
conversation_closed_at TIMESTAMP Encerramento.
conversation_sla_deadline TIMESTAMP Prazo de SLA.
conversation_last_message_at TIMESTAMP Data da última mensagem.
conversation_last_message_preview TEXT Prévia da última mensagem.
conversation_last_message_from VARCHAR(10) Origem da última mensagem.
conversation_impact_value DECIMAL(12,2) Valor de impacto.
conversation_ticket_value DECIMAL(12,2) Valor do ticket.
conversation_conversion_chance INT Chance de conversão.
conversation_optimum_window VARCHAR(20) Janela ideal.
conversation_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

10. message

Mensagens associadas a uma conversa.

Coluna Tipo Descrição
message_id SERIAL Identificador.
conversation_id INT FK para conversation.
quoted_message_id INT FK auto-referenciada para message.
message_external_id TEXT ID externo da mensagem.
message_provider_id TEXT ID no provedor.
message_sender_provider_id TEXT Remetente no provedor.
message_is_operator BOOLEAN Indica se foi enviada por operador.
message_type VARCHAR(20) Tipo da mensagem. Default: 'text'.
message_content TEXT Conteúdo.
message_seen BOOLEAN Visualizada.
message_delivered BOOLEAN Entregue.
message_edited BOOLEAN Editada. Default: FALSE.
message_deleted BOOLEAN Excluída. Default: FALSE.
message_hidden BOOLEAN Oculta. Default: FALSE.
message_is_event BOOLEAN Indica evento. Default: FALSE.
message_event_type INT Tipo do evento.
message_sent_at TIMESTAMP Data de envio.
message_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

11. message_attachment

Anexos de mensagens.

Coluna Tipo Descrição
attachment_id SERIAL Identificador.
message_id INT FK para message.
attachment_external_id TEXT ID externo.
attachment_url TEXT URL do arquivo.
attachment_type VARCHAR(50) Tipo do anexo.
attachment_mime_type VARCHAR(100) MIME type.
attachment_file_name VARCHAR(255) Nome do arquivo.
attachment_size BIGINT Tamanho em bytes.
attachment_created_at TIMESTAMP Data de criação.
attachment_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

12. message_reaction

Reações vinculadas a mensagens.

Coluna Tipo Descrição
reaction_id SERIAL Identificador.
message_id INT FK para message.
reaction_sender_provider_id TEXT Remetente da reação no provedor.
reaction_value VARCHAR(20) Valor da reação.
reaction_is_sender BOOLEAN Indica se foi enviada pelo remetente. Default: FALSE.
reaction_created_at TIMESTAMP Data de criação.
reaction_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

13. conversation_participant

Participantes de uma conversa.

Coluna Tipo Descrição
participant_id SERIAL Identificador.
conversation_id INT FK para conversation.
participant_provider_id TEXT ID do participante no provedor.
participant_name VARCHAR(100) Nome do participante.
participant_is_admin BOOLEAN Indica se é administrador. Default: FALSE.
participant_created_at TIMESTAMP Data de criação.
participant_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

14. webhook_event

Eventos recebidos por webhook.

Coluna Tipo Descrição
webhook_event_id SERIAL Identificador.
integration_id INT FK para integration.
webhook_event_type VARCHAR(50) Tipo do evento.
webhook_event_external_id TEXT ID externo do evento.
webhook_event_payload JSONB Payload bruto do evento.
webhook_event_processed BOOLEAN Processado. Default: FALSE.
webhook_event_received_at TIMESTAMP Data de recebimento.
webhook_event_processed_at TIMESTAMP Data de processamento.
webhook_event_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

15. conversation_analysis

Resultado de análise de conversa por IA.

Coluna Tipo Descrição
analysis_id SERIAL Identificador.
conversation_id INT FK para conversation. Única.
company_id INT FK para company.
conversation_analysis_sentiment VARCHAR(20) Sentimento detectado.
conversation_analysis_sentiment_score NUMERIC(3,2) Score do sentimento.
conversation_analysis_aspect VARCHAR(50) Aspecto principal.
conversation_analysis_sub_aspect VARCHAR(100) Subaspecto.
conversation_analysis_analyzed_at TIMESTAMP Data da análise.
conversation_analysis_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

16. aspect_feedback

Feedback de aspecto da conversa.

Coluna Tipo Descrição
aspect_feedback_id SERIAL Identificador.
company_id INT FK para company.
conversation_id INT FK para conversation.
aspect_feedback_aspect VARCHAR(50) Aspecto.
aspect_feedback_sentiment VARCHAR(20) Sentimento.
aspect_feedback_text TEXT Texto do feedback.
aspect_feedback_created_at TIMESTAMP Data de criação.
aspect_feedback_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

17. emotion_snapshot

Snapshot de emoções por empresa e data.

Coluna Tipo Descrição
emotion_id SERIAL Identificador.
company_id INT FK para company.
emotion_snapshot_date DATE Data do snapshot.
emotion_happiness NUMERIC(5,2) Felicidade. Default: 0.
emotion_sadness NUMERIC(5,2) Tristeza. Default: 0.
emotion_anger NUMERIC(5,2) Raiva. Default: 0.
emotion_fear NUMERIC(5,2) Medo. Default: 0.
emotion_anticipation NUMERIC(5,2) Antecipação. Default: 0.
emotion_confidence NUMERIC(5,2) Confiança. Default: 0.
emotion_surprise NUMERIC(5,2) Surpresa. Default: 0.
emotion_total_analyzed INT Total analisado. Default: 0.

Restrição:

  • UNIQUE (company_id, emotion_snapshot_date)

18. public_opinion

Opiniões públicas classificadas por conversa.

Coluna Tipo Descrição
opinion_id SERIAL Identificador.
company_id INT FK para company.
conversation_id INT FK para conversation.
opinion_is_positive BOOLEAN Indica se a opinião é positiva.
opinion_classified_at TIMESTAMP Data da classificação.
opinion_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

19. alert

Alertas gerados pelo sistema.

Coluna Tipo Descrição
alert_id SERIAL Identificador.
company_id INT FK para company.
client_id INT FK para client.
alert_type VARCHAR(20) Tipo do alerta.
alert_priority VARCHAR(10) Prioridade.
alert_title TEXT Título.
alert_description TEXT Descrição.
alert_tips TEXT Dicas.
alert_is_resolved BOOLEAN Indica se foi resolvido. Default: FALSE.
alert_created_at TIMESTAMP Data de criação.
alert_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

20. ai_action

Sugestões/ações geradas por IA.

Coluna Tipo Descrição
ai_action_id SERIAL Identificador.
company_id INT FK para company.
ai_action_idea TEXT Ideia gerada.
ai_action_is_accepted BOOLEAN Indica aceitação.
ai_action_created_at TIMESTAMP Data de criação.
ai_action_responded_at TIMESTAMP Data de resposta.
ai_action_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

21. persona

Perfis/personas da empresa.

Coluna Tipo Descrição
persona_id SERIAL Identificador.
company_id INT FK para company.
persona_name VARCHAR(100) Nome da persona.
persona_type VARCHAR(50) Tipo da persona. Default: 'O PERFIL'.
persona_description TEXT Descrição.
persona_details TEXT Detalhes.
persona_risk_level VARCHAR(10) Nível de risco. Default: 'Médio'.
persona_churn_risk_pct NUMERIC(5,2) Percentual de risco de churn.
persona_expansion_potential VARCHAR(20) Potencial de expansão.
persona_expansion_strategy TEXT Estratégia de expansão.
persona_engagement_strategy TEXT Estratégia de engajamento.
persona_created_at TIMESTAMP Data de criação.
persona_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

22. client_persona

Relacionamento entre cliente e persona.

Coluna Tipo Descrição
client_persona_id SERIAL Identificador.
client_id INT FK para client.
persona_id INT FK para persona.
client_persona_assigned_at TIMESTAMP Data de associação.
client_persona_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

23. best_action

Melhor ação sugerida por empresa e persona.

Coluna Tipo Descrição
best_action_id SERIAL Identificador.
company_id INT FK para company.
persona_id INT FK para persona.
best_action_type VARCHAR(20) Tipo da ação.
best_action_idea TEXT Ideia da ação.
best_action_created_at TIMESTAMP Data de criação.
best_action_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

24. volume_snapshot

Snapshot de volume por canal, empresa e data.

Coluna Tipo Descrição
volume_id SERIAL Identificador.
company_id INT FK para company.
volume_snapshot_date DATE Data do snapshot.
volume_channel VARCHAR(20) Canal.
volume_message_count INT Quantidade de mensagens. Default: 0.
volume_conversation_count INT Quantidade de conversas. Default: 0.

Restrição:

  • UNIQUE (company_id, volume_snapshot_date, volume_channel)

25. sentiment_evolution

Evolução de sentimento por empresa e data.

Coluna Tipo Descrição
evolution_id SERIAL Identificador.
company_id INT FK para company.
evolution_snapshot_date DATE Data do snapshot.
evolution_sentiment_score NUMERIC(3,2) Score do sentimento.

Restrição:

  • UNIQUE (company_id, evolution_snapshot_date)

26. playbooks_monitor

Monitoramento de playbooks por data.

Coluna Tipo Descrição
playbook_id SERIAL Identificador.
company_id INT FK para company.
playbook_snapshot_date DATE Data do snapshot.
playbook_new_detected INT Quantidade de novos detectados. Default: 0.
playbook_converted INT Quantidade convertida. Default: 0.
playbook_client_type VARCHAR(10) Tipo de cliente. Default: 'new'.

Restrição:

  • UNIQUE (company_id, playbook_snapshot_date)

27. operator_daily_stats

Estatísticas diárias por operador.

Coluna Tipo Descrição
stat_id SERIAL Identificador.
company_id INT FK para company.
operator_id INT FK para operator.
operator_stat_date DATE Data da estatística.
operator_attendances_count INT Quantidade de atendimentos. Default: 0.
operator_avg_response_seconds INT Tempo médio de resposta em segundos. Default: 0.
operator_sla_compliance_pct NUMERIC(5,2) Percentual de SLA. Default: 0.
operator_sales_amount DECIMAL(12,2) Valor de vendas. Default: 0.

Restrição:

  • UNIQUE (operator_id, operator_stat_date)

28. kpi_snapshot

Snapshot consolidado de KPIs da empresa.

Coluna Tipo Descrição
kpi_id SERIAL Identificador.
company_id INT FK para company.
kpi_snapshot_date DATE Data do snapshot.
kpi_current_sales DECIMAL(12,2) Vendas atuais. Default: 0.
kpi_avg_ticket DECIMAL(12,2) Ticket médio. Default: 0.
kpi_lifetime_at_risk DECIMAL(12,2) Valor em risco. Default: 0.
kpi_critical_risk_clients INT Clientes em risco crítico. Default: 0.
kpi_sla_compliance_pct NUMERIC(5,2) Percentual de compliance do SLA. Default: 0.
kpi_churn_low_pct NUMERIC(5,2) Churn baixo. Default: 0.
kpi_churn_moderate_pct NUMERIC(5,2) Churn moderado. Default: 0.
kpi_churn_high_pct NUMERIC(5,2) Churn alto. Default: 0.
kpi_churn_critical_pct NUMERIC(5,2) Churn crítico. Default: 0.
kpi_ltv_total DECIMAL(12,2) LTV total. Default: 0.
kpi_ltv_at_risk DECIMAL(12,2) LTV em risco. Default: 0.
kpi_total_registered_clients INT Total de clientes cadastrados. Default: 0.
kpi_total_active_operators INT Total de operadores ativos. Default: 0.
kpi_general_emotion VARCHAR(20) Emoção geral.

Restrição:

  • UNIQUE (company_id, kpi_snapshot_date)

29. sale

Histórico de vendas recebido do CRM. Cada linha é uma venda com a data em que ocorreu, permitindo apurar faturamento por dia, semana ou mês.

Coluna Tipo Descrição
sale_id SERIAL Identificador.
company_id INT FK para company.
sku_id INT Produto vendido. 0 quando não vinculado.
client_id INT Cliente da venda. 0 quando não vinculado.
operator_id INT Operador responsável. 0 quando não vinculado.
sale_external_id TEXT ID da venda no CRM (idempotência).
sale_amount DECIMAL(12,2) Valor faturado.
sale_quantity INT Quantidade vendida. Default: 1.
sale_occurred_at TIMESTAMP Data/hora em que a venda ocorreu.
sale_created_at TIMESTAMP Data de criação do registro.
sale_deleted_at TIMESTAMP Exclusão lógica, padrão 'infinity'.

Restrições:

  • UNIQUE (company_id, sale_external_id) (parcial, registros ativos) — evita duplicar faturamento em reenvios.
  • Índice (company_id, sale_occurred_at) para consultas de faturamento por período.

Relacionamentos principais

  • user.company_idcompany.company_id
  • operator.company_idcompany.company_id
  • operator_channel.operator_idoperator.operator_id
  • sla_config.company_idcompany.company_id
  • sku.company_idcompany.company_id
  • integration.company_idcompany.company_id
  • client.company_idcompany.company_id
  • conversation.company_idcompany.company_id
  • conversation.integration_idintegration.integration_id
  • conversation.operator_idoperator.operator_id
  • conversation.client_idclient.client_id
  • message.conversation_idconversation.conversation_id
  • message.quoted_message_idmessage.message_id
  • message_attachment.message_idmessage.message_id
  • message_reaction.message_idmessage.message_id
  • conversation_participant.conversation_idconversation.conversation_id
  • webhook_event.integration_idintegration.integration_id
  • conversation_analysis.conversation_idconversation.conversation_id
  • conversation_analysis.company_idcompany.company_id
  • aspect_feedback.company_idcompany.company_id
  • aspect_feedback.conversation_idconversation.conversation_id
  • emotion_snapshot.company_idcompany.company_id
  • public_opinion.company_idcompany.company_id
  • public_opinion.conversation_idconversation.conversation_id
  • alert.company_idcompany.company_id
  • alert.client_idclient.client_id
  • ai_action.company_idcompany.company_id
  • persona.company_idcompany.company_id
  • client_persona.client_idclient.client_id
  • client_persona.persona_idpersona.persona_id
  • best_action.company_idcompany.company_id
  • best_action.persona_idpersona.persona_id
  • volume_snapshot.company_idcompany.company_id
  • sentiment_evolution.company_idcompany.company_id
  • playbooks_monitor.company_idcompany.company_id
  • operator_daily_stats.company_idcompany.company_id
  • operator_daily_stats.operator_idoperator.operator_id
  • kpi_snapshot.company_idcompany.company_id
  • sale.company_idcompany.company_id

Observações importantes

  • O campo *_deleted_at = 'infinity' indica registro ativo.
  • A lógica da aplicação deve considerar esse valor para filtros de registros válidos.
  • O setup do projeto recria o banco PostgreSQL antes de aplicar a migration.
  • A migration atual é a fonte de verdade da estrutura do banco.

Resumo

O schema foi projetado para armazenar:

  • cadastro de empresas e usuários,
  • operação de atendimento e conversas,
  • mensagens e anexos,
  • processamento de IA,
  • estratégia comercial,
  • métricas por dia e por empresa.