- Backend respondia
/v1/catalogcom listas vazias (DB Supabase sem seed). - Viewer, com
VITE_USE_REST_SESSION_LESSON=true, não conseguia mapearchapter_id -> lesson_id, gerandolesson_id não encontrado para o capítuloe caindo para WS apenas após erro.
- Ambiente de desenvolvimento sem registros em
tracks/chapters/lessons; nenhum seed automático. - Viewer dependia do catálogo REST para iniciar sessão REST; erro não era tratado com fallback limpo.
- Fallback no backend:
/v1/catalogagora retorna dados derivados deassets/lessons.jsonquando o DB está vazio (idslesson_<chapter_id>), mantendo compatibilidade com produção (usa o DB se houver dados). - Seeder idempotente:
backend/scripts/seed_catalog.pycria/atualiza tracks, capítulos e lições mínimas a partir deassets/lessons.json. Alvomake seed-catalogadicionado e chamado emscripts/dev.sh(best-effort). - Hardening do viewer: desabilita o fallback REST se o catálogo vier vazio ou falhar, evita throw, mostra motivo na overlay meta e continua usando WebSocket.
- Teste:
backend/tests/test_catalog_fallback.pygarante que o fallback de catálogo retorna lições quando o DB está vazio.
make backend(ouscripts/dev.sh) — o script de seed roda automaticamente;/v1/catalogdeve retornar lições.- Em separado:
make seed-catalog(idempotente). - Abrir o viewer; iniciar capítulo — não deve aparecer erro de
lesson_ide a lição carrega via REST ou WS. - Teste rápido:
PYTHONPATH=backend pytest backend/tests/test_catalog_fallback.py.
- Analytics continuam desativados se faltarem chaves Supabase (mensagem já existente).
- Fallback não toca produção: só ativa quando as tabelas estão vazias.