2 Commits
Author SHA1 Message Date
lgcosta 81e945b490 build: toolchain AGP 8.13.2 + Kotlin 2.2.20 + SDK 36 (v0.4.0)
- Gradle wrapper 8.11.1 -> 8.13 (exigido pelo AGP 8.13)
- AGP 8.7.3 -> 8.13.2; Kotlin 2.0.21 -> 2.2.20; KSP -> 2.2.20-2.0.4
- compileSdk/targetSdk 35 -> 36 (Android 16 como alvo real)
- Compose BOM 2025.06 -> 2026.06 (material3 1.4.0 estável; Expressive
  completo segue beta em 1.5.x e fica de fora a pedido: só estável)
- activity-compose 1.10.1, navigation-compose 2.9.0, lifecycle 2.9.0
- Room 2.6.1 -> 2.8.3; WorkManager 2.9.1 -> 2.10.1; DataStore 1.1.7
- kotlinx-serialization 1.8.1; coroutines 1.10.2
- versionCode 7 / versionName 0.4.0

Verificado: testes unitários verdes; APKs debug+release OK; em Android 16
(API 36, Pixel 6) upgrade in-place, criar nota -> autosave -> Room -> lista,
editor e chips de modo/formato sem crashes. README atualizado.
2026-11-06 08:48:16 -03:00
lgcosta 2f63c7a2f5 feat: cliente Android offline-first (Kotlin + Jetpack Compose)
- Room (notes/outbox/categories/meta): edição 100% local, fila FIFO de mutações
- SyncEngine bidirecional: push (create/update com base_hash/delete, rekey de id
  local→servidor) + pull (categorias, notas divergentes, exclusões remotas)
- Conflito 409: servidor vence a nota + texto local preservado em cópia
  "Título (conflito)" enfileirada como create — nada perdido, sem relógios
- WorkManager: periódico 1h (rede + backoff exponencial), runNow único REPLACE
  em gatilhos (pós-save, rede restabelecida, boot, config, botão manual)
- OkHttp com timeout/retry em IOException; kotlinx.serialization; DataStore
- UI Compose: tela Servidor (URL+token+teste), Lista com banner de status
  (Offline/Sincronizando/Sincronizado/Erro/401 + pendências + conflitos),
  Editor com autosave por ociosidade (10 s) e categorias multi-seleção
- Build validado: assembleDebug (AGP 8.7.3/Kotlin 2.0.21/SDK 35, JDK 21) —
  app-debug.apk 17,6 MB; gradle-wrapper.jar fora do commit (regenerável com
  `gradle wrapper`, documentado no README)
2026-11-04 17:55:50 -03:00