Pular para conteúdo

Database

Implementação real

O CRM usa Django ORM sobre PostgreSQL. As entidades de negócio usam UUID como chave primária por meio de apps.core.models.BaseModel; User, Role, AuditLog e HistoricoEtapaOportunidade possuem estruturas próprias. O catálogo abaixo foi conferido nos models.py do repositório coreflow-crm.

Diagrama entidade-relacionamento

erDiagram ROLE ||--o{ USER : atribui USER ||--o{ CONTA : responsavel USER ||--o{ CONTATO : responsavel CONTA ||--o{ CONTATO : possui USER ||--o{ LEAD : responsavel CONTA o|--o{ LEAD : converte CONTATO o|--o{ LEAD : converte LEAD o|--o{ OPORTUNIDADE : origina PIPELINE ||--o{ PIPELINE_STAGE : contem CONTA ||--o{ OPORTUNIDADE : possui CONTATO o|--o{ OPORTUNIDADE : acompanha PIPELINE_STAGE o|--o{ OPORTUNIDADE : etapa USER ||--o{ OPORTUNIDADE : responsavel OPORTUNIDADE ||--o{ HISTORICO_ETAPA : registra PIPELINE_STAGE o|--o{ HISTORICO_ETAPA : anterior PIPELINE_STAGE ||--o{ HISTORICO_ETAPA : nova USER ||--o{ HISTORICO_ETAPA : altera USER ||--o{ ATIVIDADE : responsavel CONTA o|--o{ ATIVIDADE : relaciona CONTATO o|--o{ ATIVIDADE : relaciona LEAD o|--o{ ATIVIDADE : relaciona OPORTUNIDADE o|--o{ ATIVIDADE : relaciona USER ||--o{ TAREFA : responsavel USER ||--o{ NOTA : autor USER o|--o{ AUDIT_LOG : ator

Nota, Atividade e Tarefa possuem relacionamentos opcionais por colunas explícitas (conta, contato, lead e/ou oportunidade); o banco não usa GenericForeignKey. Lead mantém os vínculos de conversão para conta, contato e oportunidade com SET_NULL.

Tabelas e chaves

Modelo Tabela Chave Observações de integridade
Role accounts_role id bigint name único
User accounts_user id bigint role opcional, PROTECT
Conta contas_conta id UUID responsavel opcional, PROTECT
Contato contatos_contato id UUID no máximo um principal por conta
Lead leads_lead id UUID responsável obrigatório; conversões opcionais
Pipeline oportunidades_pipeline id UUID somente um pipeline padrão
PipelineStage oportunidades_pipelinestage id UUID (pipeline, ordem) único
Oportunidade oportunidades_oportunidade id UUID conta e responsável obrigatórios
HistoricoEtapaOportunidade oportunidades_historicoetapaoportunidade id bigint histórico de mudança de etapa
Atividade atividades_atividade id UUID responsável obrigatório
Tarefa tarefas_tarefa id UUID responsável obrigatório
Nota anotacoes_nota id UUID autor obrigatório; exclusão lógica
AuditLog auditoria_auditlog id bigint ator pode ser nulo

Dicionário de dados

Tipos são os tipos Django que originam as colunas PostgreSQL (UUIDField → uuid, CharField → varchar, TextField → text, DateTimeField → timestamptz, DecimalField → numeric). não na coluna Nulo significa null=False; campos opcionais aceitam NULL quando o model declara null=True.

Base, identidade e auditoria

Entidade Campo: tipo Nulo Default FK / índice
BaseModel id: uuid; created_at/updated_at: timestamptz; is_active: boolean não uuid4; auto; true PK id; ordenação por criação
Role id: bigint; name: varchar(50); description: text; timestamps não auto; —; ""; auto PK; name UNIQUE
User campos de AbstractUser; role: bigint; avatar: image; timestamps role/avatar sim defaults do Django role → Role PROTECT
AuditLog id: bigint; acao: smallint; ator: bigint; tipo_entidade/id_entidade: varchar; descricao: text; três campos jsonb; endereco_ip: inet; user_agent: text; created_at: timestamptz ator, JSON e IP sim auto; demais sem default ator → User SET_NULL; índices por ação/entidade/data

Contas, contatos e leads

Entidade Campos persistidos
Conta id: uuid; timestamps; is_active: boolean=true; razao_social/nome_fantasia: varchar(200); numero_documento: varchar (nulo); tipo_conta/status: varchar(20) (default prospect); segmento/origem: varchar(100); email; telefone: varchar(20); site; cidade: varchar(100); estado: varchar(2); pais: varchar(100)=Brasil; observacoes: text; responsavel: uuid (nulo, FK User, PROTECT).
Contato id: uuid; timestamps; is_active=true; conta: uuid (nulo, FK Conta, PROTECT); primeiro_nome/sobrenome: varchar(100); email; telefone/celular: varchar(20); cargo/departamento: varchar(100); principal: boolean=false; observacoes: text; responsavel: uuid (nulo, FK User, PROTECT). Constraint condicional: um principal por conta.
Lead id: uuid; timestamps; is_active=true; nome: varchar(200); nome_contato: varchar(150); email; telefone: varchar(20); nome_empresa: varchar(200); origem: varchar(100); status: varchar(20)=novo; pontuacao_qualificacao: smallint (0–100, nulo); interesse: text; valor_estimado: numeric(12,2) (nulo); responsavel: uuid (FK User, PROTECT); motivo_perda: text; convertido_em: timestamptz (nulo); três FKs de conversão (nulas, SET_NULL).

Pipeline, oportunidades e atividades

Entidade Campos persistidos
Pipeline id: uuid; timestamps; is_active=true; nome: varchar(100); descricao: text; padrao: boolean=false. Constraint condicional: um padrão.
PipelineStage id: uuid; timestamps; is_active=true; pipeline: uuid (FK, CASCADE); nome: varchar(100); ordem: integer; probabilidade: integer (0–100, nulo); etapa_ganho/perda: boolean=false. UNIQUE (pipeline, ordem).
Oportunidade id: uuid; timestamps; is_active=true; titulo: varchar(200); conta: uuid (FK, PROTECT); contato/etapa: uuid (nulos, SET_NULL/PROTECT); status: varchar(20)=aberta; valor_estimado: numeric(12,2); probabilidade: integer; duas datas de fechamento; responsavel: uuid (FK, PROTECT); lead_origem: uuid (nulo, SET_NULL); motivo_perda/descricao: text.
HistoricoEtapaOportunidade id: bigint; oportunidade: uuid (FK, CASCADE); etapa_anterior: uuid (nulo, SET_NULL); etapa_nova: uuid (FK, PROTECT); alterado_por: bigint (FK, PROTECT); alterado_em: timestamptz auto; motivo: text. Índice pela oportunidade/data.
Atividade id, timestamps, is_active; tipo: varchar(20); titulo: varchar(200); descricao/resultado/proxima_acao: text; quatro FKs de contexto (nulas, CASCADE); responsavel: uuid (FK User, PROTECT); ocorrida_em: timestamptz; data_proxima_acao: timestamptz (nulo).
Tarefa id, timestamps, is_active; titulo: varchar(200); descricao: text; status: varchar(20)=pendente; prioridade: varchar(10)=media; prazo/concluida_em: timestamptz (nulos); responsavel: uuid (FK User, PROTECT); quatro FKs de contexto (nulas, CASCADE).
Nota id, timestamps, is_active; titulo: varchar(200); conteudo: text; quatro FKs de contexto (nulas, CASCADE); autor: uuid (FK User, PROTECT); privada: boolean=false.

Limites confirmados

Não existe company_id, isolamento multi-tenant, created_by/updated_by universal, deleted_at ou tabelas de campanhas, propostas, produtos, concorrentes e customer success no MVP. A documentação reflete o schema real observado, não o blueprint original.