Changelog
Changelog — Bússola Financeira
Todas as mudanças relevantes do projeto são documentadas aqui. Formato baseado em Keep a Changelog.
[Pré-teste em andamento]
[0.10.3] — 2026-05-18
Adicionado
- Atalhos de período no filtro de Movimentações (BK-145): além de escolher datas customizadas, o filtro agora oferece atalhos contábeis em um clique — Mês atual, Mês anterior, Trimestre atual, Trimestre anterior, Semestre atual, Ano atual (YTD), Ano anterior, Personalizado e Todos. Cálculo baseado em trimestres e semestres calendário (T1: jan-mar, T2: abr-jun, etc.). Selecionar um atalho preenche as datas automaticamente; editar manualmente as datas troca o filtro para “Personalizado”.
Modificado
- Filtro de Movimentações abre por padrão em “Mês atual” em vez de “Todos” — visão operacional do dia a dia é mais comum no fluxo do tesoureiro.
[0.10.2] — 2026-05-18
Corrigido
- Badge “Estornado” volta a aparecer também no lançamento contrário (BK-160, regressão da v0.10.1): a release anterior introduziu o badge no lançamento original mas a regra de detecção não cobria o lançamento contrário gerado pelo estorno; agora ambos exibem o badge corretamente.
[0.10.1] — 2026-05-18
Primeira release versionada após a transição de v0.10 (beta) para semver puro. Consolida correções de UX no módulo de Movimentações, melhorias no menu superior, publicação dos documentos legais e do manual em domínio próprio, e a primeira preparação do fluxo Google em /setup para auto-conclusão (validação E2E pendente). A partir desta versão, marcadores como “(beta)” não fazem mais parte da string da versão.
Adicionado
- Avatar do usuário no menu superior (BK-141): a foto cadastrada em Configurações → Perfil agora aparece no avatar do menu superior em qualquer cenário em que a tela de perfil também exibe a foto; ao trocar a foto, o menu superior atualiza imediatamente sem precisar de F5. Iniciais continuam como fallback quando não há foto.
- Badge “Recorrente” em lançamentos recorrentes (BK-158): movimentos pertencentes a uma série recorrente não-parcelada passam a exibir um badge “Recorrente” ao lado do título, em
/movimentacoes(lista e detalhe). Visibilidade rápida do contexto sem precisar abrir o detalhe. - Manual do Usuário publicado (BK-137): novo manual público em
https://docs.bf.rit.org.br/cobrindo primeiros passos, movimentações, reembolsos, pagamentos, configurações da OSC, papéis e FAQ. Link no rodapé da aplicação. - Política de Privacidade e Termos de Uso publicados (BK-094): documentos legais publicados em
https://docs.bf.rit.org.br/privacidade/e/termos/. Links discretos no rodapé da aplicação. - Documentação em domínio próprio (BK-153): substituído o domínio padrão do GitHub Pages por
docs.bf.rit.org.br(Cloudflare DNS + custom domain + HTTPS ativo). Links de Política, Termos e Manual no rodapé já apontam para o novo domínio.
Corrigido
- Troca de OSC pelo seletor agora atualiza a tela automaticamente (BK-151): selecionar outra OSC no menu superior recarrega imediatamente todas as páginas (painel, movimentações, reembolsos, pagamentos, configurações) sem precisar de F5. Antes, a página atual mantinha os dados da OSC anterior até refresh manual.
- Badge “Parcela X de N” voltou a aparecer (BK-157): em lançamentos parcelados, o badge “Parcela X de N” deixou de ser exibido em algum refactor recente; foi restaurado. Causa raiz: a fonte de dados parou de expor a informação da série parcelada.
- Badge “Estornado” agora aparece em ambos os lançamentos (BK-156): ao estornar um pagamento, tanto o lançamento original quanto o contrário (gerado pelo estorno) passam a exibir o badge “Estornado”. Antes só o contrário recebia o badge, dando a falsa impressão de que o original ainda estava “pago” sem indicação. O status no banco do lançamento original permanece “pago” — só a visualização ganha o badge adicional.
- “Continuar com Google” em
/setupredireciona corretamente para o painel (BK-144): no fluxo de configuração inicial via convite, o usuário que escolhia “Continuar com Google” voltava para o formulário de senha em vez de seguir para o painel; agora o cadastro é concluído automaticamente com o nome e a foto do perfil Google e o usuário entra direto no painel. Validação E2E com convite real pendente em BK-152 antes de declarar verificado. - Link “Manual do Usuário” no rodapé apontava para
/manual(404); corrigido para apontar para a raiz do site de docs.
Modificado
- Formato da string da versão: passou de
v0.10 (beta)parav0.10.1. Padronizado em semver puro (MAJOR.MINOR.PATCH); marcadores como “(beta)” não fazem mais parte da string da versão exibida no rodapé e nos feedbacks. A natureza piloto/beta do projeto passa a ser sinalizada (quando necessário) fora da string da versão.
Adicionado (Documentação pública — 2026-05-15)
- Site de documentação multi-página em
https://rit-df.github.io/bussola-docs/: substituído o manual em página única por site Jekyll com navegação por abas (Início, Primeiros Passos, Módulos, Configurações, Papéis, FAQ, Changelog, Legal); cada módulo e aba de configurações tem página dedicada - Sub-navegação por seção: pills de navegação abaixo do título em todas as páginas de Módulos, Configurações e Legal, permitindo navegar entre páginas da seção sem sair da tela
- Screenshots de configurações sem dados pessoais: Organização, Contas, Categorias, Fluxo de Aprovação — imagens capturadas com dados fictícios; abas Perfil e Usuários sem screenshot (dados reais visíveis)
Corrigido (Documentação pública — 2026-05-15)
- Links absolutos quebrados no GitHub Pages: 10 links com caminhos absolutos (
/configuracoes/perfil/etc.) geravam 404; convertidos para caminhos relativos em 8 arquivos - Screenshot de perfil com dados pessoais reais:
manual-09-config-perfil.pngcontinha telefone, e-mail e CPF reais; arquivo removido e referência eliminada da página de perfil
Adicionado (Onda 4 — Pedidos de Pagamento)
- Módulo de Pedidos de Pagamento: novo módulo completo para solicitação formal de pagamentos a fornecedores e prestadores externos, com fluxo de aprovação configurável e lançamento automático em
financial_movements; tabelaspurchase_orders,purchase_order_approvals,purchase_order_attachments; EFssubmit_purchase_order,reject_purchase_order,approve_purchase_order,pay_purchase_order;movement_originestendido com valorpurchase_order - Página
/pagamentosunificada: abas “Pedidos de pagamento” e “Reembolsos” (aba de reembolsos reutiliza componente existente sem alteração); sub-abas por status (Todos / Rascunho / Aguardando aprovação / Aprovado / Rejeitado / Pago); cards-resumo condicionais ao papel (aprovador, tesoureiro, todos); coluna Ações com botões Aprovar / Reprovar condicionais ao papel e status; ícone “Marcar como pago” não aparece na lista — pagamento é confirmado via/movimentacoes(igual a Reembolsos) - “Boleto” como forma de pagamento (pós-lançamento Onda 4): formulário de criação e edição inline do pedido oferecem três opções — PIX, TED, Boleto; selecionar Boleto não exibe campos extras (o arquivo é anexado na seção Documentos);
vendor_payment_infograva{ method: 'boleto' }sem campos adicionais - Redirect
/reembolsos: rota redireciona automaticamente para/pagamentos?tab=reembolsos; links existentes e rotas/reembolsos/novoe/reembolsos/:idpermanecem funcionais - Formulário
/pagamentos/novo: criação e edição de rascunho com CRUD direto via Supabase client; carregamento de rascunho via?id=na URL; campos PIX/TED do fornecedor (sem pré-população do perfil do usuário); uploader com prefixopurchase-orders/; botões “Salvar rascunho” e “Enviar para aprovação” com validação por campo - Página
/pagamentos/:id: detalhe completo com 4 zonas (header, dados, documentos, timeline + ações); preview inline de imagens (thumbnails clicáveis, fallback) e PDF (iframe lazy); ações condicionais — “Editar e reenviar” (solicitante), “Aprovar” / “Reprovar” (aprovador elegível); dados PIX/TED do fornecedor ocultos para voluntários; seção de anexos denominada “Documentos” - TopNav: item “Reembolsos” renomeado para “Pagamentos e Reembolsos”; badge soma pedidos de pagamento aguardando + reembolsos aguardando (ambos os módulos); RPC
count_pending_purchase_orders_for_usercriada - Configurações: aba “Reembolsos” renomeada para “Pagamentos e Reembolsos”; nova subseção “Quem pode solicitar pagamentos” com checkboxes por papel (persiste em
reimbursement_workflow.allowed_requester_roles; default: Presidente, Tesoureiro, Coordenador de Projeto) - Painel: nova seção “Pedidos de pagamento” com cards condicionais ao papel (aguardando aprovação, aprovados aguardando pagamento, solicitado por mim)
Adicionado
- “Continuar com Google” em
/setup: usuários convidados podem concluir o primeiro acesso autenticando via Google OAuth em vez de definir senha; botão visível e habilitado somente após aceite da política de privacidade;setup_tokene versão da política preservados emsessionStorageatravés do redirect OAuth;complete_setupvalidaclaims.sub === uo.user_idpara garantir que a conta Google corresponde ao convite; campo “Nome completo” pré-populado com o nome do perfil Google (editável); campos de senha ocultados no fluxo Google - Upsert de
full_nameemuser_profileao concluir setup:complete_setupagora gravauser_profile.full_nameem ambos os fluxos (senha e Google) após transição bem-sucedida; fechou lacuna pré-existente onde o nome era salvo apenas emauth.user_metadata - Canal de feedback de usuários — chip no TopNav: botão/badge laranja “💬 Feedback” no TopNav, visível para todos os papéis autenticados; abre o
FeedbackModalao ser clicado FeedbackModal: modal com grade 2×2 de tiles de categoria (🐛 Bug / 💡 Sugestão / 👍 Elogio / ❓ Outro), textarea de mensagem livre, rodapé com identidade do usuário (“Enviado como [nome] · [e-mail]”) e insert direto emuser_feedbackvia Supabase client (RLS); toast de confirmação ao enviar; campos limpos ao reabrir- Tabela
user_feedback: armazena feedbacks comuser_id,organization_id,category,message,resolved(defaultfalse),resolved_at; RLS: INSERT para qualquer autenticado comuser_id = auth.uid(); SELECT e UPDATE restritos ao superadmin - Página
/superadmin/feedbacks: tabela com colunas Data, Categoria (badge colorido), Mensagem, Usuário (nome + e-mail), OSC, Resolvido; ordenação automática (não-resolvidos mais novos primeiro, resolvidos ao final); checkbox “Resolvido” executa UPDATE + re-fetch; linha resolvida fica tachada e com opacidade reduzida; contador de itens pendentes no topo - Seção “Alterar senha” em
/configuracoes/perfil: campos “Nova senha” e “Confirmar nova senha”, botão “Alterar senha”; chamasupabase.auth.updateUser({ password }); erroweak_password(HIBP) exibido inline abaixo do campo; sucesso limpa os campos e exibe toast de confirmação - Orientação de criação de senha em
/setupe em/configuracoes/perfil: texto estático “Use ao menos 8 caracteres combinando letras maiúsculas, minúsculas, números e símbolos. Evite senhas comuns.” abaixo do campo de senha; substituído por erro inline quando há falha de validação - Seção “Dados para reembolso” em
/configuracoes/perfil: seletor PIX ou TED, campos condicionais (tipo de chave + valor para PIX; banco/agência/conta para TED), todos opcionais, botão de salvar próprio desabilitado quando não há alteração; lê e grava emuser_profile.default_payment_info(JSONB) viauseUpdateProfile; formato compatível compaymentFromProfileno formulário de reembolso — prefill automático funciona sem alteração adicional
Corrigido (pós-lançamento Onda 4 — 2026-05-15)
- EF
approve_purchase_orderretornava HTTP 500 em toda tentativa de aprovação (BK-132): a CHECK constraintfm_account_required_unless_pending_reimbursementemfinancial_movementssó permitiaaccount_id = NULLparaorigin = 'reimbursement'; pedidos de pagamento aprovados (originpurchase_order) sem conta definida violavam a constraint ao criar o movimento financeiro; corrigido via migration que estendeu a constraint para também aceitarpurchase_orderpendente semaccount_id— mesmo comportamento já permitido para reembolsos; a EF já passava todos os campos corretamente (prompt #134) - Card “AGUARDANDO MINHA APROVAÇÃO” exibia
[object Object][object Object](BK-129): renderização incorreta do retorno da RPCcount_pending_purchase_orders_for_userno componente de card; corrigido para extrair corretamente o campo numérico (prompt #131) - Layout do formulário de pedido de pagamento divergia do formulário de reembolso (BK-133): DESCRIÇÃO aparecia como textarea grande no topo, antes de DATA DA DESPESA e VALOR; reordenado para DATA DA DESPESA + VALOR no topo, DESTINATÁRIO, DESCRIÇÃO (campo de linha única), CATEGORIA/PROJETO/CENTRO DE CUSTO, DADOS DE PAGAMENTO, OBSERVAÇÕES, DOCUMENTOS — igual ao padrão de
/reembolsos/novo(prompt #135)
Modificado (pós-lançamento Onda 4 — 2026-05-15)
- Rótulo da seção de anexos em pedidos de pagamento: “COMPROVANTES / NF” substituído por “Documentos” em todos os contextos do módulo (formulário de criação, formulário de edição inline, página de detalhe) — mesma terminologia de Reembolsos (prompt #133)
- Fluxo de confirmação de pagamento de pedidos: botão “Confirmar pagamento” removido da coluna AÇÕES da lista
/pagamentos; o tesoureiro confirma o pagamento diretamente na movimentação financeira gerada em/movimentacoes(ícone “Marcar como pago”), igual ao fluxo de Reembolsos; a EFpay_purchase_orderpermanece deployada mas sem ponto de entrada no frontend atual (prompt #133)
Corrigido
- Botões “Aprovar”/”Reprovar” não apareciam para aprovadores elegíveis na lista de reembolsos (BK-123): query do workflow de aprovação (
wfQ,organization_settings?key=eq.reimbursement_workflow) não disparava naReembolsosListPagepor problema de timing do React Query —enabled: !!activeOrganizationIdnunca transitava paratruea tempo; corrigido para aguardar oactiveOrganizationIdantes de executar o fetch;isEligibleApproveragora calcula sobre os dados reais da OSC em vez doEMPTY_WORKFLOWpadrão; regra de auto-aprovação (não ver botões no próprio reembolso) preservada (prompt #119) - Badge de reembolsos pendentes na TopNav não atualizava após aprovação/rejeição (BK-125): mutations de aprovação e rejeição não invalidavam a query que alimenta o badge; corrigido para invalidar também essa query ao concluir cada mutation com sucesso (prompt #122)
- Dialog “Reprovar solicitação” — botão habilitado sem motivo (BK-124): o botão “Confirmar reprovação” estava habilitado mesmo com o campo “Motivo” vazio; corrigido para desabilitar enquanto o campo estiver vazio ou só com espaços (prompt #121)
- Datas exibidas com 1 dia a menos (BK-121):
formatDate()emshared/lib/format.tsconvertia strings ISO date-only ("YYYY-MM-DD") vianew Date(value), que o JavaScript interpreta como UTC midnight; em UTC-3, isso recuava a exibição para o dia anterior. Corrigido detectando o padrãoYYYY-MM-DDe construindo oDatecom componentes locais (sem conversão de timezone). Afetava: coluna “Data da despesa” em/reembolsos, detalhe do reembolso (/reembolsos/:id) e campos Vencimento/Pagamento/Competência em/movimentacoes/:id. A lista de movimentações não era afetada (usavaparseISOdo date-fns) (prompt #120) - E-mail de convite não chegava ao usuário convidado:
add_user_to_organizationchamavasend_emailcomAuthorization: Bearer SERVICE_ROLE_KEY; após migração do Supabase para chavessb_secret_*(não-JWT), o gateway rejeitava com 401 antes do código rodar — invitation era criada masemail_send_logficava vazio; corrigido com autenticação Bearer correta + try/catch que gravafailed_allememail_send_logem caso de qualquer falha de chamada send_emailrejeita chamadas sem JWT:verify_jwt = falsedeclarado explicitamente emconfig.tomlparasend_emailecomplete_setup; autenticação manual aceita Bearer ==SUPABASE_SERVICE_ROLE_KEY(server-to-server) ou JWT comapp_metadata.is_superadmin = true(página de teste)- Cancelar convite retornava “Não foi possível aplicar a alteração”: transição
active_pending_setup → removedestava ausente dos pares válidos na função SQL_valid_uo_transition; adicionada via migration; handler doMemberActionsMenuagora também marcainvitations.status = revokedapós a transição - Botão “Reenviar e-mail de convite” não era clicável: condição de
disabledausente ou incorreta noMemberActionsMenupara membros emactive_pending_setup; corrigido comdisabled={busy}explícito durante a chamada;resend_setup_tokenusa o mesmo helperinvokeSendEmaildeadd_user_to_organizationcom try/catch +logEmailAttempt('failed_all')para rastreabilidade ememail_send_log complete_setupretornava “Erro inesperado” para senha rejeitada pelo HIBP: EF mascarava oerror_codereal do Supabase Auth como 500 genérico; agora propaga oerror_codeoriginal (incluindoweak_passwordcom status 422 e mensagem em pt-BR); demais erros do GoTrue também passam adiante oerror_codereal- Nome preenchido no setup não era salvo:
complete_setupnão executavaUPDATE user_profile SET full_nameapós a transição; corrigido para gravar o nome enviado no payload - Nome não persistia em
/configuracoes/perfil(toast de sucesso mas campo voltava vazio ao recarregar):UPDATEemuser_profileretornava 0 linhas — linha ausente ou RLS bloqueando silenciosamente; corrigido com upsert e/ou ajuste de policy - Tela em branco em
/configuracoes/reembolsosapós 1-2 segundos de exibição: violação das Rules of Hooks —useMemoememberByIdestavam declarados após early returns noConfiguracoesReembolsosPage, causando contagem diferente de hooks entre renders e desmonte da árvore pelo React; corrigido movendo todos os hooks para antes de qualquerreturncondicional - Tela em branco em
/reembolsos/:idao navegar via SPA (funcionava com F5): efeito cascata do bug anterior — o estado degradado do React contaminava navegações subsequentes na mesma sessão; resolvido com a correção do bug de Rules of Hooks acima
Adicionado (Onda 2 — melhorias pós-lançamento)
- Botão “Salvar e fazer outro” no formulário de novo lançamento (
/movimentacoes/novo): salva e reinicia o formulário mantendo tipo e conta — sem redirecionar para a lista; útil para lançamentos em sequência (prompt 69) - Indicação de filtros ativos abaixo dos cards de totais: quando qualquer filtro está ativo (
isDefault = false), exibe linha discreta “Filtrado por: [rótulos]” concatenados com “ · “; desaparece ao limpar filtros (prompt 70) - Ordenação por coluna na tabela de movimentações: Vencimento, Valor, Status e Conta ordenáveis com ciclo ASC → DESC → sem ordenação; indicador de direção no header ativo; ordenação client-side preservada ao trocar aba ou filtro (prompt 71)
- EF
delete_movements: substituibulk_update_movementscomp_action: 'delete'para exclusão de lançamentos; coletastorage_pathdefinancial_movement_attachments, remove arquivos do bucketmovement-attachments(falha individual não aborta), deleta lançamentos por CASCADE; retorna{ ok, deleted, storage_cleaned }; validação de ownership e limite de 500 IDs por chamada (prompt 72) - Coluna “Pagamento” na tabela de movimentações, entre “Vencimento” e “Lançamento”: exibe
payment_dateformatada; “—” quando não pago; ordenável com nulos por último no ASC (prompt 73) - Ordenação por Categoria na tabela de movimentações: ordena pelo nome da primeira categoria; splits com múltiplas categorias usam a primeira como critério (prompt 73)
- Ícones de ação por linha na tabela de movimentações: coluna “Ações” ao final da tabela (após Valor), sempre visível sem hover; ícone de lápis (editar) em todas as linhas; ícone contextual por status — cancelar (
pendente/atrasado), estorno (pago/efetivado), lixeira (cancelado/estornado); clicar abre o mesmo fluxo de confirmação existente (prompt 74)
Corrigido
canDelete()emmovementActions.tsexpandido para incluircanceladoeestornado— lançamentos finalizados podem ser excluídos (prompt 75)- Texto do dialog de confirmação de exclusão em lote corrigido: não menciona mais restrição de status (herdado da RPC antiga) (prompt 75)
- Botão “Excluir” na tela de detalhe (
/movimentacoes/:id) movido para fora do bloco condicional!finalized, tornando-o visível e habilitado para lançamentoscanceladoeestornado(prompt 77) - Tooltip do botão “Excluir” para lançamentos
pagoatualizado para mensagem coerente com a nova lógica de elegibilidade (prompt 77)
Modificado
- Exportação Excel: pacote
xlsx(SheetJS, abandonado, vulnerabilidades Prototype Pollution + ReDoS) substituído porexceljs(mantido ativamente); comportamento idêntico — mesmo arquivo, colunas e formatação (prompt 76) - Ícone de olho (visualizar) removido das linhas da tabela de movimentações — redundante com o clique na linha; mantido apenas o lápis (editar) (prompt 74)
- Exclusão de lançamentos (individual e em lote) migrada da RPC
bulk_update_movementspara a EFdelete_movements;bulk_update_movementscontinua sendo usada exclusivamente paramark_paid(prompt 72)
[v0.9.11] — 2026-05-14 · onda3-st9.11-configuracoes-reembolsos
Adicionado
- Aba “Reembolsos” em
/configuracoes(admin-only): seletor de aprovações necessárias (1 ou 2), checkboxes de papéis elegíveis (Dirigente, Tesoureiro), busca de pessoas específicas como aprovadores independente de papel, lista consolidada “Quem pode aprovar” com origem indicada (papel/pessoa), alerta âmbar quando nenhum aprovador configurado - Botão Salvar habilitado apenas quando há alteração (
isDirty) e ao menos um aprovador; mensagem inline “Selecione ao menos um papel ou uma pessoa aprovadora” quando inválido - Persistência via
set_organization_settings_bulkcom chavereimbursement_workflow; leitura viaread_organization_settingscom query própria e filtro client-side
[v0.9.10] — 2026-05-14 · onda3-st9.10-painel-badge
Adicionado
- Seção “Reembolsos” no
/painel: até 3 cards condicionais por papel — “Meus reembolsos pendentes” (rascunhos + rejeitados), “Aguardando minha aprovação” (aprovadores elegíveis) e “Aguardando pagamento” (tesoureiros); cada card clicável navega para/reembolsos?tab=<status> - Badge real no TopNav: exibe contagem com prioridade aprovador→tesoureiro→voluntário; oculto quando a contagem relevante = 0
- RPC
count_pending_reimbursements_for_user(p_org_id)(SECURITY DEFINER): retorna{ volunteer_pending, approver_pending, treasurer_pending }para o caller autenticado; lêreimbursement_workflowpara determinar elegibilidade do aprovador - Hook
useReimbursementsCountscompartilhado entre/painele TopNav (staleTime: 30s); elimina chamada dupla à RPC
[v0.9.9] — 2026-05-14 · onda3-st9.9-edicao-inline-rejeicao
Adicionado
- Edição inline após rejeição em
/reembolsos/:id: botão “Editar e reenviar” habilitado para requester quando status =rejeitado; expandeEditAndResubmitForminline com motivo da rejeição em destaque, campos pré-populados do reembolso e gestão de comprovantes sem ensureDraft - Sequência de salvamento:
update_reimbursement→submit_reimbursement; em sucesso, página recarrega emaguardando_aprovacao - Botão “Cancelar” recolhe sem salvar;
EditAndResubmitFormisolado emCardpróprio abaixo do grid
[v0.9.8] — 2026-05-14 · onda3-st9.8-preview-comprovantes
Adicionado
- Preview inline de comprovantes em
/reembolsos/:id: thumbnails automáticos para imagens (clicáveis para ampliar, fallback textual), botão lazy “Visualizar/Ocultar PDF” com iframe; outros tipos mantêm apenas download - Botão “Editar rascunho” (correção de gap — prompt 85b): em
/reembolsos/:idcom status =rascunho, requester navega para/reembolsos/novo?id=<uuid>; formulário carrega dados existentes, reutiliza o mesmo ID para uploads e salvamentos
[v0.9.7] — 2026-05-14 · onda3-st9.7-pay-reimbursement
Adicionado
- EF
pay_reimbursement: tesoureiro confirma pagamento; criafinancial_movementcomorigin = 'reimbursement'; salvapaid_movement_idno reembolso (link reverso); rollback best-effort do movimento em caso de falha posterior; notifica solicitante viasend_notification - Ação “Confirmar pagamento” em
/reembolsos/:id: select de conta financeira + data de pagamento; coordenado com Aprovar/Rejeitar; invalida caches definancial-movementseaccount-balances
[v0.9.6] — 2026-05-14 · onda3-st9.6-approve-reimbursement
Adicionado
- EF
approve_reimbursement: voto duplo retorna 409; suporta quorum parcial (notifica aprovadores restantes) e quorum final (notifica solicitante + tesoureiros); voto prévio do mesmo aprovador bloqueia com 409 distinto - Ação “Aprovar” em
/reembolsos/:id: comentário opcional, detecção de voto prévio desabilita botão, toasts diferenciados para aprovação parcial e final
[v0.9.5] — 2026-05-14 · onda3-st9.5-detalhe-rejeicao
Adicionado
- Página
/reembolsos/:id: 4 zonas — header (status, solicitante, valor), dados (campos + dados de pagamento condicionais por papel), comprovantes e timeline + ações - EF
reject_reimbursement: registra motivo emreimbursement_approvals, transiciona pararejeitado, notifica solicitante; motivo obrigatório lib/eligibility.ts: helper reutilizável comisApprover(roles, userId, workflow)ecanSeePayment— única fonte da verdade para elegibilidade na UI (reutilizado em ST-9.6, ST-9.7, ST-9.10 e ST-9.11)- Dados de pagamento PIX/TED ocultos para voluntários; visíveis apenas para aprovadores elegíveis e tesoureiro
[v0.9.4] — 2026-05-14 · onda3-st9.4-formulario-submit
Adicionado
- Formulário
/reembolsos/novo: data, valor, descrição, categoria, projeto, centro de custo, observações, método de pagamento PIX/TED com campos condicionais; dados pré-populados do perfil com checkbox “Salvar como padrão”; uploader com auto-create de registro rascunho - RPCs
create_reimbursement/update_reimbursement(SECURITY INVOKER): criação e edição de reembolsos com validação de organização - EF
submit_reimbursement: valida diff vs. snapshot da rejeição anterior, limpareimbursement_approvalsda rodada, transiciona paraaguardando_aprovacao, notifica aprovadores elegíveis - 3 storage policies para prefixo
reimbursements/{org_id}/{reimbursement_id}/no bucketmovement-attachments
Corrigido
- Rotas
/reembolsos,/reembolsos/novoe/reembolsos/:idausentes doApp.tsxapós ST-9.3 — registradas via prompt de continuação 81c
[v0.9.3] — 2026-05-14 · onda3-st9.3-rotas-lista
Adicionado
- Listagem
/reembolsos: 6 tabs por status (todos, rascunho, aguardando_aprovacao, aprovado, rejeitado, pago) persistidas via?tab=; coluna “Solicitante” condicional ao papel; item “Reembolsos” com badge no TopNav (placeholder — badge real na ST-9.10) - Rotas
/reembolsos,/reembolsos/novoe/reembolsos/:idregistradas emApp.tsx
[v0.9.2] — 2026-05-14 · onda3-st9.2-send-notification
Adicionado
- EF
send_notification(infraestrutura global reutilizável por todos os módulos): e-mail ativo vianodemailer@6.9.14/STARTTLS reutilizando_shared/smtp.ts; push/Telegram/WhatsApp como stubs; despacho paralelo por destinatário e canal;audit_logpor par (destinatário, canal); HTTP 200 exceto 400 de validação de input - Interface:
{ organization_id, event_type, recipients: [{ user_id, channels? }], payload: { title, body, link?, data? } } - Default quando
notification_preferencesausente: todos os canais habilitados; skip silencioso quando preferência é false ou dado de contato ausente no perfil
[v0.9.1] — 2026-05-14 · onda3-st9.1-schema-base
Adicionado
- Schema base de reembolsos: enum
reimbursement_status(rascunho → aguardando_aprovacao → aprovado → rejeitado → pago); tabelasreimbursements,reimbursement_approvals,reimbursement_attachmentscom triggersupdated_ate auditoria (reuso das funções existentes); RLS role-aware (voluntário vê apenas os próprios; dirigente/tesoureiro/admin/comissão veem todos da OSC) - Chave
reimbursement_workflowemorganization_settings(padrão EAV):{ required_approvals, allowed_approver_roles, allowed_approver_user_ids }; padrão{ required_approvals: 1, allowed_approver_roles: ["dirigente"], allowed_approver_user_ids: [] } - Campo
default_payment_info(JSONB) emuser_profilepara dados de pagamento padrão do usuário:{ payment_method, pix_key_type, pix_key, bank_name, bank_agency, bank_account }; UI adicionada em/configuracoes/perfilna correção pós-Onda 3
[v0.8.18] — 2026-05-13 · onda2-st8.18-cancelamento
Adicionado
- Cancelamento de lançamentos: status
canceladosuportado pelo trigger_fm_set_defaults_and_status; colunascancelled_at,cancelled_by,cancelled_reasonemfinancial_movements; índice parcial emorganization_id WHERE cancelled_at IS NOT NULL - EF
cancel_movement: suporta três escopos —this(lançamento isolado),this_and_future(a partir da posição na série),all(toda a série recorrente); filtra apenas elegíveis (pendenteouatrasado) e retorna{ cancelled_count, skipped_count }sem erro para os ignorados; motivo obrigatório - Modal de cancelamento em
/movimentacoes/:id: campo de justificativa obrigatório, seleção de escopo para séries/parcelamentos, exibição de erro inline quando EF recusa - Card de auditoria de cancelamento na tela de detalhe: exibe data, motivo e nome do responsável (resolvido via
get_user_display_names) - Aba “Cancelados” na lista de movimentações: tab dedicada com filtro de status
cancelado; lançamentos cancelados excluídos dos totais das demais abas - RPC
get_user_display_names(UUID[]): SECURITY DEFINER com verificação de co-membership por organização; retorna{ id, display_name }preferindofull_namedo perfil, depoisemail, depois—; usada para resolvercancelled_byereversed_byna tela de detalhe - Hook
useUserDisplayNames: chamada única com array de IDs deduplicados,staleTimede 5 min, evita N+1
Adicionado (habilitação contextual de ações — ST-8.18.1)
- Helper
movementActions.ts: única fonte da verdade para elegibilidade de ações por status —canDelete,canCancel,canReverse,canMarkPaid;disabledReason(action, status)para tooltips individuais;bulkEligibility(rows, action)para ações em lote - Matriz de elegibilidade aplicada em
MovimentoDetailPageeBulkActionsBar: botões Excluir, Cancelar, Estornar e Marcar como pago ficam visíveis mas desabilitados quando a ação não é permitida para o status atual; tooltip explicativo ao passar o cursor; lançamentoscancelado/estornadonão exibem nenhuma ação - Regra de lote: cada botão de ação em lote só habilita se TODOS os selecionados forem elegíveis; tooltip contextual quando desabilitado por seleção mista
- Botão “Estornar” em lote: adicionado à
BulkActionsBar; abre modal com motivo obrigatório; chamareverse_movementpor ID viaPromise.all
Corrigido
computeTotalsexcluía statusestornadodo cálculo mas nãocancelado— corrigido para ambosfiltersToPayloadnão tratava a tabcanceladas— adicionado override de status análogo ao deestornadas
[v0.8.17] — 2026-05-13 · onda2-st8.17-exportacao
Adicionado
- Botão “Exportar” na barra de ações da lista com dropdown “Exportar PDF” e “Exportar Excel”; aplica os filtros ativos no momento da exportação
- Exportação PDF: EF
export_movements_pdfchama Gotenberg com HTML renderizado no servidor; inclui cabeçalho (nome da OSC + período + filtros), tabela completa e rodapé com totais; download automático no browser - Exportação Excel: geração client-side via
lib/exportExcel.ts; colunas Vencimento, Pagamento, Título, Tipo, Status, Conta, Categoria(s), Valor (R$, numérico), Fornecedor, Observações;derivePeriodLabelpara nome do arquivo (inicialmente SheetJS; migrado paraexceljsem prompt 76) lib/periodLabel.ts: funçãoderivePeriodLabelque infere rótulo legível a partir dos filtros de período ativos (ex: “maio-2026”)
Corrigido
- EF
export_movements_pdfchamavalist_financial_movementsvia service_role, que retornaauth.uid() = NULLinternamente — corrigido para usar padrãocallerClientdas demais EFs que dependem deauth.uid()
[v0.8.16] — 2026-05-13 · onda2-st8.16-parcelamentos
Adicionado
- Modo “Parcelado” no toggle 3-vias do formulário de novo lançamento: número de parcelas (2–120), frequência, data da 1ª parcela
- Tabela de parcelas editável: datas calculadas pela frequência; valor por parcela editável com validação de soma em tempo real; diferença de centavos alocada na última parcela; linha de soma com indicador vermelho/verde; botão Salvar desabilitado enquanto soma divergir
- Modal de confirmação: resumo com count e intervalo de datas antes de criar
- EF
create_installment_series: criarecurring_seriescomis_installment = TRUE; cria Nfinancial_movementscomorigin = 'installment',series_positionetotal_amountindividual; valida queSUM(installment_amounts) === total_amountquando editado manualmente (tolerância de centavos); rollback total em caso de erro - Edição de parcelamentos via
update_recurring_series: escopoall/this_and_futurepreservatotal_amountindividual por parcela (sem achatar em valor único)
[v0.8.15] — 2026-05-13 · onda2-st8.15-acoes-em-lote
Adicionado
- Seleção múltipla na lista de movimentações: checkbox por linha + checkbox de seleção geral no header (com estado indeterminate); seleção limpa ao trocar de tab, filtro ou organização
- Barra de ações em lote: aparece quando ≥ 1 lançamento selecionado; exibe contador “N lançamentos selecionados”, botão “Limpar seleção”, “Marcar como pago” e “Excluir”
- Ação “Marcar como pago”: define
payment_date = hojenos selecionados com statuspendenteouatrasado; ignora os demais com aviso no toast (ex.: “3 marcados como pagos. 1 ignorado.”) - Ação “Excluir”: confirmação destrutiva com count; exclui apenas
pendenteouatrasado; toast com counts de excluídos e ignorados - RPC
bulk_update_movements(p_org_id, p_ids, p_action): executa em transação única; valida membership eorganization_idpor linha; açãomark_paidoudelete; retorna{ updated, ignored };REVOKE ALL+GRANT EXECUTE TO authenticated
Limitação conhecida: bulk delete remove registros de
financial_movement_attachmentsvia CASCADE mas não exclui os arquivos do bucketmovement-attachments(RPCs não têm acesso ao Storage). Arquivos órfãos serão endereçados em manutenção futura.
[v0.8.13b] — 2026-05-13 · onda2-melhorias-documentos
Adicionado
- Indicador de documentos na lista (
/movimentacoes): ícone de clipe (paperclip) discreto na linha do lançamento quandoattachment_count > 0; lançamentos sem documentos não exibem nada; campoattachment_countadicionado à RPClist_financial_movementsvia subqueryCOUNT(*) FROM financial_movement_attachments
Modificado
- Formatos de upload ampliados: zona de upload aceita qualquer formato exceto executáveis e scripts (
.exe,.bat,.cmd,.msi,.sh,.ps1,.vbs,.jare similares); limite de 10 MB mantido; mensagem de erro inline “Tipo de arquivo não permitido por segurança.” para formatos bloqueados - Renomeação “Comprovantes” → “Documentos”: título do card, estado vazio, mensagem de carregamento e toasts em
MovimentoDetailPage
Corrigido
- Lista de movimentações vazia após adição do
attachment_count:list_financial_movementsusavarow_to_jsonb(x)que falha com tipos anônimos de subquery em PostgreSQL; substituído porto_jsonb(x)(compatível com qualquer tipo, incluindo anônimos)
[v0.8.13] — 2026-05-13 · onda2-st8.13-comprovantes
Adicionado
- Card “Documentos” funcional em
/movimentacoes/:id: lista de anexos com nome do arquivo, tamanho formatado e data de envio; botão “Baixar” (URL assinada temporária do Storage) e botão “Remover” (com confirmação inline que exclui do banco e do bucket) - Zona de upload drag-and-drop e clicável: limite de 10 MB; validação de formato e tamanho com mensagem de erro inline; spinner durante envio; upload para bucket
movement-attachmentsno caminho{org_id}/{movement_id}/{filename}com sufixo numérico em caso de colisão de nome; registro emfinancial_movement_attachmentse atualização da lista sem reload - Substituição do stub “Nenhum documento anexado” pelo componente funcional; comportamento idêntico para lançamentos de qualquer status
[v0.8.12b] — 2026-05-13 · onda2-st8.12b-bugfixes-recorrencia
Corrigido
- Substituição de categorias em série:
replaceCategoriesfazia DELETE + INSERT em duas transações separadas; o trigger DEFERREDvalidate_split_sumdisparava no commit do DELETE (sum=0) antes do INSERT reinserir as linhas — errosplit_sum_mismatch. Solução: nova RPCreplace_movement_categories_bulkque executa DELETE + INSERT atomicamente em uma única função PL/pgSQL. - Data de vencimento em edição de série:
scope='all'escope='this_and_future'aplicavam o valor absoluto dedue_datea todos os lançamentos, achatando a distribuição temporal. Solução: cálculo de delta em dias entre a data informada e adue_datedo lançamento de referência, aplicado individualmente por linha;payment_datepreservada.
[v0.8.12] — 2026-05-13 · onda2-st8.12-edicao-recorrencia
Adicionado
- Rota
/movimentacoes/:id/editarcomEditarMovimentoPageeEditarMovimentoFormPage - Formulário de edição pré-preenchido via
get_financial_movement; reutilizaCategoriesSplitTablee helpers de opções do formulário de criação; sem toggle de tipo nem bloco de recorrência - Guard de status: se o movimento carregado não for ‘pendente’ ou ‘atrasado’, redireciona imediatamente para
/movimentacoes/:idcom toast “Este lançamento não pode ser editado.” - Banner discreto no topo indicando o escopo da edição (‘apenas este lançamento’, ‘este e os próximos’, ‘toda a série’)
- Modal de escopo em
MovimentoDetailPage: RadioGroup com 3 opções (‘Apenas este lançamento’, ‘Este e os próximos’, ‘Toda a série’), padrãothis; lançamentos semrecurring_series_idnavegam direto sem modal - EF
update_recurring_series: operação atômica para os 3 escopos —thisaplica dados e desvincula da série em uma única transação;this_and_futurecria novarecurring_seriescom os movimentos afetados reposicionados;allatualizatemplate_jsonbe todos os movimentos da série; a mutation do frontend usa sempre a EF para todos os escopos
[v0.8.11] — 2026-05-13 · onda2-st8.11-recorrencias
Adicionado
- Toggle 3-vias (Único / Parcelado stub / Recorrente) no formulário de novo lançamento
- Bloco de configuração de recorrência: frequência (diária, semanal, quinzenal, mensal, bimestral, trimestral, semestral, anual), data de início, modo de término (por nº de ocorrências ou data-fim)
- Preview dinâmico das próximas datas no bloco de recorrência
- Modal de confirmação antes de salvar série recorrente, com resumo do que será criado
- EF
create_recurring_series: criarecurring_series+ Nfinancial_movementscom datas calculadas em UTC; rollback em 3 camadas em caso de erro; suporte ais_installmentetotal_installment_amount
[v0.8.10] — 2026-05-13 · onda2-st8.10-estorno
Adicionado
- Modal de estorno em
/movimentacoes/:idcom campo de motivo obrigatório, gate no botão “Confirmar” e exibição de erro inline - Defesa contra estorno de transferências (bloqueio via validação na EF)
- EF
reverse_movement: validações (não estornado, não transferência), insert do movimento inverso comorigin='reversal'estatus='pago', cópia dos splits, atualização do original comreversed_at/reversed_by_movement_id/reversed_reason, rollback manual em caso de erro; erros 403 e 422 mapeados corretamente
[v0.8.9] — 2026-05-13 · onda2-st8.9-detalhe-lancamento
Adicionado
/movimentacoes/:id(detalhe do lançamento): header com tipo, status, título e valor; seções condicionais para split com percentuais, info de recorrência, estorno bidirecional e comprovantes placeholder- Seção de auditoria com datas de criação, atualização e campos de origem
- Botões contextuais por status: “Editar” visível para ‘pendente’/’atrasado’; “Estornar” visível para ‘pago’ não estornado
[v0.8.8] — 2026-05-13 · onda2-st8.8-split-categorias
Adicionado
- Toggle “Distribuir valor entre categorias” no formulário de novo lançamento
- Tabela de split com linhas editáveis de categoria + valor; validação de soma com tolerância de 0,005; gate do botão “Salvar” enquanto soma inválida
- Pré-população automática ao ligar o toggle (distribuição igualitária pelas categorias existentes) e limpeza ao desligar
[v0.8.7] — 2026-05-13 · onda2-st8.7-novo-lancamento + hotfixes de RPC
Corrigido
row_to_jsonb→to_jsonbem 4 RPCs da Onda 2:list_financial_movements,get_financial_movement,get_account_balances,create_financial_movement— PostgreSQL rejeitavarow_to_jsonb(record)quando usado com alias de subquery; substituído porto_jsonbque aceitarecordanônimo (via migration)- Payload de categorias em
create_financial_movement: formulário enviavacategory_idcomo campo top-level; corrigido paracategories: [{ category_id, amount }]conforme a RPC exige - Toast de erro genérico: adicionado log completo do erro Supabase (
code,message,details) antes de exibir toast, para facilitar diagnóstico futuro
[v0.8.7] — 2026-05-13 · onda2-st8.7-novo-lancamento
Adicionado
/movimentacoes/novo(formulário básico de criação de lançamento)- Toggle de tipo (Receita/Despesa/Transferência) com cores funcionais; adapta campos dinamicamente: exibe/oculta Categoria e Conta de destino conforme tipo selecionado
- Campos principais: título, data de vencimento, data de pagamento (opcional), valor total com máscara BRL, select de conta com saldo atual (
get_account_balances), select de categoria comfull_path(list_categories) - Campos de contexto: Projeto (desabilitado “Em breve” quando vazio), Centro de custo (
list_cost_centers) - Seção colapsável “Mais opções”: forma de pagamento, beneficiário/pagador, referência bancária, documento fiscal, tags, observações — inputs sempre montados para preservar estado RHF
- Sidebar reativa com resumo dinâmico (badge de tipo, título, valor, conta, categoria, vencimento) e checklist de preenchimento via
useWatch - Validações inline: valor > 0, categoria obrigatória para receita/despesa, contas distintas para transferência; botão “Salvar” desabilitado enquanto inválido
- Submissão via
create_financial_movement; sucesso invalida cache['movements', orgId]e navega para/movimentacoes - Schema Zod discriminado por tipo;
buildCreatePayloadconverte datas para ISO e campos vazios paranull
[v0.8.6] — 2026-05-13 · onda2-st8.6-lista-movimentacoes
Adicionado
/movimentacoes(lista completa): substituição do stub pela lista funcional- Filtros-chip persistidos em
sessionStoragepor orgId: Período (padrão: mês corrente), Conta, Categoria (comfull_path), Status — cada chip com X individual e botão “Limpar filtros” - 5 tabs por tipo: Todas, Receitas, Despesas, Transferências, Estornadas; tab “Estornadas” desabilita chip de Status e força
status: 'estornado'no payload - Tabela com colunas: Vencimento, Lançamento (título + meta), Conta, Categoria (
full_pathou “N categorias”), Status (badge colorido), Valor (cor por tipo) - Hover na linha: ícones Eye e Pencil navegam para
/movimentacoes/:id; linha inteira clicável para o mesmo destino - Linha de totais calculada client-side: receitas, despesas, saldo do período (ou total único para tabs Transferências/Estornadas); saldo colorido por sinal
- Skeleton de 8 linhas e estado vazio com botão “Limpar filtros”
- Hook
useMovementFilters+useMovementsList(TanStack Query); helpersfiltersToPayload,movementLabels,computeTotals
[v0.8.5] — 2026-05-13 · onda2-st8.5-configuracoes-categorias
Adicionado
/configuracoes/categorias(acesso admin): 3 tabs — Receitas, Despesas (árvore 2 níveis com indentação), Centros de custo (lista plana)- Reordenamento via botões ▲/▼ com persistência de
display_orderviaupsert_categoryemPromise.all - Slideover criar/editar categoria: kind travado ao da tab ativa na criação; texto fixo na edição; select de pai limitado a raízes do mesmo kind; desabilitado em categorias que já têm filhos
- Slideover criar/editar centro de custo: nome + descrição, via
upsert_cost_center - Diálogos de ativar/desativar para categorias e centros de custo, com toast de erro descritivo da RPC
- Modal “Aplicar template”: lista templates via
list_category_templates, preview de categorias por kind, aplicação viaapply_category_templatecom toast de contagem; segunda aplicação exibe “Nenhuma categoria nova” (comportamento idempotente) - Aba “Categorias” na sidebar do
ConfiguracoesLayout(admin-only, ícone Tag) - Helpers puros
buildCategoryTreeeswapDisplayOrder
[v0.8.4] — 2026-05-13 · onda2-st8.4-configuracoes-contas
Adicionado
/configuracoes/contas(acesso admin): lista de contas com saldo atual via VIEWaccount_current_balance, badge de status, opacidade reduzida em contas inativas, estado vazio- Slideover de criar/editar conta: campos obrigatórios (nome, tipo, saldo inicial, data de abertura) + seções colapsáveis “Dados bancários” e “Personalização” (cor, ícone); salva via
upsert_financial_account - Diálogo de ativar/desativar: confirmação antes de agir; erro da RPC exibido como toast descritivo; usa
toggle_account_status - Aba “Contas” adicionada à sidebar do
ConfiguracoesLayout(visível apenas para admins, ícone Wallet) accountTypeLabels.tscom mapa enum→label PT para os 7 tipos de conta
[v0.8.3] — 2026-05-13 · onda2-st8.3-painel-rotas
Adicionado
PainelPagefuncional: bloco de saldos por conta (VIEWaccount_current_balance, apenas contas ativas, saldo total no rodapé, estado vazio com link para/configuracoes/contas) + bloco de KPIs do mês corrente via RPClist_financial_movements(receitas, despesas, saldo do mês com cor por sinal)RequireAuthemsrc/features/auth/components/: wrapper de rota que verifica sessão viauseAuth(), exibe spinner durante carregamento e redireciona para/loginse não autenticado- 4 rotas stub registradas em
App.tsxsobRequireAuth:/movimentacoes,/movimentacoes/novo,/movimentacoes/importar,/movimentacoes/:id - Skeleton nos blocos do painel durante carregamento de dados
[v0.8.2] — 2026-05-13 · onda2-st8.2-schema-movimentacoes
Adicionado
- Enums:
movement_type(receita, despesa, transferencia),movement_origin(manual, recurring, installment, contribution),movement_status(pendente, pago, atrasado, estornado, efetivado) - Tabela
recurring_series: RLS canônica, suporte a parcelamentos viais_installment BOOLEAN+total_installment_amount - Tabela
financial_movements: FK parafinancial_accounts,recurring_series,projects,vendors; colunastatuscontrolada por triggerBEFORE INSERT OR UPDATE(não GENERATED STORED —CURRENT_DATEnão é IMMUTABLE no PostgreSQL); campotransfer_peer_idpara par de transferência - Tabela
financial_movement_categories(split): trigger DEFERREDvalidate_split_sumgarante que soma das linhas = total do movimento no COMMIT; constraint impede split em transferências - Tabela
movement_attachments: registro de comprovantes comstorage_path - Bucket
movement-attachments(privado): path{org_id}/{movement_id}/{filename} - VIEW
account_current_balance:initial_balance + receitas pagas - despesas pagas + transferências efetivadas recebidas - transferências efetivadas enviadas - 5 RPCs:
list_financial_movements(filtros: type, status, period_start/end, account_id, category_id),get_financial_movement(lançamento completo com split e anexos),create_financial_movement(com array de categories para split),update_financial_movement,get_account_balances(lêaccount_current_balance)
Técnico
- GENERATED STORED para
statusdescartado: trigger BEFORE INSERT OR UPDATE garante os 5 estados corretamente e mantém o índice(organization_id, status)populado com todos os valores (inclusiveatrasado) - Trigger DEFERRED
validate_split_sumdispara ao COMMIT, não no INSERT — permite inserir linhas de split em múltiplos statements dentro da mesma transação - Isolamento de snapshot de CTE: INSERTs em CTEs não são visíveis a SELECTs na mesma instrução — validações foram feitas em statements separados
[v0.8.1] — 2026-05-13 · onda2-st8.1-schema-base
Adicionado
- Schema base da Onda 2 (financeiro): tabelas
projects(stub para FK futura),vendors,vendor_ratings,financial_accounts,categories,cost_centers,category_templates— todas com RLS canônica e audit trigger - Enums:
account_type(7 valores) ecategory_kind(receita, despesa) - VIEW
categories_with_pathcomsecurity_invoker = true: retornafull_pathno formato “Pai > Filho” para uso em autocomplete e listagens - 12 RPCs de CRUD:
list/upsert/toggle_statuspara contas financeiras, categorias e centros de custo;list_category_templates;apply_category_template(idempotente — duas passadas: pais → filhos) - Seed “Padrão Grupo Escoteiro 2026” em
category_templates: 35 categorias (14 receitas + 21 despesas) prontas para aplicação via RPC - Função
_set_updated_at()criada localmente na migration (não existia função genérica global no projeto) - Pattern
to_regclassnas RPCs de toggle_status: checagem de movimentações associadas ativada automaticamente quandofinancial_movementsfor criada na ST-8.2, sem alterar as RPCs
Processo
- Adicionada regra ao
CLAUDE.md: aprovação de plano do Lovable com ressalvas exige prompt escrito (NNb-...-aprovacao.md) — ressalva nunca pode ficar apenas no chat
[v0.7.6] — 2026-05-12 · config-plataforma-st7.6-perfil-notificacoes
Adicionado
- Seção “Notificações” em
/configuracoes/perfil, independente do formulário principal (salva emuser_preferencesviaset_settingcomp_level: "user") - Campo WhatsApp: editável, formato E.164, validação inline, pré-preenchido com valor salvo
- Campo Telegram: read-only, exibe “Vinculado” / “Não vinculado” com base em
contact.telegram_chat_id, instrução para vincular via @BussolaBot - Nota de rodapé explicando escopo global das preferências
[v0.7.5] — 2026-05-12 · config-plataforma-st7.5-org-tabs
Adicionado
- 3 novas seções de integração ao final de
/configuracoes/organizacao(acesso admin da OSC)- Google Drive: JSON da conta de serviço (secret, não sobrescreve Vault quando em branco), ID da pasta de exportação e de importação
- WhatsApp Business: Phone Number ID + token de acesso (secret, não sobrescreve quando em branco)
- Telegram por OSC: Chat ID do grupo/canal
- Stubs funcionais: formulários salvam via
set_organization_settings_bulk, backend ativo pendente - Cada seção exibe nota “Esta integração ainda não está ativa…”
[v0.7.4] — 2026-05-12 · config-plataforma-st7.4-gotenberg-stubs
Adicionado
GotenbergIntegrationPanel: URL, timeout (UI em segundos, salvo em ms), header de autenticação (secret), botão “Testar geração” com resultado inline (tempo em ms ou erro)- 4 stubs funcionais em
/superadmin/configuracoes: Telegram, n8n, LLM/IA e S3/R2 — formulários com Salvar operacional, badge “Em breve” na sidebar _stubShared.tsx:<StubNote>e<Field>compartilhados entre os stubs
Corrigido
storage.s3.access_keyera retornado como valor em claro pela RPCread_platform_config_for_admin; corrigido paraaccess_key_is_set: boolean(Vault, nunca expõe o valor)usePlatformConfig: tipos3.access_key: string | nullatualizado paraaccess_key_is_set: boolean- Timeout do Gotenberg: UI exibia e recebia valor em segundos mas EF espera milissegundos; conversão explícita adicionada
[v0.7.3] — 2026-05-12 · config-plataforma-st7.3-email
Adicionado
PlatformSettingsPagefuncional em/superadmin/configuracoes: layout 2 colunas (sidebar + painel), hookusePlatformConfig(chamaread_platform_config_for_admin), roteamento por integração selecionadaIntegrationSidebarcom badges de status por integração (ativo / config / erro / em breve)EmailIntegrationPanelcom 3 subcards independentes: SMTP primário (6 campos + teste inline), Resend (API key + from), Padrões de e-mail (DPO, reply-to, fallback toggle)IntegrationStatusBadge+computeStatus+formatRelativeTime- Botão “Testar envio” no subcard SMTP com resultado inline (✓ / ✗ + tempo em ms)
Corrigido
- Bug crítico em
send_email/index.ts:SmtpConfig.secureébooleanmas o banco armazenavasecurity: string;loadSmtpConfigagora mapeiasecurity === 'SSL/TLS'→secure: true
[v0.7.2] — 2026-05-12 · config-plataforma-st7.2-superadmin-layout
Adicionado
SuperadminLayout: sidebar teal-dark, navegação/superadmin/configuracoes,/superadmin/organizacoes,/superadmin/usuariosSuperadminRoute: guard de acesso via RPCread_platform_config_for_admincomo proxy de verificação de superadmin- Hook
useIsSuperadminemsrc/hooks/(evita dependência invertida shared→features) - Badge ⚡ no
TopNavpara superadmins - Rotas
/superadmin/*emApp.tsx; páginas/organizacoese/usuarioscom<ComingSoonPage>
[v0.7.1] — 2026-05-12 · config-plataforma-st7.1-backend
Adicionado
- RPC
read_platform_config_for_admin(VOLATILE, SECURITY DEFINER): retorna todas as configurações de plataforma comis_set: booleanpara secrets (nunca expõe o valor) - Template
testnosend_emailpara botão de teste de SMTP - Edge Function
test_gotenberg: dispara geração de PDF de teste e retorna{ ok, ms }
[v0.6.7] — 2026-05-11 · onda1-st6.7-gate-politica
Adicionado
- Gate de aceite de política:
RootRedirectconsultacurrent_policy+user_consent; redireciona para/aceitar-politicaquando necessário (fail-open se RPC falhar) AceitarPoliticaPage: layout split teal/branco, reutiliza<PolicyConsent>e<AuthBrandPanel>, insert emuser_consentcom user_agent, redirect para/após aceite
[v0.6.6] — 2026-05-11 · onda1-st6.6-config-organizacao
Adicionado
/configuracoes/organizacaocompleto (acesso admin): dados básicos da OSC (nome, CNPJ, contato, endereço, redes sociais), logo (bucketorganization-logos, resize 512×512), configurações operacionais (moeda, timezone, ano fiscal), toggle de solicitações públicas (accepts_public_signup), permissões do papel Público- RPC
set_organization_settings_bulkpara salvar múltiplas chaves deorganization_settingsem uma única chamada - RPCs
read_organization_settings,update_organization_basic,update_organization_logo_path - Componente
OrgLogoUploader(separado doAvatarUploaderde perfil)
[v0.6.5] — 2026-05-11 · onda1-st6.5-usuarios-admin
Adicionado
/configuracoes/usuarioscompleto (acesso admin): listagem de membros com filtros, busca e paginação client-side (cap 500);AddUserDrawerdisparando EFadd_user_to_organization;MemberActionsMenucom todas as transições válidas da máquina de estado (alterar papel, desativar, reativar, remover, cancelar convite, reenviar setup)MemberAvatarcom signed URL (TTL 1h)useIsActiveOrgAdmincom fast-path JWT para superadminConfiguracoesLayoutcom sidebar adaptativa (aba “Usuários” visível apenas para admins)- RPC
list_pending_org_requestsunificandopending_organization_linkseuser_organizationpendentes, com identidade real via COALESCE
Corrigido
- GRANT em
transition_user_organization_status(estava REVOKE’d deauthenticateddesde ST-1) - Nome nulo na listagem (COALESCE com
auth.users.raw_user_meta_data->>'full_name') - Avatar no
TopNavpassou a leravatar_storage_pathdeuser_profile
[v0.6.4] — 2026-05-08 · onda1-st6.4-perfil
Adicionado
/configuracoes/perfil: Identificação (nome + avatar), Contato (telefone E.164), Dados sensíveis (data de nascimento, CPF e RG cifrados no Vault), Ações (logout global + instruções LGPD)- Tabela
user_profile1:1 comauth.users, RLS, trigger de auditoria comaudit_excluded_columnspara campos do Vault - RPCs
set_user_profile_sensitive+get_user_profile_decrypted(SECURITY DEFINER, Vault) - Bucket
user-avatarsprivado (2 MB, jpg/png/webp),<AvatarUploader>autônomo (resize 512×512 JPEG) <ConfirmDialog>emshared/components/feedback/docs/lgpd-data-inventory.md: 23 campos catalogados com base legal, prazo de retenção e mecanismo de anonimização
[v0.6.3] — 2026-05-05 · onda1-st6.3-setup-token
Adicionado
/setup?token=...funcional: FSM com 10 estados (loading → ready → submitting → 4 terminais), validação Zod com react-hook-form, layout split idêntico ao/loginSetupPagecom tratamento diferenciado porreasonretornado porvalidate_setup_token- EF
dev_seed_setup_tokencom duplo guard (APP_ENV=dev+ service-role) para QA local - Script
bin/seed-setup-token.shcom listagem interativa de OSCs e indução dos 9 cenários da FSM
[v0.6.2] — 2026-05-05 · onda1-st6.2-criar-conta
Adicionado
/criar-contaem dois modos: wizard anônimo de 3 passos (email → decisões → completar) eLoggedNoOrgViewpara usuário autenticado sem OSC- EF
create_organizationcomcreateOrganizationWithSlug(sufixo-2,-3…) list_public_organizations()SECURITY DEFINER- Tradutor pt-BR de erros em
onboarding-errors.ts
Corrigido (OPSEC sweep — ADR-004)
- Removidos
details: err.messageem 27 pontos de 8 Edge Functions (ST-6.2 + retroativos em ST-4 e ST-5 +send_email) — zero vazamento de mensagem interna em respostas 500
[v0.6.1] — 2026-05-05 · onda1-st6.1-login-redirects
Adicionado
/login: email/senha + Google OAuth,RootRedirectcom 3 branchesuseAuth(combinagetSession+onAuthStateChange),useActiveOrganizationOrgSwitchercom selo de iniciais, dropdown de avatar com logout
[v0.5.0] — 2026-05-05 · onda1-st5-self-signup-and-links
Adicionado
- EFs
start_self_signup,complete_self_signup,request_organization_link,approve_organization_link,reject_organization_link - UPDATE atômico para evitar race em approve/reject
_shared/onboarding_common.tspara reuso entre EFs
[v0.4.1] — 2026-05-05 · onda1-st4-onboarding-direct-with-resend
Adicionado
- EFs
add_user_to_organization,validate_setup_token,complete_setup,resend_setup_token,request_setup_resend - Schemas Zod, helpers compartilhados, configuração de
verify_jwtpor EF
[v0.3.0] — 2026-05-05 · onda1-st3-send-email-with-secrets
Adicionado
- Edge Function
send_email: SMTP primário + Resend fallback, 6 templates, tabelaemail_send_log - Integração com Vault via
set_setting/get_settingcom cifragem real (substituto de pgsodium)
[v0.2.0] — 2026-05-05 · onda1-st2-settings-policies
Adicionado
- 7 tabelas:
platform_settings,organization_settings,user_preferences,policies,user_consent,invitations,pending_organization_links - Auditoria com redação condicional para secrets
- Função
current_policy(type),custom_access_token_hook(não-ativável em Lovable Cloud — TODO operacional)
[v0.1.0] — 2026-05-05 · onda1-st1-schema-base
Adicionado
- Schema base PostgreSQL com RLS multi-tenant: funções
is_member_of,has_role_in,current_user_is_superadmin - Máquina de estado de
user_organizationcom guard trigger (7 estados) audit_log+ trigger genérico reutilizável- Hardening:
search_pathfixo,REVOKE EXECUTEnas funções sensíveis
Última atualização: 2026-05-13 · melhorias pós-Onda 2 (prompts 69–77)