# Execução complementar — `CC-1-14` fonte oficial de calendário

**Plano:** `CC-1-plano.md`, caso `CC-1-14` · **Data:** 07/08/2026
**Antes:** ⛔ bloqueado por credencial. **Agora:** ✅ executado com a API real.

O token da `football-data.org` chegou em 07/08. `BE-1` foi implementada como
`FootballDataAdapter`, na **mesma porta** `FonteDeDados` — nenhum service de
domínio mudou, que era a aposta feita em 03/08 ao criar a porta antes de existir
credencial.

## O que foi verificado contra a API de verdade

| Verificação | Resultado |
| ----------- | --------- |
| Competições disponíveis no plano gratuito | 13, das quais **9 ligas** entram no app |
| `BSA` com rodada atual | `Campeonato Brasileiro Série A`, rodada 22 |
| Jogos de um intervalo (23–25) | 30 jogos em **786 ms**, 1 requisição |
| Segunda leitura da mesma competição | **0 ms**, sem chamada (cache de 5 min) |
| Temporada completa | 380 jogos, rodadas 1–38, **5 adiados** |
| Registros inutilizáveis no payload real | **0** sem rodada, **0** sem time |
| Bolão criado pela API (rodadas 23–24) | 20 jogos, `openMatches: 20` |
| Jogos no app, com horário real | `Fluminense x Palmeiras` · `15/08 19:30Z` · prazo aberto |
| Bolão em rodadas passadas (1–2) | 20 jogos, **`openMatches: 0`** → o aviso de `CC-1-08` dispara com dado real |
| Placares reais importados | `Mineiro x Palmeiras 2x2`, `Coritiba x Bragantino 0x1`, … |
| Sincronização contra a fonte real | 40 jogos verificados, 0 alterações (correto: acabaram de ser importados) |
| Duas sincronizações concorrentes | uma executou, outra `ignorada` — a trava de 07/08 vale com a fonte real |
| Token inválido | `400` → `FonteIndisponivelError`, nenhum bolão criado |
| Competição inexistente | `404` → `FonteIndisponivelError` |

## Decisões tomadas na implementação

- **Só competições de liga entram no app.** O plano gratuito também dá copas
  (`CL`, `EC`), mas o produto trabalha com "rodadas 1..N e prazo por jogo"; copa
  tem chave e ida/volta, que esse modelo não representa. Oferecer levaria a bolão
  impossível de montar.
- **`shortName` em vez de `name`.** "Fluminense", não "Fluminense FC" — é o que
  cabe no cartão do celular.
- **Toda falha vira `FonteIndisponivelError`**, inclusive `403` (recurso fora do
  plano). O domínio já sabe o que fazer com isso: a criação aborta inteira, a
  sincronização preserva o que existe.
- **A fonte real não entra em teste automatizado** mesmo com token definido
  (`NODE_ENV=test` → adaptador falso, salvo `FONTE_REAL=true`). Suíte que depende
  de rede, de cota e do calendário real mudando debaixo dela deixa de ser gate.

## Efeito colateral tratado

A base tinha 370 jogos **fictícios** de `BSA` criados pelo adaptador falso durante
o desenvolvimento. Com nenhum bolão existindo (`pools = 0`), eles foram removidos:
conviver com jogos reais e fictícios na mesma competição deixaria a base ambígua —
e um dia alguém criaria um bolão de jogo que não existe.

**Limite conhecido, registrado:** dev e teste compartilham o mesmo banco. A suíte
e2e recria jogos fictícios a cada execução, e o servidor de desenvolvimento com
`JOBS_HABILITADOS=true` mexe na mesma base. O certo é `DATABASE_URL` separado para
teste — ver a nota de instabilidade em `docs/CONTROLE.md`.
