# Arquitetura — BI-CCC

Documentação técnica da arquitetura do sistema BI-CCC (Central Command Center).

## Visão Geral

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

```
                                    INTERNET
                                        │
                                        ▼
┌──────────────────────────────────────────────────────────────────────┐
│                         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 Apresentação

**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.

| 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 |

**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. Sistema de Temas

- **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

### 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 |
|--------|------------------|
| `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) |

### 5. Serviços

| 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 |

### 6. ETL & Data Quality

| 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,
  nome TEXT NOT NULL,
  role TEXT DEFAULT 'agente',
  ativo INTEGER DEFAULT 1,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```

## Cálculo de Receita

**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).

**USD→BRL:**
```
receita = ((ptax - cotacao) * valor) / ptax + fee
```

**Balance:** apenas `fee`.

## Segurança

| Aspecto | Implementação |
|---------|---------------|
| Hash de senha | bcrypt, 10 salt rounds |
| Sessão | express-session, in-memory, 8h timeout |
| SQL Injection | Queries parametrizadas (?) |
| 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 |

## Deploy

**Docker Compose** com Netbird VPN integrado:

1. `docker-entrypoint.sh` inicia Netbird VPN daemon
2. Aguarda conexão VPN (~10s)
3. Inicia `node server.js` na porta 3080

```bash
docker compose build bi-ccc && docker compose down bi-ccc && docker compose up -d bi-ccc
```

## Decisões de Arquitetura

| Decisão | Justificativa |
|---------|---------------|
| Monolito | Simplicidade para equipe pequena |
| 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 |
