## CC-1 — Criar bolão com os jogos já carregados

**PRD:** `docs/prd/criacao-e-convite.md`

**Como** administrador, **quero** criar o bolão escolhendo o campeonato e as
rodadas, com os jogos já vindo prontos, **para** não cadastrar jogo a jogo —
que é o que me faz desistir e voltar para a planilha.

**Prioridade:** Must — sem isso não existe bolão, e é a story que mais
diretamente impede o admin de abandonar.

**Critérios de aceite:**

- Dado que escolho um campeonato e um intervalo de rodadas, quando crio o
  bolão, então os jogos daquelas rodadas já estão no bolão, com data e
  horário, sem eu cadastrar nenhum.
- Dado que o bolão foi criado, então eu sou administrador dele e participante.
- Dado que a fonte de calendário está indisponível, quando tento criar, então
  recebo erro claro e o bolão **não** é criado pela metade.
- Dado que escolho um intervalo de rodadas já encerradas, então recebo aviso
  de que não haverá jogo com prazo aberto.
- Dado que não informei nome do bolão, então a criação é recusada com
  mensagem no campo.

**Tasks:**

_Backend_
- [x] `BE-1` Integrar a fonte oficial de calendário: campeonatos, rodadas, jogos, times e horários
  - **Feita em 07/08**, quando o token chegou: `FootballDataAdapter` na mesma porta
    `FonteDeDados`. A aposta de 03/08 se pagou — **nenhum** service de domínio
    mudou, só o provider do módulo. Verificação contra a API real em
    `docs/testes/CC-1-execucao-fonte-real.md`.
- [x] `BE-2` Modelar bolão, participante e vínculo com jogos (depende de BE-1)
- [x] `BE-3` Endpoint de criação de bolão que carrega os jogos das rodadas escolhidas, de forma atômica (depende de BE-1, BE-2)
- [x] `BE-4` Definir o criador como admin e participante (depende de BE-2)
- [x] `BE-5` Tratar indisponibilidade da fonte sem criar bolão incompleto (depende de BE-3)

_Mobile_
- [x] `FE-1` Fluxo de criação: nome, campeonato, intervalo de rodadas (depende de BE-3)
- [x] `FE-2` Validação de campos com erro por campo
- [x] `FE-3` Estados: carregando campeonatos, fonte indisponível, erro com retry

_DevOps_
- [x] `OPS-1` Credenciais da fonte de calendário em variável de ambiente, fora do repositório

_QA_
- [x] `QA-1` Escrever o plano de casos de teste a partir desta story
- [x] `QA-2` Executar o plano com a fonte indisponível e com rodadas já encerradas

**Riscos/Dependências:**

- **É a story mais arriscada do projeto**, e não por regra de produto: a
  fonte oficial de calendário ainda não foi escolhida (pergunta aberta com
  prazo 17/08). Ela sustenta os quatro épicos.
- Criação parcial (bolão sem jogos) é o pior estado possível — daí a
  atomicidade em BE-3.
- Bloqueia PP-1, PR-1 e praticamente todo o resto.

- **06/08:** as duas já estavam atendidas na tela de criação — validação por
  campo nos três campos e os estados de carregando/fonte indisponível/retry.
  Marcadas ao conferir.

- **07/08 — QA:** plano em `docs/testes/CC-1-plano.md`, execução em
  `docs/testes/CC-1-execucao.md` (**⚠️ 13 de 14**). `QA-2` **fica aberta**:
  `CC-1-14` (integração com a fonte oficial) não é executável sem o token.
- **07/08 — lacuna de critério, implementada:** o critério *"rodadas já
  encerradas → aviso de que não haverá jogo com prazo aberto"* não tinha task
  nem código. `BE-3` falava de carregar jogos, `FE-3` de fonte indisponível — o
  critério passou pelo recorte de tasks sem virar trabalho. O efeito era um bolão
  **criado com sucesso e inútil**: ninguém palpita e o convite é recusado (a
  entrada fecha no primeiro jogo), então o erro chegava como "não consigo
  palpitar" de dez pessoas. Agora a criação devolve `openMatches` e o app avisa
  antes de seguir, dizendo por que aquele bolão não vai funcionar.
- **07/08:** a tela de criação não tinha **nenhum** teste — é a porta de entrada
  do produto. Sete casos novos em `test/criar_bolao_test.dart`.

- **07/08 — `CC-1-14` desbloqueado e executado.** 9 ligas no app, 380 jogos da
  temporada em **uma** requisição (786 ms), cache servindo a segunda leitura em
  0 ms, bolão real criado com horários reais, e o aviso de "nenhum jogo com prazo
  aberto" disparando com rodadas passadas de verdade. Token inválido → 400 e
  competição inexistente → 404, ambos traduzidos para indisponibilidade, sem criar
  bolão pela metade. `QA-2` fecha.
- **07/08:** os 370 jogos fictícios foram removidos da base (não havia bolão
  algum). Conviver com jogos reais e fictícios na mesma competição deixaria a base
  ambígua — um dia alguém criaria bolão de jogo que não existe.
