Busca de Músicas — Design Técnico
Gerado pelo Writer (Reversa) em 2026-05-11
Interface
| Símbolo | Assinatura | Retorno |
|---|---|---|
getDetalhesTermoBusca |
(termo: string) |
{ tipo: 'indice'\|'texto'\|'vazio', valor: any } |
MusicasRepository.findAllBy |
({ termo, livro?, rotulo?, page, pageSize }) |
Promise<{ items: Musica[], hasNextPage: boolean }> |
buscarMusicas (thunk) |
(params: BuscaParams) |
ThunkAction |
Fluxo Principal
- Usuário digita no campo de busca → debounce dispara
buscarMusicas getDetalhesTermoBusca(termo)classifica:""→{ tipo: 'vazio' }parseInt(termo)não éNaN→{ tipo: 'indice', valor: parseInt(termo) }- qualquer outro → normalizar NFKD → uppercase → remove
[^A-Z0-9 ]→ trim → split por\s+→ cada token+ "*"→ join" "→ remove"**"→{ tipo: 'texto', valor: queryFTS5 } findAllByseleciona estratégia:vazio→SELECT ... FROM musica LEFT JOIN cantico_livro ... ORDER BY titulo LIMIT ? OFFSET ?indice→WHERE CAST(cantico_livro.indice AS INTEGER) = ?texto→FROM musica_busca JOIN musica ON musica_busca.rowid = musica.id_musica WHERE musica_busca MATCH ? ORDER BY bm25(musica_busca, 50, 5)- Cláusulas condicionais adicionadas se
livroourotulofornecidos LIMIT pageSize + 1→ se resultado > pageSize:hasNextPage=true, descarta último item- Resultado retornado ao thunk → store atualizado
Dependências
- op-sqlite — engine SQLite com FTS5 habilitado
musica_busca— tabela FTS5 virtual, deve estar sincronizada commusica- Redux Toolkit — store que recebe os resultados
Riscos e Lacunas
- 🟡 Termo alfanumérico como "23a" cai na busca FTS5 e pode não encontrar o índice esperado
- 🔴 Não mapeado: o que ocorre quando
musica_buscaestá dessincronizada commusica(ex.: após falha de migração)