docs: update all documentation and add AI tooling configs

- Rewrite README.md with current architecture, features and stack
- Update docs/API.md with all current endpoints (corporate, BI, client 360)
- Update docs/ARCHITECTURE.md with cache, modular queries, services, ETL
- Update docs/GUIA-USUARIO.md for all roles (admin, corporate, agente)
- Add docs/INDEX.md documentation index
- Add PROJETO.md comprehensive project reference
- Add BI-CCC-Implementation-Guide.md
- Include AI agent configs (.claude, .agents, .gemini, _bmad)
- Add netbird VPN configuration
- Add status report

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 13:29:03 -04:00
parent c5b377e788
commit 647cbec54f
3246 changed files with 479789 additions and 983 deletions

View File

@@ -1,10 +1,10 @@
# Arquitetura - BI Agentes
# Arquitetura BI-CCC
Documentacao tecnica da arquitetura do sistema BI Agentes.
Documentação técnica da arquitetura do sistema BI-CCC (Central Command Center).
## Visao Geral
## Visão Geral
O BI Agentes e uma aplicacao web monolitica construida com Node.js/Express que serve dashboards de BI para agentes de cambio. A arquitetura prioriza simplicidade, seguranca e isolamento de dados.
O BI-CCC é uma aplicação web monolítica construída com Node.js/Express que serve dashboards de BI para a operação de câmbio da CambioReal. A arquitetura prioriza simplicidade, segurança, isolamento de dados e performance via cache inteligente.
## Diagrama de Arquitetura
@@ -12,338 +12,233 @@ O BI Agentes e uma aplicacao web monolitica construida com Node.js/Express que s
INTERNET
┌───────────────────────────────────────────────────────────────────────────
SERVIDOR EXPRESS
(PORT 3080)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐
│ │ Static Session Auth Dashboard │ │
│ │ Files │ │ Middleware │ │ Middleware │ │ Generator │
│ │ /public │ │ (in-memory) │ requireAuth │ (HTML) │ │
└─────────────┘ └──────┬──────┘ └──────┬──────┘ └─────┬──────┘
│ │ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ REQUEST ROUTER │ │
│ │ │ │
│ │ GET /login ──────▶ login.html │ │
│ │ POST /login ─────▶ authenticate() ──▶ session.create() │ │
│ │ GET /logout ─────▶ session.destroy() │ │
│ │ GET /dashboard ──▶ requireAuth ──▶ fetchTransacoes() ──▶ HTML │ │
│ │ GET / ───────────▶ redirect /dashboard │ │
└────────────────────────────────────────────────────────────────────┘
│ │
└───────────────────────────────────────────────────────┼──────────────────┘
│ │
┌──────────────┘ └──────────────┐
┌───────────────────┐ ┌───────────────────┐
SQLite AWS RDS
(agentes.db) │ (cambio_db)
─────────────┐ │ │ ┌─────────────┐
│ │ agentes ││ │br_transac...│ │
│ │ - id │ │ │ │- id │ │
│ │ - email │ │ │- id_conta │ │
│ - senha_hash│ ││- amount_brl │ │
│ - agente_id │ │ │ │- amount_usd │ │
│ │ - nome │ │ - exchange...|
│ │ - ativo │ │ │- status │ │
│ └─────────────┘ │ │ └─────────────┘
│ LOCAL (WAL) │ │ ┌─────────────
WRITE + READ │pagamento_br │
───────────────────┘ │ │- id │
│ │- id_conta │ │
│ │- valor │
│ │- valor_sol │ │
│ │- cotacao │ │
│ └─────────────┘ │
│ │
│ REMOTE (MySQL)
│ READ-ONLY
└───────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
Docker Container (bi-ccc)
┌─────────────────────────────────────────────────────────────────┐
│ Express Server (PORT 3080) │
│ │
│ │ ┌──────────┐ ┌───────────┐ ┌───────────┐ ┌──────────────┐ │
│ │ │ Session │ │requireAuth│ │requireRole Static
│ │Middleware│─▶│ │─▶│ │─▶│ /public │ │
│ └──────────┘ └───────────┘ └───────────┘ └──────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐
│ │ Route Handlers │ │
│ │ │ │
│ │ │ /corporate ──▶ admin-dashboard.js ──▶ buildCorporateHTML│ │ │
│ │ │ /admin/bi ──▶ admin-bi.js ──▶ buildBiHTML │ │
│ │ │ /admin/cliente ▶ admin-cliente.js ──▶ buildClienteHTML │ │ │
│ │ │ /admin ──▶ admin-panel.js ──▶ buildPanelHTML │ │ │
│ │ │ /admin/home ─▶ admin-home.js ──▶ buildHomeHTML │ │
│ │ /admin/providers ▶ admin-providers ▶ buildProvidersHTML │ │
│ │ /dashboard ──▶ dashboard.js ──▶ buildDashHTML │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
┌─────────────┼─────────────┐
│ │ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌──────────────
cache.js │ │ services export/ │ │
(SWR cache) churn │ │ excel-export│ │
│ │ │ forecast │ │ │ │
─────────────┘ └──────────┘ └──────────────┘ │
│ │ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
src/queries/ │ │
bi.queries │ client.queries │ corporate.q │ │ │
│ │ payin.q │ payout.q │ provider.q │ │
│ │ compliance.q│ helpers.js │ │
│ └──────────────────────┬───────────────────────┘ │
│ │
│ └─────────────────────────┼────────────────────────────────────────
─────────────────────────┼───────────────────────────────────────┐
Netbird VPN daemon │ │
│ └─────────────────────────┼───────────────────────────────────────┘
└────────────────────────────┼──────────────────────────────────────────┘
┌─────────────┴─────────────┐
┌───────────────────┐ ┌───────────────────┐
│ SQLite AWS RDS
│ (agentes.db) │ │ (cambio_db)
LOCAL / R+W REMOTE / R.O. │
│ │ │ via Netbird VPN │
│ agentes (auth) │ │ │
└───────────────────┘ │ br_transaction │
│ pagamento_br │
│ conta │
│ ag_contas │
│ br_payment_methods│
│ br_cb_empresas │
│ br_cb_cobranca │
└───────────────────┘
```
## Componentes
### 1. Camada de Apresentacao
### 1. Camada de Apresentação
**Tecnologias:** HTML5, CSS3, Vanilla JavaScript, Chart.js
**Padrão:** Server-Side Rendering — cada página é um módulo em `src/` que exporta `buildXxxHTML(user)` retornando uma string HTML completa com CSS e JS inline.
| Arquivo | Responsabilidade |
|---------|------------------|
| `public/login.html` | Formulario de login estilizado |
| `src/dashboard.js` | Geracao dinamica do HTML do dashboard |
| Módulo | Página | Linhas |
|--------|--------|--------|
| `admin-bi.js` | BI Executive | ~2250 |
| `admin-cliente.js` | Client 360 | ~1400 |
| `admin-dashboard.js` | Corporate Dashboard | ~750 |
| `admin-home.js` | Daily Overview | ~510 |
| `admin-panel.js` | Gestão de Usuários | ~620 |
| `admin-providers.js` | Payment Providers | ~1070 |
| `dashboard.js` | Dashboard do Agente | ~1585 |
| `ui-template.js` | Header, footer, CSS, tema | ~600 |
**Caracteristicas:**
- Server-Side Rendering (SSR) - HTML gerado no backend
- Chart.js carregado via CDN (sem build step)
- CSS inline no dashboard para simplicidade
- Google Fonts Inter para tipografia
**Fluxo:**
1. Express recebe request → verifica auth/role
2. Chama `buildXxxHTML(user)` → retorna HTML string
3. Frontend faz `fetch()` para APIs de dados
4. JavaScript inline renderiza Chart.js e popula o DOM
### 2. Camada de Aplicacao
### 2. Sistema de Temas
**Tecnologias:** Node.js, Express.js
- **Dark Mode:** Estilo Bloomberg terminal — verde #00FF88, fontes monospace (SF Mono/Fira Code)
- **Light Mode:** Cores institucionais CambioReal — roxo #7600be, verde #2E7D32
- **Toggle:** Atributo `data-theme` no HTML, persistido no localStorage
- **Charts:** `getChartTheme()` retorna cores adaptadas ao tema ativo
- **CSS:** Variáveis CSS com breakpoints em 1200px, 900px, 768px, 480px
| Modulo | Responsabilidade |
### 3. Cache Layer
**Módulo:** `src/cache.js` — Cache em memória com padrão stale-while-revalidate.
| Dado | TTL | Auto-refresh |
|------|-----|-------------|
| KPIs | 5 min | Sim |
| Tendência 30d | 10 min | Sim |
| Top agentes | 10 min | Sim |
| Top clientes | 15 min | Não |
Dados "stale" são retornados imediatamente enquanto o refresh acontece em background.
### 4. Queries Modulares
**Diretório:** `src/queries/` — Queries SQL separadas por domínio.
| Módulo | Responsabilidade |
|--------|------------------|
| `server.js` | Entry point, rotas, middleware |
| `src/auth.js` | Autenticacao, bcrypt, sessoes |
| `src/queries.js` | Queries SQL, serializacao de dados |
| `bi.queries.js` | KPIs executivos, revenue analytics, cohort, strategic |
| `client.queries.js` | Profile, health score, churn risk, timeline |
| `corporate.queries.js` | KPIs corporate, tendências, top agentes |
| `payin.queries.js` | Transações BRL→USD |
| `payout.queries.js` | Pagamentos USD→BRL |
| `provider.queries.js` | Análise de provedores de pagamento |
| `compliance.queries.js` | Queries de compliance |
| `helpers.js` | Utilitários de query (formatação, cálculos) |
**Middleware Stack:**
```
Request
express.urlencoded() ← Parse form data
express.json() ← Parse JSON
express-session() ← Gerenciar sessao
requireAuth() ← Verificar autenticacao (rotas protegidas)
Route Handler
```
### 5. Serviços
### 3. Camada de Dados
| Módulo | Responsabilidade |
|--------|------------------|
| `services/churn-predictor.js` | Predição de churn baseada em recência, frequência, volume |
| `services/forecast.js` | Previsão de receita com tendência histórica |
#### SQLite (Local)
### 6. ETL & Data Quality
**Biblioteca:** better-sqlite3 (sincrono, WAL mode)
| Módulo | Responsabilidade |
|--------|------------------|
| `etl/daily-sync.js` | Sincronização diária de dados agregados |
| `etl/data-quality.js` | Validação e checagem de qualidade dos dados |
### 7. Alertas
| Módulo | Responsabilidade |
|--------|------------------|
| `alerts/alert-engine.js` | Motor de regras para disparar alertas |
| `alerts/channels.js` | Canais de notificação (email via nodemailer) |
### 8. Export
| Módulo | Responsabilidade |
|--------|------------------|
| `export/excel-export.js` | Exportação de dados para Excel (ExcelJS) |
## Banco de Dados
### MySQL RDS (`cambio_db`) — Transações
| Tabela | Descrição |
|--------|-----------|
| `br_transaction_to_usa` | Transações BRL→USD (amount_brl, amount_usd, exchange_rate, ptax, iof, status, cobranca_id) |
| `pagamento_br` | Pagamentos USD→BRL (valor, cotacao, ptax, valor_sol, tipo_envio, pgto, fee) |
| `conta` | Contas/clientes (id_conta, nome) |
| `ag_contas` | Mapeamento agente→conta (agente_id, conta_id) |
| `br_payment_methods` | Provedores de pagamento (id, provider) |
| `br_cb_empresas` | Merchants CambioCheckout (id, id_conta, nome_empresa, active) |
| `br_cb_cobranca` | Cobranças/links de pagamento (id, empresa_id) |
**Relação Merchant/Checkout:** `br_cb_empresas.id_conta` identifica o merchant. `br_cb_cobranca.empresa_id` liga ao merchant. `br_transaction_to_usa.cobranca_id` liga a transação à cobrança. O `id_conta` na transação é o **pagador** (cliente BR), não o merchant.
### SQLite Local (`data/agentes.db`) — Auth
```sql
CREATE TABLE agentes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT UNIQUE NOT NULL,
senha_hash TEXT NOT NULL,
agente_id INTEGER NOT NULL,
agente_id INTEGER,
nome TEXT NOT NULL,
role TEXT DEFAULT 'agente',
ativo INTEGER DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```
**Caracteristicas:**
- WAL mode para melhor concorrencia
- Arquivo em `data/agentes.db`
- Criado automaticamente no primeiro start
## Cálculo de Receita
#### MySQL (RDS)
**BRL→USD (CambioPay/CambioCheckout):**
```
receita = (amount_brl - fee_ajustado) / ptax - pfee - (amount_usd + bonus - taxa_cr)
```
Onde `fee_ajustado` depende do provider (ouribank/bs2 não descontam fee).
**Biblioteca:** mysql2/promise (pool de conexoes)
**Configuracao do Pool:**
```javascript
{
host: process.env.MYSQL_URL,
user: process.env.USER_MYSQL,
password: process.env.PW_MYSQL,
database: 'cambio_db',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
}
**USD→BRL:**
```
receita = ((ptax - cotacao) * valor) / ptax + fee
```
**Tabelas Consultadas:**
**Balance:** apenas `fee`.
| Tabela | Fluxo | Campos Principais |
|--------|-------|-------------------|
| `br_transaction_to_usa` | BRL→USD | amount_brl, amount_usd, exchange_rate, iof, ptax |
| `pagamento_br` | USD→BRL | valor, valor_sol, cotacao, ptax |
| `ag_contas` | Join | agente_id, conta_id |
| `conta` | Join | id_conta, nome |
## Segurança
## Fluxo de Dados
### Autenticacao
```
┌──────────┐ POST /login ┌──────────┐
│ Browser │ ─────────────────▶ │ Express │
│ │ email, senha │ │
└──────────┘ └────┬─────┘
┌────────────────┘
┌──────────────┐
│ SQLite │
│ SELECT WHERE │
│ email = ? │
└──────┬───────┘
┌──────────────┐
│ bcrypt │
│ compare │
└──────┬───────┘
┌───────┴───────┐
▼ ▼
[MATCH] [NO MATCH]
│ │
▼ ▼
session.agente redirect
= {...} /login?error=1
redirect
/dashboard
```
### Carregamento do Dashboard
```
┌──────────┐ GET /dashboard ┌──────────┐
│ Browser │ ─────────────────▶ │ Express │
│ (cookie) │ │ │
└──────────┘ └────┬─────┘
requireAuth()────┘
┌─────────────┴─────────────┐
▼ ▼
[NO SESSION] [HAS SESSION]
│ │
▼ ▼
redirect ┌─────────────────┐
/login │ fetchTransacoes │
│ (agente_id) │
└────────┬────────┘
┌─────────────────┘
┌──────────────┐
│ AWS RDS │
│ 2 queries: │
│ BRL→USD │
│ USD→BRL │
└──────┬───────┘
┌──────────────┐
│ serialize() │
│ merge + │
│ sort │
└──────┬───────┘
┌──────────────┐
│ buildHTML() │
│ KPIs + │
│ Charts + │
│ Table │
└──────┬───────┘
res.send(html)
```
## Seguranca
### Autenticacao
| Aspecto | Implementacao |
| Aspecto | Implementação |
|---------|---------------|
| Hash de senha | bcrypt, 10 salt rounds |
| Sessao | express-session, in-memory |
| Timeout | 8 horas (cookie maxAge) |
| Middleware | requireAuth em rotas protegidas |
### Protecao de Dados
| Aspecto | Implementacao |
|---------|---------------|
| Sessão | express-session, in-memory, 8h timeout |
| SQL Injection | Queries parametrizadas (?) |
| Isolamento | WHERE agente_id = ? em todas queries |
| RDS Access | Usuario read-only (sem INSERT/UPDATE/DELETE) |
| Isolamento | WHERE agente_id = ? em todas queries de agente |
| RDS Access | Usuário read-only (sem INSERT/UPDATE/DELETE) |
| VPN | Netbird — acesso ao RDS somente via rede privada |
### Recomendacoes para Producao
## Deploy
- [ ] Usar Redis para sessoes (em vez de in-memory)
- [ ] HTTPS obrigatorio (TLS)
- [ ] Helmet.js para headers de seguranca
- [ ] Rate limiting no login
- [ ] Logs de auditoria
**Docker Compose** com Netbird VPN integrado:
## Performance
1. `docker-entrypoint.sh` inicia Netbird VPN daemon
2. Aguarda conexão VPN (~10s)
3. Inicia `node server.js` na porta 3080
### Estrategias Atuais
- **Connection Pool**: 10 conexoes MySQL reutilizaveis
- **WAL Mode**: SQLite com Write-Ahead Logging
- **CDN**: Chart.js e fonts via CDN (cache do browser)
- **SSR**: HTML pre-renderizado (sem SPA overhead)
### Gargalos Potenciais
| Componente | Risco | Mitigacao |
|------------|-------|-----------|
| Sessoes in-memory | Perda em restart | Migrar para Redis |
| Queries RDS | Tabelas grandes | Adicionar indices, paginacao |
| HTML generation | Muitas transacoes | Paginacao server-side |
## Estrutura de Modulos
```
src/
├── auth.js # Autenticacao
│ ├── authenticate(email, senha)
│ └── requireAuth(req, res, next)
├── db-local.js # SQLite setup
│ └── initDB()
├── db-rds.js # MySQL pool
│ └── pool (export)
├── queries.js # Data access
│ ├── fetchTransacoes(agenteId)
│ └── serialize(rowsBrlUsd, rowsUsdBrl)
└── dashboard.js # View generation
└── buildHTML(data, agente)
```bash
docker compose build bi-ccc && docker compose down bi-ccc && docker compose up -d bi-ccc
```
## Dependencias
## Decisões de Arquitetura
| Pacote | Versao | Proposito |
|--------|--------|-----------|
| express | ^4.x | Framework web |
| express-session | ^1.x | Gerenciamento de sessao |
| better-sqlite3 | ^9.x | SQLite driver (sync) |
| mysql2 | ^3.x | MySQL driver (async) |
| bcrypt | ^5.x | Hash de senhas |
| dotenv | ^16.x | Variaveis de ambiente |
## Extensibilidade
### Adicionar Nova Feature
1. **Novo endpoint**: Adicionar rota em `server.js`
2. **Nova query**: Adicionar funcao em `src/queries.js`
3. **Nova UI**: Modificar `src/dashboard.js` ou criar novo modulo
### Adicionar Novo Fluxo de Transacao
1. Criar query em `src/queries.js`
2. Atualizar `serialize()` para incluir novo fluxo
3. Atualizar `buildHTML()` para exibir dados
## Decisoes de Arquitetura
| Decisao | Justificativa |
| Decisão | Justificativa |
|---------|---------------|
| Monolito | Simplicidade para equipe pequena |
| SSR | Sem necessidade de SPA, SEO nao relevante |
| SQLite para auth | Independencia do RDS, portabilidade |
| Vanilla JS | Sem build step, menor complexidade |
| better-sqlite3 | Sync API mais simples para auth |
| mysql2 | Pool de conexoes async para RDS |
| SSR com HTML inline | Sem build step, deploy simples |
| SQLite para auth | Independência do RDS, portabilidade |
| MySQL pool async | 10 conexões reutilizáveis para RDS |
| Cache SWR | Resposta rápida sem stale data prolongado |
| Queries modulares | Separação por domínio, manutenibilidade |
| Chart.js inline | Sem CDN, funciona offline via VPN |
| Netbird VPN | Acesso seguro ao RDS sem expor porta pública |