[
  {
    "chave": "SIGLA-2",
    "territorio": "infra",
    "titulo": "O chao: o Capacita tem o SEU banco, em contentor proprio, e um script que da a cada card o seu banco de teste (regra 42)",
    "escopo_paths": [
      "docker/",
      "scripts/"
    ],
    "aceites": [
      "test -f docker/docker-compose.yml && docker compose -f docker/docker-compose.yml config -q",
      "test -f docker/docker-compose.yml && ! grep -qiE '1433|sqlserver|mais[-_ ]?saude' docker/docker-compose.yml",
      "bash scripts/banco-subir.sh && bash scripts/banco-subir.sh && docker exec capacita-postgres pg_isready -U capacita -d capacita",
      "bash scripts/banco-teste.sh cap_prova_aceite >/dev/null && bash scripts/banco-teste.sh cap_prova_aceite | grep -qE '^postgresql://[^ ]+/cap_prova_aceite'"
    ],
    "depende_de": []
  },
  {
    "chave": "SIGLA-3",
    "territorio": "backend",
    "titulo": "Alicerce do backend: Nest + Prisma, `npm run build` -> dist/main, /api/v1/health, e um banco de teste POR WORKTREE",
    "escopo_paths": [
      "backend/package.json",
      "backend/package-lock.json",
      "backend/tsconfig.json",
      "backend/tsconfig.build.json",
      "backend/nest-cli.json",
      "backend/jest.config.js",
      "backend/.env.example",
      "backend/prisma/",
      "backend/src/main.ts",
      "backend/src/app.module.ts",
      "backend/src/comum/",
      "backend/test/ambiente.ts",
      "backend/test/saude.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npm install --no-audit --no-fund --prefer-offline && npm run build && test -f dist/main.js",
      "cd backend && npx jest test/saude.e2e-spec.ts --runInBand --ci",
      "test -f backend/prisma/schema.prisma && grep -qE 'provider *= *\"postgresql\"' backend/prisma/schema.prisma && ! grep -qiE 'sqlserver|1433|mais[-_ ]?saude' backend/prisma/schema.prisma",
      "test -f backend/.env.example && ! git ls-files | grep -qx 'backend/.env'",
      "cd backend && npx jest test/saude.e2e-spec.ts --runInBand --ci -t 'o banco deste worktree e so deste worktree'"
    ],
    "depende_de": [
      "SIGLA-2"
    ]
  },
  {
    "chave": "SIGLA-4",
    "territorio": "backend",
    "titulo": "Identidade: os QUATRO papeis, entrada e sessao; o medico nasce PENDENTE e so ATIVO ve produto (regras 46, 55)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/identidade/",
      "backend/src/app.module.ts",
      "backend/test/identidade.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/identidade.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/identidade.e2e-spec.ts --runInBand --ci -t 'o medico criado pelo link nasce pendente'",
      "cd backend && npx jest test/identidade.e2e-spec.ts --runInBand --ci -t 'papel de fora recebe 403'",
      "test -f backend/prisma/schema.prisma && grep -cE 'SECRETARIA|COORDENADOR|MEDICO|ESPECIALISTA' backend/prisma/schema.prisma | grep -qE '^[4-9]|^[1-9][0-9]'"
    ],
    "depende_de": [
      "SIGLA-3"
    ]
  },
  {
    "chave": "SIGLA-5",
    "territorio": "backend",
    "titulo": "A lista de UPAs e da SECRETARIA, e cada UPA tem o seu coordenador e o seu link de cadastro (regra 44)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/upa/",
      "backend/src/app.module.ts",
      "backend/test/upa.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/upa.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/upa.e2e-spec.ts --runInBand --ci -t 'so a secretaria mexe na lista de UPAs'",
      "cd backend && npx jest test/upa.e2e-spec.ts --runInBand --ci -t 'cada UPA tem o seu proprio token de link'",
      "cd backend && npx jest test/identidade.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-4"
    ]
  },
  {
    "chave": "SIGLA-6",
    "territorio": "backend",
    "titulo": "Cadastro pelo link do coordenador: o medico declara o CRM, escolhe N UPAs e entra PENDENTE (regras 44, 46)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/cadastro/",
      "backend/src/app.module.ts",
      "backend/test/cadastro.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/cadastro.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/cadastro.e2e-spec.ts --runInBand --ci -t 'o medico selecciona 2 das 3 UPAs e fica pendente nas duas'",
      "cd backend && npx jest test/cadastro.e2e-spec.ts --runInBand --ci -t 'link invalido devolve 404 e nao cria ninguem'",
      "test -d backend/src/modules/cadastro && ! grep -rqiE 'mais[-_ ]?saude|maissaude' backend/src/modules/cadastro/",
      "cd backend && npx jest test/upa.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-5"
    ]
  },
  {
    "chave": "SIGLA-7",
    "territorio": "backend",
    "titulo": "So o coordenador DA UPA QUE O MEDICO ESCOLHEU o aceita ou o tira; o de outra UPA leva 403 (regras 44, 46)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/vinculo/",
      "backend/src/app.module.ts",
      "backend/test/vinculo.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/vinculo.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/vinculo.e2e-spec.ts --runInBand --ci -t 'o coordenador da UPA A aceita e o medico fica ativo'",
      "cd backend && npx jest test/vinculo.e2e-spec.ts --runInBand --ci -t 'o coordenador da UPA C nao aceita nem tira o medico que nao o escolheu'",
      "cd backend && npx jest test/cadastro.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-6"
    ]
  },
  {
    "chave": "SIGLA-8",
    "territorio": "backend",
    "titulo": "Aula ao vivo: a secretaria cadastra, indica o especialista responsavel (TROCAVEL) e o calendario que o PENDENTE nao ve (regras 46, 57)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/aula/",
      "backend/src/app.module.ts",
      "backend/test/aula.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/aula.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/aula.e2e-spec.ts --runInBand --ci -t 'so a secretaria cadastra aula e troca o responsavel'",
      "cd backend && npx jest test/aula.e2e-spec.ts --runInBand --ci -t 'o medico pendente ve zero aulas no calendario'",
      "cd backend && npx jest test/aula.e2e-spec.ts --runInBand --ci -t 'aula de 80 minutos tem 4 blocos de 20'",
      "cd backend && npx jest test/identidade.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-4"
    ]
  },
  {
    "chave": "SIGLA-9",
    "territorio": "backend",
    "titulo": "As questoes pertencem A AULA: o responsavel escreve uma por bloco de 20 min, e trocar o especialista NAO as apaga (regras 56, 57)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/questao/",
      "backend/src/app.module.ts",
      "backend/test/questao.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/questao.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/questao.e2e-spec.ts --runInBand --ci -t 'S1 escreve 4 questoes, a secretaria troca para S2 e as 4 ficam com o mesmo id e o mesmo texto'",
      "cd backend && npx jest test/questao.e2e-spec.ts --runInBand --ci -t 'aula de 40 minutos recusa a terceira questao'",
      "cd backend && npx jest test/questao.e2e-spec.ts --runInBand --ci -t 'especialista que nao e o responsavel leva 403'",
      "cd backend && npx jest test/aula.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-8"
    ]
  },
  {
    "chave": "SIGLA-10",
    "territorio": "backend",
    "titulo": "A tabela de pontos e PARAMETRO da secretaria, nao codigo: X, Y, dias da gravacao e multiplicador, sem deploy",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/parametro/",
      "backend/src/app.module.ts",
      "backend/test/parametro.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/parametro.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/parametro.e2e-spec.ts --runInBand --ci -t 'a secretaria muda X, Y, dias da gravacao e multiplicador e o valor lido muda sem reiniciar'",
      "cd backend && npx jest test/parametro.e2e-spec.ts --runInBand --ci -t 'coordenador e medico levam 403 ao tentar parametrizar'",
      "cd backend && npx jest test/identidade.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-4"
    ]
  },
  {
    "chave": "SIGLA-11",
    "territorio": "backend",
    "titulo": "Presenca e ponto no ao vivo: responder valida os 20 min do bloco, X por responder, X+Y por acertar, errar NAO tira, bloco mudo conta 0 (regras 45, 48, 56)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/participacao/",
      "backend/src/app.module.ts",
      "backend/test/participacao.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/participacao.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/participacao.e2e-spec.ts --runInBand --ci -t 'responde 3 das 4 e acerta 2: 60 minutos validados, 3X mais 2Y'",
      "cd backend && npx jest test/participacao.e2e-spec.ts --runInBand --ci -t 'o bloco nao respondido conta 0 minutos e 0 pontos mesmo com a pessoa la'",
      "cd backend && npx jest test/participacao.e2e-spec.ts --runInBand --ci -t 'errar fica com X e nao tira minutos nem pontos'",
      "cd backend && npx jest test/participacao.e2e-spec.ts --runInBand --ci -t 'mudar X no parametro muda o ponto da mesma participacao'",
      "cd backend && npx jest test/participacao.e2e-spec.ts --runInBand --ci -t 'os minutos validados ficam guardados e sao legiveis depois da aula'",
      "cd backend && npx jest test/questao.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-9",
      "SIGLA-10"
    ]
  },
  {
    "chave": "SIGLA-12",
    "territorio": "backend",
    "titulo": "A gravacao do ao vivo abre por x dias: parametro POR AULA com omissao global; ao 7 dia abre, ao 8 nao (regra 49)",
    "escopo_paths": [
      "backend/prisma/",
      "backend/src/modules/gravacao/",
      "backend/src/app.module.ts",
      "backend/test/gravacao.e2e-spec.ts"
    ],
    "aceites": [
      "cd backend && npx jest test/gravacao.e2e-spec.ts --runInBand --ci",
      "cd backend && npx jest test/gravacao.e2e-spec.ts --runInBand --ci -t 'com o parametro a 7 a gravacao abre ao 7 dia e nao abre ao 8'",
      "cd backend && npx jest test/gravacao.e2e-spec.ts --runInBand --ci -t 'a aula pode ter os seus proprios dias e eles mandam sobre o global'",
      "cd backend && npx jest test/gravacao.e2e-spec.ts --runInBand --ci -t 'medico pendente nao abre a gravacao'",
      "test -f backend/test/gravacao.e2e-spec.ts && ! grep -rqE 'setTimeout|sleep\\(' backend/test/gravacao.e2e-spec.ts",
      "cd backend && npx jest test/aula.e2e-spec.ts --runInBand --ci"
    ],
    "depende_de": [
      "SIGLA-8",
      "SIGLA-10"
    ]
  },
  {
    "chave": "SIGLA-13",
    "territorio": "frontend",
    "titulo": "Alicerce do frontend: Next, playwright 1.60 preso ao chromium desta maquina, entrada por papel e os quatro inicios",
    "escopo_paths": [
      "frontend/package.json",
      "frontend/package-lock.json",
      "frontend/next.config.js",
      "frontend/tsconfig.json",
      "frontend/playwright.config.ts",
      "frontend/src/app/layout.tsx",
      "frontend/src/app/page.tsx",
      "frontend/src/app/entrar/",
      "frontend/src/componentes/",
      "frontend/src/lib/",
      "frontend/e2e/entrada.spec.ts"
    ],
    "aceites": [
      "cd frontend && npm install --no-audit --no-fund --prefer-offline && npm run build",
      "grep -qE '\"@playwright/test\" *: *\"[^\"]*1\\.60' frontend/package.json",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line -g 'cada um dos quatro papeis entra e cai no seu inicio'"
    ],
    "depende_de": [
      "SIGLA-4"
    ]
  },
  {
    "chave": "SIGLA-14",
    "territorio": "frontend",
    "titulo": "Ecra da secretaria: a lista de UPAs e o coordenador de cada uma (regra 44)",
    "escopo_paths": [
      "frontend/src/app/secretaria/upas/",
      "frontend/e2e/upas.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/upas.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/upas.spec.ts --reporter=line -g 'a secretaria cria 3 UPAs e ve o link de cada coordenador'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-5",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-15",
    "territorio": "frontend",
    "titulo": "O ecra publico do link: o medico declara o CRM, escolhe as suas UPAs e fica a espera do coordenador (regras 44, 46)",
    "escopo_paths": [
      "frontend/src/app/cadastro/",
      "frontend/e2e/cadastro.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/cadastro.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/cadastro.spec.ts --reporter=line -g 'declara o CRM, selecciona 2 das 3 UPAs e ve que fica pendente'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-6",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-16",
    "territorio": "frontend",
    "titulo": "Ecra do coordenador: aceitar ou tirar o medico, e SO na sua UPA (regras 44, 46)",
    "escopo_paths": [
      "frontend/src/app/coordenador/",
      "frontend/e2e/coordenador.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/coordenador.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/coordenador.spec.ts --reporter=line -g 'o coordenador da UPA A aceita e o medico passa a ativo'",
      "cd frontend && npx playwright test e2e/coordenador.spec.ts --reporter=line -g 'o coordenador da UPA C nao ve esse medico na sua lista'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-7",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-17",
    "territorio": "frontend",
    "titulo": "Calendario das aulas: o medico aceite ve; o PENDENTE ve zero (regras 46, 57)",
    "escopo_paths": [
      "frontend/src/app/calendario/",
      "frontend/e2e/calendario.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/calendario.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/calendario.spec.ts --reporter=line -g 'o medico pendente ve zero aulas'",
      "cd frontend && npx playwright test e2e/calendario.spec.ts --reporter=line -g 'depois de aceite ve a aula com dia, hora e especialista'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-8",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-18",
    "territorio": "frontend",
    "titulo": "Ecra da secretaria: cadastrar a aula ao vivo de 80 min e TROCAR o especialista responsavel (regra 57)",
    "escopo_paths": [
      "frontend/src/app/secretaria/aulas/",
      "frontend/e2e/aulas.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/aulas.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/aulas.spec.ts --reporter=line -g 'cadastra aula de 80 minutos e indica S1'",
      "cd frontend && npx playwright test e2e/aulas.spec.ts --reporter=line -g 'troca o responsavel para S2 e o ecra continua a mostrar as questoes escritas'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-8",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-19",
    "territorio": "frontend",
    "titulo": "Ecra do especialista: escrever as questoes da SUA aula, uma por bloco de 20 min (regras 56, 57)",
    "escopo_paths": [
      "frontend/src/app/especialista/questoes/",
      "frontend/e2e/questoes.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/questoes.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/questoes.spec.ts --reporter=line -g 'escreve as 4 questoes da aula de 80 minutos e o ecra nao deixa escrever a quinta'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-9",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-20",
    "territorio": "frontend",
    "titulo": "A sala do ao vivo: a pergunta de 20 em 20 min, e ao fim os minutos validados e os pontos a vista (regras 45, 48, 56)",
    "escopo_paths": [
      "frontend/src/app/ao-vivo/",
      "frontend/e2e/ao-vivo.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/ao-vivo.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/ao-vivo.spec.ts --reporter=line -g 'a pergunta do bloco aparece sozinha e fecha quando o bloco passa'",
      "cd frontend && npx playwright test e2e/ao-vivo.spec.ts --reporter=line -g 'responde 3 das 4 e o ecra mostra 60 minutos validados'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-11",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-21",
    "territorio": "frontend",
    "titulo": "O leitor da gravacao: a barra NAO avanca e o relogio PARA quando a aba perde o foco (regra 49)",
    "escopo_paths": [
      "frontend/src/app/gravacao/",
      "frontend/src/componentes/leitor/",
      "frontend/e2e/gravacao.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/gravacao.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/gravacao.spec.ts --reporter=line -g 'arrastar a barra para a frente nao muda o tempo do video'",
      "cd frontend && npx playwright test e2e/gravacao.spec.ts --reporter=line -g 'a aba perde o foco e o relogio para'",
      "cd frontend && npx playwright test e2e/gravacao.spec.ts --reporter=line -g 'ao 8 dia o leitor nao abre'",
      "cd frontend && npx playwright test e2e/entrada.spec.ts --reporter=line"
    ],
    "depende_de": [
      "SIGLA-12",
      "SIGLA-22"
    ]
  },
  {
    "chave": "SIGLA-22",
    "territorio": "frontend",
    "titulo": "A parede: os seis tokens, a junta, a virada e A MARCA DA UPA gerada dos dados — nenhum ecra nasce sem ela (regras 62 a 68)",
    "escopo_paths": [
      "frontend/src/estilo/",
      "frontend/src/componentes/ladrilho/",
      "frontend/e2e/ladrilho.spec.ts"
    ],
    "aceites": [
      "cd frontend && npx playwright test e2e/ladrilho.spec.ts --reporter=line",
      "cd frontend && npx playwright test e2e/ladrilho.spec.ts --reporter=line -g 'a mesma UPA da SEMPRE o mesmo ladrilho, e UPA San Martin normaliza para UPASANMARTIN'",
      "cd frontend && npx playwright test e2e/ladrilho.spec.ts --reporter=line -g 'o quadrante 2x2 espelha para 4x4 e o ladrilho sai sem rede, sem ficheiro e sem imagem gerada'",
      "cd frontend && npx playwright test e2e/ladrilho.spec.ts --reporter=line -g 'UPA por carregar NAO inventa ladrilho: a grelha fica so em argamassa'",
      "test -f frontend/src/estilo/tokens.css && [ \"$(grep -oE -- '--cor-[a-z-]+:' frontend/src/estilo/tokens.css | sort -u | wc -l)\" = 6 ]",
      "test -d frontend/src/app && test -f frontend/src/estilo/tokens.css && ! grep -rniE '#[0-9a-fA-F]{3,8}' frontend/src/app frontend/src/componentes",
      "test -d frontend/src/app && test -f frontend/src/estilo/tokens.css && ! grep -rniE 'border-radius|box-shadow' frontend/src/app frontend/src/componentes frontend/src/estilo",
      "grep -qE 'prefers-reduced-motion' frontend/src/estilo/tokens.css"
    ],
    "depende_de": [
      "SIGLA-13"
    ]
  }
]