Capítulo 20: Projeto Capstone: App Mobile de Gestão Financeira com Auditoria JSON

Especialização em Mobile Nativo com Android • Kotlin 2.0 & Jetpack Compose


🗺️ Mapa Conceitual da Arquitetura Limpa do Projeto Capstone

flowchart TD
    subgraph PRESENTATION["Camada de Apresentação (Jetpack Compose M3 + MVI)"]
        UI_MAIN["AppGestaoFinanceiraScreen (Scaffold, TopAppBar, FAB)"]
        CARD_BALANCO["CardBalancoPatrimonial (Gradiente, Saldo Total)"]
        LISTA["LazyColumnTransacoes (Itens com Animação e Swipe)"]
        BOTTOM_SHEET["ModalBottomSheet (Formulário de Novo Lançamento)"]
        VM["FinanceiroViewModel (StateFlow<FinanceiroUiState>)"]
        
        UI_MAIN --> CARD_BALANCO
        UI_MAIN --> LISTA
        UI_MAIN --> BOTTOM_SHEET
        VM -->|"Emite UiState"| UI_MAIN
        UI_MAIN -->|"Dispara Intent"| VM
    end

    subgraph DOMAIN["Camada de Domínio (Pure Kotlin / Use Cases)"]
        UC_CALC["CalcularBalancoPatrimonialUseCase"]
        UC_AUDIT["GerarRelatorioAuditoriaJsonUseCase"]
        REPO_INTERFACE["TransacaoRepository (Interface)"]
        
        VM --> UC_CALC
        VM --> UC_AUDIT
        UC_CALC --> REPO_INTERFACE
        UC_AUDIT --> REPO_INTERFACE
    end

    subgraph DATA["Camada de Dados (Room Database + Ktor + DataStore)"]
        REPO_IMPL["TransacaoRepositoryImpl"]
        ROOM_DB["AppFinanceiroRoomDb"]
        DAO["TransacaoDao (Flow<List<TransacaoEntity>>)"]
        KTOR_CLIENT["KtorBackupHttpClient"]
        
        REPO_INTERFACE -.-> REPO_IMPL
        REPO_IMPL --> DAO
        DAO --> ROOM_DB
        REPO_IMPL --> KTOR_CLIENT
    end

    style PRESENTATION fill:#ede7f6,stroke:#7e57c2,stroke-width:2px
    style DOMAIN fill:#b3e5fc,stroke:#0288d1,stroke-width:2px
    style DATA fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
    style VM fill:#fff3e0,stroke:#ff9800,stroke-width:2px
    style UI_MAIN fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px

🏛️ 1. O Desafio Corporativo do Projeto Capstone

Neste projeto de consolidação de especialização, sintetizamos todas as tecnologias canônicas estudadas ao longo dos 20 capítulos em uma aplicação robusta de nível bancário e corporativo: um Aplicativo Mobile de Gestão Financeira com Auditoria JSON:

  1. Separação Rigorosa de Responsabilidades (Clean Architecture): A camada de apresentação (Compose) desconhece se os dados vêm de uma API REST em nuvem ou de uma tabela SQLite local. A camada de domínio contém regras de negócio puras (cálculo de balanço, validação de transações) escritas em Kotlin puro, viabilizando 100% de cobertura em testes unitários ultra-rápidos na JVM.
  2. Offline-First e Reatividade Extremo a Extremo: Toda inserção ou remoção feita pelo usuário é persistida atomicamente no Room Database. A interface reage em tempo real através da cadeia Room DAO -> Flow -> Repository -> ViewModel StateFlow -> Composable, sem nenhuma sincronização manual imperativa.
  3. Módulo de Auditoria e Exportação JSON: Implementamos um caso de uso dedicado à geração de relatórios de auditoria contábil estruturados em JSON, compatíveis com microsserviços de tesouraria empresarial, demonstrando a integração com kotlinx.serialization e o envio seguro via Ktor Client.

📊 2. Matriz de Componentes Tecnológicos do Projeto Capstone

Módulo / Camada Tecnologia Adotada Responsabilidade no Aplicativo
Interface Visual (UI) Jetpack Compose + Material Design 3 Componentes declarativos reativos, suporte a Dark Mode e animações de mola
Arquitetura de Estado AndroidX ViewModel + MVI / UDF Centralização da Fonte Única da Verdade (FinanceiroUiState) com StateFlow
Injeção de Dependências Koin 3.5+ (Kotlin DSL) Provisão desacoplada de Repositórios, DAOs e ViewModels com viewModelOf
Persistência Local Room Database (SQLite + KSP) Armazenamento seguro de transações com consultas reativas assíncronas
Concorrência Kotlin Coroutines (viewModelScope) Execução de cálculos e I/O de disco em Dispatchers.IO sem bloquear a UI
Exportação e Auditoria Kotlinx Serialization + Ktor Client Serialização determinística de relatórios financeiros para integração corporativa

💻 3. Laboratório Prático: Estrutura do Caso de Uso e Repositório Capstone

O código a seguir apresenta a camada de domínio e dados do projeto capstone, destacando o cálculo do balanço e a emissão do relatório consolidado:

package br.com.portal.mobile.android.cap20

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

// 1. Modelos de Domínio Imutáveis
enum class CategoriaLancamento {
    SALARIO, INVESTIMENTOS, ALIMENTACAO, TRANSPORTE, INFRAESTRUTURA
}

enum class NaturezaOperacao {
    CREDITO, DEBITO
}

data class LancamentoFinanceiro(
    val id: Long,
    val descricao: String,
    val valor: Double,
    val natureza: NaturezaOperacao,
    val categoria: CategoriaLancamento,
    val dataIso: String
)

// 2. DTO de Auditoria para Integração com Sistemas Contábeis
@Serializable
data class RelatorioAuditoriaJson(
    val versaoContrato: String = "2.0",
    val dataGeracao: String,
    val saldoConsolidado: Double,
    val totalCreditos: Double,
    val totalDebitos: Double,
    val quantidadeLancamentos: Int
)

// 3. Contrato de Repositório de Domínio
interface FinanceiroRepository {
    fun observarLancamentos(): Flow<List<LancamentoFinanceiro>>
    suspend fun registrarLancamento(lancamento: LancamentoFinanceiro)
    suspend fun excluirLancamento(id: Long)
}

// 4. Caso de Uso: Consolidação de Balanço e Auditoria
class GerarRelatorioAuditoriaUseCase(
    private val repository: FinanceiroRepository
) {
    fun executar(dataIsoHoje: String): Flow<String> {
        return repository.observarLancamentos().map { lista ->
            val creditos = lista.filter { it.natureza == NaturezaOperacao.CREDITO }.sumOf { it.valor }
            val debitos = lista.filter { it.natureza == NaturezaOperacao.DEBITO }.sumOf { it.valor }
            val saldo = creditos - debitos

            val relatorio = RelatorioAuditoriaJson(
                dataGeracao = dataIsoHoje,
                saldoConsolidado = saldo,
                totalCreditos = creditos,
                totalDebitos = debitos,
                quantidadeLancamentos = lista.size
            )

            Json { prettyPrint = true }.encodeToString(relatorio)
        }
    }
}

⚠️ 4. Checklist para Publicação Profissional na Google Play

  1. Ativação do R8 e Proguard: No arquivo build.gradle.kts, garanta isMinifyEnabled = true e isShrinkResources = true para o build de release. Isso reduz o tamanho do APK em até 60% e ofusca o código contra engenharia reversa.
  2. Geração de Baseline Profiles: Utilize o plugin de Baseline Profiles do AndroidX para compilar antecipadamente (AOT) as rotas críticas de inicialização do Compose, eliminando quedas de frames no primeiro uso pelo cliente.
  3. Formato Android App Bundle (.aab): Nunca envie arquivos .apk monolíticos para a Google Play. O envio em .aab permite que a loja gere pacotes dinâmicos otimizados para a densidade de tela, ABI da CPU (ARM64 vs x86) e idioma específico de cada aparelho.