Máquinas de Estado — canta-igreja
Gerado pelo Detective (Reversa) em 2026-05-11
1. Autenticação do Usuário
Entidade: Auth + UsuarioLogadoRepository
stateDiagram-v2
[*] --> Anonimo : App abre sem credenciais
Anonimo --> Autenticando : Usuário toca "compartilhar"/"folheto"
Autenticando --> Autenticado : OAuth PKCE bem-sucedido + POST /auth OK
Autenticando --> Anonimo : Usuário cancela ou erro de rede
Autenticado --> RefreshEmAndamento : Token expira em ≤ 1 min
RefreshEmAndamento --> Autenticado : refresh() bem-sucedido
RefreshEmAndamento --> Anonimo : refresh() falha (token revogado)
Autenticado --> Anonimo : logout() — keychain + MMKV limpos
note right of Autenticado
idToken disponível
UsuarioLogado no MMKV
end note
note right of Anonimo
Todas as funcionalidades de
leitura disponíveis normalmente
end note
Gatilhos de transição:
| Transição | Gatilho |
|-----------|---------|
| Anonimo → Autenticando | Usuário toca compartilhar/gerar folheto |
| Autenticando → Autenticado | Auth.autenticar() completa com sucesso |
| Autenticado → RefreshEmAndamento | (expirationDate - 1min) < agora |
| Autenticado → Anonimo | Auth.logout() |
2. Download de Obra (Biblioteca)
Entidade: ObraService + BibliotecaRepository
stateDiagram-v2
[*] --> Disponivel : Obra listada pela API
Disponivel --> Baixando : Usuário toca "baixar"
Baixando --> Baixando : downloadEmAndamento = true (mutex)
Baixando --> Importando : Arquivo .db recebido no cache
Importando --> Instalada : ATTACH → upsert → DETACH concluídos
Baixando --> Erro : Falha de rede ou disco
Importando --> Erro : Falha no ATTACH/upsert
Erro --> Disponivel : Usuário retenta
Instalada --> Desatualizada : API retorna crc32 diferente
Desatualizada --> Baixando : Usuário toca "atualizar"
note right of Baixando
Apenas 1 download
simultâneo permitido
end note
Regra de mutex: ObraService.downloadEmAndamento — se true, tentativa de novo download lança exceção imediatamente.
3. Sincronização de Sugestões de Repertório
Entidade: BibliotecaSugestoesRepertorioRepository
stateDiagram-v2
[*] --> Vazio : Primeira instalação
Vazio --> Semeado : popularSugestoesIniciais() — cópia do asset repertorios.db
Semeado --> Atualizado : importarSugestoes() — substituição total via ATTACH
Atualizado --> Baixando : App detecta novo banco na API
Baixando --> Atualizando : Arquivo .db baixado para cache
Atualizando --> Atualizado : ATTACH → DELETE ALL → INSERT ALL → DETACH
Baixando --> Atualizado : Falha no download — mantém versão atual
note right of Semeado
Funciona offline
(banco embarcado no app)
end note
note right of Atualizando
Substituição TOTAL —
não incremental
end note
4. Repertório — Ciclo de Vida
Entidade: Repertorio
stateDiagram-v2
[*] --> Criado : createRepertorio()
Criado --> EmEdicao : Usuário abre e adiciona/remove músicas
EmEdicao --> Criado : Usuário fecha sem mais alterações
Criado --> Compartilhado : CompartilharService.repertorio() — API sync
Compartilhado --> Criado : Usuário edita após compartilhar (slug.corrente mantido)
Compartilhado --> Compartilhado : Re-compartilhamento (slug.corrente atualizado)
Criado --> Excluido : deactivateRepertorio() — soft-delete
state Compartilhado {
[*] --> SlugAtribuido : slug.referencia + slug.corrente definidos
SlugAtribuido --> ReferenciaOriginal : slug.referencia ≠ slug.corrente (importado)
SlugAtribuido --> CorrenteProprietario : slug.referencia = slug.corrente (próprio)
}
note right of Excluido
data_exclusao preenchida
Registro permanece no banco
end note
5. Player YouTube
Entidade: YoutubePlayerView + usePlayerState + useLoopControl
stateDiagram-v2
[*] --> Fechado
Fechado --> FullScreen : Usuário abre música com vídeo
FullScreen --> Paused : Usuário pausa
Paused --> FullScreen : Usuário retoma
FullScreen --> MiniPlayer : Usuário minimiza
MiniPlayer --> FullScreen : Usuário expande
FullScreen --> Fechado : Usuário fecha
MiniPlayer --> Fechado : Usuário fecha no mini
state FullScreen {
[*] --> Reproduzindo
Reproduzindo --> LoopAtivo : Usuário define início/fim do loop
LoopAtivo --> Reproduzindo : Usuário desativa loop
Reproduzindo --> VelocidadeAlterada : Usuário muda velocidade (0.5x–2x)
VelocidadeAlterada --> Reproduzindo
}
state LoopAtivo {
[*] --> Polling : setInterval 500ms
Polling --> SeekToInicio : currentTime >= loopState.end
SeekToInicio --> Polling
}
6. Sugestão → Repertório (Conversão)
Entidade: SugestaoRepertorio → Repertorio
stateDiagram-v2
[*] --> SugestaoDisponivel : Sugestão listada por dia litúrgico
SugestaoDisponivel --> SugestaoSelecionada : Usuário abre sugestão
SugestaoSelecionada --> RepertorioCriado : Usuário toca "Usar sugestão"
RepertorioCriado --> [*] : Navega para edição do repertório criado
state RepertorioCriado {
[*] --> IterandoItens
IterandoItens --> ItemIgnorado : metadata.ignorar = true
IterandoItens --> ItemAdicionado : id_musica + momento inseridos
ItemIgnorado --> IterandoItens
ItemAdicionado --> IterandoItens
}
note right of RepertorioCriado
Métrica: repertorio_criado_por_sugestao
end note