Files
sar-android/_bmad-output/implementation-artifacts/1-1-migracao-do-schema-sqlite-para-suporte-a-acrescimo.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

10 KiB

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

Status: done

Story

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

  1. 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

  2. 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

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

  4. Dado que o VO FormaPagamento é instanciado após a migração Quando FormaPagamentoDB preencher o objeto a partir do SQLite Então o campo txAcrescimo está acessível no VO, com valor 0.0 para registros antigos

Tasks / Subtasks

  • Task 1: Incrementar versão e adicionar migração em DatabaseHelper (AC: 1, 2, 3)

    • 1.1 - Alterar dbVersao de 40 para 41 na linha 10 de DatabaseHelper.java
    • 1.2 - Adicionar bloco de migração em onUpgrade() após o bloco v40 existente (linhas 700-703):
      if (oldVersion < 41) {
          db.execSQL("ALTER TABLE formapag ADD COLUMN tx_acrescimo REAL DEFAULT 0;");
      }
      
    • 1.3 - Atualizar o CREATE TABLE formapag em onCreate() (linhas 82-95) para incluir tx_acrescimo REAL DEFAULT 0 antes do fechamento dos parênteses (após libera_credito INT)
  • Task 2: Adicionar campo txAcrescimo ao Value Object FormaPagamento (AC: 4)

    • 2.1 - Adicionar campo private double txAcrescimo; em FormaPagamento.java
    • 2.2 - Adicionar getter getTxAcrescimo() e setter setTxAcrescimo(double txAcrescimo)
    • 2.3 - Inicializar txAcrescimo = 0.0 (padrão implícito para double, mas documentar intenção)
  • Task 3: Atualizar FormaPagamentoDB para incluir tx_acrescimo em todas as operações (AC: 4)

    • 3.1 - Atualizar INSERT em FormaPagamentoDB.java: adicionar tx_acrescimo na lista de colunas e formaPagamento.getTxAcrescimo() nos valores (linha ~68)
    • 3.2 - Atualizar UPDATE em FormaPagamentoDB.java: adicionar tx_acrescimo = ? na cláusula SET e o valor correspondente nos ContentValues (linha ~89-103)
    • 3.3 - Atualizar todos os SELECT em FormaPagamentoDB.java que mapeiam ResultSet para o VO: adicionar leitura de tx_acrescimo e chamar setTxAcrescimo() com cursor.getDouble(colIndex) — verificar linhas ~115-116, ~163-164, ~227, ~255, ~282
    • 3.4 - Usar cursor.isNull(colIndex) ? 0.0 : cursor.getDouble(colIndex) ao ler tx_acrescimo para tratar NULL defensivamente (NFR3)

Dev Notes

Escopo desta história

Esta história cobre APENAS migração de schema SQLite e atualização do VO/DAO local (FR3, FR4). A sincronização com PostgreSQL (gestao.formapag.acresctx_acrescimo) é escopo da Story 1.2. A UI do pedido e cálculo são escopo do Epic 2.

Arquivos a modificar

Arquivo Caminho O que muda
DatabaseHelper.java src/br/com/jcsinformatica/sarandroid/database/ dbVersao 40→41, onCreate() CREATE TABLE, onUpgrade() bloco v41
FormaPagamento.java src/br/com/jcsinformatica/sarandroid/vo/ Novo campo txAcrescimo, getter/setter
FormaPagamentoDB.java src/br/com/jcsinformatica/sarandroid/database/ INSERT, UPDATE, todos os SELECTs

NÃO modificar nesta história:

  • FormaPagamentoPGSQL.java — escopo da Story 1.2
  • ComunicaActivity.java — escopo da Story 1.2
  • Qualquer Activity ou layout de pedido — escopo do Epic 2

Estado atual do código (verificado em análise)

DatabaseHelper.java linha 10:

private static int dbVersao = 40;

formapag CREATE TABLE atual (linhas 82-95):

CREATE TABLE formapag (
    id_formapag    INTEGER PRIMARY KEY AUTOINCREMENT,
    id_empresa     INT     NOT NULL,
    id_erp         INT     NOT NULL,
    codigo         INT     NOT NULL,
    descricao      TEXT    NOT NULL,
    ativo          INT     NOT NULL,
    parcelas       INT     NOT NULL,
    desco_perc     REAL    NOT NULL,
    md5            TEXT    NOT NULL,
    vl_ped_min     REAL    ,
    libera_credito INT     ,
    FOREIGN KEY ( id_empresa ) REFERENCES empresa ( id_empresa ),
    UNIQUE ( id_empresa, id_erp ) ON CONFLICT ABORT
)

Último bloco onUpgrade() — v40 (linhas 700-703):

if (oldVersion < 40){
    db.execSQL("ALTER TABLE empresa ADD COLUMN id_empresa_prod INT NOT NULL DEFAULT 0;");
    db.execSQL("ALTER TABLE empresa ADD COLUMN id_empresa_grup INT NOT NULL DEFAULT 0;");
}

FormaPagamento.java — campos atuais: id, idErp, codigo, descricao, ativo (boolean), parcelas, descontoPerc, md5, vlPedMin, liberaCredito

Regras críticas do projeto

  • Sem testes automatizados — o projeto não tem JUnit/Espresso. Validação é manual via dispositivo/emulador. Não criar arquivos de teste.
  • Sem Kotlin — somente Java puro
  • Sem Gradle — projeto Eclipse ADT, não criar build.gradle
  • guard obrigatório: if (oldVersion < 41) — idempotência da migração (NFR4)
  • NULL defensivo: cursor.isNull() antes de cursor.getDouble() em tx_acrescimo (NFR3)
  • DEFAULT 0 na coluna: garante que registros existentes não ficam com NULL após ALTER TABLE (FR4)
  • Strings visíveis ao usuário em res/values/strings.xml — esta história não tem UI, regra não se aplica aqui
  • onUpgrade() sem guard de versão apaga dados de produção — nunca omitir o if (oldVersion < N)

Tratamento de NULL

SQLite ALTER TABLE ... ADD COLUMN com DEFAULT 0 preenche automaticamente os registros existentes com 0, mas registros inseridos antes da migração com NULL explícito precisam ser tratados no código. Usar sempre:

double txAcrescimo = cursor.isNull(colIndex) ? 0.0 : cursor.getDouble(colIndex);
formaPagamento.setTxAcrescimo(txAcrescimo);

Mapeamento PostgreSQL → SQLite (referência para Story 1.2)

A coluna PostgreSQL é gestao.formapag.acresc → mapeia para formapag.tx_acrescimo no SQLite. O FormaPagamentoPGSQL.java precisa ser atualizado na próxima história para incluir este mapeamento.

Verificação manual após implementação

  1. Instalar app em dispositivo/emulador com banco v40 existente → verificar que formapag ganha coluna tx_acrescimo sem perda de dados
  2. Instalar app em dispositivo limpo (fresh install) → verificar que formapag é criado com tx_acrescimo
  3. Reinstalar app (v41 → v41) → verificar que não ocorre erro (idempotência)

Project Structure Notes

  • Estrutura Eclipse ADT: código em src/, recursos em res/, libs em lib/
  • Pacote raiz: br.com.jcsinformatica.sarandroid
  • Nomenclatura DAO SQLite: *DB.javaFormaPagamentoDB.java já segue o padrão

References

  • [Source: _bmad-output/project-context.md#Schema SQLite] — regras de migração, dbVersao, guard obrigatório
  • [Source: _bmad-output/project-context.md#Regras Críticas] — proibições absolutas (sem Kotlin, sem Gradle, sem testes)
  • [Source: _bmad-output/planning-artifacts/epics.md#Story 1.1] — ACs e requisitos funcionais FR3, FR4
  • [Source: _bmad-output/planning-artifacts/prd.md#Schema e Migração] — FR3, FR4, NFR3, NFR4
  • [Source: src/br/com/jcsinformatica/sarandroid/database/DatabaseHelper.java] — estrutura atual, dbVersao=40
  • [Source: src/br/com/jcsinformatica/sarandroid/vo/FormaPagamento.java] — campos atuais do VO
  • [Source: src/br/com/jcsinformatica/sarandroid/database/FormaPagamentoDB.java] — INSERT linha ~68, UPDATE linha ~89, SELECTs linhas ~115, ~163, ~227, ~255, ~282

Review Findings

  • [Review][Defer] FormaPagamentoPGSQL não lê acresc do PostgreSQL — tx_acrescimo sempre sincroniza como 0.0 até Story 1.2 ser implementada [postgres/FormaPagamentoPGSQL.java] — deferred, escopo da Story 1.2
  • [Review][Defer] ClienteDB join em formapag não lê tx_acrescimoFormaPagamento carregado via consulta de cliente terá txAcrescimo=0.0; considerar ao implementar Story 2 [database/ClienteDB.java] — deferred, pre-existing
  • [Review][Defer] PedidoDB join em formapag não inclui tx_acrescimo — formapag hydratado em contexto de pedido/consulta terá txAcrescimo=0.0 [database/PedidoDB.java] — deferred, pre-existing
  • [Review][Defer] selectIdErp com lista de colunas incompleta (falta desco_perc e tx_acrescimo) — bug pré-existente, sem impacto pois o método só verifica existência [database/FormaPagamentoDB.java:194] — deferred, pre-existing
  • [Review][Defer] Padrão de SQL por concatenação de strings (SQL injection risk) — pré-existente em toda a classe, não introduzido por este diff [database/FormaPagamentoDB.java] — deferred, pre-existing

Dev Agent Record

Agent Model Used

claude-sonnet-4-6 (create-story workflow)

Debug Log References

Completion Notes List

  • Story 1.1 implementada em 2026-04-16.
  • dbVersao incrementado 40→41 em DatabaseHelper.java.
  • Bloco if (oldVersion < 41) adicionado em onUpgrade() com ALTER TABLE formapag ADD COLUMN tx_acrescimo REAL DEFAULT 0.
  • onCreate() atualizado para incluir tx_acrescimo REAL DEFAULT 0 na definição da tabela formapag.
  • Campo txAcrescimo (double) adicionado ao VO FormaPagamento.java com getter/setter.
  • 5 métodos SELECT em FormaPagamentoDB.java atualizados: selectAll, select, selectUltimoUsado, selectAvista, selectId — todos lendo índice 11 com isNull defensivo.
  • Métodos insert e update em FormaPagamentoDB.java atualizados para persistir tx_acrescimo.
  • Sem testes automatizados (projeto não possui infraestrutura de testes). Validação é manual via emulador/dispositivo.

File List

  • src/br/com/jcsinformatica/sarandroid/database/DatabaseHelper.java
  • src/br/com/jcsinformatica/sarandroid/vo/FormaPagamento.java
  • src/br/com/jcsinformatica/sarandroid/database/FormaPagamentoDB.java