[
 {
  "chave": "CS-71",
  "territorio": "backend",
  "titulo": "A CENA DE PROVA, SEMEADA E ⛔ NAO MONTADA A' MAO: hoje `prisma/seed.ts` cria UMA pessoa (a secretaria) e mais nada — medido, 65 linhas. `prisma/seed-demonstracao.ts` poe a cena dos criterios 1/2/4/5: 3 UPAs · 5 medicos com `Utilizador.estado=ATIVO` e vinculo `situacao=ACEITO` (um deles em DUAS UPAs) · 1 medico PENDENTE · 1 aula de 80 min com 4 blocos, 4 questoes e 4 participacoes de 80+60+60+40 = 240 min. ⚠️ CONTA-SE `ACEITO` E ⛔ NUNCA `ATIVO`: `SituacaoVinculo.ATIVO` e' valor MORTO do enum (schema.prisma:222 di-lo a letra — ⛔ nao ha' uma linha em banco com ele), e quem contar por ele conta ZERO. Idempotente, e ⛔ RECUSA a base do publico `capacita` pelo mesmo gesto do `scripts/banco-instancia.sh` (CS-54) — senao a guarda do CS-57 passa a gritar todos os dias com razao",
  "escopo_paths": [
   "backend/prisma/seed-demonstracao.ts",
   "backend/package.json",
   "backend/test/semente-demonstracao.e2e-spec.ts"
  ],
  "aceites": [
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci",
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci -t 'a cena tem 3 UPAs, 5 medicos com vinculo ACEITO e 1 medico PENDENTE'",
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci -t 'um dos cinco esta em DUAS UPAs, e e o mesmo id de medico nas duas'",
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci -t 'a aula tem 80 minutos, 4 blocos, 4 questoes e 4 participacoes'",
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci -t 'os minutos validados somam 240 e um dos quatro validou so 2 blocos, 40 minutos'",
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci -t 'o medico PENDENTE nao tem participacao nenhuma nem vinculo ACEITO'",
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci -t 'correr a semente duas vezes da exactamente a mesma cena'",
   "cd backend && npx jest test/semente-demonstracao.e2e-spec.ts --runInBand --ci -t 'a semente recusa a base do publico e a mensagem diz o que fazer'",
   "cd backend && test -f prisma/seed-demonstracao.ts && grep -q 'ACEITO' prisma/seed-demonstracao.ts",
   "cd backend && ! grep -q 'SituacaoVinculo.ATIVO' prisma/seed-demonstracao.ts",
   "cd backend && grep -q 'semente:demonstracao' package.json",
   "cd backend && grep -q 'capacita' prisma/seed-demonstracao.ts",
   "cd backend && npx jest test/upa.e2e-spec.ts test/vinculo.e2e-spec.ts test/participacao.e2e-spec.ts --runInBand --ci"
  ],
  "depende_de": []
 },
 {
  "chave": "CS-72",
  "territorio": "backend",
  "titulo": "OS DOIS NUMEROS DE «QUANTOS ASSISTIRAM», E ⛔ NUNCA UM SO': modulo `relatorio` NOVO — medido hoje, `relatorio` da' ZERO ficheiros em `backend/src` e `groupBy`/`.aggregate(` dao ZERO — com `GET /relatorios/aulas`, `@Papeis(SECRETARIA)`, que devolve POR AULA quantos ENTRARAM, quantos MINUTOS VALIDARAM e a DIFERENCA entre os dois, os tres campos OBRIGATORIOS na resposta para que ⛔ nenhum possa sair sozinho (regra 80, estado PARCIAL). O PENDENTE ⛔ nao entra em contagem nenhuma (regra 46) e conta-se `situacao=ACEITO`, ⛔ nunca `ATIVO`. 🩸 E O MODULO SO' LE': ⛔ zero escrita, ⛔ zero recalculo — o numero de uma aula fechada e' o MESMO daqui a um mes, porque vem do FACTO GRAVADO `participacao_aula.minutosValidados` (schema.prisma:370). ⚠️ O nome dessa coluna aparece em UM SO' ficheiro do modulo, que e' a costura por onde o CS-32, quando for publicado, troca a fonte sem mexer em quatro sitios",
  "escopo_paths": [
   "backend/src/modules/relatorio/",
   "backend/src/app.module.ts",
   "backend/test/relatorio-aula.e2e-spec.ts"
  ],
  "aceites": [
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci -t 'a aula de 80 min diz 4 de 5 entraram e 240 minutos validados, os dois na mesma resposta'",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci -t 'a resposta traz sempre os tres campos: entraram, minutos validados e a diferenca'",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci -t 'o medico PENDENTE nao entra no de 5 nem em contagem nenhuma'",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci -t 'conta-se vinculo ACEITO e nunca ATIVO, que e valor morto do enum'",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci -t 'so a secretaria le: coordenador, medico e especialista levam 403'",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci -t 'ler o relatorio nao escreve uma linha na base, e ler duas vezes da o mesmo numero'",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts --runInBand --ci -t 'o numero de uma aula ja fechada nao se recalcula de relogio nenhum'",
   "cd backend && test -d src/modules/relatorio && ! grep -rqE 'prisma\\.[A-Za-z]+\\.(create|update|upsert|delete)' src/modules/relatorio/",
   "cd backend && test -d src/modules/relatorio && ! grep -rqE '\\$executeRaw|\\$transaction' src/modules/relatorio/",
   "cd backend && test $(grep -rl 'minutosValidados' src/modules/relatorio/ | wc -l) -eq 1",
   "cd backend && grep -q 'ModuloRelatorio' src/app.module.ts",
   "cd backend && npx jest test/participacao.e2e-spec.ts test/aula.e2e-spec.ts --runInBand --ci"
  ],
  "depende_de": [
   "CS-71"
  ]
 },
 {
  "chave": "CS-73",
  "territorio": "backend",
  "titulo": "«QUE UPAs ESTAO ATRAS», COM O PERIODO A MANDAR: `GET /relatorios/upas` devolve POR UPA as HORAS VALIDADAS da equipa no TRIMESTRE CIVIL EM CURSO por omissao (regra 117 — Jan-Mar, Abr-Jun, Jul-Set, Out-Dez, o MESMO para toda a rede, para o relatorio e o ranking darem o MESMO numero) e em periodo livre quando pedido, ordenado da MENOR media por medico da equipa para a maior. 🩸 O medico de DUAS UPAs conta nas DUAS lentes com os MESMOS minutos e UMA so' vez no total da rede (regra 117); o PENDENTE ⛔ fora do denominador (regra 46). ⚠️ A PERCENTAGEM DA EQUIPA QUE ATINGIU A CARGA OBRIGATORIA ⛔ NAO ENTRA AQUI, e ⛔ nao e' esquecimento: a obrigatoriedade de dois niveis e' da DEMANDA 29 (regra 114), ⛔ nao existe no codigo (medido: `obrigator` da' 0 em `backend/src` fora de mensagens de validacao) e ⛔ NAO se inventa alvo",
  "escopo_paths": [
   "backend/src/modules/relatorio/",
   "backend/test/relatorio-upa.e2e-spec.ts"
  ],
  "aceites": [
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'as 3 UPAs saem ordenadas da menor media por medico para a maior'",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'por omissao o periodo e o trimestre civil em curso, e e o mesmo para toda a rede'",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'trocar o periodo muda os numeros, e nenhum minuto e recalculado'",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'o medico das duas UPAs conta nas duas lentes com os mesmos minutos'",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'o total da rede conta o medico das duas UPAs uma so vez'",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'o medico PENDENTE nao entra no denominador de nenhuma UPA'",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'so a secretaria le: os outros tres papeis levam 403'",
   "cd backend && npx jest test/relatorio-upa.e2e-spec.ts --runInBand --ci -t 'nenhuma percentagem de carga obrigatoria sai desta rota, porque a obrigatoriedade ainda nao existe'",
   "cd backend && test -d src/modules/relatorio && ! grep -rqiE 'obrigatori|cargaObrigatoria|meta_horas|metaHoras' src/modules/relatorio/",
   "cd backend && test -d src/modules/relatorio && ! grep -rqE 'prisma\\.[A-Za-z]+\\.(create|update|upsert|delete)' src/modules/relatorio/",
   "cd backend && test $(grep -rl 'minutosValidados' src/modules/relatorio/ | wc -l) -eq 1",
   "cd backend && npx jest test/relatorio-aula.e2e-spec.ts test/vinculo.e2e-spec.ts --runInBand --ci"
  ],
  "depende_de": [
   "CS-72"
  ]
 },
 {
  "chave": "CS-74",
  "territorio": "frontend",
  "titulo": "A OITAVA PORTA E' «Relatorios», E E' DA SECRETARIA: entra em `lib/navegacao.ts`, que e' a FONTE UNICA das portas — ⛔ nenhum `href` a' mao (regra 120.8) — e hoje sao SETE e ⛔ nenhuma e' esta. `/secretaria/relatorios` mostra POR AULA «4 de 5 entraram» E os 240 MINUTOS VALIDADOS **LADO A LADO**, mais a LINHA QUE DIZ A DIFERENCA entre quem entrou e o que contou: ⛔ nenhum dos dois sozinho, e ⛔ NENHUMA BARRA LISA (regra 48 — uma barra mentiria). Os SEIS ESTADOS (regra 80), e SEM PERMISSAO para o coordenador que escreva a morada a' mao — ⛔ sem deixar ver o dado por baixo, ⛔ NEM DESFOCADO. ⚠️ ESTE CARD ⛔ NAO CONSERTA A REGRA 112: `navegacao.ts` continua a aplicar o criterio antigo que o dono desfez em 30/09, e abrir as OUTRAS portas a' secretaria e' da DEMANDA 30 — ⛔ nao se estica a cerca para la'",
  "escopo_paths": [
   "frontend/src/lib/navegacao.ts",
   "frontend/src/app/secretaria/relatorios/",
   "frontend/e2e/relatorios.spec.ts",
   "frontend/e2e/navegacao.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'a secretaria entra e tem a porta Relatorios no menu'",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'a aula de 80 min mostra 4 de 5 entraram e 240 minutos validados lado a lado'",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'a linha que explica a diferenca entre quem entrou e o que contou esta no ecra'",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'nenhum dos dois numeros aparece sozinho, e nao ha barra de progresso nenhuma'",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'o medico PENDENTE nao aparece em numero nenhum do ecra'",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'o coordenador que escreve a morada a mao ve SEM PERMISSAO e nao o dado por baixo'",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'os seis estados do relatorio por aula: vazio, a carregar, erro, sem permissao, sucesso e parcial'",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line -g 'com prefers-reduced-motion reduce as duracoes sao zero e o estado final e o mesmo pixel'",
   "cd frontend && npx playwright test e2e/navegacao.spec.ts --reporter=line",
   "cd frontend && grep -q \"'/secretaria/relatorios'\" src/lib/navegacao.ts",
   "cd frontend && test -d src/app/secretaria/relatorios && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|<progress|LinearProgress|blur\\(' src/app/secretaria/relatorios/",
   "cd frontend && grep -rq 'tabular' src/app/secretaria/relatorios/",
   "cd frontend && test $(grep -c \"papeis: \\['SECRETARIA'\\]\" src/lib/navegacao.ts) -eq 5",
   "cd frontend && npx playwright test --reporter=line"
  ],
  "depende_de": [
   "CS-72"
  ]
 },
 {
  "chave": "CS-75",
  "territorio": "frontend",
  "titulo": "AS 3 UPAs EM LISTA DENSA, DA MAIS ATRAS PARA A MAIS A' FRENTE, em `/secretaria/relatorios/upas`: as horas validadas do TRIMESTRE CIVIL EM CURSO por omissao — com o trimestre DITO por extenso no ecra — e o periodo livre AO LADO; trocar o periodo muda os numeros e o de uma aula fechada fica o MESMO. O medico das DUAS UPAs aparece nas DUAS lentes com os MESMOS minutos. `AvatarUpa` ⛔ NUNCA vai sozinho: o NOME DA UNIDADE esta' SEMPRE a uma linha dele (regra 84a) e os numeros vao em `tabular-nums` (regra 85). Entra em `ORFAS_DELIBERADAS` com o motivo escrito — e' a segunda lente do mesmo relatorio e chega-se pelo ecra por aula —, que e' a unica forma de uma pagina nova ⛔ nao ser orfa POR ACIDENTE. Os SEIS ESTADOS, com SEM PERMISSAO a ⛔ nao deixar ver o dado por baixo, ⛔ nem desfocado",
  "escopo_paths": [
   "frontend/src/app/secretaria/relatorios/upas/",
   "frontend/src/lib/navegacao.ts",
   "frontend/e2e/relatorios-upas.spec.ts",
   "frontend/e2e/navegacao.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'as 3 UPAs saem da mais atras para a mais a frente'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'por omissao o periodo e o trimestre civil em curso, e o ecra diz qual e'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'trocar o periodo muda os numeros e a aula ja fechada mantem o seu'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'o medico das duas UPAs aparece nas duas lentes com os mesmos minutos'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'o medico PENDENTE nao entra no denominador de nenhuma UPA no ecra'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'cada UPA leva o nome escrito a uma linha do avatar, e nunca so o avatar'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'os seis estados do relatorio por UPA: vazio, a carregar, erro, sem permissao, sucesso e parcial'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'o coordenador que escreve a morada a mao ve SEM PERMISSAO e nao o dado por baixo'",
   "cd frontend && npx playwright test e2e/relatorios-upas.spec.ts --reporter=line -g 'com prefers-reduced-motion reduce as duracoes sao zero e o estado final e o mesmo pixel'",
   "cd frontend && grep -q '/secretaria/relatorios/upas' src/lib/navegacao.ts",
   "cd frontend && test -d src/app/secretaria/relatorios/upas && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|<progress|LinearProgress|blur\\(' src/app/secretaria/relatorios/upas/",
   "cd frontend && grep -rq 'tabular' src/app/secretaria/relatorios/upas/",
   "cd frontend && npx playwright test e2e/navegacao.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/relatorios.spec.ts --reporter=line",
   "cd frontend && npx playwright test --reporter=line"
  ],
  "depende_de": [
   "CS-74",
   "CS-73"
  ]
 }
]
