4.9 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
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_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.
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.
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.
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.