# Registo de decisões técnicas ## ADR-001 — Monólito modular Laravel/Inertia **Data:** 2026-08-04 **Estado:** aceite Usar Laravel 13 com React/TypeScript através de Inertia no mesmo projeto. Mantém autenticação, autorização, filas e transações numa única unidade operacional, sem impedir separação por domínio. ## ADR-002 — PostgreSQL como garantia de conflitos **Data:** 2026-08-04 **Estado:** aceite Usar PostgreSQL e períodos semiabertos `[início, fim)`. A lógica aplicacional melhora a mensagem ao utilizador; uma restrição de exclusão GiST garante que concorrência ou um erro aplicacional não cria sobreposição bloqueante. ## ADR-003 — Cache local, sem replicação total do Snipe-IT **Data:** 2026-08-04 **Estado:** aceite Guardar apenas os campos de ativos necessários ao catálogo e reservas. A sincronização desativa registos ausentes em vez de os apagar. A base de dados do Snipe-IT nunca é acedida diretamente. ## ADR-004 — Registo público desativado **Data:** 2026-08-04 **Estado:** aceite Contas são criadas por administrador, convite ou identidade institucional verificada. Mantêm-se recuperação de palavra-passe, verificação de email, 2FA e passkeys do starter kit. ## ADR-005 — Ambiente reproduzível em Docker Compose **Data:** 2026-08-04 **Estado:** aceite Desenvolvimento e primeira instalação utilizam serviços separados para Nginx, PHP-FPM, PostgreSQL, Redis, Vite, filas, scheduler e Mailpit. Produção deve usar imagens imutáveis, HTTPS e gestão externa de segredos, mantendo a mesma topologia lógica. ## ADR-006 — Português de Portugal na interface **Data:** 2026-08-04 **Estado:** aceite Textos funcionais são escritos em português europeu. Nomes de código, eventos e tabelas permanecem em inglês para consistência técnica. ## ADR-007 — Sincronização Snipe-IT convergente por execução **Data:** 2026-08-04 **Estado:** aceite Consumir `/api/v1/hardware` por `offset`/`limit`, com páginas configuráveis até ao máximo oficial de 500 registos. Cada ativo visto recebe o ID da execução em `last_seen_sync_run_id`; a desativação de ausentes só ocorre depois de todas as páginas terminarem com sucesso. Upserts de páginas já válidas podem permanecer após uma falha, permitindo convergência na execução seguinte sem manter uma transação aberta durante chamadas HTTP. Repetir apenas falhas de ligação, HTTP 429 e HTTP 5xx. Usar lock distribuído, job único e token exclusivo de leitura. ## ADR-008 — Pré-reserva bloqueante com expiração auditada **Data:** 2026-08-04 **Estado:** aceite Uma requisição submetida cria itens em `held` e bloqueia o período durante 48 horas, até decisão, cancelamento ou expiração. O próprio requisitante pode cancelar apenas enquanto a máquina de estados admite a transição. Um job único executado a cada cinco minutos expira pedidos `pending_approval` ou `awaiting_information` com prazo vencido. Cancelamento e expiração usam bloqueio transacional da requisição, libertam todos os itens bloqueantes e produzem eventos de auditoria; intervalos que se tocam continuam permitidos pela semântica `[início, fim)`.