Skip to content

Repertórios

Gerado pelo Writer (Reversa) em 2026-05-11 doc_level: detalhado | Granularidade: híbrida (módulo + casos de uso)

Visão Geral

Módulo responsável pela criação, edição, reordenação, compartilhamento, importação e duplicação de repertórios musicais. Um repertório é uma lista de músicas (ou termos livres) organizada pelo usuário, com metadados de data e dia litúrgico. É o módulo com maior complexidade de fluxo do app, envolvendo integração com auth, API remota, geração de PDF e compartilhamento nativo.

Responsabilidades

  • Criar e editar repertórios localmente (CRUD SQLite)
  • Gerenciar itens do repertório (adicionar, remover, editar momento e tonalidade)
  • Compartilhar um repertório via API Canta.app e dialog nativo do SO (WhatsApp, etc.)
  • Importar um repertório de outra conta via link/slug
  • Duplicar um repertório existente
  • Gerar folheto PDF online a partir de um repertório
  • Proteger repertórios padrão ("Músicas favoritas" e "Visto recentemente") contra exclusão

Regras de Negócio

  • Título do repertório é limitado a 50 caracteres (CHECK SQL, migration v8) 🟢
  • termo de um item de repertório é limitado a 300 caracteres (CHECK SQL, migration v8) 🟢
  • Deleção de repertório é soft-deletedata_exclusao é preenchida; o registro permanece no banco 🟢
  • Repertórios com tipo_repertorio = 1 ("Músicas favoritas" id=1 e "Visto recentemente" id=2) não podem ser excluídos 🟢
  • A ordem dos itens é armazenada como array JSON ordem_musicas no registro do repertório, não pela posição na tabela item_repertorio 🟢
  • Reordenação de itens está temporariamente desabilitada na UI (DT-08) 🟢
  • momento e tonalidade têm espaços nas extremidades automaticamente removidos ao salvar 🟢
  • momento e tonalidade têm sugestões automáticas baseadas no histórico de uso do usuário 🟡
  • Compartilhar requer autenticação Google; a mensagem gerada é formatada em Markdown compatível com WhatsApp 🟢
  • Ao duplicar um repertório, o slug fica undefined até o usuário compartilhar novamente 🟢
  • slug.referencia guarda quem originou o repertório; slug.corrente reflete a versão após último compartilhamento 🟢
  • Geração de folheto via GerarFolhetoComSlugStrategy requer autenticação; GerarFolhetoBase64Strategy não requer 🟢
  • Um item de repertório pode ser uma música do catálogo (id_musica) ou um texto livre (termo), mas não ambos 🟢

Requisitos Funcionais

ID Requisito Prioridade Critério de Aceite
RF-01 Listar todos os repertórios do usuário (excluídos ficam ocultos) Must Repertórios com data_exclusao não aparecem na lista
RF-02 Criar um novo repertório com título obrigatório Must Repertório é criado com Timestamp.now e aparece na lista; título vazio deve ser rejeitado
RF-03 Editar o título de um repertório Must Novo título (≤ 50 chars) é persistido; erro se exceder
RF-04 Excluir um repertório (soft-delete) Must data_exclusao é preenchida; repertórios padrão (id=1, id=2) não podem ser excluídos
RF-05 Adicionar música do catálogo a um repertório Must Música aparece na lista de itens; ordem_musicas é atualizado
RF-06 Adicionar texto livre (termo) a um repertório Should Termo (≤ 300 chars) é salvo como ItemRepertorio sem id_musica
RF-07 Remover item de um repertório Must Item é deletado do banco; ordem_musicas é atualizado
RF-08 Editar momento e tonalidade de um item de repertório Should Valores são salvos sem espaços nas extremidades; sugestões de últimos usados são exibidas
RF-09 Compartilhar um repertório via API + dialog nativo Must Autenticação ocorre se necessária; mensagem Markdown é gerada e o dialog nativo de compartilhamento abre
RF-10 Importar repertório de outra conta via link/slug Should Itens são copiados localmente; slug.referencia é preservado
RF-11 Duplicar repertório local Should Nova cópia é criada sem slug; métricas de duplicação são registradas
RF-12 Gerar folheto PDF do repertório (online) Should Folheto é aberto em livreto.canta.app via browser; requer autenticação (estratégia com slug) ou não (estratégia Base64)
RF-13 Exibir metadados de dia litúrgico no compartilhamento Could Data em formato longo pt-BR e nome do dia litúrgico aparecem na mensagem gerada
RF-14 Exibir índice e sigla do livro ao lado da música no repertório compartilhado Should Sigla + índice do livro aparecem na mensagem de compartilhamento quando disponíveis

Requisitos Não Funcionais

Tipo Requisito inferido Evidência no código Confiança
Integridade Títulos ≤ 50 chars e termos ≤ 300 chars são garantidos por CHECK SQL Migration v8, schema item_repertorio 🟢
Disponibilidade Criação e edição de repertórios funcionam offline; compartilhamento requer internet RepertoriosRepository (local) vs CompartilharService (API) 🟢
Segurança Compartilhamento exige Bearer JWT obtido via Google OAuth com PKCE CompartilharService.getTokenAuth.autenticar 🟢
Performance ordem_musicas como JSON array evita N queries de reordenação Repertorio.ordem_musicas 🟢
Rastreabilidade Eventos de criação, duplicação, compartilhamento e folheto são monitorados via Sentry Metricasrepertorio_criado, repertorio_duplicado etc 🟢

Critérios de Aceitação

Dado que o usuário está na tela de repertórios
Quando ele cria um repertório com título "Missa de Domingo"
Então o repertório aparece na lista e contém `data_exclusao = null`

Dado que o usuário tenta excluir o repertório "Músicas favoritas"
Quando a ação de exclusão é acionada
Então o sistema rejeita a operação (tipo_repertorio = 1 é protegido)

Dado que o usuário edita o título de um repertório para uma string com 51 caracteres
Quando a validação é executada
Então o título é rejeitado com mensagem de erro e o banco não é atualizado

Dado que o usuário adiciona uma música a um repertório
Quando a adição é confirmada
Então o `id_musica` aparece no array `ordem_musicas` e um `ItemRepertorio` é criado no banco

Dado que o usuário quer compartilhar um repertório sem estar logado
Quando o botão de compartilhar é acionado
Então o fluxo OAuth Google é iniciado antes de prosseguir com o compartilhamento

Dado que o usuário compartilha um repertório com sucesso
Quando a API retorna `conta.slug` e `slug`
Então `slug.corrente` é atualizado localmente e o dialog nativo de compartilhamento abre com a mensagem Markdown

Dado que o usuário acessa um item de repertório e edita a tonalidade para " Lá menor "
Quando o valor é salvo
Então o valor persistido é "Lá menor" (espaços removidos)

Dado que o usuário duplica um repertório
Quando a duplicação é concluída
Então o novo repertório não tem `slug` e a métrica `repertorio_duplicado` é registrada no Sentry

Prioridade (MoSCoW)

Requisito MoSCoW Justificativa
Listar repertórios (RF-01) Must Ponto de entrada do módulo
Criar repertório (RF-02) Must Funcionalidade básica do módulo
Editar título (RF-03) Must Corrigir erros de nomenclatura é essencial
Excluir repertório soft-delete (RF-04) Must Gestão do ciclo de vida dos repertórios
Adicionar música (RF-05) Must Sem isso o módulo não tem valor
Remover item (RF-07) Must Sem remoção, o módulo seria inutilizável em longo prazo
Compartilhar repertório (RF-09) Must Feature principal de valor do módulo; requer auth
Editar momento/tonalidade (RF-08) Should Enriquece a experiência mas não bloqueia uso básico
Adicionar texto livre (RF-06) Should Útil para itens não-musicais (ex.: "Abertura") mas não crítico
Duplicar repertório (RF-11) Should Poupa tempo, não é essencial
Gerar folheto (RF-12) Should Recurso avançado de alto valor para grupos litúrgicos
Importar repertório (RF-10) Should Habilita colaboração, mas requer API ativa
Metadados litúrgicos no compartilhamento (RF-13) Could Enriquece a mensagem, mas compartilhamento funciona sem isso
Índice/sigla do livro no compartilhamento (RF-14) Should Importante para usuários com livros físicos em mãos

Rastreabilidade de Código

Arquivo Função / Classe Cobertura
src/model/repertorio/Repertorio.ts Repertorio, ItemRepertorio, RepertorioSlug 🟢
src/repository/repertorios/RepertoriosRepository.ts findAllBy, createRepertorio, deactivateRepertorio 🟢
src/store/Repertorios/ Thunks Redux, reducer EntityAdapter 🟢
src/store/ItensRepertorio/ Estado de itens em edição ativa 🟢
src/service/RepertorioService.ts gerarMensagemCompartilhamento 🟢
src/service/CompartilharService.ts repertorio, getToken 🟢
src/service/FolhetoService.ts GerarFolhetoComSlugStrategy, GerarFolhetoBase64Strategy 🟢