coda/docs/requirements.md

9.0 KiB

Transcoder para Lidarr — Documento de Requisitos

Objetivo

Desenvolver uma aplicação em Go, executada em contêiner Docker, responsável por converter álbuns de FLAC para MP3 320 kbps CBR.

A aplicação pode ser acionada automaticamente por Webhooks enviados pelo Lidarr após a importação de um álbum, ou manualmente através da interface web. Em ambos os fluxos, realiza a conversão dos arquivos, valida o resultado, remove os arquivos FLAC originais e solicita ao Lidarr a atualização da biblioteca.


1. Requisitos Funcionais

RF-001 Recebimento de Webhooks

A aplicação deverá disponibilizar um endpoint HTTP para recebimento de Webhooks enviados pelo Lidarr.

O endpoint deverá:

  • aceitar requisições POST;
  • validar o payload recebido;
  • extrair o caminho do álbum importado;
  • registrar a solicitação no log.

RF-002 Fila de Processamento

Cada webhook recebido deverá gerar uma nova tarefa de conversão.

A aplicação deverá possuir uma fila interna para impedir que uma falha interrompa o processamento de novos álbuns.

Cada tarefa possuirá estados:

  • Recebido
  • Em processamento
  • Concluído
  • Erro

RF-003 Conversão de Áudio

Para cada arquivo FLAC encontrado no diretório informado:

  • converter para MP3;
  • utilizar o codec libmp3lame;
  • bitrate constante (CBR);
  • 320 kbps;
  • preservar metadados;
  • preservar capa do álbum quando existir.

RF-004 Conversão Paralela

Os arquivos deverão ser convertidos em paralelo.

A quantidade máxima de conversões simultâneas deverá ser configurável.


RF-005 Validação da Conversão

Antes da remoção dos arquivos FLAC deverá ser verificado que:

  • todos os MP3 esperados foram gerados;
  • o ffmpeg retornou código de sucesso;
  • os arquivos possuem tamanho maior que zero;
  • opcionalmente executar ffprobe para validar o arquivo.

Caso qualquer verificação falhe:

  • nenhum FLAC deverá ser removido;
  • a tarefa será marcada como erro.

RF-006 Limpeza

Após validação:

  • remover os arquivos FLAC;
  • manter demais arquivos do álbum (cover.jpg, booklet.pdf, etc.).

RF-007 Atualização do Lidarr

Após a conclusão da conversão, a aplicação deverá realizar uma chamada para a API do Lidarr solicitando um rescan do diretório.


RF-008 Registro de Logs

A aplicação deverá registrar:

  • início da tarefa;
  • álbum processado;
  • duração;
  • arquivos convertidos;
  • erros;
  • chamadas ao Lidarr;
  • notificações enviadas.

Os logs deverão ser persistidos em SQLite e permanecer disponíveis para consulta via interface web.


RF-009 Interface Web

A aplicação deverá disponibilizar uma interface web para operação e monitoramento.

A interface deverá permitir:

Dashboard (/)

  • aplicação online
  • número de workers
  • fila atual (incluindo tarefas retidas pela janela de trabalho)
  • quantidade de tarefas
  • status da janela de trabalho (ativa/inativa e horário configurado, quando habilitada)

Tarefas recentes (/jobs)

Tabela contendo:

  • data
  • artista
  • álbum
  • duração
  • status
  • origem (webhook ou manual)

Consulta de logs (/logs)

Visualização dos logs registrados, persistidos em SQLite.

Biblioteca / Busca de FLACs (/library)

  • navegação por árvore de diretórios a partir de MUSIC_PATH
  • scan recursivo com detecção automática de álbuns com arquivos FLAC
  • seleção individual ou em lote dos álbuns encontrados
  • botão para enfileirar a conversão dos álbuns selecionados

Configurações (/settings)

Exibição e edição das configurações persistidas, incluindo:

  • workers, dry run, nível de log
  • janela de trabalho (ativar/desativar, horário início/fim, timezone)
  • URL e chave da API do Lidarr
  • demais parâmetros operacionais

As alterações têm efeito imediato e substituem os defaults definidos por variáveis de ambiente até que sejam sobrescritas novamente.


RF-010 Modo Dry Run

Quando habilitado:

  • nenhuma conversão será realizada;
  • nenhum arquivo será apagado;
  • nenhuma chamada ao Lidarr será executada.

Todas as ações deverão apenas ser registradas no log.


RF-011 Configuração

A configuração da aplicação é definida através de variáveis de ambiente (valores default) e pode ser sobrescrita via interface web, com persistência em SQLite.

Ao iniciar, a aplicação carrega as variáveis de ambiente como valores iniciais. Se houver configurações salvas no SQLite de execuções anteriores, estas têm prioridade.

Exemplos de variáveis de ambiente:

PORT=8080
WORKERS=4
FFMPEG_BIN=/usr/bin/ffmpeg
FFPROBE_BIN=/usr/bin/ffprobe
LOG_LEVEL=INFO
DRY_RUN=false
LIDARR_URL=http://lidarr:8686
LIDARR_API_KEY=...
WEBHOOK_SECRET=...
MUSIC_PATH=/music
DB_PATH=/data/coda.db
TIMEZONE=America/Sao_Paulo
WORK_WINDOW_ENABLED=false
WORK_WINDOW_START=08:00
WORK_WINDOW_END=18:00
NTFY_ENABLED=false
NTFY_URL=
NTFY_TOPIC=
NTFY_TOKEN=

RF-012 Mapeamento de Volume de Mídia

A aplicação dependerá de um volume Docker contendo os arquivos de música, montado no mesmo caminho utilizado pelo Lidarr (MUSIC_PATH).

O webhook enviado pelo Lidarr conterá caminhos absolutos que correspondem diretamente ao ponto de montagem do container, sem necessidade de tradução.

Sem o volume montado, a aplicação deverá registrar um aviso no log e operar apenas em modo dry run (quando habilitado), ou rejeitar tarefas que tentem acessar caminhos inexistentes.


RF-013 Persistência (SQLite)

A aplicação deverá utilizar SQLite embarcado como mecanismo de persistência.

O banco de dados deverá armazenar:

  • histórico completo de tarefas (jobs)
  • logs estruturados
  • configurações editadas via web (overrides)

O arquivo do banco (DB_PATH) deverá residir em um volume Docker persistente para garantir a durabilidade dos dados entre reinicializações do container.

Na primeira execução, a aplicação deverá criar as tabelas necessárias automaticamente (migrações).


RF-014 Janela de Trabalho

A aplicação deverá suportar uma janela de trabalho opcional, desabilitada por padrão, que restrinja o processamento a um intervalo de horário definido.

Quando habilitada:

  • a aplicação só despacha tarefas da fila para os workers dentro do intervalo configurado (WORK_WINDOW_STARTWORK_WINDOW_END);
  • fora do intervalo, as novas tarefas são aceitas e enfileiradas, mas não processadas;
  • se uma tarefa estiver em andamento quando a janela fechar, ela é finalizada normalmente; as demais aguardam a próxima abertura;
  • o fuso horário é definido pela configuração TIMEZONE (ex: America/Sao_Paulo), que pode ser sobrescrita pela web.

RF-015 Busca e Conversão Manual de FLACs

A interface web deverá permitir descobrir e converter álbuns FLAC existentes na biblioteca, sem depender de webhooks do Lidarr.

A funcionalidade deve oferecer duas formas de navegação:

  1. Navegação por diretórios: o usuário explora a árvore de diretórios sob MUSIC_PATH e seleciona pastas para conversão.
  2. Scan recursivo: a aplicação varre todo o MUSIC_PATH atrás de arquivos FLAC, agrupa por álbum (diretório) e apresenta uma lista para seleção individual ou em lote.

Ao confirmar, os álbuns selecionados são enfileirados seguindo o pipeline completo: conversão, validação, remoção dos FLACs e rescan no Lidarr (mesmo fluxo do webhook).


RF-016 Configuração via Web

A interface web deverá expor uma página de configurações (/settings) onde o usuário pode visualizar e alterar os parâmetros operacionais.

Os valores salvos via web são persistidos no SQLite e têm precedência sobre os definidos por variáveis de ambiente.

Alterações têm efeito imediato (não exigem reinicialização do container). Caso o usuário remova um override, o valor volta ao default definido pela variável de ambiente.


RF-017 Notificações via ntfy

A aplicação deverá enviar notificações para um servidor ntfy (self-hosted ou público) ao final de cada job, informando o resultado da conversão.

  • Notificação de sucesso: prioridade default, tag white_check_mark, título com artista/álbum.
  • Notificação de falha: prioridade high, tag x, título com artista/álbum e mensagem de erro.
  • Falha ao enviar notificação não interrompe o pipeline — o job não é revertido.
  • Respeita o modo DRY_RUN: nenhuma notificação é enviada.
  • Desabilitada por padrão (NTFY_ENABLED=false).
  • Suporte a token de autenticação (Authorization: Bearer).

2. Requisitos Não Funcionais

RNF-001

Implementação em Go.


RNF-002

Distribuição via Docker.


RNF-003

Imagem baseada em Alpine Linux.


RNF-004

Baixo consumo de memória.


RNF-005

Utilizar SQLite embarcado como banco de dados — sem servidor externo, sem dependência de infraestrutura adicional. O arquivo do banco deve residir em volume Docker persistente.


RNF-006

Inicialização inferior a 5 segundos.


RNF-007

Suportar processamento contínuo durante longos períodos.