401 lines
14 KiB
Markdown
401 lines
14 KiB
Markdown
# Schemas de Banco de Dados - Workspace
|
||
|
||
Este documento define os schemas de tabelas necessários para alimentar os módulos do Workspace: **Entradas Planejadas**, **Clientes**, **Despesas** e **Fornecedores**.
|
||
|
||
---
|
||
|
||
## Convenções
|
||
|
||
- **Tipos de Dados**:
|
||
- `INT`: Números inteiros
|
||
- `VARCHAR(n)`: Strings de tamanho variável (máximo n caracteres)
|
||
- `TEXT`: Textos longos sem limite definido
|
||
- `DECIMAL(p,s)`: Números decimais (p = precisão total, s = casas decimais)
|
||
- `DATE`: Data no formato YYYY-MM-DD
|
||
- `TIMESTAMP`: Data/hora com timezone
|
||
- `ENUM`: Valores pré-definidos
|
||
|
||
- **Constraints**:
|
||
- `PK`: Primary Key (Chave Primária)
|
||
- `FK`: Foreign Key (Chave Estrangeira)
|
||
- `NOT NULL`: Campo obrigatório
|
||
- `DEFAULT`: Valor padrão
|
||
- `AUTO_INCREMENT`: Incremento automático
|
||
|
||
- **Índices**: Criados para otimizar consultas frequentes
|
||
|
||
---
|
||
|
||
## 1. Tabela: `entradas_planejadas`
|
||
|
||
**Descrição**: Armazena estimativas de receitas planejadas (quotes/estimates) que podem ser convertidas em faturas.
|
||
|
||
### Estrutura
|
||
|
||
```sql
|
||
CREATE TABLE entradas_planejadas (
|
||
id VARCHAR(50) PRIMARY KEY COMMENT 'Identificador único (formato EST-000001)',
|
||
data_criacao DATE NOT NULL COMMENT 'Data de criação da estimativa',
|
||
data_estimativa DATE NOT NULL COMMENT 'Data da estimativa',
|
||
numero_referencia VARCHAR(50) COMMENT 'Número de referência externa',
|
||
cliente_id INT COMMENT 'ID do cliente (FK -> clientes.id)',
|
||
cliente_nome VARCHAR(255) COMMENT 'Nome do cliente (denormalizado para performance)',
|
||
vendedor VARCHAR(255) COMMENT 'Nome do vendedor responsável',
|
||
total DECIMAL(15,2) NOT NULL COMMENT 'Valor total da estimativa',
|
||
subtotal DECIMAL(15,2) NOT NULL COMMENT 'Subtotal antes de descontos',
|
||
desconto DECIMAL(15,2) DEFAULT 0 COMMENT 'Valor do desconto aplicado',
|
||
status ENUM('RASCUNHO', 'ENVIADA', 'APROVADA', 'REJEITADA', 'CONVERTIDA') DEFAULT 'RASCUNHO' COMMENT 'Status da estimativa',
|
||
observacoes TEXT COMMENT 'Observações gerais',
|
||
email_destinatario VARCHAR(255) COMMENT 'Email para envio da estimativa',
|
||
termos_condicoes TEXT COMMENT 'Termos e condições comerciais',
|
||
endereco_cobranca TEXT COMMENT 'Endereço completo de cobrança',
|
||
endereco_entrega TEXT COMMENT 'Endereço completo de entrega',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Data/hora de criação',
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Data/hora de atualização',
|
||
|
||
INDEX idx_cliente (cliente_id),
|
||
INDEX idx_status (status),
|
||
INDEX idx_data_estimativa (data_estimativa),
|
||
FOREIGN KEY (cliente_id) REFERENCES clientes(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
```
|
||
|
||
### Validações de Negócio
|
||
|
||
- `id` deve seguir o padrão `EST-{número com 6 dígitos}` (ex: EST-000001)
|
||
- `total` = `subtotal` - `desconto`
|
||
- `status` segue o fluxo: RASCUNHO → ENVIADA → APROVADA/REJEITADA → CONVERTIDA
|
||
- `data_estimativa` não pode ser anterior a `data_criacao`
|
||
|
||
---
|
||
|
||
## 2. Tabela: `entradas_planejadas_itens`
|
||
|
||
**Descrição**: Itens que compõem uma estimativa (produtos/serviços).
|
||
|
||
### Estrutura
|
||
|
||
```sql
|
||
CREATE TABLE entradas_planejadas_itens (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
entrada_planejada_id VARCHAR(50) NOT NULL COMMENT 'ID da estimativa (FK -> entradas_planejadas.id)',
|
||
item VARCHAR(255) NOT NULL COMMENT 'Descrição do item',
|
||
quantidade DECIMAL(10,2) DEFAULT 1 COMMENT 'Quantidade',
|
||
preco DECIMAL(15,2) NOT NULL COMMENT 'Preço unitário',
|
||
montante DECIMAL(15,2) NOT NULL COMMENT 'Quantidade × Preço',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_entrada (entrada_planejada_id),
|
||
FOREIGN KEY (entrada_planejada_id) REFERENCES entradas_planejadas(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
```
|
||
|
||
### Validações de Negócio
|
||
|
||
- `montante` = `quantidade` × `preco`
|
||
- `quantidade` > 0
|
||
- `preco` >= 0
|
||
|
||
---
|
||
|
||
## 3. Tabela: `clientes`
|
||
|
||
**Descrição**: Cadastro de clientes da empresa.
|
||
|
||
### Estrutura
|
||
|
||
```sql
|
||
CREATE TABLE clientes (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
nome VARCHAR(255) NOT NULL COMMENT 'Nome completo ou razão social',
|
||
nome_exibicao VARCHAR(255) COMMENT 'Nome para exibição (fantasia)',
|
||
email VARCHAR(255) COMMENT 'Email de contato principal',
|
||
telefone VARCHAR(50) COMMENT 'Telefone de contato',
|
||
cpf_cnpj VARCHAR(20) COMMENT 'CPF ou CNPJ (sem formatação)',
|
||
tipo_pessoa ENUM('FISICA', 'JURIDICA') NOT NULL COMMENT 'Tipo de pessoa',
|
||
status_serv ENUM('Ativo', 'Inativo') DEFAULT 'Ativo' COMMENT 'Status do cliente',
|
||
caixinha VARCHAR(50) COMMENT 'ID da caixinha financeira associada',
|
||
endereco VARCHAR(255) COMMENT 'Logradouro',
|
||
bairro VARCHAR(100) COMMENT 'Bairro',
|
||
cidade VARCHAR(100) COMMENT 'Cidade',
|
||
uf CHAR(2) COMMENT 'Estado (UF)',
|
||
cep VARCHAR(20) COMMENT 'CEP',
|
||
dominio VARCHAR(255) COMMENT 'Domínio do site (se aplicável)',
|
||
data_vencimento INT DEFAULT 30 COMMENT 'Dias para vencimento padrão',
|
||
obs TEXT COMMENT 'Observações gerais',
|
||
valor_servico DECIMAL(15,2) DEFAULT 0 COMMENT 'Valor total de serviços contratados',
|
||
contas_receber DECIMAL(15,2) DEFAULT 0 COMMENT 'Total de contas a receber',
|
||
creditos_nao_utilizados DECIMAL(15,2) DEFAULT 0 COMMENT 'Créditos não utilizados',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
UNIQUE KEY uk_cpf_cnpj_tipo (cpf_cnpj, tipo_pessoa),
|
||
INDEX idx_email (email),
|
||
INDEX idx_status (status_serv),
|
||
INDEX idx_cidade (cidade),
|
||
INDEX idx_uf (uf)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
```
|
||
|
||
### Validações de Negócio
|
||
|
||
- `cpf_cnpj` deve ser único por `tipo_pessoa`
|
||
- `email` deve ser válido (validação no frontend/backend)
|
||
- `uf` deve ser um código válido de 2 caracteres (ex: SP, RJ)
|
||
- `data_vencimento` deve ser um número positivo
|
||
- Valores monetários não podem ser negativos
|
||
|
||
---
|
||
|
||
## 4. Tabela: `despesas`
|
||
|
||
**Descrição**: Registro de despesas da empresa com lançamentos contábeis.
|
||
|
||
### Estrutura
|
||
|
||
```sql
|
||
CREATE TABLE despesas (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
data DATE NOT NULL COMMENT 'Data da despesa',
|
||
conta_despesa VARCHAR(255) NOT NULL COMMENT 'Nome da conta de despesa',
|
||
numero_referencia VARCHAR(50) COMMENT 'Número de referência externa',
|
||
fornecedor_id INT COMMENT 'ID do fornecedor (FK -> fornecedores.id)',
|
||
nome_fornecedor VARCHAR(255) COMMENT 'Nome do fornecedor (denormalizado)',
|
||
pago_por_meio_de VARCHAR(255) COMMENT 'Método de pagamento (ex: Transferência Bancária, Cartão de Crédito, Boleto)',
|
||
cliente_id INT COMMENT 'ID do cliente (se despesa faturável) (FK -> clientes.id)',
|
||
nome_cliente VARCHAR(255) COMMENT 'Nome do cliente (denormalizado)',
|
||
status ENUM('FATURÁVEL', 'NÃO FATURÁVEL', 'PENDENTE', 'PAGO') DEFAULT 'PENDENTE' COMMENT 'Status da despesa',
|
||
montante DECIMAL(15,2) NOT NULL COMMENT 'Valor da despesa',
|
||
categoria VARCHAR(100) COMMENT 'Categoria da despesa (ex: TI, Operacional, Serviços, Marketing)',
|
||
descricao TEXT COMMENT 'Descrição detalhada',
|
||
metodo_pagamento VARCHAR(255) COMMENT 'Método de pagamento utilizado',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_data (data),
|
||
INDEX idx_status (status),
|
||
INDEX idx_fornecedor (fornecedor_id),
|
||
INDEX idx_cliente (cliente_id),
|
||
INDEX idx_categoria (categoria),
|
||
FOREIGN KEY (fornecedor_id) REFERENCES fornecedores(id) ON DELETE RESTRICT,
|
||
FOREIGN KEY (cliente_id) REFERENCES clientes(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
```
|
||
|
||
### Validações de Negócio
|
||
|
||
- `montante` > 0
|
||
- `status` segue o fluxo: PENDENTE → PAGO (ou FATURÁVEL → PAGO)
|
||
- Se `status` = 'FATURÁVEL', então `cliente_id` deve ser preenchido
|
||
- `data` não pode ser futura (ou permitir conforme regra de negócio)
|
||
|
||
---
|
||
|
||
## 5. Tabela: `despesas_diario`
|
||
|
||
**Descrição**: Lançamentos contábeis (diário) de cada despesa (débito e crédito).
|
||
|
||
### Estrutura
|
||
|
||
```sql
|
||
CREATE TABLE despesas_diario (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
despesa_id INT NOT NULL COMMENT 'ID da despesa (FK -> despesas.id)',
|
||
conta VARCHAR(255) NOT NULL COMMENT 'Nome da conta contábil',
|
||
debito DECIMAL(15,2) DEFAULT 0 COMMENT 'Valor débito',
|
||
credito DECIMAL(15,2) DEFAULT 0 COMMENT 'Valor crédito',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_despesa (despesa_id),
|
||
FOREIGN KEY (despesa_id) REFERENCES despesas(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
```
|
||
|
||
### Validações de Negócio
|
||
|
||
- Para cada despesa, a soma de `debito` deve ser igual à soma de `credito` (partidas dobradas)
|
||
- `debito` >= 0 e `credito` >= 0
|
||
- Pelo menos um dos campos (`debito` ou `credito`) deve ser > 0
|
||
|
||
---
|
||
|
||
## 6. Tabela: `fornecedores`
|
||
|
||
**Descrição**: Cadastro de fornecedores da empresa.
|
||
|
||
### Estrutura
|
||
|
||
```sql
|
||
CREATE TABLE fornecedores (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
nome VARCHAR(255) NOT NULL COMMENT 'Nome completo ou razão social',
|
||
nome_exibicao VARCHAR(255) COMMENT 'Nome para exibição (fantasia)',
|
||
email VARCHAR(255) COMMENT 'Email de contato',
|
||
telefone VARCHAR(50) COMMENT 'Telefone de contato',
|
||
cpf_cnpj VARCHAR(20) COMMENT 'CPF ou CNPJ (sem formatação)',
|
||
tipo_pessoa ENUM('FISICA', 'JURIDICA') NOT NULL COMMENT 'Tipo de pessoa',
|
||
status ENUM('Ativo', 'Inativo') DEFAULT 'Ativo' COMMENT 'Status do fornecedor',
|
||
endereco VARCHAR(255) COMMENT 'Logradouro',
|
||
bairro VARCHAR(100) COMMENT 'Bairro',
|
||
cidade VARCHAR(100) COMMENT 'Cidade',
|
||
uf CHAR(2) COMMENT 'Estado (UF)',
|
||
cep VARCHAR(20) COMMENT 'CEP',
|
||
moeda_padrao CHAR(3) DEFAULT 'BRL' COMMENT 'Moeda padrão (ISO 4217)',
|
||
periodo_vencimento VARCHAR(100) DEFAULT 'Pagar no recebimento' COMMENT 'Período de vencimento padrão',
|
||
obs TEXT COMMENT 'Observações gerais',
|
||
contas_pagar DECIMAL(15,2) DEFAULT 0 COMMENT 'Total de contas a pagar',
|
||
creditos_nao_utilizados DECIMAL(15,2) DEFAULT 0 COMMENT 'Créditos não utilizados',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
UNIQUE KEY uk_cpf_cnpj_tipo (cpf_cnpj, tipo_pessoa),
|
||
INDEX idx_email (email),
|
||
INDEX idx_status (status),
|
||
INDEX idx_cidade (cidade),
|
||
INDEX idx_uf (uf)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
```
|
||
|
||
### Validações de Negócio
|
||
|
||
- `cpf_cnpj` deve ser único por `tipo_pessoa`
|
||
- `email` deve ser válido (validação no frontend/backend)
|
||
- `uf` deve ser um código válido de 2 caracteres
|
||
- `moeda_padrao` deve ser um código ISO 4217 válido (ex: BRL, USD, EUR)
|
||
- Valores monetários não podem ser negativos
|
||
|
||
---
|
||
|
||
## Relacionamentos
|
||
|
||
### Diagrama de Relacionamentos
|
||
|
||
```
|
||
clientes (1) ──< (N) entradas_planejadas
|
||
clientes (1) ──< (N) despesas (quando faturável)
|
||
fornecedores (1) ──< (N) despesas
|
||
despesas (1) ──< (N) despesas_diario
|
||
entradas_planejadas (1) ──< (N) entradas_planejadas_itens
|
||
```
|
||
|
||
### Chaves Estrangeiras
|
||
|
||
1. `entradas_planejadas.cliente_id` → `clientes.id`
|
||
2. `despesas.fornecedor_id` → `fornecedores.id`
|
||
3. `despesas.cliente_id` → `clientes.id` (opcional)
|
||
4. `despesas_diario.despesa_id` → `despesas.id`
|
||
5. `entradas_planejadas_itens.entrada_planejada_id` → `entradas_planejadas.id`
|
||
|
||
### Políticas de Exclusão
|
||
|
||
- **ON DELETE RESTRICT**: Impede exclusão se houver registros relacionados (clientes, fornecedores, despesas)
|
||
- **ON DELETE CASCADE**: Exclui registros relacionados automaticamente (itens de estimativa, lançamentos de diário)
|
||
|
||
---
|
||
|
||
## Índices para Performance
|
||
|
||
### Índices Criados
|
||
|
||
1. **entradas_planejadas**:
|
||
- `idx_cliente`: Busca por cliente
|
||
- `idx_status`: Filtro por status
|
||
- `idx_data_estimativa`: Ordenação por data
|
||
|
||
2. **clientes**:
|
||
- `uk_cpf_cnpj_tipo`: Unicidade de CPF/CNPJ
|
||
- `idx_email`: Busca por email
|
||
- `idx_status`: Filtro por status
|
||
- `idx_cidade`, `idx_uf`: Filtros geográficos
|
||
|
||
3. **despesas**:
|
||
- `idx_data`: Filtro e ordenação por data
|
||
- `idx_status`: Filtro por status
|
||
- `idx_fornecedor`: Busca por fornecedor
|
||
- `idx_cliente`: Busca por cliente (despesas faturáveis)
|
||
- `idx_categoria`: Filtro por categoria
|
||
|
||
4. **fornecedores**:
|
||
- `uk_cpf_cnpj_tipo`: Unicidade de CPF/CNPJ
|
||
- `idx_email`: Busca por email
|
||
- `idx_status`: Filtro por status
|
||
- `idx_cidade`, `idx_uf`: Filtros geográficos
|
||
|
||
---
|
||
|
||
## Exemplos de Consultas
|
||
|
||
### Buscar estimativas de um cliente
|
||
|
||
```sql
|
||
SELECT
|
||
ep.*,
|
||
COUNT(epi.id) as total_itens,
|
||
SUM(epi.montante) as total_calculado
|
||
FROM entradas_planejadas ep
|
||
LEFT JOIN entradas_planejadas_itens epi ON ep.id = epi.entrada_planejada_id
|
||
WHERE ep.cliente_id = ?
|
||
GROUP BY ep.id;
|
||
```
|
||
|
||
### Buscar despesas por fornecedor com total
|
||
|
||
```sql
|
||
SELECT
|
||
d.*,
|
||
f.nome as fornecedor_nome,
|
||
SUM(dd.debito) as total_debito,
|
||
SUM(dd.credito) as total_credito
|
||
FROM despesas d
|
||
LEFT JOIN fornecedores f ON d.fornecedor_id = f.id
|
||
LEFT JOIN despesas_diario dd ON d.id = dd.despesa_id
|
||
WHERE d.fornecedor_id = ?
|
||
GROUP BY d.id;
|
||
```
|
||
|
||
### KPIs de receitas
|
||
|
||
```sql
|
||
SELECT
|
||
COUNT(*) as total_estimativas,
|
||
SUM(CASE WHEN status = 'APROVADA' THEN total ELSE 0 END) as total_aprovado,
|
||
SUM(CASE WHEN status = 'ENVIADA' THEN total ELSE 0 END) as total_enviado,
|
||
SUM(CASE WHEN status = 'RASCUNHO' THEN total ELSE 0 END) as total_rascunho
|
||
FROM entradas_planejadas
|
||
WHERE data_estimativa BETWEEN ? AND ?;
|
||
```
|
||
|
||
---
|
||
|
||
## Migração de Dados
|
||
|
||
### Do Mock para Banco de Dados
|
||
|
||
Os dados atualmente mockados nos hooks devem ser migrados seguindo este mapeamento:
|
||
|
||
1. **MOCK_CLIENTS** → `clientes`
|
||
2. **MOCK_ENTRADAS** → `entradas_planejadas` + `entradas_planejadas_itens`
|
||
3. **MOCK_DESPESAS** → `despesas` + `despesas_diario`
|
||
4. **MOCK_FORNECEDORES** → `fornecedores`
|
||
|
||
### Scripts de Migração
|
||
|
||
Scripts SQL devem ser criados para:
|
||
- Criação das tabelas
|
||
- Inserção de dados iniciais (se necessário)
|
||
- Migração de dados existentes (se houver)
|
||
|
||
---
|
||
|
||
## Observações Finais
|
||
|
||
- Todos os valores monetários utilizam `DECIMAL(15,2)` para garantir precisão
|
||
- Timestamps são gerenciados automaticamente pelo banco
|
||
- Campos denormalizados (`nome_cliente`, `nome_fornecedor`) são mantidos para performance
|
||
- Validações de negócio devem ser implementadas tanto no banco (triggers/constraints) quanto no backend (validações de aplicação)
|
||
|
||
---
|
||
|
||
*Documentação mantida pelo Documentation Agent. Última atualização: 2026-01-24*
|