feat: protect production Snipe-IT operations

This commit is contained in:
2026-08-05 12:37:12 +01:00
parent 26330b75f7
commit 8c69331118
13 changed files with 289 additions and 26 deletions

View File

@@ -1,7 +1,7 @@
# Estado do projeto e handoff
**Atualizado em:** 4 de agosto de 2026
**Fase:** Fases 1 a 6 concluídas; Fase 7 em curso (base técnica de identidade, saúde e recuperação concluída)
**Atualizado em:** 5 de agosto de 2026
**Fase:** Fases 1 a 6 concluídas; Fase 7 em curso (identidade, saúde, recuperação e ligação de leitura ao Snipe-IT de produção concluídas)
**Último agente:** Codex
## Resultado disponível
@@ -35,6 +35,9 @@
- Substituição de equipamento apenas por ativo livre da mesma categoria, mantendo a pré-reserva e todo o histórico.
- Fila de aprovação com filtros por referência, requisitante, categoria e período, incluindo histórico de ações.
- Cliente Snipe-IT operacional com token separado, checkout para utilizador, check-in para a localização habitual e validação de erros transportados em HTTP 200.
- Preflight remoto obrigatório antes de checkout; ativos já atribuídos são recusados sem qualquer pedido de escrita.
- Check-in condicionado a checkout confirmado pelo portal para o mesmo requisitante e a atribuição remota atual ao respetivo utilizador Snipe-IT.
- Snipe-IT de produção formalmente limitado a leitura, checkout e check-in: criar, editar ou eliminar inventário é proibido no código, diagnóstico e procedimentos de agentes.
- Área diária do operador protegida pelo perfil `inventory_operator`/`administrator`, com leitura por scanner-teclado ou pesquisa de referência, requisitante, etiqueta e ID Snipe-IT.
- Preparação, entrega, devolução e conclusão com máquina de estados, condição física, observações, operador, destinatário e resposta externa em `handover_records`.
- Associação persistente entre o utilizador do portal e o respetivo ID no Snipe-IT, confirmada durante uma entrega bem-sucedida.
@@ -59,7 +62,7 @@
## Limites conhecidos
- A integração está implementada e testada contra respostas simuladas; falta configurar e validar URL, versão e token da instância institucional. Até lá, o catálogo utiliza dados fictícios do seeder.
- A URL e os dois tokens distintos estão configurados localmente e responderam com sucesso a pedidos `GET` em 5 de agosto de 2026. A sincronização integral de leitura importou 2367 ativos para o cache local, dos quais 716 estavam atribuídos e 144 marcados como requisitáveis. Não foi executada qualquer escrita real. Falta confirmar institucionalmente a versão, o menor privilégio efetivo dos tokens e as categorias/estados autorizados.
- Microsoft Entra ID está implementado e testado com tokens assinados simulados; falta registar/configurar a aplicação no tenant institucional e validar Conditional Access/MFA real.
- As notificações estão implementadas com Mailpit em desenvolvimento; falta validar SMTP institucional antes do piloto.
- O calendário atual é a vista mensal pessoal do MVP; vistas diária, semanal, global e por equipamento/categoria/localização ficam para as áreas operacional e administrativa.
@@ -72,7 +75,7 @@
Implementar a **Fase 7 — hardening e entrada em produção**:
1. configurar e validar Microsoft Entra no tenant institucional, incluindo Conditional Access/MFA;
2. validar a integração contra o Snipe-IT institucional e configurar tokens reais de menor privilégio;
2. confirmar com o responsável Snipe-IT a versão, o âmbito de menor privilégio dos tokens e as categorias/estados requisitáveis; validar checkout/check-in apenas no primeiro movimento institucional legítimo;
3. configurar SMTP institucional, domínio, HTTPS e gestão externa de segredos;
4. ligar os health checks a monitorização/alertas e agendar backups cifrados externos;
5. executar testes de segurança, concorrência, desempenho e end-to-end com equipamentos reais;
@@ -81,12 +84,12 @@ Implementar a **Fase 7 — hardening e entrada em produção**:
## Testes da última sessão
Validação concluída em 4 de agosto de 2026:
Validação concluída em 5 de agosto de 2026:
- `docker compose exec -T app composer test`: passou;
- Laravel Pint: 141 ficheiros sem desvios;
- PHPStan/Larastan nível 7: 107 ficheiros, zero erros;
- Pest: 103 testes passaram, 585 asserções e 2 testes de registo ignorados por a funcionalidade estar deliberadamente desativada;
- Pest: 108 testes passaram, 609 asserções e 2 testes de registo ignorados por a funcionalidade estar deliberadamente desativada;
- TypeScript (`tsc --noEmit`): passou;
- ESLint: passou;
- Prettier: passou;
@@ -109,6 +112,12 @@ Validação concluída em 4 de agosto de 2026:
- smoke tests via Nginx: `/health/live` devolveu `ok` e `/health/ready` devolveu `ready`.
- diagnóstico de login local: a base de desenvolvimento estava vazia apesar de migrada; `db:seed --force` repôs 2 utilizadores ativos, 5 perfis e 18 ativos fictícios, sem substituir dados existentes;
- login real no browser validado com `demo@escola.pt`: redirecionou para `/dashboard` e não produziu erros de consola.
- testes focados das salvaguardas Snipe-IT: 17 passaram, com 106 asserções, incluindo prova de ausência de `POST` em ativos atribuídos e check-in sem proveniência ou destinatário válidos;
- tokens Snipe-IT confirmados como configurados e distintos; ambos responderam a uma consulta `GET` com sucesso, sem revelar credenciais ou URL;
- sincronização real exclusivamente de leitura concluída: 2367 ativos processados e criados no cache local, sem qualquer pedido de escrita no Snipe-IT;
- cache local após sincronização: 2367 ativos ativos, 716 atribuídos e 144 marcados como requisitáveis;
- frontend: TypeScript, ESLint, Prettier e build Vite passaram novamente; Composer Audit sem avisos conhecidos;
- smoke tests após a sincronização: liveness `ok`, readiness `ready` e `/login` HTTP 200.
## Decisões pendentes do contexto institucional
@@ -124,4 +133,4 @@ Estas decisões não bloqueiam o desenvolvimento com defaults seguros, mas devem
## Próximo ficheiro a abrir
Começar em `docs/PRODUCTION_CHECKLIST.md`. A próxima alteração de código pode preparar testes de concorrência/desempenho e observabilidade local; as validações Entra, Snipe-IT e SMTP só ficam concluídas quando existirem serviços institucionais concretos, sem guardar os respetivos segredos no repositório.
Começar em `docs/PRODUCTION_CHECKLIST.md`. Para Snipe-IT, confirmar versão, categorias/estados e permissões efetivas com o responsável institucional; não executar testes de escrita. A próxima alteração de código pode preparar testes de concorrência/desempenho e observabilidade local. Entra, SMTP e o primeiro movimento Snipe-IT só ficam concluídos com validação institucional, sem guardar segredos no repositório.