# Execução — plano `PP-6` (06/08)

**Veredito inicial: ❌ Reprovado** — `PP-6-07` falhou.
**Depois da correção: ✅ Aprovado** — 10 de 10 casos (o plano ganhou `PP-6-07b`).

| Caso | Resultado | Evidência |
| ---- | --------- | --------- |
| PP-6-01 | passou | `test/pp6-reabertura.e2e-spec.ts` |
| PP-6-02 | passou | idem |
| PP-6-03 | passou | idem |
| PP-6-04 | passou | inspeção de rotas: nenhuma reabre palpite sem mudança de horário |
| PP-6-05 | passou | idem — antecipação fecha e **não** conta como reabertura |
| PP-6-06 | passou | idem |
| PP-6-07 | **falhou → corrigido** | idem |
| PP-6-07b | passou | idem (novo) — aviso da reversão |
| PP-6-08 | passou | idem — job idempotente |
| PP-6-09 | passou | idem — horário e placar na mesma volta |
| PP-6-10 | passou | idem — adiamento sem data não trava o bolão |

---

## Como a fonte foi controlada

A suíte **substitui a porta de dados** por um stub que envelopa o adaptador
falso e aplica ajustes por `externalId`. Isso foi necessário porque o adaptador
falso é determinístico: não há como fazer o mesmo jogo voltar com outro horário.

O teste que já existia ("sincronização detecta adiamento e reabre o palpite")
alterava o banco **direto** e depois verificava que o palpite era aceito — ou
seja, verificava a regra de prazo, não o job. A lógica de reabertura do
`SyncService` não tinha cobertura nenhuma.

## Bug encontrado por `PP-6-07`

**Título:** jogo já apurado que é adiado mantém os pontos antigos

**Passos para reproduzir:**
1. Jogo termina `1x1` e é apurado — participante com palpite `1x1` fica com 10
   pontos.
2. A fonte oficial passa a informar o jogo como `POSTPONED`, sem placar, com data
   nova no futuro (acontece quando o lançamento do resultado foi um erro, ou
   quando o jogo é anulado e remarcado).
3. Rodar a sincronização.

**Esperado:** o palpite reabre **e** a apuração feita sobre o placar retirado
sai junto.

**Obtido:** o palpite reabre e o participante continua com os 10 pontos.

**Severidade: alta.** O estado resultante é incoerente de um jeito que favorece
quem já sabe o resultado: a pessoa repalpita **conhecendo** o placar que houve, e
mantém a pontuação que ganhou pelo palpite antigo. Se ela repalpitar errado, fica
com 10 pontos de um palpite que não existe mais; se repalpitar igual, pontua duas
vezes na prática, porque a reapuração soma sobre o que ficou.

E nada nisso aparece: não há erro, não há log, e o ranking simplesmente mostra um
total que não corresponde a nenhum palpite.

**Corrigido** desfazendo a apuração quando a fonte **retira** o placar de um jogo
que já tinha (`atual.homeScore !== null && externo.golsCasa === null`).

## Decisão de produto embutida na correção

A reversão silenciosa seria quase tão ruim quanto o bug: o participante veria o
total cair sem explicação. Acrescentei aviso (`PONTO_REVERTIDO`) dizendo qual
jogo, quantos pontos saíram e que o palpite volta a valer quando o jogo
acontecer — na linha de `PR-7`, com a diferença de que aqui a queda não vem de
correção de placar, e sim de o resultado ter deixado de existir.

Quem tinha zero ponto naquele jogo **não** é avisado: seria ruído sobre uma
mudança que não afetou ninguém.
