Plano de ImplementaΓ§Γ£o: MetaSet no ArcadiaSuite (Atualizado - 07/04/2026) πŸ“Š VisΓ£o Geral da Arquitetura Atual β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ARCADIA KERNEL (5001) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Dashboard β”‚ β”‚ Process β”‚ β”‚ Health β”‚ β”‚ LogAggregator β”‚ β”‚ β”‚ β”‚ (Web UI) β”‚ β”‚ Manager β”‚ β”‚ Monitor β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Service Registry β”‚ β”‚ β”‚ β”‚ (services.json) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”΄β”€β”€β” β”Œβ”€β”€β”΄β”€β”€β” β”Œβ”€β”€β”΄β”€β”€β” β”‚ β”‚ β”‚9001 β”‚ β”‚9002 β”‚ β”‚9003 β”‚ + NOVO: 8004 β”‚ β”‚ β”‚Comm β”‚ β”‚Core β”‚ β”‚Workerβ”‚ + NOVO: 8100 β”‚ β”‚ β”‚Whatsβ”‚ β”‚ API β”‚ β”‚Queue β”‚ (MetaSet) β”‚ β”‚ β””β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ πŸ†• SERVIΓ‡OS BI: β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ 8004 β”‚ β”‚ 8100 β”‚ β”‚ 8200 β”‚ β”‚ β”‚ β”‚ BI-API │──│ MetaSet β”‚ β”‚ FDB-Bridge β”‚ β”‚ β”‚ β”‚ (Node.js) β”‚ β”‚ (Python) β”‚ β”‚ (Python) β”‚ β”‚ β”‚ β”‚ Gateway β”‚ β”‚ Superset β”‚ β”‚ Firebird β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PostgreSQL 16 β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ arcadia_db β”‚ β”‚ β”‚ β”‚ metaset_db β”‚ β”‚ βœ… Schema criado e migrado β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ πŸ”§ ConfiguraΓ§Γ£o dos ServiΓ§os (services.json) { "services": [ { "id": "communication", "name": "Communication Service", "type": "node", "command": "node", "args": ["server/communication/index.js"], "cwd": ".", "port": 9001, "autoStart": true, "healthCheck": { "path": "/health", "interval": 30000, "timeout": 5000, "retries": 3 }, "maxRestarts": 5 }, { "id": "core-api", "name": "Core API", "type": "node", "command": "node", "args": ["server/core/index.js"], "cwd": ".", "port": 9002, "autoStart": true, "healthCheck": { "path": "/health", "interval": 30000, "timeout": 5000, "retries": 3 }, "maxRestarts": 5 }, { "id": "bi-api", "name": "BI API Gateway", "type": "node", "command": "node", "args": ["server/bi/index.js"], "cwd": ".", "port": 8004, "autoStart": true, "env": { "METASET_PORT": "8100", "METASET_HOST": "127.0.0.1", "FDB_BRIDGE_PORT": "8200" }, "healthCheck": { "path": "/bi/health", "interval": 30000, "timeout": 5000, "retries": 3 }, "maxRestarts": 5, "description": "Gateway de BI com proxy para MetaSet e FDB-Bridge" }, { "id": "metaset", "name": "MetaSet BI", "type": "python", "command": "python", "args": ["server/bi/metaset/run.py", "--port=8100", "--host=127.0.0.1"], "cwd": ".", "port": 8100, "autoStart": false, "env": { "PYTHONPATH": "server/bi/metaset", "FLASK_ENV": "production", "SUPERSET_CONFIG_PATH": "server/bi/metaset/superset_config.py", "SUPERSET_SECRET_KEY": "${SUPERSET_SECRET_KEY}" }, "healthCheck": { "path": "/health", "interval": 30000, "timeout": 10000, "retries": 3 }, "maxRestarts": 3, "description": "Apache Superset rebrandado como MetaSet (Docker-managed)" }, { "id": "fdb-bridge", "name": "FDB Bridge", "type": "python", "command": "python", "args": ["server/bi/fdb-bridge/main.py", "--port=8200"], "cwd": ".", "port": 8200, "autoStart": false, "env": { "PYTHONPATH": "server/bi/fdb-bridge", "FDB_HOST": "${FDB_HOST}", "FDB_PORT": "${FDB_PORT:-3050}" }, "healthCheck": { "path": "/health", "interval": 60000, "timeout": 5000, "retries": 3 }, "maxRestarts": 3, "description": "Conector Firebird para sincronizaΓ§Γ£o de dados (Docker-managed)" } ] } πŸ—οΈ Estrutura de DiretΓ³rios Final arcadiasuite/ β”œβ”€β”€ server/ β”‚ β”œβ”€β”€ kernel/ # βœ… Kernel finalizado β”‚ β”‚ β”œβ”€β”€ core/ β”‚ β”‚ β”‚ β”œβ”€β”€ ProcessManager.ts # βœ… Suporta 'python' e 'node' β”‚ β”‚ β”‚ β”œβ”€β”€ HealthMonitor.ts β”‚ β”‚ β”‚ └── LogAggregator.ts β”‚ β”‚ β”œβ”€β”€ dashboard/ # Dashboard Web UI (porta 5001) β”‚ β”‚ β”œβ”€β”€ config/ β”‚ β”‚ β”‚ └── services.json # βœ… ConfiguraΓ§Γ£o dos serviΓ§os β”‚ β”‚ └── index.ts β”‚ β”‚ β”‚ β”œβ”€β”€ bi/ # πŸ†• MΓ“DULO BI COMPLETO β”‚ β”‚ β”œβ”€β”€ index.ts # BI-API Gateway (porta 8004) β”‚ β”‚ β”œβ”€β”€ routes/ β”‚ β”‚ β”‚ β”œβ”€β”€ query.ts # Queries nativas Drizzle β”‚ β”‚ β”‚ β”œβ”€β”€ export.ts # ExportaΓ§Γ£o PDF/Word β”‚ β”‚ β”‚ └── sync.ts # SincronizaΓ§Γ£o FDB β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ metaset/ # πŸ†• METASET (Superset) β”‚ β”‚ β”‚ β”œβ”€β”€ run.py # Entry point Python β”‚ β”‚ β”‚ β”œβ”€β”€ superset_config.py # ConfiguraΓ§Γ£o Arcadia β”‚ β”‚ β”‚ β”œβ”€β”€ security_manager.py # ArcadiaSecurityManager β”‚ β”‚ β”‚ β”œβ”€β”€ requirements.txt # DependΓͺncias Python β”‚ β”‚ β”‚ β”œβ”€β”€ Dockerfile # Multi-stage build β”‚ β”‚ β”‚ β”œβ”€β”€ init.sh # Container init script β”‚ β”‚ β”‚ β”œβ”€β”€ branding/ # 🎨 Assets MetaSet β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ metaset-logo-horiz.png β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ metaset-icon.png β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ favicon-16x16.png β”‚ β”‚ β”‚ β”‚ └── favicon-32x32.png β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── superset-src/ # Fork Apache Superset 4.1.0 β”‚ β”‚ β”‚ β”œβ”€β”€ superset-frontend/ # βœ… Rebuild com branding MetaSet β”‚ β”‚ β”‚ β”‚ └── src/ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ features/home/RightMenu.tsx # βœ… Textos atualizados β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ components/ErrorMessage/OAuth2RedirectMessage.tsx β”‚ β”‚ β”‚ β”‚ └── pages/... # βœ… TraduΓ§Γ΅es atualizadas β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ superset/ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ config.py # βœ… APP_NAME = "MetaSet" β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ constants.py # βœ… USER_AGENT = "MetaSet" β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ cli/ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ templates/ # βœ… HTML templates atualizados β”‚ β”‚ β”‚ β”‚ └── translations/ # βœ… TraduΓ§Γ΅es en/pt_BR β”‚ β”‚ β”‚ └── ... β”‚ β”‚ β”‚ β”‚ β”‚ └── fdb-bridge/ # πŸ†• FIREBIRD CONNECTOR (skeleton) β”‚ β”‚ β”œβ”€β”€ main.py # ServiΓ§o Python porta 8200 β”‚ β”‚ β”œβ”€β”€ sync.py # LΓ³gica de sincronizaΓ§Γ£o β”‚ β”‚ β”œβ”€β”€ models.py # Modelos SQLAlchemy β”‚ β”‚ └── requirements.txt β”‚ β”‚ β”‚ └── ... (outros serviΓ§os) β”‚ β”œβ”€β”€ client/ β”‚ └── src/ β”‚ └── pages/ β”‚ └── bi/ # πŸ†• FRONTEND BI β”‚ β”œβ”€β”€ index.tsx # Dashboard BI Arcadia β”‚ β”œβ”€β”€ metaset/ # Embed MetaSet β”‚ β”‚ β”œβ”€β”€ Dashboard.tsx β”‚ β”‚ β”œβ”€β”€ SQLLab.tsx β”‚ β”‚ └── Explore.tsx β”‚ └── components/ β”‚ β”œβ”€β”€ QueryBuilder.tsx β”‚ β”œβ”€β”€ ExportButton.tsx β”‚ └── FDBSyncStatus.tsx β”‚ └── branding/ # πŸ†• ASSETS COMPARTILHADOS β”œβ”€β”€ logos/ β”‚ β”œβ”€β”€ arcadia-suite-logo.svg β”‚ β”œβ”€β”€ arcadia-suite-logo-horiz.svg β”‚ β”œβ”€β”€ metaset-logo.svg β”‚ └── metaset-icon.svg β”œβ”€β”€ colors/ β”‚ └── arcadia-palette.json └── fonts/ └── Inter-Variable.ttf πŸ” Arquitetura de SeguranΓ§a & Multi-tenancy Fluxo de AutenticaΓ§Γ£o β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Cliente │────▢│ Arcadia │────▢│ BI-API │────▢│ MetaSet β”‚ β”‚ (React) β”‚ β”‚ Login β”‚ β”‚ (8004) β”‚ β”‚ (8100) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ Headers: β”‚ SET LOCAL β”‚ X-Tenant-ID: 123 β”‚ app.current_tenant β”‚ X-User-Role: admin β”‚ = 123; β”‚ Authorization: JWT β”‚ β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ RLS Check β”‚ β”‚ PostgreSQL β”‚ β”‚ Middleware β”‚ β”‚ (RLS) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ArcadiaSecurityManager (server/bi/metaset/security_manager.py) βœ… CORRIGIDO """ Security Manager integrado ao Arcadia Kernel - Extrai tenant e usuΓ‘rio do token JWT - Aplica RLS automaticamente - Sincroniza roles com ArcadiaSuite - Preserva comportamento padrΓ£o do Superset (chama super().before_request()) """ from superset.security import SupersetSecurityManager from flask import g, request, current_app from sqlalchemy import text import jwt import logging logger = logging.getLogger(__name__) class ArcadiaSecurityManager(SupersetSecurityManager): ROLE_MAPPING = { 'superadmin': 'Admin', 'admin': 'Alpha', 'analyst': 'Gamma', 'viewer': 'Public', } def before_request(self): """Executado antes de cada requisiΓ§Γ£o - preserva comportamento padrΓ£o""" super().before_request() # ← CRÍTICO: preserva autenticaΓ§Γ£o padrΓ£o auth_header = request.headers.get('Authorization', '') if not auth_header.startswith('Bearer '): return token = auth_header.replace('Bearer ', '') try: payload = jwt.decode( token, current_app.config.get('SECRET_KEY', 'default-key'), algorithms=['HS256'] ) g.tenant_id = payload.get('tenant_id') g.user_id = payload.get('sub') g.user_role = payload.get('role', 'viewer') g.user_email = payload.get('email') if g.tenant_id: try: from superset import db db.session.execute( text(f"SET LOCAL app.current_tenant = {g.tenant_id}") ) except Exception as e: logger.warning(f"Erro ao aplicar RLS: {e}") except jwt.ExpiredSignatureError: logger.warning("JWT token expirado") except jwt.InvalidTokenError: logger.warning("JWT token invΓ‘lido") except Exception as e: logger.warning(f"Erro ao processar JWT: {e}") 🐍 CΓ³digo dos ServiΓ§os Python 1. MetaSet Entry Point (server/bi/metaset/run.py) """ MetaSet - ServiΓ§o Apache Superset integrado ao Arcadia Kernel Porta: 8100 (Docker container) Gunicorn: 2 workers, gthread, 120s timeout """ import os import sys import logging from pathlib import Path logging.basicConfig( level=logging.INFO, format='[MetaSet] %(levelname)s: %(message)s', handlers=[logging.StreamHandler(sys.stdout)] ) logger = logging.getLogger(__name__) def create_app(): """Criar aplicaΓ§Γ£o Flask do Superset com endpoints customizados""" from superset import create_app as create_superset_app from datetime import datetime app = create_superset_app() @app.route('/health') def health_check(): return {'status': 'healthy', 'service': 'metaset'}, 200 @app.route('/info') def service_info(): return { 'name': 'MetaSet', 'description': 'Business Intelligence by ArcadiaSuite', 'version': app.config.get('VERSION_STRING', '4.1.0'), 'features': ['sql_lab', 'dashboards', 'charts', 'rls', 'embedding'] } return app # MetaSetApplication: custom Gunicorn app # Config: 2 workers, gthread, 120s timeout, stdout/stderr logging 2. BI-API Gateway (server/bi/index.ts) """ * BI-API Gateway * Porta: 8004 * Integra MetaSet (8100) e FDB-Bridge (8200) ao ArcadiaSuite * Proxy manual usando mΓ³dulo http nativo (bypass http-proxy-middleware ECONNRESET) """ import express from 'express'; import http from 'http'; const METASET_URL = `http://${process.env.METASET_HOST || 'metaset'}:${process.env.METASET_PORT || '8100'}`; // Manual proxy: http.request() com pathRewrite // SoluΓ§Γ£o para ECONNRESET com Gunicorn keepalive // Health check agrega MetaSet + FDB-Bridge status 🎨 ConfiguraΓ§Γ£o de Branding (superset_config.py) """ ConfiguraΓ§Γ£o do MetaSet (Superset) para ArcadiaSuite """ import os from pathlib import Path BASE_DIR = Path(__file__).parent.absolute() SUPERSET_HOME = BASE_DIR / 'superset_home' # ========================================== # BRANDING - ARCADIASUITE βœ… IMPLEMENTADO # ========================================== APP_NAME = "MetaSet by ArcΓ‘dia" APP_ICON = "/static/assets/images/branding/metaset-logo-horiz.png" LOGO_TARGET_PATH = "/" LOGO_TOOLTIP = "MetaSet - Business Intelligence by ArcadiaSuite" # Favicons FAVICONS = [ {"href": "/static/assets/images/branding/favicon-16x16.png", "sizes": "16x16"}, {"href": "/static/assets/images/branding/favicon-32x32.png", "sizes": "32x32"}, {"href": "/static/assets/images/branding/apple-touch-icon.png", "sizes": "180x180"}, ] # Cores ArcadiaSuite ARCADIA_PRIMARY = "#0ea5e9" # Azul celeste ARCADIA_SECONDARY = "#10b981" # Verde ARCADIA_ACCENT = "#f59e0b" # Laranja ARCADIA_BG = "#f8fafc" # Background claro ARCADIA_TEXT = "#1e293b" # Texto escuro # Desabilitar cache de arquivos estΓ‘ticos SEND_FILE_MAX_AGE_DEFAULT = 0 THEME_DEFAULT = { "token": { "brandAppName": "MetaSet", "brandLogoAlt": "MetaSet by ArcadiaSuite", "brandLogoUrl": "/static/assets/images/branding/metaset-logo-horiz.png", "brandLogoMargin": "16px 0", "brandLogoHeight": "28px", "colorPrimary": ARCADIA_PRIMARY, "colorLink": ARCADIA_PRIMARY, "colorSuccess": ARCADIA_SECONDARY, "colorWarning": ARCADIA_ACCENT, "colorError": "#ef4444", "colorInfo": "#3b82f6", "colorBgLayout": ARCADIA_BG, "colorBgContainer": "#ffffff", "colorText": ARCADIA_TEXT, "colorTextSecondary": "#64748b", "fontFamily": "Inter, -apple-system, BlinkMacSystemFont, sans-serif", "fontSize": 14, "borderRadius": 8, "borderRadiusLG": 12, "boxShadow": "0 1px 3px 0 rgba(0, 0, 0, 0.1)", "boxShadowSecondary": "0 4px 6px -1px rgba(0, 0, 0, 0.1)", }, "algorithm": "default", } THEME_DARK = { ... } # Tema escuro # ========================================== # SEGURANΓ‡A & MULTI-TENANCY # ========================================== from security_manager import ArcadiaSecurityManager CUSTOM_SECURITY_MANAGER = ArcadiaSecurityManager # βœ… Funcionando AUTH_TYPE = 1 WTF_CSRF_ENABLED = True WTF_CSRF_TIME_LIMIT = 3600 SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SECURE = False # True em produΓ§Γ£o com HTTPS SESSION_COOKIE_SAMESITE = "Lax" # ========================================== # BANCO DE DADOS # ========================================== SQLALCHEMY_DATABASE_URI = os.getenv( 'DATABASE_URL', 'postgresql://arcadia:arcadia123@db:5432/metaset_db' ) SQLALCHEMY_ENGINE_OPTIONS = { "connect_args": {"options": "-c row_security=on"}, "pool_pre_ping": True, "pool_recycle": 300, } # ========================================== # FEATURE FLAGS # ========================================== FEATURE_FLAGS = { "EMBEDDED_SUPERSET": True, "EMBEDDABLE_CHARTS": True, "DASHBOARD_RBAC": True, "SQLLAB_BACKEND_PERSISTENCE": True, "DASHBOARD_VIRTUALIZATION": True, "DRILL_BY": True, "CSS_TEMPLATES": True, "ENABLE_JAVASCRIPT_CONTROLS": False, "ALERT_REPORTS": False, } πŸ“‹ Roadmap de ImplementaΓ§Γ£o (8 Semanas) Semana Foco EntregΓ‘veis 1 Setup MetaSet Fork Superset, branding bΓ‘sico (logo, cores), superset_config.py 2 IntegraΓ§Γ£o Kernel services.json atualizado, BI-API gateway, proxy funcionando 3 SeguranΓ§a ArcadiaSecurityManager, JWT validation, injeΓ§Γ£o de headers 4 Multi-tenancy RLS PostgreSQL, isolamento de datasources, testes de seguranΓ§a 5 FDB Bridge ServiΓ§o Python porta 8200, conexΓ£o Firebird, testes de sync 6 Sync Engine SincronizaΓ§Γ£o incremental, agendamento, resoluΓ§Γ£o de conflitos 7 Frontend PΓ‘ginas BI no React, embed de dashboards, SQL Lab integrado 8 Go-Live Testes E2E, documentaΓ§Γ£o, otimizaΓ§Γ£o de performance βœ… Checklist de ImplementaΓ§Γ£o - STATUS ATUAL Semana 1-2: Setup e IntegraΓ§Γ£o βœ… CONCLUÍDO βœ… Clonar superset (4.1.0rc4) para server/bi/metaset/superset-src βœ… Criar superset_config.py com branding ArcadiaSuite (APP_NAME, cores, tema) βœ… Rebuild do frontend React com logos MetaSet (COMPLETO - 07/04/2026) - SubstituiΓ§Γ£o de textos: "Superset" β†’ "MetaSet" em todo codebase - TraduΓ§Γ΅es atualizadas: en/LC_MESSAGES/messages.po, pt_BR/LC_MESSAGES/messages.po - Arquivos fonte atualizados: RightMenu.tsx, OAuth2RedirectMessage.tsx, SliceHeaderControls, HeaderActionsDropdown, AnchorLink, EmbeddedModal, useExploreAdditionalActionsMenu - Templates HTML: basic.html, public_welcome.html, 404.html, 500.html - Config Python: config.py (APP_NAME), constants.py (USER_AGENT), cli/*.py - Build webpack concluΓ­do com sucesso (429 warnings, 0 errors) - Assets compilados com branding MetaSet incorporado βœ… Criar server/bi/metaset/run.py entry point (Gunicorn) βœ… Criar server/bi/metaset/init.sh container initialization βœ… Criar server/bi/index.ts BI-API gateway (proxy manual Node.js) βœ… Atualizar server/kernel/config/services.json (autoStart: false, Docker Discovery) βœ… Docker Compose: metaset + bi-api + redes configuradas βœ… Dockerfile multi-stage build com assets locais (nΓ£o mais copiando de apache/superset:latest) βœ… Deploy: https://bi.onboardbi.com.br (MetaSet rodando com branding completo) βœ… Container antigo arcadia-prod-superset-1 removido βœ… Container metaset conectado Γ  rede coolify para Traefik βœ… Banco de dados metaset_db migrado e inicializado βœ… UsuΓ‘rio admin criado (login: admin / senha: admin) βœ… BI-API Gateway proxy /bi/metaset funcionando (porta 8004) βœ… Health checks integrados (metaset + bi-api) βœ… requirements.txt corrigido (compatΓ­vel apache-superset 4.1.0) βœ… extra_hosts configurado para resolver db β†’ 10.0.10.2 (IPv4) Semana 3-4: SeguranΓ§a πŸ”„ EM ANDAMENTO βœ… Implementar ArcadiaSecurityManager (CORRIGIDO - chama super().before_request()) βœ… Configurar JWT validation πŸ”„ Criar schema metaset no PostgreSQL (banco criado, migraΓ§Γ΅es aplicadas) ☐ Configurar RLS em tabelas do arcadia_db ☐ Testar isolamento entre tenants Semana 5-6: FDB Bridge ⏳ PENDENTE ☐ Criar server/bi/fdb-bridge/main.py ☐ Implementar conexΓ£o Firebird (fdb library) ☐ Criar lΓ³gica de sincronizaΓ§Γ£o incremental ☐ Configurar agendador APScheduler ☐ Testar sync Matriz + 5 Filiais Semana 7-8: Frontend e Go-Live ⏳ PENDENTE ☐ Criar pΓ‘ginas BI no frontend React ☐ Implementar embed de dashboards MetaSet ☐ Criar componente de status de sincronizaΓ§Γ£o ☐ Testes E2E completos ☐ DocumentaΓ§Γ£o do mΓ³dulo BI πŸ“ LiΓ§Γ΅es Aprendidas (07/04/2026) 1. Frontend rebuild obrigatΓ³rio: Substituir arquivos estΓ‘ticos PNG no Docker nΓ£o funciona porque os assets sΓ£o compilados em bundles JS pelo webpack. Γ‰ necessΓ‘rio rebuildar o superset-frontend com npm run build. 2. DependΓͺncias faltantes: O build pode falhar por pacotes nΓ£o instalados: @react-spring/web, global-box, currencyformatter.js. Instalar com npm install --legacy-peer-deps. 3. Security Manager: O ArcadiaSecurityManager DEVE chamar super().before_request() no inΓ­cio do mΓ©todo para preservar o comportamento de autenticaΓ§Γ£o padrΓ£o do Flask-AppBuilder. Sem isso, o login falha com AttributeError: user. 4. IPv6 vs IPv4: O hostname "db" resolve para IPv6 (fd20:a15a:c2d4::c) mas o psycopg2 falha na autenticaΓ§Γ£o via IPv6. SoluΓ§Γ£o: mapear db β†’ IP IPv4 via extra_hosts no docker-compose.yml. 5. Container antigo: Sempre verificar se hΓ‘ containers antigos com labels do Traefik apontando para o mesmo domΓ­nio. Eles podem conflitar com o novo container. 6. Traefik discovery: O container DEVE estar na mesma rede Docker que o Traefik (coolify) para ser descoberto automaticamente. πŸ’° Custos Adicionais Componente EspecificaΓ§Γ£o Custo Estimado MemΓ³ria extra +2GB para Python (MetaSet + FDB-Bridge) ~$20/mΓͺs Storage PostgreSQL +10GB para metadata MetaSet ~$5/mΓͺs CPU Processamento de sync FDB ~$15/mΓͺs Total ~$40/mΓͺs πŸš€ Comandos de Deploy # 1. Build da imagem Docker cd /opt/arcadia_merged docker compose build --no-cache metaset # 2. Recriar container com nova imagem docker compose up -d --force-recreate metaset # 3. Verificar status curl http://localhost:8100/health curl https://bi.onboardbi.com.br/login/ | grep "" # 4. Logs docker logs -f arcadia-dev-metaset-1 # 5. Migrar banco (se necessΓ‘rio) docker exec -e FLASK_APP=superset \ -e DATABASE_URL="postgresql://arcadia:arcadia123@10.0.10.2:5432/metaset_db" \ arcadia-dev-metaset-1 superset db upgrade # 6. Inicializar docker exec -e FLASK_APP=superset \ -e DATABASE_URL="postgresql://arcadia:arcadia123@10.0.10.2:5432/metaset_db" \ arcadia-dev-metaset-1 superset init πŸ“Œ URLs de Acesso ServiΓ§o URL Status MetaSet UI https://bi.onboardbi.com.br βœ… Online com branding MetaSet MetaSet Health http://localhost:8100/health βœ… OK BI-API Gateway http://localhost:8004 ⚠️ Unhealthy (esperado - requer JWT) Traefik Dashboard http://localhost:8080 βœ… Online πŸ”§ PrΓ³ximos Passos PrioritΓ‘rios 1. Configurar RLS (Row Level Security) no PostgreSQL para isolamento de tenants 2. Testar fluxo completo de autenticaΓ§Γ£o com token JWT do Arcadia 3. Criar datasource de exemplo conectado ao arcadia_db 4. Implementar FDB Bridge (conector Firebird) 5. Criar pΓ‘ginas BI no frontend React 6. Configurar cache Redis para MetaSet