# CHANGELOG — SpotOnFide

Registro de toda mudança relevante feita no projeto. Cada entrada tem:
data, arquivo(s) tocado(s), o motivo, e se foi **validada em produção** pelo
Marsan ou não. Antes de reverter/culpar qualquer arquivo por uma regressão,
consultar aqui primeiro.

---

## 2026-07-13

### ✅ VALIDADO — Share Service (compartilhamento de episódio/faixa)
**Arquivos:** `server/_core/share.ts` (novo), `server/_core/static.ts`,
`server/musica-db.ts`, `server/_core/index.ts`, `vite.config.ts`,
`server/_core/uploads.ts`, `server/_core/createApp.ts`,
`AddToPlaylistMenu.tsx`, `AddToPlaylistMenuMusica.tsx`, `EpisodioCardHome.tsx`

**Problema:** card do WhatsApp mostrava o logo genérico em vez da capa
real do episódio/faixa.

**Causa raiz real:** Service Worker aplicava o fallback da SPA por cima
de `/share/*` porque `navigateFallbackDenylist` usava `/^\/share\//` (a
âncora `^` nunca batia, já que o caminho real inclui o prefixo `/app`).

**Status:** confirmado funcionando pelo Marsan depois de várias rodadas
de debug (zumbis de processo, cache do LiteSpeed, e por fim o regex).

---

### ✅ VALIDADO — Redesenho da linha de faixa/episódio (mobile)
**Arquivos:** `FaixaRow.tsx`, `EpisodioRow.tsx`, `AddToPlaylistMenu.tsx`,
`AddToPlaylistMenuMusica.tsx`

**Mudança:** seta sempre visível (era só no hover) vira equalizer ao
tocar; menu "⋮" virou Dialog centralizado (era DropdownMenu que cortava
em tela pequena); título maior; duração ao lado do subtítulo.

**Status:** validado pelo Marsan.

---

### ✅ VALIDADO — Padding duplicado nas páginas de Música
**Arquivos:** `MusicaAlbum.tsx`, `MusicaAlbuns.tsx`, `MusicaArtista.tsx`,
`MusicaArtistas.tsx`, `MusicaFaixa.tsx`, `MusicaFaixas.tsx`

**Causa raiz:** `MainLayout.tsx` já aplica `px-5 lg:px-8` globalmente;
essas páginas tinham `p-8` próprio por cima, dobrando a margem no mobile.

**Status:** validado.

---

### ✅ VALIDADO — Bug de modo em `/episodios`
**Arquivo:** `Explorar.tsx`

**Causa raiz:** `forcePodcast` era passado pela rota mas o componente
nunca aceitava esse prop — `/episodios` mostrava Música se o seletor
global estivesse em "Música". Corrigido com `effectiveMode`.

**Status:** validado.

---

### ❌ ABORTADO — Fase 4 (Áudiolivro) + TTS (Piper)
**Arquivos afetados:** schema novo (`audiolivro_livros`, `audiolivro_capitulos`,
3 tabelas de biblioteca), `server/audiolivro-db.ts`, `server/audiolivro-router.ts`,
admin de Livros/Capítulos, `server/_core/tts.ts`

**O que aconteceu:** gerar áudio com Piper (modelo ONNX de 63MB por
chamada) esgotou os processos da conta cPanel (98/100), servidor caiu
com 503.

**Decisão do Marsan:** reverter tudo — schema removido do banco (5
`DROP TABLE` confirmados), código revertido via backup, seletor
"Áudiolivro" removido do Topbar (`Topbar.tsx`, `ModeContext.tsx`).

**Não retomar** sem resolver capacidade de processos da hospedagem
primeiro (ver memória: "SPOTONFIDE ÁUDIOLIVRO — PAUSADO/REMOVIDO").

---

### ⚠️ TENTATIVA SEM SUCESSO — Rádio de transmissão contínua (laboratório)
**Onde:** `radio.onfide.com.br` (cópia isolada, nunca tocou o site
principal) — `server/radio-stream.ts`, `client/public/radio-teste.html`

**Ideia:** servidor entrega um único fluxo HTTP contínuo, sem o celular
precisar trocar de `src` — eliminaria o instante de silêncio entre
faixas.

**Resultado:** funcionou tecnicamente (áudio tocava, reconectava), mas
não alcançou estabilidade suficiente em tempo hábil — log de erro
cresceu descontroladamente (10GB, esgotamento de conexões/processos),
depois um loop de reconexão infinito no cliente. Várias camadas de
correção aplicadas (backpressure, limite de ouvintes, freio no log,
reconexão sem depender de `setTimeout`) sem chegar a uma validação de
horas como o AutoDJ antigo já tinha.

**Decisão do Marsan:** abandonar essa frente por hoje, voltar pro
`spot.onfide.com.br` (nunca foi tocado por essa tentativa).

---

### 🔴 REVERTIDO — Transição antecipada de faixa (0,3s antes do fim)
**Arquivo:** `client/src/contexts/PlayerContext.tsx`

**O que era:** tentativa de disparar `handleEnded()` antes do áudio
terminar de verdade, pra evitar uma janela de silêncio entre faixas que
o Android poderia usar pra suspender a aba em segundo plano.

**Por que foi revertido:** código novo, nunca validado por horas — ao
contrário do comportamento anterior (trocar de faixa só no evento
`ended`), que **já tinha funcionado por horas sem interrupção** antes
desta sessão. Sem evidência de que a mudança ajudasse, e com o Marsan
relatando que a continuidade piorou depois dela, revertida por
segurança.

**Mantido:** a correção do `<audio>` único (movido pra dentro do
`PlayerProvider`, nunca mais duplicado entre o player expandido e o
recolhido) — essa é uma correção de arquitetura real e válida
(ADR-004), não relacionada à regressão relatada.

**⚠️ ATENÇÃO — lição aprendida (jul/2026):** essa correção é um PAR
inseparável: `PlayerContext.tsx` (cria o `<audio>`) + `Player.tsx`
(parou de criar o próprio `<audio>`). Subir um sem o outro quebra a
reprodução por completo (dois elementos de áudio disputando a mesma
`ref`). **Sempre entregar e subir os dois juntos, no mesmo deploy.**

**Status:** revertido, aguardando novo teste de validação do Marsan em
produção (`spot.onfide.com.br`) antes de marcar como ✅ ou ❌.

---

---

## 2026-07-14 — RECONSTRUÇÃO COMPLETA (auditoria total)

**Contexto:** depois da crise do Audiolivro/TTS e da tentativa da Rádio
(ambas abandonadas), o Marsan pediu uma auditoria completa do backup
feito antes do Audiolivro, reconstruindo com todos os conceitos
validados até aqui, para eliminar de vez os problemas de continuidade.

### O que a auditoria confirmou já estar correto (sem mexer)
- `<audio>` único dentro do `PlayerProvider` (nunca duplicado) ✅
- Sem a "transição antecipada" de 0,3s (revertida antes, confirmado) ✅
- Media Session completa (setPositionState, todos os handlers, artwork
  multi-tamanho) ✅
- Cache de áudio `NetworkOnly` no Service Worker (nunca `CacheFirst`) ✅
- Share Service (`/share/*`) com `navigateFallbackDenylist` correto ✅
- Redesenho de linha (seta sempre visível → equalizer) em
  `FaixaRow`/`EpisodioRow` ✅
- `package.json` limpo, sem `ffmpeg-static`/`edge-tts` ✅
- Nenhuma tabela/arquivo de Audiolivro no banco ou no código ✅

### Corrigido nesta reconstrução
- **`Topbar.tsx`**: botão "Áudiolivro" ainda estava presente neste
  backup (o fix de remover era de uma sessão mais recente que este
  backup não tinha) — removido.
- **`ModeContext.tsx`**: fallback do localStorage ainda aceitava
  `"audiolivro"` como valor salvo — corrigido para cair em `"podcast"`.
- **`EpisodioCardHome.tsx`**: menu "⋮" tinha 2 opções ("Ouvir em
  seguida", "Adicionar à fila") chamando `playNextItem()`/`addToQueue()`
  — métodos que **nunca existiram** no `PlayerContext` — clicar
  quebraria com erro de runtime. Removidas por segurança. **Pendência
  registrada**: se o Marsan quiser essa funcionalidade de fila a partir
  da Home, precisa ser construída do zero no `PlayerContext`.

### Removido (limpeza — órfãos sem nenhuma referência confirmada)
- `client/src/pages/AdminMusica.tsx` — órfão do antigo "Executor"
  (pendente de remoção desde memória #7, nunca confirmado feito)
- `client/src/pages/home/Home.tsx` — duplicata não usada do
  `pages/Home.tsx` real (o que o `App.tsx` de fato importa)
- `server/routers-episodios-bloco.ts`, `server/podcast-db-bloco.ts` —
  rascunhos ("blocos para colar"), nunca foram código de verdade

### Pendências conhecidas, não corrigidas nesta rodada (baixa gravidade,
não travam nada, não relacionadas a áudio)
- 12 avisos do `tsc --noEmit`: um padrão repetido de `.map()` passando
  índice numérico onde um objeto opcional era esperado (inofensivo em
  JS em runtime); `onError` desatualizado nos formulários admin de
  Música (formulário funciona, só não mostra toast de erro em falha de
  consulta).
- Menu do admin sem itens de Música (memória #24, aguardando pedido
  explícito do Marsan).

**Status:** build de produção limpo, sem erro. Aguardando teste em
produção pelo Marsan antes de marcar como ✅ VALIDADO.

## Como usar este arquivo daqui pra frente

- Toda entrega de código relevante ganha uma entrada aqui, no mesmo dia.
- Assim que o Marsan confirmar "funcionou de verdade, testei por horas" —
  a entrada vira ✅ VALIDADO, e vale a pena guardar um zip do `dist/`
  rotulado (ex: `dist-VALIDADO-2026-07-13-autodj-ok.zip`) como ponto de
  restauração imediato.
- Se algo quebrar depois, primeiro passo é olhar aqui — qual foi a
  última entrada ✅ VALIDADO antes do problema aparecer — antes de
  arriscar culpar um arquivo sem checar.
