8.2 KiB
Runbook de desenvolvimento e operação
Desenvolvimento local
- Copiar
.env.examplepara.env. - Executar
docker compose build. - Gerar a chave com
docker compose run --rm app php artisan key:generate. - Iniciar com
docker compose up -d. - Preparar dados com
docker compose exec app php artisan migrate --seed. - Abrir o portal em
http://localhost:8000e emails emhttp://localhost:8025.
Diagnóstico
docker compose ps
docker compose logs --tail=100 app
docker compose logs --tail=100 queue
docker compose exec app php artisan about
docker compose exec app php artisan migrate:status
docker compose exec postgres pg_isready -U reserva -d reserva
docker compose exec redis redis-cli ping
Página em branco no desenvolvimento
Se o HTML responder mas a interface React não aparecer, confirmar que public/hot contém http://localhost:5173 e não http://0.0.0.0:5173. Depois validar os módulos:
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:
curl -s http://localhost:8000/login | grep 'data-server-rendered="true"'
Se o endpoint Vite devolver um erro SSR, procurar primeiro componentes globais montados em withApp que chamem hooks Inertia como usePage(). Os elementos irmãos do argumento app não pertencem ao respetivo contexto; devem receber as propriedades através do segundo argumento de withApp.
Atualização de código
docker compose exec app composer install
docker compose exec node npm install
docker compose exec app php artisan migrate --force
docker compose exec app php artisan optimize:clear
docker compose restart queue scheduler
Integração Snipe-IT
Definir no ambiente, sem colocar tokens no repositório:
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 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:
# Sincronização imediata e resultado no terminal
docker compose exec app php artisan snipe:sync-assets
# Colocar na fila
docker compose exec app php artisan snipe:sync-assets --queue
# Confirmar o agendamento horário
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:
- preparar a requisição;
- confirmar fisicamente todos os equipamentos e o estado à saída;
- confirmar o ID do destinatário no Snipe-IT;
- registar a entrega e verificar a mensagem de sucesso;
- se existir erro, não voltar a submeter antes de consultar o estado do ativo no Snipe-IT.
Procedimento de devolução:
- localizar a requisição ou ler a etiqueta;
- verificar equipamento, acessórios, danos e localização;
- registar a devolução;
- criar um incidente e bloqueio temporal quando o ativo não deva voltar ao catálogo;
- 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:
# Expirar imediatamente os pedidos vencidos
docker compose exec app php artisan reservations:expire
# Colocar a operação na fila
docker compose exec app php artisan reservations:expire --queue
# Confirmar ambos os agendamentos
docker compose exec app php artisan schedule:list
Uma expiração ou cancelamento muda itens held, reserved, ready e delivered para cancelled, libertando o período. Confirmar os eventos reservation.expired ou reservation.cancelled em audit_logs quando existir uma divergência operacional.
Aprovações
Utilizadores com perfil approver ou administrator acedem a http://localhost:8000/aprovacoes. Uma decisão válida deve criar uma linha em approval_actions e outra em audit_logs. Se a aprovação indicar que a disponibilidade mudou, confirmar primeiro a atribuição/estado sincronizado do ativo e conflitos entretanto criados; não alterar o estado diretamente na base de dados.
As decisões geram jobs de notificação. Em desenvolvimento, confirmar o email em http://localhost:8025 e a notificação interna em http://localhost:8000/notificacoes. Se uma mensagem não chegar, consultar primeiro docker compose logs --tail=100 queue e a tabela failed_jobs; não repetir a decisão já confirmada.
Administração e relatórios
Administradores usam:
http://localhost:8000/administracao/utilizadorespara contas, perfis e IDs Snipe-IT;http://localhost:8000/administracao/regraspara políticas aplicadas a novos pedidos;http://localhost:8000/administracao/notificacoes/modelospara assuntos e mensagens;http://localhost:8000/administracao/snipe-itpara diagnóstico da integração.
As alterações são registadas em audit_logs. A margem de uma reserva já submetida não muda quando a política é alterada; confirmar buffer_starts_at e buffer_ends_at do item ao investigar um conflito.
Administradores e auditores consultam http://localhost:8000/relatorios e http://localhost:8000/auditoria. O CSV usa ;, UTF-8 com BOM e neutralização de fórmulas para abertura segura em aplicações de folha de cálculo. Cada pedido está limitado a 366 dias; para análises plurianuais, exportar períodos separados. Aprovadores, operadores, administradores e auditores consultam o planeamento consolidado em http://localhost:8000/calendario-global.
Produção
Antes de disponibilizar:
- definir
APP_ENV=production,APP_DEBUG=falsee HTTPS; - substituir todas as palavras-passe do exemplo;
- montar segredos fora do repositório;
- remover exposição pública das portas PostgreSQL, Vite e Mailpit;
- configurar volumes persistentes e backups cifrados;
- executar
php artisan optimizee frontend compilado; - definir health checks, alertas e rotação de logs;
- testar recuperação de backup e falha Snipe-IT.
Backups
Salvaguardar diariamente PostgreSQL e uploads. Manter retenção semanal/mensal e uma cópia fora do servidor. Segredos são salvaguardados através de procedimento separado. Executar um teste de restauro periódico e registar o resultado.