feat: complete equipment handover workflow

This commit is contained in:
2026-08-04 17:15:51 +01:00
parent 809eab9d4a
commit d829f34580
24 changed files with 1800 additions and 28 deletions

View File

@@ -30,6 +30,8 @@ curl -I -H 'Origin: http://localhost:8000' http://localhost:5173/@vite/client
curl -I -H 'Origin: http://localhost:8000' http://localhost:5173/resources/js/app.tsx
```
Para executar a validação backend use `docker compose exec app composer test`, não `php artisan test` diretamente. O script isola as variáveis de teste das variáveis `local` injetadas pelo Docker Compose e evita que jobs únicos deixem locks no Redis de desenvolvimento.
Ambos devem responder com estado 200 e `Access-Control-Allow-Origin: http://localhost:8000`. Reiniciar o serviço com `docker compose restart node` se o ficheiro `public/hot` estiver desatualizado.
Confirmar também que o HTML inicial já contém conteúdo SSR:
@@ -57,13 +59,14 @@ Definir no ambiente, sem colocar tokens no repositório:
```dotenv
SNIPE_IT_URL=https://inventario.exemplo.pt
SNIPE_IT_READ_TOKEN=
SNIPE_IT_OPERATIONAL_TOKEN=
SNIPE_IT_TIMEOUT=10
SNIPE_IT_PAGE_SIZE=100
SNIPE_IT_RETRIES=3
SNIPE_IT_RETRY_DELAY_MS=250
```
O token deve pertencer a uma conta técnica com acesso apenas de leitura aos ativos. A aplicação acrescenta `/api/v1` automaticamente quando a URL não o contém.
O token de leitura deve pertencer a uma conta técnica com acesso apenas de leitura aos ativos. O token operacional deve ser separado e ter apenas as permissões necessárias para checkout/check-in. A aplicação acrescenta `/api/v1` automaticamente quando a URL não o contém.
Operações:
@@ -80,6 +83,28 @@ docker compose exec app php artisan schedule:list
Administradores podem testar a ligação, iniciar uma execução e consultar as últimas dez sincronizações em `http://localhost:8000/administracao/snipe-it`. Uma execução falhada mantém o último catálogo válido e não desativa registos ausentes. Consultar `sync_runs`, os logs do worker e o painel antes de repetir.
## Entregas, devoluções e reconciliação
Utilizadores com perfil `inventory_operator` ou `administrator` acedem a `http://localhost:8000/operacoes`. A fila inclui as reservas do dia e todos os processos entregues, atrasados, devolvidos ou com incidente ainda pendente. O campo inicial aceita referência, nome, email, etiqueta, ID Snipe-IT ou a saída de um leitor QR/código de barras configurado como teclado.
Procedimento de entrega:
1. preparar a requisição;
2. confirmar fisicamente todos os equipamentos e o estado à saída;
3. confirmar o ID do destinatário no Snipe-IT;
4. registar a entrega e verificar a mensagem de sucesso;
5. se existir erro, não voltar a submeter antes de consultar o estado do ativo no Snipe-IT.
Procedimento de devolução:
1. localizar a requisição ou ler a etiqueta;
2. verificar equipamento, acessórios, danos e localização;
3. registar a devolução;
4. criar um incidente e bloqueio temporal quando o ativo não deva voltar ao catálogo;
5. concluir o processo apenas depois de todos os itens estarem devolvidos.
Uma operação parcial fica em `incident`. Consultar `handover_records` para movimentos confirmados e os eventos `reservation.delivery_failed`/`reservation.return_failed` em `audit_logs`. Comparar cada item com o estado atual no Snipe-IT; corrigir apenas os itens ainda `ready` ou `delivered`. Não alterar estados diretamente na base de dados nem repetir em bloco, porque as escritas externas são deliberadamente não idempotentes e não têm retry automático.
## Ciclo de vida das pré-reservas
As requisições pendentes têm, por defeito, um prazo de decisão de 48 horas. O scheduler coloca a expiração na fila a cada cinco minutos. Para operar ou diagnosticar manualmente: