Estado do Modo TV em SQLite 📺
O Modo TV guardava as transmissões ativas e o sync de reprodução em dois JSONs (live-sessions.json e live-sync.json), reescritos por inteiro a cada heartbeat e sem nenhum lock. Na prática isso dava dois problemas: dois dispositivos batendo heartbeat ao mesmo tempo liam a mesma lista e um sobrescrevia o outro — o dispositivo sumia da tela do Modo TV até o próximo heartbeat; e, como a escrita não é atômica, quem lesse o arquivo no meio de uma gravação podia pegar um JSON truncado.
Agora esse estado vive em data/tv-mode.sqlite, com upsert por linha e transações: cada heartbeat mexe só na própria linha, e as leituras nunca enxergam um estado pela metade.
Por que um banco separado
Já existiam dois bancos com ciclos de vida opostos — o cache de catálogo (xstream-player.sqlite, descartável) e os dados do usuário (user-data.sqlite, insubstituível). O estado do Modo TV não pertence a nenhum dos dois: ele é efêmero (toda linha expira em segundos sem heartbeat) e recebe escrita o tempo todo. Colocá-lo no banco de usuário incharia justamente o arquivo que importa no backup; colocá-lo no cache faria a limpeza do catálogo — uma operação normal — derrubar transmissões em andamento.
Com um terceiro banco, apagar o tv-mode.sqlite a qualquer momento não custa nada: os dispositivos se re-anunciam no heartbeat seguinte.
O que fazer
Nada. Não há migração: os JSONs antigos são apagados sozinhos na primeira execução, e todo o conteúdo deles expiraria em segundos de qualquer forma. Quem roda várias instâncias compartilhando a pasta data/ continua funcionando igual — o estado compartilhado só mudou de arquivo.