Repertórios — Casos de Borda
Gerado pelo Writer (Reversa) em 2026-05-11
doc_level: detalhado
EC-01: Tentativa de excluir repertório padrão
Trigger: Usuário aciona exclusão nos repertórios "Músicas favoritas" (id=1) ou "Visto recentemente" (id=2).
Comportamento esperado: deactivateRepertorio verifica tipo_repertorio = 1 e rejeita a operação com erro explícito. A interface não deve sequer exibir o botão de exclusão para esses repertórios.
Fonte: tipo_repertorio migration v8. 🟢
EC-02: Título com exatamente 50 caracteres
Trigger: Usuário salva título com exatamente 50 caracteres.
Comportamento esperado: Aceito normalmente — o CHECK SQL é length(titulo) <= 50.
Fonte: Migration v8 CHECK constraint. 🟢
EC-03: Título com 51 ou mais caracteres
Trigger: Usuário salva título com 51 caracteres.
Comportamento esperado: Erro SQL lançado; nenhuma mudança persistida; Toast de erro exibido ao usuário.
Fonte: Migration v8 CHECK constraint. 🟢
EC-04: ordem_musicas dessincronizada com itens reais
Trigger: Bug ou falha de transação deixa um id_item_repertorio no array ordem_musicas que não existe mais na tabela item_repertorio.
Comportamento observado: 🟡 INFERIDO — não há tratamento defensivo. A montagem final usa repertorio.ordem_musicas.map(it => rowById[it]); IDs órfãos retornam undefined, com risco de quebrar telas que assumem ItemRepertorio válido.
Rastreabilidade: src/repository/repertorios/RepertoriosRepository.ts — findItensRepertorio
EC-05: Importar repertório com slug já existente localmente
Trigger: Usuário tenta importar um repertório cujo slug já foi importado anteriormente.
Comportamento esperado: findRepertorioSimilar detecta o slug existente e redireciona para o repertório local, sem criar duplicata.
Fonte: RepertorioService.findRepertorioSimilar. 🟢
EC-06: Compartilhamento falha por ausência de internet
Trigger: Usuário aciona compartilhamento sem conexão com a internet.
Comportamento esperado: Api.compartilharRepertorio lança erro de rede; Toast "sem internet" é exibido; slug.corrente não é alterado.
Fonte: Flowchart repertorios.md, bloco "Erro de rede". 🟢
EC-07: Usuário cancela o fluxo de autenticação durante compartilhamento
Trigger: Dialog OAuth Google é aberto e o usuário o fecha sem concluir.
Comportamento esperado: Auth.autenticar retorna undefined; CompartilharService aborta o fluxo sem erro visível para o usuário (ou exibe Toast de cancelamento).
Fonte: Auth.autenticar — retorno undefined quando cancelado. 🟢
EC-08: Duplicar repertório com muitos itens
Trigger: Usuário duplica um repertório com dezenas de itens.
Comportamento esperado: Todos os itens são copiados individualmente via createItemRepertorio em loop. 🟡 INFERIDO — não há evidência de transação explícita neste fluxo; uma falha a meio pode gerar repertório incompleto.
Risco: Médio — sem rollback, a cópia pode ficar parcialmente populada.
EC-09: Compartilhar repertório vazio
Trigger: Usuário compartilha um repertório sem itens.
Comportamento esperado: 🔴 LACUNA — comportamento não encontrado no código. A mensagem gerada provavelmente terá apenas título e URL, sem itens. Pode confundir o destinatário.
EC-10: Folheto Base64 com URL excessivamente longa
Trigger: Repertório muito grande (50+ itens com textos longos) é serializado para Base64.
Comportamento esperado: 🟡 INFERIDO — URL pode exceder limites de alguns navegadores ou apps de mensagens (~2000 chars para IE, ~8000 para Chrome). Não há evidência de truncamento ou validação do tamanho.
EC-11: momento ou tonalidade com apenas espaços
Trigger: Usuário salva momento = " ".
Comportamento esperado: Trim resulta em string vazia (""), que deve ser equivalente a nulo no contexto de exibição. 🟡 INFERIDO — sem evidência de validação de string vazia pós-trim.
EC-12: Slug com formato inválido recebido via deeplink
Trigger: App recebe deeplink canta.app/repertorios/?invalido sem separador :.
Comportamento esperado: 🔴 LACUNA — parsing do slug provavelmente falha silenciosamente ou lança erro não tratado. Requer validação humana.