Capítulo 20: Projeto Capstone: App Mobile de Gestão Financeira com Auditoria JSON
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:
- 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.
- 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. - 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.serializatione 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
- Ativação do R8 e Proguard: No arquivo
build.gradle.kts, garantaisMinifyEnabled = trueeisShrinkResources = truepara o build de release. Isso reduz o tamanho do APK em até 60% e ofusca o código contra engenharia reversa. - 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.
- Formato Android App Bundle (
.aab): Nunca envie arquivos.apkmonolíticos para a Google Play. O envio em.aabpermite 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.