Files
backspace/docs/roadmap-resenha.md
T
devsyncwrld ff55d9d486
CI / Build & test (Node 20) (push) Waiting to run
CI / Build & test (Node 24) (push) Waiting to run
CI / Build & test (push) Blocked by required conditions
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
OpenSSF Scorecard / Scorecard analysis (push) Waiting to run
Security / Secret scan (gitleaks) (push) Waiting to run
Security / Dependency scan (OSV-Scanner) (push) Waiting to run
Security / IaC/config scan (Trivy) (push) Waiting to run
Security / License compliance scan (Trivy) (push) Waiting to run
docs: plan desktop features and diagnose the Spotify sync bugs
2026-08-31 14:02:21 -03:00

10 KiB

Roadmap — fork Resenha

Plano de features próprias desta instância. Arquivo exclusivo do fork (nome com sufixo para não colidir com arquivos do upstream em merges).

Escrito em português por ser documento de planejamento do dono do fork; o código e os commits seguem em inglês, como o resto do repositório.

Entregue

Feature Commit Nota
Ir para a call clicando no nome do canal c70b0095 Exigiu o voiceStore passar a guardar o espaço da call — antes ele não sabia onde a call estava assim que o usuário navegava para outro servidor
Botão de GIF redesenhado 20526e1b Contorno vazado com letras cheias, no lugar do bloco sólido
Explorador de GIF no banner 20526e1b Sem upload: banner já aceita URL absoluta no cliente e no servidor
Teste de microfone com retorno bfe62d70 AudioManager.startMicTest/stopMicTest; devolve o microfone ao parar, com duas travas independentes
Bloco de atividade no perfil d7da0ff2 ProfileActivity; inclui correção de validação de assets no servidor
Favoritar GIFs + categorias (#6) fb662bfe Favoritos no servidor, por conta; guarda o resultado inteiro porque o provedor não busca por id
Registro de auditoria (#9) bbb190cb Tabela append-only genérica; 8 ganchos; sair ≠ ser expulso
Estatísticas do grupo 18300517 Tabela própria de sessões de voz; ganchos no ponto único de entrada/saída
Spotify por OAuth (atividade com capa e progresso) 75316b08 Token só no servidor; state assinado; atividades por fonte para não brigar com o detector do Electron
Menu do próprio nome f5451e1b Perfil, status e copiar ID. Sem Clips/trocar conta — não existem aqui
Cronômetro da call f5451e1b startedAt do servidor; zera sozinho porque sala vazia é destruída
Fundação de i18n (en + pt-BR) 688a1335 src/i18n/; pt-BR é parcial e cai para inglês. Aba Idioma nas configurações
Preview de perfil nos participantes da call (ver git log) O popout já existia e era aberto de 11 lugares; nenhum era de voz. Ligado nas linhas da lista de voz e no nome dos tiles da grade

Já existia no código (verificado, não construir de novo)

  • Animação de digitaçãoTypingIndicator.tsx, três pontos animate-bounce escalonados em 0/150/300ms.
  • Sons de call/streamSoundController.tsx, montado no AppLayout: stream started/ended, alguém entra/sai da tela, entra/sai da call, câmera, mute, ringing. Os .ogg estão em web/public/sounds/.
  • Preview de perfil ancoradouiStore.openUserProfile(user, anchor, placement) guarda userProfilePopout; popout posicionado no desktop, tela cheia no mobile. Já era aberto por mensagens, menções, avatares, lista de membros, DMs e painel de atividade. O que faltava era só a voz — agora ligado. Continua faltando o bloco de atividade do print do Discord, que é a #8.

Se qualquer um dos dois não se manifestar em uso, o trabalho é depuração, não implementação.

Pendente — pedido original

Ordem sugerida: as pequenas primeiro, as grandes uma de cada vez.

# Feature Tamanho Observação técnica

Pendente — ideias aprovadas

Feature Tamanho Observação técnica
Soundboard Média AudioManager já carrega e toca .ogg sob demanda; falta upload por espaço, permissão e disparo na sala LiveKit
Estatísticas do grupo Grande Horas em call, quem mais falou, ranking. Depende do mesmo registro de eventos da auditoria (#9)
Watch party Grande O screen share do LiveKit já existe; falta sincronizar posição de reprodução entre participantes
Emojis e stickers do grupo Média UPLOAD_DIR e o pipeline de upload já existem; falta tabela por espaço e resolução no render de mensagem

Regra de idioma (a partir de 2026-08-31)

Funcionalidade nova sai com interface em pt-BR, e a cada update um sistema existente é traduzido. Os dois idiomas coexistem. Código, comentários e commits seguem em inglês.

A fundação está pronta (src/i18n/). Para traduzir um sistema: adicione as chaves em locales/en.ts, traduza em locales/pt-BR.ts e troque as strings fixas por t('chave'). O que faltar cai para o inglês sozinho.

Sistemas já traduzidos

  • Configurações → navegação e aba Idioma
  • Configurações → Voz (dispositivo de entrada, volume, teste de microfone)
  • Cartão de perfil (sobre mim, membro desde, enviar mensagem, atividade)
  • Configurações → Privacidade
  • Configurações → Conexões (nasceu bilíngue)
  • Seletor de GIF
  • Registro de auditoria e Estatísticas (nasceram bilíngues)

Fila sugerida de tradução

Mensagens e composer · lista de membros · servidores e canais · amigos e DMs · modais de convite · configurações restantes · telas de erro

Correções pendentes

Problema Causa provável Correção
Enviar som ao soundboard não funciona no app desktop (funciona no navegador) SoundboardPopover pede o nome do som com window.prompt, que o Electron não implementa — não abre nada e devolve vazio, então o fluxo aborta em silêncio, sem erro. window.prompt aparece em exatamente um lugar no projeto: esse. O resto do código já o evitava Trocar por um campo de texto dentro do próprio popover (ou um modal reutilizável). Some o prompt e passa a funcionar igual nos dois. Vale criar o modal de entrada genérico, já que não existe nenhum e outras features vão precisar
Bloco do Spotify dessincronizado (mostra a faixa errada por um tempo) Soma de duas esperas: a consulta roda a cada 20s (useSpotifyActivity) e o envio pelo WebSocket ainda passa por um debounce de 5s no activityStore. Na pior hipótese os outros veem a música anterior por ~25s Consultar de novo perto do fim da faixa (a duração é conhecida) em vez de só por intervalo fixo, e encurtar o debounce para esta fonte
Bloco do Spotify some sozinho Três caminhos apagam a atividade inteira: faixa pausada (is_playing: false devolve null), o vão entre faixas (o Spotify responde 204) e qualquer falha transitória. Some e volta = a piscada que você viu Manter a última faixa conhecida por alguns segundos antes de apagar, e enviar um estado pausado explícito em vez de sumir com o bloco
Barra de progresso errada / andando pausada Duas causas independentes: (1) o progresso é derivado de carimbos calculados com o relógio do servidor e desenhado contra o relógio de quem olha — se os relógios divergem, a barra fica deslocada; (2) a barra continua avançando localmente depois que a pessoa pausa, até a próxima consulta Enviar o horário do servidor junto no payload para o cliente corrigir a diferença, e congelar a barra quando o estado for pausado

Aprovadas para o app desktop (2026-08-31)

Só entram aqui coisas que o navegador não consegue fazer — o resto seria trabalho dobrado sem ganho. Nenhuma iniciada.

Feature Tamanho Observação técnica
Áudio do sistema no compartilhamento de tela Média Hoje o som do jogo/vídeo não vai junto com a tela. O Electron captura áudio do sistema; o navegador não. É pré-requisito da watch party — sem isso, assistir junto é assistir mudo. No Linux depende do servidor de áudio (PipeWire/PulseAudio), então vale confirmar o alvo antes
Bandeja do sistema Pequena Fechar minimiza em vez de sair; ícone com menu de mudo/silenciar e sair de verdade. Cuidado clássico: sem um "sair" explícito no menu, a pessoa não consegue fechar o app
Notificações nativas do sistema Pequena Mais confiáveis que as do navegador e funcionam com a janela minimizada. Já existe um NotificationController no web; a parte desktop é rotear pelo processo principal

Aprovadas, a fazer depois (2026-08-31)

Escolhidas pelo dono, inspiradas no Discord. Nenhuma iniciada.

Feature Tamanho Observação técnica
Fixar mensagens no canal Pequena Tabela de fixadas por canal + rota de listagem; permissão natural é MANAGE_MESSAGES
Busca com filtros Média SearchPopover já existe; falta filtrar por autor, canal e presença de anexo — e índice no banco, senão fica lento quando o histórico crescer
Resposta rápida de voz (soundboard por atalho) Pequena O soundboard já está pronto; falta só marcar favoritos e ligar a atalhos de teclado, sem abrir painel. Cuidado: o limite de repetição do servidor continua valendo e é o que impede virar metralhadora
Cargos com ícone e exibição separada Média Cargos e cores já existem; falta ícone, o campo "exibir separadamente" e o agrupamento na lista de membros

Ideias novas — a avaliar

Ordenadas por relação valor/custo para um servidor de grupo fechado.

Sistema Tamanho Por que faz sentido aqui
Backup fora da VPS Pequena Hoje app, banco, uploads, backups e as três cópias do repositório morrem no mesmo evento. Um envio periódico para fora resolve
Aniversários e lembretes Pequena Alto retorno afetivo, custo baixo: campo de data + verificação diária + mensagem no canal
Perfis por servidor Média Apelido e avatar diferentes por espaço, como no Discord. O modelo já tem membro por espaço
Eventos agendados com presença Média "Sexta 21h" com confirmação. Encaixa nas notificações e no PWA já instalado
Notificações push de verdade Média O vite-plugin-pwa e o service worker já estão lá; falta Web Push (VAPID) e o registro no servidor
Níveis e conquistas Média Gamificação por tempo em call e mensagens. Mesmo registro de eventos da auditoria e das estatísticas — três features, um mecanismo
Clipes de call Grande "Salvar os últimos 30 segundos" depois de alguém falar besteira. O LiveKit tem egress; exige buffer contínuo e armazenamento
Fila de música compartilhada Grande Um participante-robô publicando faixa de áudio na sala LiveKit. É o que mais muda o uso de um servidor de amigos, e o mais caro
Autenticação em duas etapas Média Só faz sentido depois de decidir o modelo de cadastro

Dependência que vale respeitar

Auditoria (#9) e Estatísticas compartilham o mesmo mecanismo: uma tabela de eventos append-only no servidor. Construir a auditoria primeiro e as estatísticas como leitura agregada dessa mesma tabela evita escrever dois sistemas de registro paralelos que divergem com o tempo.