vendaweb-api/docs/database.md

265 lines
7.0 KiB
Markdown

# Banco de Dados - DRE Gerencial
## Visão Geral
O sistema utiliza PostgreSQL como banco de dados principal, com Drizzle ORM para type-safe database operations. A estrutura é baseada em views materializadas para performance otimizada.
## Configuração do Banco
### Variáveis de Ambiente
```env
POSTGRES_DB=dre_gerencial
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=sua_senha
```
### Conexão (src/db/index.ts)
```typescript
import 'dotenv/config';
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import * as schema from './schema';
const pool = new Pool({
database: process.env.POSTGRES_DB,
host: process.env.POSTGRES_HOST,
port: Number(process.env.POSTGRES_PORT),
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
});
const db = drizzle({
client: pool,
schema,
});
```
## Schema do Banco
### View Principal (src/db/schema.ts)
```typescript
export const view = pgView('view_dre_gerencial', {
codfilial: text(),
data_competencia: date(),
data_caixa: date(),
grupo: text(),
subgrupo: text(),
centro_custo: text(),
codigo_conta: integer(),
conta: text(),
valor: numeric(),
});
```
### Estrutura da View
A view `view_dre_gerencial` consolida dados de múltiplas tabelas para fornecer uma estrutura hierárquica otimizada:
| Campo | Tipo | Descrição |
|-------|------|-----------|
| `codfilial` | text | Código da filial |
| `data_competencia` | date | Data de competência do lançamento |
| `data_caixa` | date | Data de caixa |
| `grupo` | text | Descrição do grupo (ex: "01 - RECEITAS") |
| `subgrupo` | text | Descrição do subgrupo |
| `centro_custo` | text | Centro de custo |
| `codigo_conta` | integer | Código numérico da conta |
| `conta` | text | Descrição da conta |
| `valor` | numeric | Valor do lançamento |
## Tabelas Base (Inferidas)
### Tabela Principal: `fato_financeiro_analitico`
Baseada na API analítica, esta tabela contém os dados detalhados:
| Campo | Tipo | Descrição |
|-------|------|-----------|
| `id` | integer | ID único |
| `codfilial` | text | Código da filial |
| `recnum` | integer | Número do registro |
| `data_competencia` | date | Data de competência |
| `data_vencimento` | date | Data de vencimento |
| `data_pagamento` | date | Data de pagamento |
| `data_caixa` | date | Data de caixa |
| `codigo_conta` | text | Código da conta |
| `conta` | text | Descrição da conta |
| `codigo_centrocusto` | text | Código do centro de custo |
| `codigo_fornecedor` | text | Código do fornecedor |
| `nome_fornecedor` | text | Nome do fornecedor |
| `valor` | numeric | Valor do lançamento |
| `historico` | text | Histórico principal |
| `historico2` | text | Histórico secundário |
| `created_at` | timestamp | Data de criação |
| `updated_at` | timestamp | Data de atualização |
## Queries Principais
### 1. **Dados DRE Gerencial**
```sql
SELECT * FROM view_dre_gerencial
```
- **Uso**: Carregamento inicial da interface hierárquica
- **Performance**: Otimizada via view materializada
### 2. **Dados Analíticos com Filtros**
```sql
SELECT
ffa.codigo_fornecedor,
ffa.nome_fornecedor,
ffa.id,
ffa.codfilial,
ffa.recnum,
ffa.data_competencia,
ffa.data_vencimento,
ffa.data_pagamento,
ffa.data_caixa,
ffa.codigo_conta,
ffa.conta,
ffa.codigo_centrocusto,
ffa.valor,
ffa.historico,
ffa.historico2,
ffa.created_at,
ffa.updated_at
FROM fato_financeiro_analitico AS ffa
WHERE to_char(ffa.data_competencia, 'YYYY-MM') BETWEEN $1 AND $2
AND ffa.codigo_centrocusto = $3 -- Opcional
AND ffa.codigo_conta = $4 -- Opcional
```
### 3. **Query com Filtros de Grupo/Subgrupo**
```sql
SELECT ffa.*
FROM fato_financeiro_analitico AS ffa
WHERE EXISTS (
SELECT 1 FROM public.view_dre_gerencial AS dre
WHERE ffa.codigo_conta = dre.codigo_conta::text
AND ffa.codigo_centrocusto = dre.centro_custo
AND to_char(ffa.data_competencia, 'YYYY-MM') = to_char(dre.data_competencia, 'YYYY-MM')
AND SUBSTRING(dre.grupo FROM '^\\s*(\\d+)\\s*\\.') = $1
AND SUBSTRING(dre.subgrupo FROM '^\\s*(\\d+(?:\\.\\d+)+)\\s*-') = $2
)
AND to_char(ffa.data_competencia, 'YYYY-MM') BETWEEN $3 AND $4
```
## Índices Recomendados
### Índices para Performance
```sql
-- Índice para filtros por data
CREATE INDEX idx_fato_financeiro_data_competencia
ON fato_financeiro_analitico (data_competencia);
-- Índice para filtros por centro de custo
CREATE INDEX idx_fato_financeiro_centro_custo
ON fato_financeiro_analitico (codigo_centrocusto);
-- Índice para filtros por conta
CREATE INDEX idx_fato_financeiro_conta
ON fato_financeiro_analitico (codigo_conta);
-- Índice composto para queries analíticas
CREATE INDEX idx_fato_financeiro_analitico_composto
ON fato_financeiro_analitico (data_competencia, codigo_centrocusto, codigo_conta);
```
## Migrações e Versionamento
### Drizzle Kit Configuration
```typescript
// drizzle.config.ts
export default defineConfig({
out: './drizzle',
schema: './src/db/schema.ts',
dialect: 'postgresql',
dbCredentials: {
database: process.env.POSTGRES_DB || 'dre_gerencial',
host: process.env.POSTGRES_HOST || 'localhost',
port: Number(process.env.POSTGRES_PORT) || 5432,
user: process.env.POSTGRES_USER || 'postgres',
password: process.env.POSTGRES_PASSWORD || '',
},
});
```
### Comandos de Migração
```bash
# Gerar migração
npx drizzle-kit generate
# Aplicar migração
npx drizzle-kit migrate
# Visualizar schema
npx drizzle-kit studio
```
## Backup e Manutenção
### Backup Automático
```bash
# Backup diário
pg_dump -h localhost -U postgres -d dre_gerencial > backup_$(date +%Y%m%d).sql
# Restore
psql -h localhost -U postgres -d dre_gerencial < backup_20240101.sql
```
### Manutenção da View
```sql
-- Refresh da view materializada (se aplicável)
REFRESH MATERIALIZED VIEW view_dre_gerencial;
-- Análise de performance
ANALYZE fato_financeiro_analitico;
ANALYZE view_dre_gerencial;
```
## Monitoramento
### Queries de Monitoramento
```sql
-- Tamanho das tabelas
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
-- Queries lentas
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
```
## Troubleshooting
### Problemas Comuns
1. **Conexão Recusada**
- Verificar se PostgreSQL está rodando
- Validar credenciais de conexão
- Verificar firewall/portas
2. **Performance Lenta**
- Verificar índices existentes
- Analisar query execution plan
- Considerar particionamento por data
3. **Dados Inconsistentes**
- Verificar refresh da view
- Validar integridade referencial
- Executar VACUUM ANALYZE
## Próximos Passos
1. **Implementar Cache Redis** para queries frequentes
2. **Adicionar Particionamento** por data para tabelas grandes
3. **Implementar Replicação** para alta disponibilidade
4. **Adicionar Monitoramento** de performance em tempo real
5. **Implementar Backup Automático** com retenção configurável