Roadmap#
Visão geral de onde o Sulfite está e para onde estamos indo.
Estado atual#
| Componente | Status | Descrição |
|---|---|---|
| sulfite_core |
Motor de relatórios com 12 tipos de elementos, parser JSON, processamento de dados, ScriptEngine (filter/sort/limit/distinct/addField), GroupBands, geração multiformato (PDF, HTML, CSV, Excel), parâmetros de impressão com lookups HTTP e banco de dados, paginação de lookups, novos tipos de parâmetro (
currency
,
datetime
), campos
format
/
rounding
por parâmetro, formatos numéricos estilo Excel (
#,##0.00
), pacote
.sulfite
(RFC-017),
pivot mode no TableElement
(ordenação, overrides de coluna, estilos condicionais)
|
|
| sulfite_studio |
Editor visual com canvas interativo, inspetor de propriedades, desfazer/refazer, tradução, seletor de cores, tema personalizado, editor de gráficos, GroupBands, Transform Pipeline Editor, filtros dinâmicos com lookups e cascata (RFC-015), autocomplete de agregados (RFC-013), persistência de layout (RFC-014), preview em tempo real, save/load de
.sulfite
(RFC-017),
aba Scripts com code_forge + Dart
(RFC-016)
|
|
| sulfite_report_manager | Widget Flutter completo de gerenciamento de relatórios — CRUD, busca, permissões granulares, visualizador integrado com filtros automáticos, exportações e abertura no Designer (RFC-018) | |
| sulfite_server | Servidor REST completo — CRUD de relatórios, geração síncrona/assíncrona (SSE), conexões criptografadas AES-256-GCM, autenticação HMAC com permissões granulares e refresh rotation, assinatura digital de relatórios, compartilhamento público com OTP, export/edit policy, rate limiting por endpoint, consumer API e deploy via Docker/Render (RFC-025, 026, 027, 028) | |
| sulfite_cli | Gera PDFs pela linha de comando — compilável para executável nativo (~42ms por PDF) | |
| Exportação multiformato | Gera PDF, HTML, CSV e Excel a partir do mesmo JSON | |
| FontBytesLoader |
Interface para carregamento de fontes — desacopla o motor de relatórios do Flutter (
AssetFontBytesLoader
) e permite uso em CLI/servidor (
FileFontBytesLoader
)
|
|
| ScriptEngine | Motor de transformação declarativa — filter, sort, limit, distinct, addField com expressões, AND/OR/NOT; parâmetros injetados no contexto | |
| GroupBands |
Quebra de grupo com
groupHeader
e
groupFooter
— subtotais automáticos por grupo
|
|
| Advanced Scripting |
Scripts Dart com
afterQuery
/
beforeRender
hooks via dart_eval; replaces declarative transforms (RFC-016)
|
|
| Print Filters |
Parâmetros interativos antes de imprimir — diálogo automático, lookups HTTP e banco de dados (
LookupConfig.http
/
LookupConfig.db
), paginação de lookup, novos tipos
currency
e
datetime
, campos
format
/
rounding
por parâmetro, validação declarativa, dependências em cascata, injeção em expressões e URLs REST (RFC-011, RFC-015)
|
|
| sulfite_datasources |
Arquitetura modular com 4 pacotes especializados:
sulfite_datasources_rest
,
sulfite_datasources_postgres
,
sulfite_datasources_postgrest
(Supabase),
sulfite_datasources_sqlite3
. Cada resolver pode ser usado individualmente ou via pacote guarda-chuva
sulfite_datasources
. Inclui
DbLookupResolver
com queries SQL parametrizadas, paginação e cache; suporte completo a ConnectionRegistry (RFC-019)
|
|
| Pacote .sulfite | Formato ZIP portátil com definição + assets embutidos — save/load no Studio e suporte no Manager (RFC-017) | |
| Documentação | Documentação com playground interativo no navegador |
Próximos passos#
Fase 1 — Editores mais completos no Studio #
- Edição visual de colunas de tabela (
TableColumnEditor) - Estilização de trechos de texto — negrito, itálico, cor (
TextSpanEditor) - Configuração visual dos modos de arredondamento (
RoundingConfigEditor) - Seletor de formatos numéricos e de data (
FormatPickerField) -
Seletor de cores com paleta, campo hex e sincronização bidirecional (
StudioColorPickerDialog) - Reordenar séries de gráfico por drag & drop (
ChartEditorDialog) - Seleção de idioma (pt-BR / en-US) com aplicação imediata
- Tema personalizado: cor primária livre via picker de cores; tabela de papéis do tema com hex
Fase 2 — Edição JSON ↔ Canvas (RFC 004) #
- Editar o JSON e ver o canvas atualizar automaticamente (e vice-versa)
- Validação em tempo real — erros e avisos aparecem inline no editor de código
-
Editor com syntax highlighting, busca, formatação automática e tooltips de propriedades (
JsonEditorWidget)
Fase 2a — Chat IA integrado ao Studio #
-
Agente LLM que gera
ReportDefinitioncompleto a partir de descrição em linguagem natural - 5 provedores: OpenAI, Anthropic, Ollama (local), GitHub Models, GitHub Copilot
- Auto-correção automática de JSON inválido (até 3 tentativas)
- Painel flutuante arrastável + modo dockado como aba lateral
- Contexto dinâmico: JSON do relatório atual é injetado a cada mensagem
- Suporte a imagens no chat (envia como data URI)
- Sem efeito no bundle quando
chatConfignão é fornecido
Fase 2b — printWhen por elemento + ScriptEngine #
-
printWhenem qualquerReportElement— expressão booleana que oculta o elemento quando avaliafalse - Expressões com
AND,OR,NOTlógicos -
AdvancedScriptEnginecom hooksafterQueryebeforeRender— substituiu o campotransformsremovido
Fase 2c — Studio auto-explicativo + DataSource + Editors visuais #
- Tooltips e help cards em todo o Studio com i18n (pt-BR / en-US)
-
DataSourceResolver+RestDataSourceResolver— interface abstrata para fontes externas TableColumnEditor— edição visual de colunas de tabelaTextSpanEditor— estilização visual de trechos de texto (negrito, itálico, cor)
Fase 2d — GroupHeader / GroupFooter Bands (RFC 009) #
-
Novos tipos de band:
groupHeaderegroupFootercom campogroupBy DataProcessoragrupa registros automaticamente pela chave- Subtotais por grupo:
AggregateElementrespeita o escopo de grupo - PDF, HTML, CSV e Excel renderizam a hierarquia grupo → detalhe → subtotal
-
Studio:
AddBandDialogcom tiposgroupHeader/groupFooter,PropertyInspectorcom campogroupBy
Fase 2e — Transform Pipeline no Studio (RFC 010) #
TransformPipelineEditor— painel visual com lista reordenável de operações- Cada operação: dropdown de tipo, dropdown de source, campos de parâmetros específicos
ExpressionEditorBackendcom syntax highlighting e autocomplete de campos do schema- Preview em tempo real via
compute()(isolate) — executa pipeline nos dados de amostra -
DesignerViewModel:addTransform,removeTransform,reorderTransforms,updateTransform - 28 chaves i18n (pt-BR + en-US)
Fase 2f — Print Filters, Unify Rect, Aggregate AutoComplete, Layout Persistence (RFC 011–014) #
RFC-011 — Print Filters (parâmetros estáticos)
ReportParameter— model Freezed com tipotext/number/date/selectScriptEngine.execute()— injeta parâmetros no contexto de expressões-
RestDataSourceResolver.expandUrl()— expande{paramId}em templates de URL REST PrintParamsDialog— diálogo modal automático antes de imprimir/exportarParameterEditor— editor inline no painel de configurações do relatório-
ExpressionEvaluator— comparação lexicográfica>=/<=/>/<para strings/datas
RFC-015 — sulfite_filtros (lookups dinâmicos)
LookupConfig— modelo para busca de opções via HTTP com cache e placeholders-
LookupResolver/HttpLookupResolver— interface e implementação HTTP com proteção SSRF SulfiteFilterScreen— widget de filtros com lookups, cascata e validação inline-
ValidationRule— 9 regras de validação declarativa (required, min, max, dateBefore, dateAfter, etc.) dependsOn— dependências em cascata entre parâmetros
RFC-012 — Unify Rect + RoundedRect
borderRadiusadicionado aoRectElement(default0.0)-
JSONs antigos com
type: roundedRectmigram automaticamente paraRectElement RoundedRectElementremovido do código
RFC-013 — Aggregate AutoComplete
AggregateComputer— utilitário:compute/preview/fieldsFromRows_AggregateTargetKeyField— autocomplete para campotargetKeyno designer
RFC-014 — Layout Persistence
collapsedPanels: List<String>adicionado aStudioPreferences-
PreferencesProvider:isPanelCollapsed / togglePanelCollapsed / updatePanelWeight
Fase 2g — sulfite_filtros: Lookups Dinâmicos e Cascata (RFC 015) #
-
LookupConfig— modelo Freezed: URL com{paramId}, método HTTP, cache,refreshOnDependencyChange LookupResolver— interface abstrata +HttpLookupResolvercom proteção SSRF-
SulfiteFilterScreen— widget standalone: campos text/number/date/select + select com lookup (loading state) -
ValidationRule— 9 regras declarativas: required, minLength, maxLength, min, max, dateBefore, dateAfter, lessThan, greaterThan -
dependsOn— cascata automática: quando o valor de um parâmetro-pai muda, filhos são recarregados - 14 chaves i18n adicionadas (pt-BR + en-US)
Fase 2h — Advanced Scripting Engine (RFC 016) #
-
ReportScriptmodel Freezed —id,hook(afterQuery / beforeRender / onFilter),code,description -
AdvancedScriptEngine— registra handlers Dart porscriptId, executa hooks em ordem de declaração -
ScriptContext— API segura:datasource(),param(),context(),query(),setBandVisible(),setElementVisible(),setElementProperty(),removeBand(),log() -
ScriptMutations— acumula mutações de layout (hide/show bands e elementos, property overrides) SqlBridge— interface para execução de queries SQL auxiliares (PostgreSQL, REST, Mock)-
Campo
scripts: List<ReportScript>adicionado aoReportDefinition(backward compatible, default[])
Fase 2h2 — Studio: code_forge + aba Scripts (RFC 016 Sprint 3) #
- Flutter 3.41.5 (Dart 3.11.3) — migração de todos os pacotes para SDK
^3.11.1via FVM -
code_forge ^9.2.0substituire_editor— Rope data structure, LSP builtin, multi-cursor, code folding avançado -
CodeForgeBackend— novo backend do JSON Editor (substituiReEditorBackend) com syntax highlighting JSON -
CodeForgeExpressionBackend— novo backend do Expression Editor com snippets de campos de schema -
Aba Scripts no Studio — quarto modo no toolbar (
SegmentedButton) ao lado de Design / Preview / CodeScriptEditorWidget— lista lateral de scripts com drag-to-reorder, add/deleteCodeForgecomlangDart+vs2015Theme+ 11 snippets deScriptContext(ctx.datasource, ctx.query, ctx.param, etc.)- Toolbar por script: seletor de hook (afterQuery / beforeRender / onFilter) + campo de descrição
- Modo scripts oculta sidebar de design (sem toolbar de elementos)
-
DesignerViewModel.updateScripts()— atualiza a lista de scripts sem registrar no undo/redo global
Fase 2i — Formato .sulfite (RFC 017) #
-
SulfitePackageWriter— serializaReportDefinition+ assets em ZIP portátil (.sulfite) SulfitePackageReader— extrai e reconstrói a definição a partir do ZIP- Studio: salva/abre pacotes
.sulfitecom opção de incluir dados de exemplo -
ReportManagerWidget: detectastorageKind: packagee usaSulfitePackageReaderautomaticamente - Assets (fontes, imagens) embutidos no pacote — relatório autocontido e portátil
Fase 2j — sulfite_report_manager (RFC 018) #
ReportManagerWidget— tela completa com lista, busca, CRUD e permissões granulares-
ReportRepository— interface abstrata + 4 implementações:InMemory,Sqlite,Rest,Postgres -
Fluxo viewer-first: relatório abre no visualizador (
SulfiteConsumerScreen); Designer só abre secanSettings: true - Carregamento diferido pós-animação +
compute()para parsear definição em background -
inlineDataPayload— fornece dados inline por relatório (relatórios estáticos/demo) viaSulfiteConsumerScreen -
SulfiteConsumerScreen.onEdit— callbackVoidCallbackchamado com aReportDefinitionjá parseada (sem re-parsear no Designer) - Suporte a
.sulfitee JSON como formatos de armazenamento -
SulfiteFilterScreenmigrado paraStudioDialogShell(visual consistente com o Studio)
Fase 2k — Lookups DB, novos tipos de parâmetro e formatos numéricos #
LookupConfig: union http / db
-
LookupConfigrefatorado para union selada com discriminador"source"— backward-compatible (documentos semsourcecontinuam funcionando como HTTP) -
LookupConfig.db— novo backend de lookup que executa SQL contra uma entrada doConnectionRegistry -
DbLookupResolver(pacotesulfite_datasources) — resolves queries PostgreSQL parametrizadas com{_search},{_page},{_page_size},{_offset}e{_schema} -
Paginação em lookups HTTP e DB —
pageSize+fetchPage()com suporte a respostameta.total/page/perPage -
Cache separado para resultados paginados (
_pageCache) para evitar recomputação inconsistente dehasMore -
SSRF: adicionado
http://127.0.0.1como origem permitida além dehttps://ehttp://localhost
Novos tipos de parâmetro
currency— campo com máscara monetária e arredondamento configuráveldatetime— seletor de data e hora (yyyy-MM-ddTHH:mm)-
Campo
formatemReportParameter— padrãointlparadate/datetime, máscara"<milhar><decimal><casas>"paracurrency, precisão paranumber -
Campo
roundingemReportParameter— aplicahalf_even,half_up,half_down,up,down,truncateao reformatar no blur
Formatos numéricos estilo Excel
-
ValueFormatteraceita padrões#,##0.00,#,##0,0.00,#,##0.000, etc. — mesmo estilo do Excel e JasperReports -
_formatNumberagora usaroundNumWithModecomhalf_evenem vez detoStringAsFixeddireto
Fase 3 — Conectar a bancos e APIs (RFC 001, 024) #
Arquitetura modular de resolvers
-
4 pacotes dedicados:
sulfite_datasources_rest,sulfite_datasources_postgres,sulfite_datasources_postgrest,sulfite_datasources_sqlite3 -
Pacote guarda-chuva
sulfite_datasourcesre-exporta todos os resolvers (consumidores escolhem dependências granulares) -
PostgresDataSourceResolver— conexões PostgreSQL diretas comConnectionRegistry RestDataSourceResolver— APIs HTTP/REST com suporte a headers customizados-
PostgRestDataSourceResolver— suporte nativo a Supabase/PostgREST com sintaxe de query PostgREST (RFC-024) -
Sqlite3DataSourceResolver— bancos SQLite3 locais (plataformas nativas, guardado por!kIsWeb)
Studio: DataSource Dialog unificado
-
Campo
drivernoDataSource— seleção explícita de resolver (rest,postgres,postgrest,sqlite3, ou driver customizado) kDriverLabelsexportado — labels human-friendly reutilizáveis em toda UI- Suporte completo a drivers customizados — formulário genérico preserva driver e permite URL/connectionRef/query/headers
ConnectionManagerWidget— gerenciamento visual de conexões PostgreSQL, HTTP e SQLite3- Editor de headers HTTP — configuração visual de API keys e tokens de auth
- Proxy pattern — padrão documentado para usar PostgREST/Supabase em Flutter Web sem expor credenciais
Lookups de banco
DbLookupResolver— lookups de banco já funcionam (concluído na Fase 2k)LookupConfig.db— union selada com queries SQL parametrizadas-
Paginação automática via
{_page},{_page_size},{_offset},{_search},{_schema}
Fase 4 — Relatórios com milhões de registros (RFC 007) #
-
True Streaming Pipeline —
processDataStreamconsomeStream<Map>incrementalmente processDataStreamChunkedpara processamento em lotes semOutOfMemoryErrorDataSourceResolver+RestDataSourceResolverpara fontes externas via HTTP
Fase 5 — Novos tipos de elementos (RFC 002) #
| Elemento / Feature | Descrição | Status |
|---|---|---|
ChartElement |
Gráficos (barra, linha, pizza) com legenda, grade, rótulos | |
| Chart: barras agrupadas | Múltiplas séries lado a lado com offset automático | |
| Chart: barras empilhadas | stacked: true em PDF, HTML e Studio |
|
| Chart: borda | hasBorder, borderDashed, cores e espessura |
|
| Chart: paleta consistente | 10 cores compartilhadas entre PDF, HTML e Studio | |
forcePageBreakBefore |
Quebra de página por band (Header, Detail, Summary, Footer) | |
BandVisibility |
Controla em quais páginas Header/Footer são renderizados (firstPage, lastPage, oddPages…) | |
showOnPage |
Renderiza a band somente em uma página específica | |
printWhen |
Expressão booleana para ocultar band condicionalmente | |
TableElement pivot mode |
Tabela pivot com totais, ordenação, overrides de coluna e estilos condicionais — campo
pivot
no
TableElement
existente
|
Fase 6 — Editar gráficos no Studio (RFC 008) #
- Editar propriedades do gráfico visualmente — tipo, cores, legendas (
ChartEditorDialog) - Adicionar e remover séries de dados com poucos cliques
- Gráfico atualiza em tempo real no canvas
- Reordenar séries por drag & drop
Fase 7 — sulfite_server REST backend (RFC-025) #
SulfiteServer— servidor REST completo construído sobre o framework Relic-
CRUD de relatórios —
GET/POST/PUT/DELETE /api/v1/reportscom suporte a JSON e pacotes.sulfite -
Geração síncrona e assíncrona —
POST /generate+ jobs com polling e Server-Sent Events (GET /jobs/:id/stream) - Gerenciamento de conexões — registre bancos (PostgreSQL, SQLite) e APIs com criptografia AES-256-GCM em repouso
-
Autenticação HMAC-SHA256 — tokens de acesso com permissões granulares (
canRead,canInsert,canSettings,canDelete) e refresh rotation com detecção de reuso -
Consumer API — endpoint read-only
GET /consumer/reportspara usuários finais sem token completo -
Resolução de datasources —
POST /datasources/resolvee/introspectcom suporte a REST, PostgreSQL e PostgREST -
Deploy via Docker e Render.com — Dockerfile multi-stage com AOT compilation; variáveis
PUBLIC_URL/RENDER_EXTERNAL_URL - Pool de isolates — geração concorrente de relatórios sem bloquear o event loop principal
Fase 8 — Security hardening (RFC-026) #
- SEC-01 a SEC-17: auditoria abrangente com 17+ pontos de correção de segurança
- Rate limiting por endpoint — sliding window com LRU eviction; limites separados para leitura, escrita e geração; bypass por IP configurável
-
Headers de segurança —
X-Content-Type-Options,X-Frame-Options,Cache-Control: no-store,Referrer-Policy,CSP: default-src 'none',HSTS - SSRF guard — bloqueio de IPs internos em lookups HTTP configurável
- Fail2ban em OTP e shares — bloqueio automático após N tentativas inválidas por IP
- Comparação em tempo constante — proteção contra timing attacks na verificação de segredos
- Validação de permissões — camada de autenticação verifica permissões antes de chegar ao handler
Fase 9 — Criptografia, assinatura e rotação de tokens (RFC-027) #
-
EnvelopeEncryptor— AES-256-GCM com rotação de chave:ENCRYPTION_KEY(ativa) +ENCRYPTION_KEY_PREV(leitura legada); envelope com salt e IV aleatórios por blob -
ReportSigner— assinatura digital por role (author,deployer,reviewer) com cadeia de confiança; signatures embutidas no pacote.sulfite -
VerifiedIdentity— identidade verificada (email + timestamp + origin) anotada na assinatura - Rotação de refresh tokens — cada uso emite um novo par e invalida o anterior; detecção de reuso invalida toda a família
Fase 10 — Compartilhamento de relatórios (RFC-028) #
-
Links de compartilhamento —
POST /sharegera URL pública com slug aleatório,maxViews,expiresAt, código de acesso de 8 caracteres e fail2ban -
Páginas HTML públicas com nonce CSP — landing page e página de erro usam nonce criptográfico por request (
Random.secure()); script/style comnonce-$nonceem vez deunsafe-inline -
PUBLIC_URL— URLs de share usam o domínio externo configurado (Render, etc.) em vez dehost:portlocal
Fase 11 — Exportação verificada com autenticação por domínio (RFC-029) #
-
ExportPolicy— allowlist de domínios de e-mail e e-mails individuais; habilitada viaEXPORT_POLICY_ENABLED,EXPORT_POLICY_DOMAINS,EXPORT_POLICY_EMAILS -
Fluxo OTP de exportação —
POST /export/verifyvalida e-mail contra a policy e envia OTP;POST /export/confirmverifica o código e devolve o pacote.sulfiteassinado com identidade verificada -
VerifiedIdentityna assinatura — e-mail, domínio, timestamp e origin embutidos naSignatureEntrydo pacote exportado -
Rastreabilidade de exportação — cada download de
.sulfitecarrega quem exportou, quando e de qual organização -
Studio —
VerifiedExportDialogdetecta policy ativa viaGET /export/policye substitui o fluxo de exportação padrão
Fase 12 — Edit policy com OTP no Studio (RFC-030) #
-
EditPolicy— allowlist de domínios e e-mails para quem pode editar; habilitada viaEDIT_POLICY_ENABLED,EDIT_POLICY_DOMAINS,EDIT_POLICY_REQUIRE_OTP -
editToken— token de vida moderada (1h) emitido após OTP de intençãoedit; destravar o canvas e o editor de código no Studio -
saveToken— token de vida ultra-curta (5min) emitido por OTP independente no momento de salvar; exigido emPUT /reports/:idpara prevenir overwrites não autorizados -
Separação de risco — computador aberto perde o direito de editar após expiração do
editTokene nunca consegue salvar sem novo OTP de salvamento -
Middleware server-side —
PUT /reports/:idrejeita com403se EditPolicy ativa eX-Edit-Token/X-Save-Tokenausentes ou inválidos
RFCs#
Todas as propostas técnicas estão documentadas como RFCs no repositório:
| RFC | Título | Status |
|---|---|---|
| 001 | Dynamic DataSource Resolution with Plugin System | |
| 002 | Advanced PDF Elements & Multi-Format Export | |
| 004 | Studio DX — Bidirectional Sync & Real-time Validation | |
| 006 | Studio Layout & Preferences Persistence | |
| 007 | True Streaming Pipeline | |
| 008 | Charts Integration in Studio | |
| 009 | GroupHeader / GroupFooter Bands | |
| 010 | Transform Pipeline Studio | |
| 011 | Print Filters — Parâmetros interativos antes de imprimir | |
| 012 | Unify Rect + RoundedRect | |
| 013 | Aggregate AutoComplete no Studio | |
| 014 | Layout Persistence — collapsedPanels + panelWeight | |
| 015 |
sulfite_filtros — Lookups HTTP e DB, Paginação, Cascata, Validação,
currency
/
datetime
|
|
| 016 | Advanced Scripting Engine | |
| 017 | Formato .sulfite — Pacote portátil com assets embutidos | |
| 018 | sulfite_report_manager — Gerenciador de relatórios Flutter | |
| 019 | Named Connection Registry — Desacoplar credenciais do relatório | |
| 024 | PostgREST Studio Support — Supabase/PostgREST como data source | |
| 025 | sulfite_server — Servidor REST backend com auth, CRUD, geração assíncrona e consumer API | |
| 026 | Security Hardening — Rate limiting, SSRF guard, headers, fail2ban e auditoria SEC-01–17 | |
| 027 | Criptografia e Assinatura — AES-256-GCM envelope encryption, assinatura por role e rotação de tokens | |
| 028 | Compartilhamento — Links públicos com slug, código de acesso e fail2ban | |
| 029 | Exportação Verificada — OTP por e-mail, allowlist de domínios e VerifiedIdentity na assinatura | |
| 030 | Edit Policy — OTP para abrir o Studio e OTP independente para salvar; editToken + saveToken |
Quer contribuir ou sugerir uma RFC? Abra uma issue no GitHub.