Files
sar-android/_bmad-output/planning-artifacts/epics.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

17 KiB
Raw Blame History

stepsCompleted, inputDocuments
stepsCompleted inputDocuments
step-01-validate-prerequisites
step-02-design-epics
step-03-create-stories
_bmad-output/planning-artifacts/prd.md
_bmad-output/project-context.md

SARAndroid - Epic Breakdown

Overview

Este documento apresenta o epic e histórias para a funcionalidade de Acréscimo Financeiro no Pedido, decompondo os requisitos do PRD em histórias implementáveis para o agente desenvolvedor.

Requirements Inventory

Functional Requirements

FR1: O sistema sincroniza gestao.formapag.acresc (PostgreSQL) para formapag.tx_acrescimo (SQLite) durante a comunicação FR2: O sistema trata tx_acrescimo = NULL como 0.0, sem erro ou interrupção FR3: O sistema migra o schema SQLite de v40 para v41, adicionando tx_acrescimo REAL DEFAULT 0 na tabela formapag FR4: A migração preserva todos os registros existentes de formas de pagamento FR5: O representante visualiza o valor do acréscimo financeiro em campo dedicado no pedido, sempre visível FR6: O sistema calcula o acréscimo ao selecionar forma de pagamento: acrescimo = subtotal × (tx_acrescimo / 100) FR7: O sistema recalcula o acréscimo automaticamente ao trocar a forma de pagamento FR8: O campo acréscimo exibe R$ 0,00 quando tx_acrescimo = 0 ou NULL FR9: O total do pedido reflete subtotal + acrescimo FR10: O sistema grava o valor calculado do acréscimo no registro do pedido ao fechar FR11: O sistema grava o total com acréscimo no registro do pedido ao fechar FR12: O representante visualiza o total com acréscimo em pedidos fechados que possuem o campo gravado FR13: O sistema exibe pedidos sem campo de acréscimo sem alteração ou erro FR14: Ao enviar pedido ao ERP (PedidoPGSQL.insert), o app grava a taxa (% acréscimo) e o valor calculado nos campos corretos conforme o sistema (Gerente: gerente.pedidos.acrep + acrev; SIG: sig.pedidos.tx_acrescimo) FR15: Ao sincronizar pedidos de consulta do ERP (PedidoPGSQL.selectAllPedConsulta), o app lê o acréscimo dos campos corretos conforme o sistema e popula Pedido.vlAcrescimo (para SIG, calcula vlAcrescimo = total × tx_acrescimo / 100 server-side não grava valor) FR16: Sync tolera ausência das colunas de acréscimo no PostgreSQL (DDL server-side pode preceder ou seguir o deploy do app sem interromper a comunicação) FR17: MD5 de pedido_consulta inclui vl_acrescimo no cálculo de hash, garantindo que mudanças isoladas de acréscimo disparem re-sync

NonFunctional Requirements

NFR1: Recálculo do acréscimo ao trocar forma de pagamento: < 100ms (operação aritmética em memória, sem I/O) NFR2: Leitura de tx_acrescimo do SQLite executada em thread background, sem impacto na responsividade da UI NFR3: tx_acrescimo = NULL nunca causa NullPointerException — tratamento defensivo obrigatório em todo ponto de acesso NFR4: Migração v40→v41 idempotente: múltiplas execuções de onUpgrade() não corrompem dados NFR5: Sync tolera ausência da coluna acresc no PostgreSQL (schemas antigos) sem interromper a comunicação NFR6: Após sync bem-sucedido, tx_acrescimo reflete acresc para 100% das formas de pagamento ativas

Additional Requirements

  • Migração implementada em DatabaseHelper.onUpgrade() com guard if (oldVersion < 41)
  • dbVersao incrementado para 41 em DatabaseHelper
  • Nenhuma dependência nova — sem JARs adicionais em libs/
  • Toda leitura SQLite em thread background (regra absoluta do projeto)
  • tx_acrescimo = NULL tratado como 0.0 em todo ponto de acesso
  • Valor do acréscimo gravado no pedido no fechamento (não recalculado na consulta)
  • ⚠️ Verificar antes da implementação se tabela pedido já possui campo para acréscimo calculado

UX Design Requirements

Sem documento UX — feature brownfield sem nova tela. Requisitos de UI derivados do PRD:

  • Campo acréscimo sempre visível na tela de edição do pedido (R$ 0,00 quando zero)
  • Recálculo disparado automaticamente na seleção/troca da forma de pagamento
  • Total do pedido atualizado na mesma interação

FR Coverage Map

FR Epic Descrição
FR1 Epic 1 Sync gestao.formapag.acrescformapag.tx_acrescimo
FR2 Epic 1 Tolerância a NULL no SQLite
FR3 Epic 1 Migração schema v40→v41
FR4 Epic 1 Preservação de registros na migração
FR5 Epic 2 Campo acréscimo sempre visível no pedido
FR6 Epic 2 Cálculo ao selecionar forma de pagamento
FR7 Epic 2 Recálculo ao trocar forma de pagamento
FR8 Epic 2 Exibir R$ 0,00 quando sem acréscimo
FR9 Epic 2 Total = subtotal + acréscimo
FR10 Epic 2 Gravar acréscimo calculado no pedido
FR11 Epic 2 Gravar total com acréscimo no pedido
FR12 Epic 2 Consulta: exibir total com acréscimo se existir
FR13 Epic 2 Consulta: pedidos antigos sem alteração
FR14 Epic 3 Envio outbound do acréscimo ao PG (Gerente: acrep+acrev; SIG: tx_acrescimo)
FR15 Epic 3 Leitura inbound do acréscimo do PG na sync de consulta
FR16 Epic 3 Tolerância a ausência das colunas de acréscimo no PG
FR17 Epic 3 MD5 de pedido_consulta incluindo vl_acrescimo

Epic List

Epic 1: Disponibilizar Taxa de Acréscimo no Dispositivo

O sistema armazena a taxa de acréscimo de cada forma de pagamento localmente, sincronizada do ERP, pronta para uso offline. FRs cobertos: FR1, FR2, FR3, FR4

Epic 2: Acréscimo Financeiro no Pedido

O representante visualiza e utiliza o acréscimo financeiro ao criar pedidos, com cálculo automático ao selecionar a forma de pagamento, total correto e histórico preservado na consulta. FRs cobertos: FR5, FR6, FR7, FR8, FR9, FR10, FR11, FR12, FR13

Epic 3: Sync Bidirecional do Acréscimo entre App e ERP

O acréscimo calculado localmente é enviado ao PostgreSQL ao fechar o pedido, e pedidos históricos sincronizados do ERP trazem o acréscimo de volta ao SQLite — tornando a feature end-to-end funcional em Gerente e SIG. FRs cobertos: FR14, FR15, FR16, FR17


Epic 1: Disponibilizar Taxa de Acréscimo no Dispositivo

O sistema armazena a taxa de acréscimo de cada forma de pagamento localmente no SQLite, sincronizada do ERP, pronta para uso offline.

Story 1.1: Migração do Schema SQLite para Suporte a Acréscimo

Como desenvolvedor do sistema, quero migrar o schema SQLite de v40 para v41 adicionando tx_acrescimo na tabela formapag, para que as taxas de acréscimo possam ser armazenadas localmente sem afetar dados existentes.

Acceptance Criteria:

Dado que o app está sendo atualizado em um dispositivo com schema SQLite v40 Quando DatabaseHelper.onUpgrade() for executado Então a coluna tx_acrescimo REAL DEFAULT 0 é adicionada à tabela formapag E todos os registros existentes de formas de pagamento são preservados com tx_acrescimo = 0

Dado que onUpgrade() é chamado com oldVersion >= 41 Quando o bloco de migração v41 for avaliado Então a migração é ignorada (guard if (oldVersion < 41)) sem erro

Dado que dbVersao em DatabaseHelper Quando a migração for aplicada Então dbVersao = 41


Story 1.2: Sincronização da Taxa de Acréscimo do ERP

Como representante de vendas, quero que a taxa de acréscimo de cada forma de pagamento seja sincronizada do ERP para o app durante a comunicação, para que os cálculos de acréscimo usem sempre os valores atualizados do servidor.

Acceptance Criteria:

Dado que gestao.formapag no PostgreSQL possui a coluna acresc com valores preenchidos Quando a ComunicaActivity executar o sync de formas de pagamento Então o valor de acresc é gravado em formapag.tx_acrescimo no SQLite para cada forma de pagamento

Dado que gestao.formapag no PostgreSQL não possui a coluna acresc (schema antigo) Quando o sync de formas de pagamento for executado Então a comunicação continua sem erro e tx_acrescimo permanece com o valor anterior (ou 0)

Dado que o VO FormaPagamento é carregado após o sync Quando FormaPagamentoDB preencher o objeto Então o campo tx_acrescimo está acessível no VO, com valor 0.0 quando NULL no banco


Epic 2: Acréscimo Financeiro no Pedido

O representante visualiza e utiliza o acréscimo financeiro ao criar pedidos, com cálculo automático ao selecionar a forma de pagamento, total correto e histórico preservado na consulta.

Story 2.1: Exibir Campo de Acréscimo na Tela do Pedido

Como representante de vendas, quero ver um campo de acréscimo sempre visível na tela do pedido, para que eu saiba em todo momento se há acréscimo aplicado, mesmo que seja zero.

Acceptance Criteria:

Dado que estou na tela de edição do pedido (UpdatePedidoActivity) Quando a tela for exibida Então um campo "Acréscimo" é visível mostrando R$ 0,00 por padrão

Dado que nenhuma forma de pagamento foi selecionada ou a selecionada tem tx_acrescimo = 0 Quando o campo acréscimo for exibido Então mostra "R$ 0,00" — nunca fica oculto ou em branco


Story 2.2: Calcular Acréscimo ao Selecionar Forma de Pagamento

Como representante de vendas, quero que o acréscimo seja calculado e exibido automaticamente ao selecionar a forma de pagamento, para que eu veja o valor real do pedido sem precisar calcular manualmente.

Acceptance Criteria:

Dado que estou editando um pedido com subtotal R$ 3.500,00 Quando selecionar "Boleto 30/60/90" com tx_acrescimo = 2.5 Então o campo "Acréscimo" exibe R$ 87,50 e o total exibe R$ 3.587,50

Dado que já selecionei "Boleto 30/60/90" (2,5%) e troco para "Dinheiro" (tx_acrescimo = 0) Quando a forma de pagamento for alterada Então o campo "Acréscimo" retorna a R$ 0,00 e o total retorna a R$ 3.500,00

Dado que a forma de pagamento selecionada tem tx_acrescimo = NULL Quando o cálculo for executado Então acréscimo = R$ 0,00, sem crash ou NullPointerException

Dado que o cálculo é disparado Quando a troca de forma de pagamento ocorrer Então o recálculo conclui em menos de 100ms (aritmética em memória)


Story 2.3: Persistir Acréscimo ao Fechar o Pedido

Como sistema, quero gravar o valor do acréscimo calculado e o total com acréscimo no registro do pedido ao fechar, para que o valor histórico seja preservado independente de alterações futuras na taxa.

⚠️ Pré-condição de implementação: Verificar se a tabela pedido no SQLite já possui colunas para acréscimo e total-com-acréscimo. Se não existirem, esta história inclui a adição dessas colunas na migração (incrementar dbVersao conforme necessário).

Acceptance Criteria:

Dado que um pedido foi editado com acréscimo R$ 87,50 e total R$ 3.587,50 Quando o pedido for salvo/fechado Então o valor do acréscimo (87,50) está gravado no registro do pedido no SQLite

Dado que um pedido foi salvo com acréscimo Quando a taxa de acréscimo da forma de pagamento for alterada no ERP e sincronizada Então o valor gravado no pedido antigo permanece inalterado

Dado que um pedido é criado com forma de pagamento sem acréscimo Quando o pedido for salvo Então o acréscimo gravado é 0,00


Story 2.4: Exibir Acréscimo na Consulta de Pedidos

Como representante de vendas, quero ver o total correto (com acréscimo) na consulta de pedidos já fechados, para que o histórico reflita os valores reais praticados.

Acceptance Criteria:

Dado que consulto um pedido fechado que possui acréscimo gravado Quando a tela de consulta exibir o pedido Então o valor total exibido inclui o acréscimo registrado no pedido

Dado que consulto um pedido fechado criado antes desta funcionalidade (sem campo de acréscimo) Quando a tela de consulta exibir o pedido Então o pedido é exibido normalmente sem erro, sem tentativa de recalcular acréscimo


Epic 3: Sync Bidirecional do Acréscimo entre App e ERP

O acréscimo calculado localmente é enviado ao PostgreSQL ao fechar o pedido, e pedidos históricos sincronizados do ERP trazem o acréscimo de volta ao SQLite. Torna a feature end-to-end funcional em ambos os sistemas (Gerente e SIG), fechando as Jornadas 3 e 4 do PRD para pedidos que trafegam pelo ERP.

Pré-condições server-side (DDL no PostgreSQL)

Estas alterações no PostgreSQL podem ser executadas antes, durante ou depois do deploy do app — o código trata a ausência das colunas (FR16). Recomenda-se executar ANTES do deploy para que o primeiro sync já carregue dados completos.

Sistema Gerente:

ALTER TABLE gerente.pedidos ADD COLUMN acrep REAL DEFAULT 0;  -- % de acréscimo
ALTER TABLE gerente.pedidos ADD COLUMN acrev REAL DEFAULT 0;  -- valor calculado do acréscimo

Sistema SIG:

ALTER TABLE sig.pedidos ADD COLUMN tx_acrescimo REAL DEFAULT 0;  -- % de acréscimo (valor é derivado server-side)

Assimetria Gerente vs SIG

  • Gerente armazena taxa + valor → histórico congelado no ERP mesmo se a taxa em formapag mudar depois
  • SIG armazena só a taxa → valor é sempre calculado server-side; histórico reflete a taxa vigente no pedido no momento do envio

Esta assimetria é uma característica dos schemas de destino e deve ser respeitada — não é uma inconsistência a corrigir.


Story 3.1: Enviar Acréscimo ao PostgreSQL ao Salvar Pedido

Como sistema, quero enviar a taxa e o valor do acréscimo ao PostgreSQL quando um pedido for sincronizado para o ERP, para que o valor praticado localmente seja registrado no sistema central e fique disponível para relatórios do escritório.

Acceptance Criteria:

Dado que Global.sistema == SISTEMA_GERENTE e um pedido com vl_acrescimo = 87.50 (calculado sobre taxa 2,5%) é enviado via PedidoPGSQL.insert Quando o INSERT em gerente.pedidos for executado Então a coluna acrep contém 2.5 (taxa da forma de pagamento) e acrev contém 87.50 (valor calculado)

Dado que Global.sistema == SISTEMA_SIG e o mesmo pedido é enviado Quando o INSERT em sig.pedidos for executado Então a coluna tx_acrescimo contém 2.5 (só a taxa; o valor é derivado server-side)

Dado que um pedido sem acréscimo (forma de pagamento com tx_acrescimo = 0) é enviado Quando o INSERT for executado em qualquer dos dois sistemas Então o campo correspondente recebe 0.0 sem erro

Dado que a coluna de acréscimo ainda não existe no PostgreSQL (schema antigo) Quando o INSERT tentar gravar o campo Então a comunicação falha de forma graciosa (registra no gestao.log e segue) OU o INSERT é construído condicionalmente sem o campo quando o DBA ainda não aplicou o DDL — decisão de design a resolver na implementação


Story 3.2: Ler Acréscimo do PostgreSQL no Sync de Consulta

Como representante de vendas, quero que pedidos históricos sincronizados do ERP cheguem ao app com o acréscimo correto gravado, para que a consulta exiba os valores reais praticados mesmo em pedidos que não foram criados neste dispositivo.

Acceptance Criteria:

Dado que Global.sistema == SISTEMA_GERENTE e gerente.pedidos possui acrep = 3.0 e acrev = 105.00 para um pedido Quando PedidoPGSQL.selectAllPedConsulta ler o registro Então o VO Pedido retornado tem vlAcrescimo = 105.00

Dado que Global.sistema == SISTEMA_SIG e sig.pedidos possui tx_acrescimo = 3.0 e total = 3500.00 para um pedido Quando PedidoPGSQL.selectAllPedConsulta ler o registro Então o VO Pedido retornado tem vlAcrescimo calculado como 3500.00 × 3.0 / 100 = 105.00

Dado que a coluna de acréscimo não existe no PostgreSQL ou está NULL Quando selectAllPedConsulta for executado Então o VO recebe vlAcrescimo = 0.0, sem erro, sem crash

Dado que PedidoConsultaDB.saveAll recebe os VOs retornados Quando gravar em pedido_consulta Então pedido_consulta.vl_acrescimo reflete o valor lido do PG (via Story 2.4 que já aceita o campo)


Story 3.3: Incluir vl_acrescimo no MD5 de Change-Detection

Como sistema, quero que mudanças isoladas de vl_acrescimo num pedido disparem re-sync do registro local, para que ajustes de acréscimo no ERP (reabertura, correção manual server-side) sejam propagados ao dispositivo.

Acceptance Criteria:

Dado que um pedido já sincronizado no SQLite tem vl_acrescimo = 87.50 Quando o ERP alterar só o vl_acrescimo do registro (ex: correção do escritório) e recalcular o MD5 Então o MD5 recebido muda, e PedidoConsultaDB.saveAll detecta a divergência e dispara updateErp

Dado que o MD5 do PG inclui vl_acrescimo (ou acrev / tx_acrescimo × total) no hash Quando o app calcular o MD5 local para comparação Então o cálculo reflete o mesmo campo — evitando loop de "está diferente" / "está igual" entre as duas direções

Dado que pedidos pré-Epic 3 no ERP têm acrep/acrev/tx_acrescimo com valor default (0) Quando o primeiro sync após o deploy rodar Então esses pedidos aparecem como "atualizados" (MD5 mudou devido ao novo campo), mas o vl_acrescimo gravado é 0.0 — comportamento aceitável