# D28 · CS-53 — O QA DEIXA DE ESCREVER NA BASE QUE O PUBLICO VE

## 0 · O que eu medi antes de partir nada

A demanda diz que a fuga e' **da instancia `main`**, e que «ela ganha base propria **como os
epics ja' tem**». ⛔ **Medi, e ⛔ nao e' assim.** Os epics ⛔ NAO tem base propria — ⛔ nenhum deles.

| medicao | como se reproduz | resultado |
|---|---|---|
| ⛔ NENHUMA instancia deste produto declara `DATABASE_URL` | `sqlite3 /srv/fab/estado.db "select ramo,papel,ambiente from instancia where produto='capacitasalvador'"` | as 9 linhas trazem so' `API_PORT`/`NODE_ENV`/`PORT`/`INTERNAL_API_ORIGIN` |
| **21 de 21** chaos apontam a' base do publico | `for w in repo worktrees/*; do grep -h '^DATABASE_URL' $w/backend/prisma/.env; done` | 21 linhas, todas `.../capacita` |
| o `.env` **esta' versionado** | `git ls-files backend/prisma/.env` | devolve o caminho ⟹ cada worktree novo nasce ja' apontado a' base do publico |
| a base do publico esta' limpa HOJE | `psql -d capacita -tAc "select count(*) from utilizador"` | **17** utilizadores · **0** aulas · 10 nucleos · 1 UPA |
| e os 17 sao reais | `select split_part(email,'@',2), count(*) ... group by 1` | `saude.salvador.ba.gov.br` 9 · `salvador.ba.gov.br` 7 · `hotmail.com` 1 |

⟹ 133 − 116 = **17**, e 58 − 58 = **0**: a minha contagem de hoje **confirma numero a numero** a
da demanda, depois da limpeza a' mao.

🩸 **A CAUSA ⛔ NAO E' O `main`: E' O `backend/prisma/.env`, QUE ESTA' NO GIT E DIZ `capacita` EM
TODA A PARTE.** A prova esta' nos proprios dados que o dono viu: os 42 utilizadores
`@qa4.cs26.local` sao de um QA do **CS-26**, que vive na demanda 15, cujo epic e' o **CS-23** —
instancia nas portas **3116/3118**, worktree `CS-23__integracao`, ⛔ **nunca** o `main`. Esse QA
escreveu na base do publico **atraves da instancia do epic**. ⟹ Fechar so' o `main` deixava a
fuga aberta em quatro instancias.

⚠️ E a razao pela qual o mecanismo da casa ⛔ nao cobriu isto esta' medida: `bin/banco` — a peca
que da' base por card — le' `backend/.env` (este produto tem-no em `backend/prisma/.env`) e fala
**SQL Server** (`sqlcmd`, `BACKUP DATABASE`, `sys.databases`). Este produto e' **Postgres**.
⟹ `bin/banco` ⛔ **nunca** funcionou para o Capacita. Isso e' da FABRICA e ⛔ **nao me impediu de
enquadrar** — fica aqui como **OBSERVACAO**, ⛔ nao como achado.

## 1 · O que ja' existe e ⛔ nao se reinventa

O produto **ja' sabe** dar uma base por chao — so' que ⛔ **so' nos testes**:
`backend/test/ambiente.ts:14` tem `nomeDoBancoDoWorktree()` (funcao pura, `worktrees/CS-3` ⟹
`cap_teste_cs_3`), `scripts/banco-teste.sh` cria-a e o `globalSetup` corre `prisma migrate deploy`.
⟹ Prova viva: **26 bases `cap_teste_*`** no Postgres, e os testes de backend estao certos.

⟹ **A fatia deste enquadramento e' levar o mecanismo que ja' existe do `jest` para o ARRANQUE do
servidor.** ⛔ Nada de invencao.

E o ponto exacto onde se mexe esta' escrito pelo proprio produto:
`backend/src/comum/ambiente.ts::garantirUrlDoBanco()` — «⚠️ O AMBIENTE MANDA SEMPRE … e' o que
mantem o isolamento por worktree de pe'». A casa ⛔ nao poe `DATABASE_URL` no ambiente, logo cai
**sempre** no `prisma/.env` partilhado. O comentario estava certo; a premissa dele ⛔ nao.

🩸 **E HA' UMA ARMADILHA QUE OBRIGA OS DOIS LADOS A ANDAR JUNTOS:** o comando da instancia e'
`npx prisma migrate deploy && npm run build && node dist/main` (`bin/instanciadeclara.py:133`). O
**CLI do Prisma** le' o `prisma/.env` sozinho; o **cliente** ⛔ nao. ⟹ Se so' se mudasse o codigo,
o `migrate deploy` continuava a escrever esquema na base do publico; se so' se mudasse o `.env`,
o servidor arrancava contra uma base sem migracoes. Por isso **CS-55 e' UM card e ⛔ nao dois**:
partido, deixa o produto partido no meio.

## 2 · Os territorios

| territorio | porque' | cards |
|---|---|---|
| **infra** (`scripts/`, `docker/`) | quem cria bases e quem sobe a maquina | CS-54, CS-57 |
| **backend** (`backend/src/comum/`, `backend/prisma/`) | quem resolve a ligacao e quem sabe ler a base | CS-55, CS-56 |
| ~~frontend~~ | ⛔ **NENHUM.** Medido: `frontend/playwright.config.ts` sobe o SEU `next dev` numa porta derivada do worktree (3200–3599) e `src/lib/api.ts` chama `/api/v1` **relativo**, interceptado pelo e2e ⟹ o e2e de ecra ⛔ nao toca em base nenhuma. Ecra sem trabalho e' card sem razao. | — |

## 3 · Os cards, e porque' a ordem e' esta

```
CS-54 (infra) ───────────────► CS-55 (backend)
      └──────────────┐
CS-56 (backend) ─────┴───────► CS-57 (infra)
```

Duas raizes (CS-54 e CS-56) ⟹ **dois devs arrancam ao mesmo tempo**. ⛔ Nao fiz corrente de
quatro: o dependente so' nasce depois de o pai ser **APROVADO PELO QA**, e uma corrente serial de
quatro custaria quatro voltas de QA em fila.

- **CS-54 · infra** — a peca que cria+migra a base de UM chao, idempotente, e que **RECUSA
  `capacita`**. ⛔ Nao toca em `banco-teste.sh`: as 26 bases de teste estao certas e sao o desenho
  a funcionar (a propria demanda o diz).
- **CS-55 · backend** — a ligacao deixa de sair do `.env` partilhado. `repo` ⟹ `capacita` (a do
  publico, e so' ela); `worktrees/<X>` ⟹ base propria, criada, migrada e semeada no arranque. E um
  worktree que caia na base do publico ⛔ **NAO ARRANCA**. Depende do CS-54 porque e' dele que sai
  a peca que cria a base.
- **CS-56 · backend** — o detector. ⛔ **Nao toca em `/health`**: o `saude.controller.ts` diz, por
  escrito, que e' «liveness PURA» e que a casa mede a vida por ai'; meter banco la' dentro fazia
  uma base em manutencao ler-se como produto partido. Independente do CS-55 de proposito: recebe a
  base por argumento.
- **CS-57 · infra** — a guarda que **avisa**, que e' o criterio 3. Usa `fab avisar`, que ja' existe
  e ja' vai ao telemovel do dono («informa, ⛔ nao pede» — ⛔ nao entra na fila dele).

## 4 · O que o dono tem de saber ANTES de aprovar

1. 🩸 **AS INSTANCIAS DOS EPICS VAO ACORDAR COM A BASE VAZIA.** Hoje CS-1, CS-23, CS-27 e CS-42
   servem-se da base do publico. Depois do CS-55, cada uma passa a ter a sua, **criada do zero**
   (migracoes + os dez nucleos). O que os QAs la' acumularam ⛔ nao vai com elas. E' consequencia
   directa da ordem dele («o que serve o publico ⛔ nao e' o que se julga») e ⛔ nao de uma escolha
   minha — mas ⛔ nao se aprova as cegas. ⚠️ **O CS-48 esta' `entregue` e a' espera de QA**: se este
   epic for a' frente primeiro, esse QA julga contra uma base nova.
2. **A base `capacita` ⛔ NAO MUDA DE NOME e ⛔ nao se copia para lado nenhum.** Ela continua a ser
   a do publico, com os 17 utilizadores reais la' dentro. ⟹ ⛔ **Zero mexida nos dados dele.** Quem
   muda de base sao os OUTROS. Foi assim de proposito: mover dados reais e' irreversivel, e o
   irreversivel e' dele.
3. **`capacita.ssa` escapa a' regra que ele escreveu.** O criterio 3 diz `*.local`, `*.teste`,
   `*.test` — e **6 dos 116** utilizadores de ensaio tinham `@capacita.ssa`, que ⛔ **nao casa com
   nenhum dos tres**. ⟹ O CS-56 entrega as duas metades: os tres padroes dele **acusam**, e
   qualquer dominio fora dos da Secretaria e' **RELATADO** (⛔ nao acusado) — porque ha' 1
   utilizador `@hotmail.com` que e' real. ⛔ Nao inventei lista nova: relata-se, ⛔ nao se julga.
4. **Instalar o temporizador e' acto de maquina, ⛔ fora da cerca do dev.** O CS-57 entrega a
   unidade `systemd` e a linha que a instala; correr essa linha e' de um humano. Se ele preferir
   outro cano, diz e troca-se — ⛔ nao gastei pergunta da fila dele com isto.

## 5 · O que ⛔ NAO entra, por ordem da propria demanda

⛔ A limpeza a' mao de hoje (feita, copia em `_produto/backups/capacita-20260929-2338.sql`) ·
⛔ mexer nas 26 bases `cap_teste_*` · ⛔ mexer nas `cap_qa_*`.

⚠️ **OBSERVACOES** (⛔ nao sao achados: ⛔ nada disto me impediu de enquadrar)
- `bin/banco` e' SQL Server e le' `backend/.env` ⟹ ⛔ nunca serviu este produto (ver §0).
- `backend/prisma/.env` esta' **versionado com a senha do Postgres la' dentro**. Fica assim: tirar
  a credencial do git ⛔ nao e' desta demanda e teria de vir com o sitio novo onde ela passa a
  viver.
- Existe uma base **`capacita_demo` orfa** no Postgres: **0 tabelas**, ⛔ nenhuma referencia em
  `/srv/fab/bin` nem no repo. ⛔ Nao lhe toquei.

## 6 · A chave
O rastreador deste produto e' **o livro da propria fabrica** — ⛔ ⛔ nao ha' Jira aqui (a regra 3,
`MSS-<n>` do Jira, tem ambito `produto:maissaude`). As chaves `CS-<n>` correm em sequencia:
o maior em uso e' **CS-52** (demanda 24). ⟹ **CS-53 para o epic, CS-54…CS-57 para os cards.**
