## PR-7 — Avisar quem foi afetado por um recálculo

**PRD:** `docs/prd/pontuacao-e-ranking.md`

**Como** participante, **quero** ser avisado quando meu ponto ou minha
posição mudar por correção de placar, **para** não achar que o app está com
defeito.

**Prioridade:** Must — o PRD é explícito: o aviso não é opcional. Sem ele, a
decisão de recalcular (PR-6) vira o problema que ela deveria resolver.

**Critérios de aceite:**

- Dado que um recálculo alterou meu ponto ou minha posição, quando o aviso
  chega, então ele diz **qual jogo mudou, qual era o placar antes e qual é
  agora**.
- Dado que meu ponto não mudou no recálculo, então eu **não** recebo aviso.
- Dado que eu recebo o aviso, quando toco nele, então caio no extrato daquele
  jogo (PR-2).
- Dado que eu neguei a permissão de notificação, então o aviso continua
  visível dentro do app, no extrato e no ranking.
- Dado que vários jogos foram corrigidos de uma vez, então recebo um aviso
  consolidado, não um por jogo.

**Tasks:**

_Backend_
- [x] `BE-1` Montar a mensagem de aviso a partir do histórico da correção (depende de PR-6 BE-4)
- [x] `BE-2` Enviar apenas aos participantes com ponto ou posição alterada (depende de PR-6 BE-5)
- [x] `BE-3` Consolidar múltiplas correções simultâneas num único aviso por participante (depende de BE-1)

_Mobile_
- [x] `FE-1` Receber o aviso e levar ao extrato do jogo corrigido (depende de BE-1)
- [x] `FE-2` Exibir a marca de "ponto corrigido" dentro do app, independente de push
- [x] `FE-3` Não travar quando a permissão de notificação estiver negada

_QA_
- [x] `QA-1` Escrever o plano de casos de teste a partir desta story
- [ ] `QA-2` Executar o plano com correção que afeta e que não afeta o participante, e com permissão negada

**Riscos/Dependências:**

- **Deve entrar junto com PR-6, não depois.** Recalcular sem avisar é pior
  que não recalcular.
- Depende de PR-6 e da infra de push (PP-8 OPS-1).
- Aviso genérico ("seus pontos mudaram") não cumpre a story: o critério exige
  dizer qual jogo e qual placar.

- **06/08:** `FE-1` fica aberta na parte de **navegar** do aviso para o extrato
  do jogo corrigido — o aviso é listado e legível, mas ainda não é tocável.
- `FE-3` está satisfeita por construção: não existe push nesta versão, então não
  há permissão a negar. Os avisos vivem no banco e são lidos dentro do app.
- Verificado em device com aviso **real**, gerado por correção manual em bolão
  já encerrado: a pontuação foi recalculada (30 → 23) e o aviso apareceu
  identificado como intervenção do administrador.

- **06/08:** tocar num aviso de pontuação leva ao extrato da rodada, que é onde
  está a conta. Sem isso o participante lia "sua pontuação mudou" e não tinha
  para onde ir.

- **07/08 — QA:** plano em `docs/testes/PR-7-plano.md`, execução em
  `docs/testes/PR-7-execucao.md` (**⚠️ 9 de 10**). `QA-2` **fica aberta**: a parte
  de "permissão negada" não é executável — não existe push nesta versão
  (`PushDesativadoAdapter`, e o app nunca pede permissão), então a condição não
  muda nada. Volta junto com o FCM.
- **07/08 — `BE-3` reaberta e refeita (falhou `PR-7-05`).** O critério pede aviso
  **consolidado** quando vários jogos são corrigidos de uma vez; a consolidação
  existia **dentro** de uma correção, não entre correções — cada jogo corrigido
  gravava a sua notificação. Uma sincronização que corrigia três placares mandava
  três avisos "sua pontuação mudou" em segundos, que é o comportamento que faz
  alguém silenciar o app — e aí perder o lembrete de prazo, que é a notificação
  que sustenta o produto.
  Corrigido com um **coletor** de avisos em `CorrecaoService.aplicar`, consolidado
  por participante e bolão no fim da sincronização, listando os jogos e informando
  a mudança **líquida** de posição. Correção manual segue avisando na hora: é uma
  por vez e o admin está olhando a tela.
