Files
bi-agents/docs/ARCHITECTURE.md
root 96222aa6a2 chore: adiciona Docker, scripts e documentacao
- Adiciona Dockerfile e docker-compose para containerizacao
- Adiciona docker-entrypoint.sh com inicializacao
- Adiciona scripts/seed-admin.js para criar admin inicial
- Adiciona docs/ com logos originais CambioReal
- Atualiza README.md com instrucoes de uso
- Atualiza queries.js com metricas de portfólio

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 13:20:15 -05:00

14 KiB

Arquitetura - BI Agentes

Documentacao tecnica da arquitetura do sistema BI Agentes.

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

Diagrama de Arquitetura

                                    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       │
                                                          └───────────────────┘

Componentes

1. Camada de Apresentacao

Tecnologias: HTML5, CSS3, Vanilla JavaScript, Chart.js

Arquivo Responsabilidade
public/login.html Formulario de login estilizado
src/dashboard.js Geracao dinamica do HTML do dashboard

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

2. Camada de Aplicacao

Tecnologias: Node.js, Express.js

Modulo Responsabilidade
server.js Entry point, rotas, middleware
src/auth.js Autenticacao, bcrypt, sessoes
src/queries.js Queries SQL, serializacao de dados

Middleware Stack:

Request
   │
   ▼
express.urlencoded()     ← Parse form data
   │
   ▼
express.json()           ← Parse JSON
   │
   ▼
express-session()        ← Gerenciar sessao
   │
   ▼
requireAuth()            ← Verificar autenticacao (rotas protegidas)
   │
   ▼
Route Handler

3. Camada de Dados

SQLite (Local)

Biblioteca: better-sqlite3 (sincrono, WAL mode)

CREATE TABLE agentes (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  email TEXT UNIQUE NOT NULL,
  senha_hash TEXT NOT NULL,
  agente_id INTEGER NOT NULL,
  nome TEXT NOT NULL,
  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

MySQL (RDS)

Biblioteca: mysql2/promise (pool de conexoes)

Configuracao do Pool:

{
  host: process.env.MYSQL_URL,
  user: process.env.USER_MYSQL,
  password: process.env.PW_MYSQL,
  database: 'cambio_db',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
}

Tabelas Consultadas:

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

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
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
SQL Injection Queries parametrizadas (?)
Isolamento WHERE agente_id = ? em todas queries
RDS Access Usuario read-only (sem INSERT/UPDATE/DELETE)

Recomendacoes para Producao

  • 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

Performance

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)

Dependencias

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