Files
sar-android/_bmad-output/implementation-artifacts/deferred-work.md
Julio Schlickmann dc61705c91 add project files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 22:33:42 -03:00

13 KiB
Raw Blame History

Deferred Work

Deferred from: code review de 3-2-ler-acrescimo-do-postgresql-no-sync-de-consulta (2026-04-16)

  • hasColunaAcrescimoSig() chamado duas vezes por sessão de sync em PedidoPGSQL.save() (insert path, Story 3.1) e em PedidoPGSQL.selectAllPedConsulta() (consult read path, Story 3.2) — durante janela de DDL migration, os dois boolean podem divergir, causando insert com tx_acrescimo + read sem (ou vice-versa). Em produção, DDL deve ocorrer fora de janelas de sync. Mitigação: elevar o boolean para campo de instância ou parâmetro compartilhado de sessão se a migração ao vivo se tornar necessária.

Deferred from: code review de 3-3-incluir-vl-acrescimo-no-md5-de-change-detection (2026-04-16)

  • Ramo Gerente sem guard hasColunaAcrescimoGerente() para acrev em PedidoPGSQL.selectAllPedConsulta() linha 629 — premissa verificada em Story 3.1: coluna acrev existe em gerente.pedidos desde antes do Epic 3 (estava no INSERT sendo gravada como 0). Adicionar guard seria over-engineering; se aparecer instalação Gerente legada hipotética, considerar simetria com SIG.
  • Colisão teórica por concatenação MD5 sem delimitador entre A.total e COALESCE(A.acrev, 0.0) (e entre outros termos numéricos adjacentes já presentes no hash) em PedidoPGSQL.selectAllPedConsulta() — risco pré-existente em todo o MD5 Gerente/SIG. Mitigação seria refatorar o hash inteiro para usar separador (ex: || '|' ||), forçando novo re-sync em massa e sendo inconsistente se aplicado só ao novo termo. Avaliar em refatoração maior do sync de consulta.
  • Hash pode variar entre versões do PostgreSQL por mudanças em extra_float_digits / float4out afetando formatação textual de REAL em concatenações || A.total || COALESCE(A.acrev, 0.0) — risco pré-existente (A.total já sofria a mesma exposição). Mitigação: usar to_char(campo, 'FM999999990.00') em todos os termos numéricos do hash; upgrade do PG pode causar re-sync em massa silencioso.
  • pedido_consulta.md5 TEXT sem NOT NULL em DatabaseHelperped.setMd5(null) gera literal "'null'" no INSERT e loop de update infinito — pré-existente; caminho requer falha do MD5() server-side (improvável). Adicionar guard em PedidoConsultaDB.insert/updateErp ou NOT NULL na coluna em migração futura.

Deferred from: code review de 3-1-enviar-acrescimo-ao-postgresql-ao-salvar-pedido (2026-04-16)

  • ped.getFormapag() sem null-check antes de getTxAcrescimo() em PedidoPGSQL.insert() linha 182 e insertSig() linha 425 — pré-existente: a mesma ausência de null-check existe nas linhas 160 e 387 que vêm antes; se formapag fosse null, crasharia antes das novas chamadas.
  • Schema 'sig' hardcoded como string literal em hasColunaAcrescimoSig() — pré-existente projeto-wide; toda a classe usa literais 'sig' e 'gerente' sem constante.
  • Valores monetários com setDouble para acrep/acrev — pré-existente projeto-wide; todos os campos monetários usam setDouble.
  • codVend2 = null pode causar NullPointerException em st.setInt(36, codVend2) se sig.corrent não tiver registro para o cliente — bug pré-existente em insertSig().
  • information_schema.columns sem filtro table_catalog — baixo risco prático em JDBC por-banco; consistente com schemaTes().
  • information_schema.columns mais lento que pg_attribute — consistente com padrão de schemaTes() na mesma classe; otimizar se latência se tornar problema.
  • keys.close()/st.close() não garantidos se loop de itens lança exceção em insertSig() — pré-existente; conexão fecha ao final da sessão.
  • Comentário morto //int ultimoNumeroPedido = 0; em save() — pré-existente.

Deferred from: code review de 2-4-exibir-acrescimo-na-consulta-de-pedidos (2026-04-16)

  • PedidoPGSQL não inclui vl_acrescimo na sync com PostgreSQL — nem no envio local→PG nem no retorno PG→pedido_consulta; pedidos recém-sincronizados via PG terão vl_acrescimo = 0 em pedido_consulta até que o sync PG do acréscimo seja implementado em story futura; já deferred em Story 2.3.
  • MD5 de pedido_consulta não inclui vl_acrescimo em change-detection — mudanças isoladas de acréscimo não disparam re-sync; reavaliar junto com sync PG; já deferred em Story 2.3.
  • total é recalculado de itens em tempo real enquanto vl_acrescimo é congelado quando status >= STATUS_ENVIADO — mesmo padrão que descontoV estabelecido em Story 2.3; risco teórico de inconsistência se itens forem reprecificados após envio, mas cenário improvável (itens de pedido enviado geralmente não mudam localmente).
  • Índice 66 hard-coded em PedidoConsultaDB.selectFull() — lista de índices posicionais cresceu para 4366; migrar para c.getColumnIndexOrThrow("vl_acrescimo") em refatoração futura da camada DB.
  • SQL por concatenação de strings em PedidoConsultaDB.insert/updateErp — padrão projeto-wide pré-existente; migrar para PreparedStatement/bind params em refatoração maior.
  • Lógica duplicada de cálculo+guard de acréscimo em MainPedidoFragment.fillFields, MainPedidoFragment.atualizarResumoPedido e TotalPedidoFragment.FillFields — três cópias da mesma lógica; extrair para helper em refatoração futura; já deferred em Story 2.2.
  • Ausência de onDowngrade() em DatabaseHelper — padrão projeto-wide pré-existente; instalação de APK mais antigo após v43 crashará com SQLiteException; implementar política de downgrade (drop+recreate ou reject) em refatoração futura.

Deferred from: code review de 2-3-persistir-acrescimo-ao-fechar-o-pedido (2026-04-16)

  • PedidoPGSQL não inclui vl_acrescimo — sync para PostgreSQL não transmite o acréscimo calculado; escopo de story futura de sincronização; reavaliar quando PedidoPGSQL for atualizado para enviar pedidos com acréscimo.
  • fillFields() recalcula vlAcrescimo com taxa atual ao abrir pedido existente — se o usuário abrir e re-salvar um pedido sem alterações, o vl_acrescimo é recalculado com o tx_acrescimo vigente, potencialmente perdendo o valor histórico. By-design para esta história; AC2 cobre apenas sync automático.
  • MD5 do pedido não inclui vl_acrescimo — change-detection para sync pode não detectar pedidos cujo único campo alterado é o acréscimo; reavaliar quando PedidoPGSQL for atualizado.
  • Índice 59 do cursor lê DATE(D.data_inicio) em vez de C.md5 — bug pré-existente em PedidoDB.selectAllFull() e selectFull() que preenche FormaPagamento.md5 com um valor de data incorreto; não introduzido por esta story.
  • SQL building via string concatenation — toda a camada PedidoDB usa StringBuilder em vez de PreparedStatement; risco de SQL injection se campos String forem concatenados no futuro; padrão projeto-wide.
  • Global.pedido sem null-check antes de setVlAcrescimo() — padrão pré-existente em MainPedidoFragment; mesmo risco de NPE existente em todos os outros acessos a Global.pedido.
  • Aritmética de ponto flutuante para valor monetáriovl_acrescimo usa double / REAL, padrão projeto-wide; arredondamento gerenciado por Util.formataValorMonetario().

Deferred from: code review de 1-1-migracao-do-schema-sqlite-para-suporte-a-acrescimo (2026-04-16)

  • FormaPagamentoPGSQL não lê acresc do PostgreSQL — tx_acrescimo sempre sincronizará como 0.0 até Story 1.2 ser implementada. Esperado — escopo da Story 1.2.
  • ClienteDB join em formapag não lê tx_acrescimoFormaPagamento carregado via consulta de cliente terá txAcrescimo=0.0. Considerar ao implementar Story 2 (cálculo do acréscimo no pedido): garantir que o cálculo use FormaPagamentoDB.selectId() ou equivalente, não o VO hidratado via ClienteDB.
  • PedidoDB join em formapag não inclui tx_acrescimo — formapag hidratado em contexto de pedido/consulta terá txAcrescimo=0.0. Sem impacto em Story 1.x; monitorar em Story 2.
  • selectIdErp com lista de colunas incompleta (falta desco_perc e tx_acrescimo) — bug pré-existente em FormaPagamentoDB.java:194. O método só verifica existência, sem impacto funcional. Corrigir quando refatorar a classe.
  • Padrão de SQL por concatenação de strings (SQL injection risk) em FormaPagamentoDB.java — risco pré-existente em toda a classe. Migrar para db.execSQL() com ? placeholders quando houver refatoração maior.

Deferred from: code review de 2-1-exibir-campo-de-acrescimo-na-tela-do-pedido (2026-04-16)

  • layout_weight="1" com layout_width="wrap_content" nos layouts de pedido — tecnicamente 0dp é o correto para distribuição de peso em LinearLayout/TableRow, mas padrão pré-existente em todos os rows do projeto. Considerar corrigir em refatoração de layout futura.
  • atualizarResumoPedido() em MainPedidoFragment não possui null-guard nem try/catch — tvAcrescimoPedido (e os demais campos tvQtdTotal, tvTotalGeral) podem lançar NPE se chamado antes de onCreateView() ou após Global.pedido = null. Risco pré-existente; adicionar try/catch em refatoração futura.
  • setUserVisibleHint() em TotalPedidoFragment pode disparar FillFields() antes de onCreateView() — todos os TextViews (incluindo tvAcrescimo) seriam null; NPE silenciosamente engolido pelo catch(Exception e){} sem log. Pré-existente; adicionar null-check no início de FillFields().
  • Strings hardcoded no XML dos layouts de pedido ("Acréscimo", "Acréscimo (+)", etc.) em vez de @string/ resources — padrão pré-existente em todo o projeto; migrar para strings.xml em refatoração de internacionalização futura.
  • new UpdatePedItemActivity().precoComIpi() instancia Activity fora do ciclo de vida Android — anti-padrão pré-existente em MainPedidoFragment e TotalPedidoFragment; extrair para método estático ou utilitário em refatoração futura.

Deferred from: code review de 2-2-calcular-acrescimo-ao-selecionar-forma-de-pagamento (2026-04-16)

  • txAcrescimo negativo não guardado no cálculo do acréscimo — banco de dados do ERP possui checagem para valores negativos; guard Math.max(0.0, txAcrescimo) desnecessário.
  • Global.pedido sem null-check em atualizarResumoPedido() — método já acessa Global.pedido.* sem guard; padrão pré-existente [MainPedidoFragment.java:958].
  • Global.pedido sem null-check em TotalPedidoFragment.FillFields() — NPE seria silenciosa dentro do catch(Exception e){} vazio [TotalPedidoFragment.java:74].
  • Lógica de cálculo do acréscimo duplicada em fillFields() e atualizarResumoPedido() sem método auxiliar — padrão DRY violado pré-existente no projeto.
  • catch (Exception e) {} vazio em TotalPedidoFragment.FillFields() engole exceções sem log — pré-existente.
  • Aritmética de ponto flutuante (double) para valores monetários — padrão projeto-wide; Util.formataValorMonetario() já trata formatação.
  • codigoLiberacao2() computa hash de autorização sem acréscimo — supervisor autoriza valor menor que o real quando txAcrescimo > 0; endereçar em Story 2.3 ao persistir o total com acréscimo.
  • validaCampos() verificações de limite de crédito e vlPedMin usam getTotalProduto() excluindo acréscimo — pré-existente, avaliar em Story 2.3.
  • Race condition: listForPagtos preenchido em background thread vs UI thread — pré-existente [MainPedidoFragment.java:193].
  • Inconsistência de threshold em fillFields() (≤ STATUS_LIBERADO) vs atualizarResumoPedido() (< STATUS_ENVIADO) para descontoV — pré-existente.
  • FormaPagamento em Global.pedido pode estar stale após sync — txAcrescimo reflete taxa pré-sync até usuário navegar da tela.

Deferred from: code review de 1-2-sincronizacao-da-taxa-de-acrescimo-do-erp (2026-04-16)

  • Resource leak: PreparedStatement e ResultSet em FormaPagamentoPGSQL.executaSelectAll() não são fechados em bloco finally — se uma exceção ocorrer mid-iteration, os recursos não são liberados. Pre-existente na classe; corrigir com try-with-resources ou bloco finally em refatoração futura.
  • SQL injection via concatenação de strings no WHERE em FormaPagamentoPGSQLid_empresa e dt_atual interpolados diretamente. Pre-existente; mesma origem que o item acima de FormaPagamentoDB.
  • coalesce(libera_credito) sem argumento padrão no SELECT do PostgreSQL — COALESCE com argumento único é no-op e não protege contra NULL. Pre-existente; usar coalesce(libera_credito, 0) em refatoração futura.
  • setDescontoPerc(rs.getInt(6)) lê coluna decimal como inteiro, truncando frações — pre-existente; usar rs.getDouble() em refatoração futura.
  • Chave mal colocada em AtualizaDados.atualizaFormaPag(): bloco if (ultAtualizacao == null) tem { após a declaração mas antes de inativaAll, fazendo inativaAll executar sempre. Pre-existente; verificar comportamento real em testes manuais e corrigir.