## PP-6 — Reabertura automática do palpite quando o horário oficial muda

**PRD:** `docs/prd/palpite-e-prazo.md`

**Como** participante, **quero** que o palpite reabra sozinho quando o jogo
é adiado, **para** poder repalpitar na nova data sem depender de o admin
liberar na mão.

**Prioridade:** Must — a reabertura ser automática é o que impede o admin de ser
acusado de favorecer alguém. **Decidido em 03/08: não existem jogo cancelado nem
W.O. — todo jogo não realizado é adiado**, o que torna esta story o **único**
tratamento de jogo que não aconteceu.

⚠️ **Risco conhecido e aceito:** o tier gratuito da `football-data.org` atrasa
não só o placar, mas também o _schedule_, e **o tamanho desse atraso não é
documentado**. A story entra no escopo, mas sua confiabilidade só pode ser
medida em operação — `QA-2` precisa registrar o tempo real entre o adiamento
oficial e a reabertura no app.

**Critérios de aceite:**

- Dado que um jogo é adiado para uma nova data oficial, quando a mudança
  chega ao sistema, então o prazo daquele jogo passa a ser o novo horário e o
  palpite volta a aceitar edição.
- Dado que o palpite reabriu, quando eu não altero nada, então o palpite que
  eu já tinha continua valendo.
- Dado que o jogo já estava fechado e ninguém viu palpite de ninguém (o jogo
  não terminou), quando reabre, então nenhum palpite foi revelado.
- Dado que sou admin, quando tento reabrir um palpite manualmente, então não
  existe essa ação — a reabertura só acontece por mudança do horário oficial.
- Dado que o jogo é adiado sem nova data definida, então o prazo **não**
  reabre e o jogo fica sem prazo aberto.

**Tasks:**

_Backend_
- [x] `BE-1` Detectar mudança do horário oficial do jogo a partir da fonte de calendário
- [x] `BE-2` Atualizar o prazo do jogo e reabrir o palpite ao detectar novo horário (depende de BE-1)
- [x] `BE-3` Preservar o palpite existente na reabertura, sem apagar (depende de BE-2)
- [x] `BE-4` Garantir que não exista endpoint de reabertura manual por admin

_Mobile_
- [x] `FE-1` Refletir o jogo reaberto na lista, com o novo prazo e o palpite anterior preenchido (depende de BE-2)
- [x] `FE-2` Avisar o participante de que um jogo reabriu, para ele não descobrir por acaso

_QA_
- [x] `QA-1` Escrever o plano de casos de teste a partir desta story
- [x] `QA-2` Executar o plano incluindo adiamento sem nova data e tentativa de reabertura manual via API

**Riscos/Dependências:**

- **Depende inteiramente da fonte oficial de calendário** — se a mudança de
  horário não chegar, esta story nunca dispara e o prazo fica errado. **É o
  item nº 1 do spike da fonte de dados**, e a decisão de tratar tudo como
  adiado tornou essa verificação mais crítica, não menos: não há mais caminho
  alternativo para um jogo que não aconteceu.
- ⚠️ **W.O. real não é reagendado.** Como o sistema não tem esse conceito, um
  jogo decidido por W.O. ficaria adiado para sempre. A saída é o admin lançar
  o placar oficial à mão (`PR-10`) — sem isso o bolão nunca encerra.
- Adiamento para depois de rodadas seguintes reabre o palpite muito tempo
  depois, com o participante sabendo mais. O PRD aceitou esse custo; vale
  medir reclamação.
- Interage com PP-5 (bloqueio) e com o encerramento do bolão (CV-1).

- **06/08 — plano em `docs/testes/PP-6-plano.md`; execução: ❌ reprovada, depois
  ✅ 10 de 10** (`docs/testes/PP-6-execucao.md`).
- A lógica de reabertura do `SyncService` **não tinha cobertura nenhuma**. O teste
  que existia alterava o banco direto e verificava a regra de prazo, não o job.
  A suíte nova substitui a porta de dados por um stub controlável — sem isso não
  há como fazer o mesmo jogo voltar com outro horário, porque o adaptador falso é
  determinístico.
- `PP-6-07` achou um bug alto: **jogo já apurado que é adiado mantinha os pontos
  antigos**. O estado favorecia quem já sabia o resultado — a pessoa repalpitava
  conhecendo o placar e mantinha a pontuação do palpite anterior, sem erro, sem
  log, com o ranking mostrando um total que não corresponde a palpite nenhum.
  Corrigido desfazendo a apuração quando a fonte **retira** o placar de um jogo
  que já tinha.
- Decisão embutida na correção: reverter em silêncio seria quase tão ruim quanto
  o bug. Acrescentei o aviso `PONTO_REVERTIDO` dizendo qual jogo, quantos pontos
  saíram e que o palpite volta a valer. Quem tinha zero não é avisado — seria
  ruído.
- ⚠️ Segue valendo o risco já registrado na story: o atraso do tier gratuito no
  *schedule* não é documentado, e o tempo real entre o adiamento oficial e a
  reabertura no app só pode ser medido em operação.

- **06/08:** `FE-1` já estava satisfeita por construção (a tela relê do servidor,
  então o novo prazo e o palpite salvo aparecem) e agora tem teste provando os
  dois estados, com o horário local do novo apito visível.
- `FE-2` exigiu **gerar** o aviso: o job reabria o palpite e não avisava ninguém.
  Reabertura silenciosa é pior que não reabrir — quem não fica sabendo mantém o
  palpite antigo sem revisar e descobre na apuração que jogou um placar escolhido
  para outra data. O aviso traz o palpite que continua valendo, para dispensar
  abrir o app só para conferir.
