8.5 KiB
Transcoder para Lidarr — Documento de Arquitetura
Objetivo
Este documento descreve a arquitetura da aplicação responsável por converter álbuns de FLAC para MP3 320 kbps CBR, acionada automaticamente por webhooks do Lidarr ou manualmente pela interface web, conforme os requisitos funcionais e não funcionais definidos no documento de requisitos.
1. Visão Geral
+--------------------+
| Lidarr |
+---------+----------+
|
Webhook HTTP
|
▼
+----------------------+ +----------------------+
| HTTP Server | | Library Scanner |
+----------+-----------+ +----------+-----------+
| |
cria nova tarefa busca manual (web)
| |
+---------------+---------------+
|
▼
+--------------+
| Job Queue |
+------+-------+
|
Scheduler
(Work Window)
|
▼
Worker Pool
+--------------+-------------+
| | |
Worker 1 Worker 2 Worker N
| | |
+--------------+-------------+
|
▼
Conversor (ffmpeg)
|
▼
Validação (ffprobe)
|
▼
Atualização do Lidarr
|
▼
Config Service ← → SQLite
↓ ↑
Logger / Histórico ←┘
|
▼
Interface Web
2. Componentes
HTTP Server
Responsável por:
- receber webhooks do Lidarr;
- servir a interface web (dashboard, jobs, logs, library, settings);
- expor endpoints REST para a interface web (jobs, logs, config, scan);
- receber requisições de scan e conversão manual.
Queue
Fila interna baseada em canais (channels) do Go.
Responsável por:
- armazenar tarefas;
- controlar ordem de execução.
Worker Pool
Executa tarefas paralelamente, respeitando a janela de trabalho (quando habilitada).
Cada worker:
- recebe um álbum;
- converte todos os arquivos;
- valida;
- remove FLAC;
- atualiza o Lidarr;
- registra o resultado no SQLite.
Transcoder
Wrapper para execução do ffmpeg.
Responsável por:
- montar comandos;
- acompanhar progresso;
- capturar saída.
Validator
Executa verificações pós-conversão.
Pode utilizar:
- ffprobe;
- verificação de tamanho;
- existência dos arquivos.
Lidarr Client
Cliente HTTP responsável por:
- autenticação;
- envio do comando de rescan;
- tratamento de erros e tentativas de repetição.
Logger
Responsável por:
- logs estruturados;
- persistência em SQLite;
- disponibilização para consulta via interface web.
Storage (SQLite)
Responsável por:
- repositório de jobs (CRUD + consultas);
- repositório de logs (escrita e consulta paginada);
- repositório de configurações (persistência de overrides);
- execução de migrações automáticas na inicialização.
Scheduler / Work Window
Responsável por controlar o dispatch de tarefas para os workers com base na janela de trabalho configurada.
- se a janela está desabilitada (padrão), libera todas as tarefas imediatamente;
- se habilitada, só libera tarefas dentro do intervalo configurado (
WORK_WINDOW_START—WORK_WINDOW_END); - tarefas em andamento quando a janela fecha são finalizadas normalmente;
- utiliza o timezone configurado (
TIMEZONE) para determinar o horário atual.
Config Service
Responsável por gerenciar a configuração da aplicação, fazendo merge entre:
- valores default (hard-coded);
- variáveis de ambiente (sobrescrevem os defaults);
- overrides persistidos no SQLite (sobrescrevem os env).
Expõe métodos para leitura e alteração em runtime, propagando as alterações para os componentes afetados.
Library Scanner
Responsável por:
- navegação por árvore de diretórios sob
MUSIC_PATH; - scan recursivo para detecção de arquivos FLAC e agrupamento por álbum;
- exposição dos resultados via API REST para a interface web;
- enfileiramento dos álbuns selecionados para conversão.
Ntfy Client
Cliente HTTP responsável por:
- envio de notificações de sucesso/falha ao final de cada job;
- suporte a servidor self-hosted ou público;
- autenticação opcional via token (
Authorization: Bearer).
Web UI
Interface para operação e monitoramento do serviço.
Páginas sugeridas:
/ Dashboard (status geral, fila, janela de trabalho)
/jobs Histórico de tarefas
/logs Consulta de logs
/library Navegação e busca de FLACs
/settings Configuração da aplicação
/health Health Check
3. Estrutura de Diretórios
cmd/
server/
internal/
config/
scheduler/
webhook/
queue/
worker/
transcoder/
validator/
lidarr/
logger/
web/
models/
store/
scanner/
ntfy/
web/
styles/
static/
templates/
data/
Dockerfile
go.mod
4. Decisões Técnicas
| Decisão | Escolha | Justificativa |
|---|---|---|
| Linguagem | Go 1.25.x | Performance, concorrência nativa, baixo footprint |
| Distribuição | Docker (Alpine Linux) | Imagem leve, portabilidade |
| HTTP Router | chi (go-chi/chi/v5) | Leve, stdlib-compatível (http.Handler), middlewares organizados, sem contexto próprio |
| Banco de Dados | SQLite embarcado (modernc.org/sqlite) | Histórico e config consultáveis, sem servidor externo, footprint baixo, sem CGO |
| Logging estruturado | log/slog (stdlib) + handler SQLite | Zero dependência, handler customizado para persistir no BD |
| ID de tarefa | github.com/google/uuid | Padrão simples e seguro para chave primária |
| Frontend | html/template + htmx + Tailwind CSS v4 + DaisyUI | Interatividade sem SPA; CSS gerado pelo Tailwind CLI standalone (sem Node) |
| Assets estáticos | Embutidos no binário (//go:embed) |
Binário único, deploy simples, alinhado ao footprint baixo |
| Fila interna | Channels do Go | Simples, sem dependência externa |
| Conversão de áudio | ffmpeg (libmp3lame) | Maturidade, suporte a codecs |
| Validação | ffprobe | Padrão da indústria, integrado ao ffmpeg |
| Configuração | Env (default) + overrides no SQLite | Env define defaults; web permite override persistido |
| Agendador de tarefas | Scheduler interno (work window) | Evita processamento fora do horário desejado |
| Volume de mídia | Docker bind mount (mesmo path do Lidarr) | Acesso físico aos arquivos para conversão/remoção |
| Atualização do Lidarr | API REST do Lidarr | Integração direta, sem polling |