v1.1.0: release → main #39

Merged
caio merged 16 commits from release into main 2026-10-10 19:45:48 -03:00
Owner

Versão v1.1.0 — tudo o que entrou na develop desde a v1.0.2.

Para quem usa

  • Área Funcional: escolha de onde está de serviço ao entrar, lançamentos na ordem do serviço (almoço, 2ª Jornada, pernoite, 1ª Jornada), Livro do Dia com texto pronto pra enviar, dispensa médica com Oficial Médico responsável, posto de serviço na chamada.
  • Painel: situação do efetivo agora (quem está em pane) na página inicial, postos de serviço com quem está de serviço, Efetivo com números clicáveis, tabelas enxutas com painel lateral, visual institucional.
  • Ikarus37: mesmo visual em tema escuro, escopo das chaves de API.

Segurança

  • Chaves de API com escopo (app / admin): a chave do app deixa de alcançar os endpoints administrativos. Ver docs/SEGURANCA-API.md.

Banco

  • Migrations 014 a 019. Ensaiadas sobre uma cópia do backup de produção de 10/10 em MariaDB 10.11, pelo mesmo deploy/migrar.php do deploy, com a suíte inteira passando em cima (37 + 94 + 40 testes e o smoke).

CI da develop: run 28, verde nos dois runners.

Versão **v1.1.0** — tudo o que entrou na `develop` desde a v1.0.2. **Para quem usa** - Área Funcional: escolha de onde está de serviço ao entrar, lançamentos na ordem do serviço (almoço, 2ª Jornada, pernoite, 1ª Jornada), Livro do Dia com texto pronto pra enviar, dispensa médica com Oficial Médico responsável, posto de serviço na chamada. - Painel: situação do efetivo agora (quem está em pane) na página inicial, postos de serviço com quem está de serviço, Efetivo com números clicáveis, tabelas enxutas com painel lateral, visual institucional. - Ikarus37: mesmo visual em tema escuro, escopo das chaves de API. **Segurança** - Chaves de API com escopo (`app` / `admin`): a chave do app deixa de alcançar os endpoints administrativos. Ver `docs/SEGURANCA-API.md`. **Banco** - Migrations 014 a 019. Ensaiadas sobre uma cópia do backup de produção de 10/10 em MariaDB 10.11, pelo mesmo `deploy/migrar.php` do deploy, com a suíte inteira passando em cima (37 + 94 + 40 testes e o smoke). CI da `develop`: run 28, verde nos dois runners.
caio added 16 commits 2026-10-10 19:45:42 -03:00
tests/api_test.php cobre o que o teste de integração (fluxo da PWA) não
cobria: CRUD administrativo de alunos, grupos e usuários do Painel,
relatórios, situação, casos de erro das retiradas e o que é comum a
todos os endpoints (CORS, api_logs, sessão expirada, rate limit por IP).

O mini framework de teste saiu de integracao_test.php pra tests/lib_teste.php,
compartilhado pelos dois arquivos.

Refs #7 #8 #9 #10 #11 #12 #13

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scripts/dev/gerar-seed-qrcodes.php gera database/seed_dev.sql (25 alunos
fictícios com qrcode_hash fixo) e docs/dev/qrcodes-seed.html (folha com
o QR de cada um, pra escanear, copiar ou imprimir). O QR é desenhado por
um encoder mínimo no próprio script (versão 5-M), sem dependência nova.

O Docker local importa o seed_dev.sql quando não há backup nem seed_db.sql
real, e o lint confere se os arquivos gerados estão em dia.

Refs #14 #15 #16 #17

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Skills de design: imagem → SVG → implementação no site
All checks were successful
CI / Lint (debian) (push) Successful in 22s
CI / Lint (ubuntu-latest) (push) Successful in 20s
CI / Testes (debian) (push) Successful in 36s
CI / Testes (ubuntu-latest) (push) Successful in 35s
d4d2f784ed
Três skills do Claude Code em .claude/skills/, uma por etapa:
- design-por-imagem: das imagens de referência ao brief e mockup em docs/design/
- imagem-para-svg: logo, ícone ou ilustração vira SVG limpo no padrão do projeto
- implementar-design: aplica brief, tokens e SVGs no site e confere no navegador

Refs #18 #19 #20 #22

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
retirada_marcar.php chama listarServicos(), que consulta postos_servico —
tabela que nenhum schema ou migration cria. Num banco montado só pelo
init_db.sql a consulta falha e a página inteira dava erro fatal. Sem a
tabela, a lista de serviços agora só vem vazia.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docker-compose.demo.yml sobe um Argos completo em localhost:8090 com banco
novo (init_db.sql + seed_dev.sql), separado do compose do dia a dia. O seed
ganhou dois usuários do Painel (CA e Esquadrão Prata) e
scripts/dev/simular-atividade.php cria chamadas de exemplo pela API.
Roteiro em docs/dev/COMO-TESTAR.md.

Refs #21

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Segue docs/design/sistema/brief.md, tirado dos mockups hero-app.png e
tela-login.png: azul de comando, títulos em Barlow Semi Condensed,
cartões com sombra, pílulas de estado.

- Painel e Ikarus37 carregam web/css/argos-admin.css depois do <style> de
  cada página (tokens, barra superior, cartões, tabelas, botões, campos,
  login); o Ikarus37 soma argos-ikarus.css, que troca os tokens pro tema
  escuro. A impressão não muda (tudo em @media screen).
- PWA: cabeçalho com pendentes/enviadas do dia, cartões de retirada com
  selo do tipo, chamada com Presente/Falta em botões de 44px e placar,
  login com brasão. Cache do service worker vai pra v3.
- SVGs novos: argos-olho.svg (marca) e especialista.svg (insígnia, 2 KB no
  lugar do PNG de 147 KB onde é usada pequena).

Refs #21 #22

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Teste das telas logadas do Painel e do Ikarus37
All checks were successful
CI / Lint (debian) (push) Successful in 21s
CI / Lint (ubuntu-latest) (push) Successful in 21s
CI / Testes (debian) (push) Successful in 36s
CI / Testes (ubuntu-latest) (push) Successful in 36s
4fc98ab5cd
tests/paginas_test.php entra nos dois painéis como um navegador (formulário
+ cookie) e abre cada página: 200, sem erro de PHP, sem acesso negado e com
a folha de estilo comum. Teria pego o erro fatal da tela de chamada.
banco()/sql() saem de api_test.php pra tests/lib_teste.php.

Refs #21

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
O aluno de serviço passa a ter no app:
- Livro: o Livro do Dia do esquadrão montado a partir das chamadas enviadas
  e das dispensas, com "Copiar texto" e "Enviar" (texto padronizado pra
  mandar ao Aluno de Dia ao CA, no lugar do que era digitado no WhatsApp).
- Dispensas: lista das ativas e lançamento de dispensa médica.

API nova, sempre restrita ao esquadrão da sessão: GET/POST /api/dispensas.php
e GET /api/livro.php. A montagem do livro saiu de painel/livro_do_dia.php
pra core/livro_core.php, usada pelos dois: a situação do aluno vai por
extenso ("Falta", não "FALT") e "Chamada não enviada" é diferente de
"Não há". No app também: marca ARG(olho)S, versão e crédito no rodapé, e
correção da rolagem das telas longas (o fim ficava atrás da barra inferior).

Refs #25 #26 #27 #29 #31

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A página inicial abre com a situação do efetivo agora: prontos, em pane,
  sem chamada, e a lista dos alunos em pane com a situação por extenso. Cada
  aluno aparece uma vez (última chamada enviada) — não é soma de faltas.
- Efetivo: cada número dos quadros de quantitativo (esquadrilha, total, M/F,
  especialidade) filtra a listagem; filtro novo por sexo; filtros em vigor
  aparecem acima da lista.
- Painel Argos: os números do período passam a se chamar "registros".

Refs #28 #30

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Visual institucional, marca ARG(olho)S, rodapé com versão e tabelas enxutas com painel lateral
All checks were successful
CI / Lint (debian) (push) Successful in 22s
CI / Lint (ubuntu-latest) (push) Successful in 20s
CI / Testes (debian) (push) Successful in 37s
CI / Testes (ubuntu-latest) (push) Successful in 36s
f2d881b693
- Tom institucional no Painel e no Ikarus37: azul EEAR, filete dourado,
  cantos de 6px, quase sem sombra, badges retangulares.
- A marca escrita é A R G (olho) S em barras, logins e landing.
- Rodapé em todas as páginas: instituição, versão publicada e crédito do
  CIDIT (Esquadrão Prata, Turma Ikarus 37).
- Tabelas com data-enxuta mostram só as colunas essenciais; "Ver / editar"
  abre um painel lateral com todos os campos e as ações (web/js/argos-admin.js,
  sem mudar o PHP das páginas).
- Aba selecionada do Controle do Domínio de Negócio voltou a ser legível
  (estava texto azul sobre fundo azul).

Refs #24 #27 #31 #32

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Segurança (docs/SEGURANCA-API.md):
- Toda chave de API passa a ter escopo. "app" só serve nas rotas do app e
  sempre junto com a sessão do aluno; os endpoints administrativos (alunos
  POST/PUT/DELETE, grupos, painel_usuarios, relatorios, situacao, DELETE de
  retirada) exigem chave "admin" e respondem 403 pra chave de app. Antes,
  a chave do app — que qualquer um lê no navegador — criava usuário do Painel.
- GET /api/retiradas.php exige sessão (restrita ao esquadrão de serviço) ou
  chave admin; buscar por id confere o esquadrão.
- 401 com WWW-Authenticate, 403 com insufficient_scope, 429 com Retry-After;
  sessão aceita também em Authorization: Bearer; no-store e nosniff em tudo.
- As chaves que já existem viram "app" (migration 015): a PWA segue igual.
  Ikarus37 → API mostra o escopo e deixa escolher ao gerar chave.

Posto de serviço: a sessão guarda em qual esquadrão/esquadrilha o aluno está
de serviço (GET/PUT /api/servico.php, migration 017) e é esse esquadrão que
limita o que ele vê e lança, não o de origem.

Refs #34 #36

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Postos de serviço: tabela postos_servico (migration 014, que faltava),
  cadastro em Controle do Domínio de Negócio → Postos de serviço, e a chamada
  guarda o posto quando o motivo é Serviço (retirada_itens.servico_id).
- Dispensa médica: campo Oficial Médico responsável (migration 016),
  obrigatório ao lançar, no cadastro, na lista e no Livro do Dia.
- Tipos de retirada: entra o almoço (migration 018); a ordem passa a ser
  almoço, 2ª Jornada, pernoite e 1ª Jornada. Educação Física deixa de ser
  oferecida (continua válida pro histórico). Uma lista só de tipos, em
  core/retiradas_core.php, no lugar do array repetido em seis telas.
- Livro do Dia segue o dia de serviço: almoço, 2ª Jornada e pernoite do dia
  e a 1ª Jornada do dia seguinte.

Refs #23 #33 #35 #37

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Depois do QR, o app pergunta em qual esquadrão/esquadrilha o aluno está de
  serviço; é esse o esquadrão das chamadas, do efetivo, das dispensas e do
  livro. Dá pra trocar tocando no cabeçalho.
- Tipos na ordem do serviço: Almoço, 2ª Jornada, Pernoite, 1ª Jornada.
- Na chamada, motivo Serviço abre a escolha do posto de serviço.
- Dispensa pede o Oficial Médico responsável.
- Marcações em sequência do mesmo aluno não se perdem mais: a última fica na
  fila em vez de ser descartada enquanto a anterior ainda está indo.

Refs #33 #35 #36 #37

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Testes e documentação: escopo das chaves, posto de serviço, postos, almoço
All checks were successful
CI / Lint (debian) (push) Successful in 21s
CI / Lint (ubuntu-latest) (push) Successful in 20s
CI / Testes (debian) (push) Successful in 38s
CI / Testes (ubuntu-latest) (push) Successful in 36s
2d95401df1
tests/api_test.php vai a 94 testes: a chave do app é recusada em cada
endpoint administrativo, isolamento por esquadrão de serviço, cabeçalhos,
Bearer, posto de serviço da sessão, postos na chamada, Oficial Médico, e o
livro na ordem do serviço. Os testes administrativos usam uma chave de
escopo admin da fixture. O ambiente de demonstração aplica as migrations
ao subir.

Refs #33 #34 #35 #36 #37

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Postos de serviço com quem está de serviço agora, sem membros fixos
All checks were successful
CI / Lint (debian) (push) Successful in 21s
CI / Lint (ubuntu-latest) (push) Successful in 20s
CI / Testes (debian) (push) Successful in 37s
CI / Testes (ubuntu-latest) (push) Successful in 37s
CI / Testes (ubuntu-latest) (pull_request) Successful in 38s
CI / Lint (debian) (pull_request) Successful in 20s
CI / Lint (ubuntu-latest) (pull_request) Successful in 20s
CI / Testes (debian) (pull_request) Successful in 37s
9f3ceab76c
O posto é criado à mão numa tela própria (Painel → Postos de serviço), como
um clube, mas quem está nele não é fixo: registra-se quem está de serviço
agora, e a troca (rendição do dia ou pane no meio do serviço) encerra o
período de quem sai, com o motivo, e abre o de quem entra. Nada é apagado —
fica o histórico de quem tirou cada serviço (migration 019).

Quem está de serviço num posto já entra na chamada como ausente por Serviço,
com o posto preenchido, do mesmo jeito que a dispensa médica já fazia.

O cadastro sai do Controle do Domínio de Negócio. O teste das telas faz o
caminho inteiro: criar, colocar de serviço, render e conferir na chamada.

Refs #33

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge pull request 'v1.1.0: develop → release' (#38) from develop into release
All checks were successful
CI / Lint (debian) (pull_request) Successful in 20s
CI / Lint (ubuntu-latest) (pull_request) Successful in 20s
CI / Testes (debian) (push) Successful in 38s
CI / Testes (ubuntu-latest) (push) Successful in 37s
CI / Lint (debian) (push) Successful in 20s
CI / Lint (ubuntu-latest) (push) Successful in 20s
CI / Testes (debian) (pull_request) Successful in 36s
CI / Testes (ubuntu-latest) (pull_request) Successful in 37s
fa04d1833a
caio merged commit 48a8b9ae70 into main 2026-10-10 19:45:48 -03:00
Sign in to join this conversation.
No description provided.