## CC-3 — Travar as regras no primeiro palpite

**PRD:** `docs/prd/criacao-e-convite.md` e `docs/prd/ciclo-de-vida-do-bolao.md`

> Esta story consolida duas entradas duplicadas nos PRDs: "travar as regras
> do bolão no primeiro palpite" (_Criação e convite_) e "bloquear mudança de
> pontuação e desempate após o primeiro palpite" (_Ciclo de vida_). É a mesma
> regra e a mesma implementação.

**Como** participante competitivo, **quero** que a pontuação e o desempate
não possam mudar depois que o bolão começou, **para** não ter as regras do
jogo alteradas no meio — inclusive pelo admin, que também disputa.

**Prioridade:** Must — é o que torna justa a participação do admin no próprio
bolão; sem isso o sigilo de PP-7 não é suficiente.

**Critérios de aceite:**

- Dado que nenhum palpite foi registrado no bolão, quando o admin altera as
  regras, então a alteração é aceita.
- Dado que existe pelo menos um palpite registrado, quando o admin tenta
  alterar pontuação ou desempate, então o servidor recusa e explica o motivo.
- Dado que as regras estão travadas, quando o admin quer regra nova, então a
  saída oferecida é encerrar o bolão e abrir outro — não há alteração.
- Dado que o único palpite existente foi feito e depois o jogo foi anulado,
  então as regras **continuam travadas**: o travamento é pelo registro do
  palpite, não pela existência de pontos.
- Dado que tento alterar as regras chamando a API diretamente, então a recusa
  também acontece no servidor.

**Tasks:**

_Backend_
- [x] `BE-1` Marcar o bolão como "regras travadas" ao registrar o primeiro palpite (depende de CC-2 BE-1, PP-1 BE-2)
- [x] `BE-2` Recusar alteração de pontuação e desempate quando travado, com erro explicativo (depende de BE-1)
- [x] `BE-3` Garantir que o travamento não seja revertido por anulação de jogo ou remoção de palpite (depende de BE-1)

_Mobile_
- [x] `FE-1` Exibir as regras como somente leitura quando travadas, com o motivo (depende de BE-2)
- [x] `FE-2` Oferecer o caminho de encerrar e abrir outro bolão quando o admin tenta mudar regra travada

_QA_
- [x] `QA-1` Escrever o plano de casos de teste a partir desta story
- [x] `QA-2` Executar o plano via API direta, e no caso de palpite registrado e depois jogo anulado

**Riscos/Dependências:**

- Depende de CC-2 e PP-1.
- **É a story que sustenta a confiança no admin-jogador.** Se furar, o
  conflito entre admin e competitivo volta inteiro.
- O caso de borda de BE-3 é o mais fácil de errar: travar por "existe ponto"
  em vez de "existe palpite" reabre a brecha.

- **06/08:** travado, o editor não abre e a tela explica o motivo. `FE-2` foi
  feita como texto para o admin: encerrar este bolão e abrir outro é o caminho —
  sem ele, o admin tenta burlar ou pede para alguém mexer no banco.
- Defeito achado por teste: quando o travamento acontecia **durante** a edição
  (409), a explicação aparecia no formulário e a tela voltava para o modo
  leitura no mesmo instante, **apagando a mensagem**. Agora o aviso sobrevive à
  volta, em faixa própria.

- **06/08:** plano de casos em `docs/testes/CC-3-plano.md`. Escrito a partir da
  story, não do código — caso escrito depois de olhar a implementação valida o
  que foi feito, não o que foi pedido.

- **06/08 — execução: ✅ 9 de 9** (`docs/testes/CC-3-execucao.md`). Único plano
  executado até agora sem lacuna de cobertura: `CC-3` é regra de servidor, com
  uma transição de estado só e sem variação de dado. Onde a cobertura falhou nos
  outros planos foi sempre borda de tempo, escopo de rota ou estado de tela.
