# Demanda 15 — CHAT NA AULA AO VIVO (sala aberta) · enquadramento

**3 cards · 2 backend · 1 frontend.** Epic **CS-23**, cards **CS-24..CS-26**.
Cards em `ENQUADRAMENTO-D15.cards.json`. Escopo fechado em `D15-chat-ao-vivo-ENTREGUE.md`.

## A sigla NÃO foi improvisada
`CS` é resposta do dono ao **pedido 35**, 25/09 01:38, literal: «CS». D14 entregou `CS-1` com
`CS-2..CS-22` (pedido 47, 01:41:50). ⟹ o próximo espaço livre é `CS-23` (epic) e `CS-24..26`.
⚠️ O projecto no Jira dele ⛔ não existe ainda e ⛔ a fábrica ⛔ não o cria — quando ele o criar, as
chaves já estão nesta forma.

## Porque são TRÊS cards, e ⛔ não um
| card | território | a tarefa |
|---|---|---|
| CS-24 | backend | o módulo `chat`: guardar e ler a mensagem, e as TRAVAS (aceite/pendente, janela da aula, ⛔ não pontua, ⛔ não funde com as questões) |
| CS-25 | backend | o canal em tempo real: uma sala POR AULA, a mensagem chega a todos os presentes |
| CS-26 | frontend | o painel dentro da sala do ao vivo: os SEIS estados, o nome do autor, e a gravação sem chat |

CS-24 e CS-25 são dois porque são duas tarefas com dois modos de falhar: **guardar/autorizar** e
**entregar em tempo real**. Partido assim, reverter o transporte ⛔ não leva o registo com ele.

## As dependências, e são de FORA desta demanda
`CS-24 → CS-7, CS-11` · `CS-25 → CS-24` · `CS-26 → CS-20, CS-22, CS-25`
- **CS-7** (vínculo) porque «ACEITE» e «PENDENTE» só existem depois dele (regra 46).
- **CS-11** (participação) porque o critério (3) conta **minutos validados e pontos** antes e depois
  das 3 mensagens — sem ele ⛔ não há o que contar (regras 48, 56).
- **CS-20** (a sala do ao vivo) é o único sítio onde o chat cabe; **CS-22** é o sistema de interface
  sem o qual ⛔ nenhum ecrã nasce (regras 79 a 86).
- CS-3, CS-4, CS-8, CS-9, CS-10, CS-13 vêm por transitividade — ⛔ não se repetem.
🩸 Cada dependente só nasce depois de o pai ser **APROVADO PELO QA**. Verificado: os 4 pais existem
na base, 0 órfãos, 0 ciclos (`CS-7`, `CS-11`, `CS-20`, `CS-22` = `a_especificar` na demanda 14).

## As cercas, medidas
0 cercas largas. `backend/src/modules/chat/` e `.../chat-tempo-real/` são módulos NOVOS e próprios —
🩸 **⛔ nunca dentro de `questao/` nem de `participacao/`**: são duas coisas distintas, e trocar o
especialista responsável ⛔ não toca em nenhuma (regras 56, 57).
`frontend/src/componentes/chat/` é novo; `frontend/src/app/ao-vivo/` é partilhado com CS-20, que é
pai — o dev de CS-26 entra depois de CS-20 estar aprovado.
⚠️ CS-25 toca `backend/package.json` e `package-lock.json` (o pacote do transporte). É deliberado e
é a única forma de acrescentar a biblioteca; CS-3 é pai transitivo.

## Os 27 aceites, e os 27 falham na base
Medido hoje em `/srv/produtos/capacitasalvador/repo` (ramo `main`, **0 ficheiros**):
**27 falham · 0 passam.** ⟹ ⛔ nenhum aceite mede o que já passava sem o card.
Forma dos comandos: a MESMA que a demanda 14 fixou neste produto —
`cd backend && npx jest test/<x>.e2e-spec.ts --runInBand --ci` e
`cd frontend && npx playwright test e2e/<x>.spec.ts --reporter=line`.
Cada card corre também **o teste do vizinho** (`participacao`, `questao`, `ao-vivo`, `gravacao`):
é assim que se prova que o chat ⛔ não partiu a pontuação nem a sala.

## O que o dono já decidiu e que estes cards ⛔ NÃO contradizem
- **Sala aberta** (pedido 36, literal «todos veem as mensagens de todos»): a mensagem aparece a
  todos os médicos ACEITES da aula e ao especialista responsável, com o nome do autor.
  ⛔ Sem mensagem privada, ⛔ sem liberação prévia.
- **Regras 45/48/56** — o chat ⛔ NÃO dá ponto e ⛔ NÃO prova presença; ⛔ não é um segundo canal de
  questões. Há UM único mecanismo de questão.
- **Regra 46** — PENDENTE ⛔ não entra e ⛔ não escreve. **Regra 42** — ⛔ nada de maisSaúde.
- **Regra 57** — trocar o especialista ⛔ não apaga mensagem nenhuma (aceite próprio em CS-24).
- **Regras 79 a 86** — Material 3, Inter, pt-BR, cantos arredondados, os SEIS estados,
  ⛔ sem vermelho de castigo, ⛔ sem foto no painel, ⛔ sem brilho de esqueleto, ⛔ sem snackbar.
  Travado por grep no aceite 11 de CS-26.

## Leituras minhas, REVERSÍVEIS, nomeadas para ele corrigir no aceite
1. **Quem vê é quem está na sala**: médicos aceites da aula + especialista responsável. ⛔ Não dei
   vista do chat ao coordenador nem à secretaria — ele ⛔ não os nomeou, e inventar permissão ⛔ não
   é meu. ⟹ ⛔ Não voltei a perguntar: o pedido 36 já respondeu quem lê.
2. **Transporte**: uma sala por aula no MESMO backend (o precedente medido desta casa, regra 59, é
   socket.io no maisSaúde). ⛔ Sem porta nova, ⛔ sem tocar no caddy ⟹ **⛔ nenhum card de infra**.
   Medido em `bin/instanciadeclara.py:131-139`: a instância já dá ao browser
   `NEXT_PUBLIC_API_URL=http://127.0.0.1:<porta-backend>`, logo o navegador do QA alcança o canal.
3. **Fecha com a aula**; ⛔ não aparece na gravação (aceite 7 de CS-26).
4. As mensagens ficam guardadas com autor, aula e instante, em módulo PRÓPRIO.

## ⛔ FORA, e ⛔ não se adivinha
**Apagar uma mensagem** e **calar um médico** são PERMISSÃO, e permissão é sempre dele. A sala
aberta funciona inteira sem eles. Se ele os quiser, sobem por pergunta própria e viram demanda.

## OBSERVAÇÃO de mecanismo (⛔ NÃO me impediu — por isso ⛔ não é achado)
🩸 **O ramo do epic nasce de `main`, e o `main` deste produto tem 0 ficheiros.**
Medido em `bin/motorbase.py:233` — `base = os.environ.get("FAB_BASE_RAMO", "main")` — e
`git ls-files` em `main` = **0**. Toda a fatia 1 vive em `epic/CS-1`, que só chega ao `main` pela
mão dele (`fab publicar`, PR para `homolog`, regra 38).
⟹ Se `epic/CS-23` for cortado de `main` **antes de a fatia 1 lá estar**, o dev de CS-24 abre o
worktree e ⛔ não encontra `backend/`. A liberação por dependência olha o **estado do card pai**, e
⛔ não o ramo onde o código dele ficou.
⟹ **O que resolve:** `epic/CS-23` cortar-se DEPOIS de a fatia 1 estar no `main` — ou nascer com
`FAB_BASE_RAMO=epic/CS-1`. ⛔ Não é decisão minha e ⛔ não é pergunta de negócio: fica escrito aqui,
onde quem vier a seguir o lê em contexto, e no texto do pedido de aprovação.
