Repository navigation
Description
Contexto
Fatia 2 do epic #24 (Practice/Solo mode §V.5). A Fatia 1 (#25, PR #40) já entregou o Treino Livre solo em src/components/PracticeView.tsx — hoje é só o jogador contra o cronômetro, sem ninguém pra comparar em tempo real. A spec (§V.5) pede um modo "contra bots": um WPM-alvo configurável (40/60/80/100) dá ao Iniciante alguém pra "competir" sem precisar de sala/amigos — reduz a sensação de vazio do treino solo.
Escopo
- Seletor de WPM-alvo no
PracticeView.tsx(ex.: chips 40/60/80/100, ou "sem bot"), ao lado dos seletores de linguagem/dificuldade já existentes. - Um "racer fantasma" que avança a progresso linear no ritmo do WPM escolhido (progresso =
f(tempo decorrido, wpm_alvo, tamanho do snippet)), iniciando no mesmostartedAtdo jogador (1º keystroke). - Barra de progresso do bot visível ao lado/abaixo da corrida do jogador (reusar visual de progresso já usado no multiplayer, se der pra extrair sem acoplar a
useRoom/Realtime — o Treino Livre não pode ganhar dependência de sala). - Ao terminar, mostrar quem venceu (jogador vs bot) nas stats de conclusão (
statsemPracticeView.tsx).
Acceptance criteria (verificáveis)
- Seletor de WPM-alvo (ou "sem bot") funcional; default = sem bot (comportamento atual preservado).
- Bot avança de forma determinística e visível durante a corrida, sincronizado ao mesmo
startedAtdo jogador. - Tela de conclusão mostra o resultado da comparação (jogador venceu/perdeu pro bot, ou nenhum bot ativo).
- Zero chamada a
/api/rooms, Supabase ou Realtime — o bot é 100% client-side/determinístico (mantém a garantia da Fatia 1 de treino sem sala). - Área sagrada intacta: nada no bot compete com a
textarea/o loop de digitação (TypingCore); a barra do bot é só leitura visual. -
pnpm typecheck+pnpm buildverdes;node scripts/validate-metrics.mjsverde se tocar cálculo de progresso/WPM.
Dica de abordagem
Progresso do bot em função do tempo é puro e testável: botProgress(elapsedMs, targetWpm, charCount) — mesma filosofia dos builders extraídos em #50/#32 (função pura ao lado da lógica de UI, fácil de cobrir com Vitest). Evite reinventar o cálculo de WPM→progresso; se Race.tsx/TypingCore já expõe algo equivalente, reuse.
Refs: spec docs/UI-AAA-OVERHAUL.md §V.5 (modo 3, "contra bots"); epic #24; Treino Livre atual em src/components/PracticeView.tsx.
Activity