Passo 11 completo. Build limpo, AC verificado.
O que foi construído no admin-web (localhost:3001):
Infraestrutura completa a partir do zero: Tailwind, tRPC client/server, auth por autologin, env.ts, providers
/maintenance — cliente de polling com refetchInterval: 5000ms:
Header com contador de pedidos abertos + filtros por estado (checkboxes) e área (select)
Grid de cards com thumbnail (presigned GET), posto, descrição, reporter + tempo relativo, badge de status
OPEN → botão Aceitar (mutation claim)
CLAIMED → info "Aceite por X há Ym" + botão Marcar resolvido (dialog com nota opcional)
RESOLVED → badge verde + info "Resolvido por X há Ym"
Badge no document.title: (N) FieldOps — Manutenção
Toggle de notificação sonora via Web Audio API (beep ao detectar novo OPEN)
Passo 10 completo. AC verificado end-to-end:
Sem foto — row criada com photoKey=null ✓
Com foto — upload para MinIO via presigned PUT + row criada com photoKey correto + conteúdo verificado via presigned GET ✓
O que foi implementado:
/maintenance/new — Client Component com: select de posto (carregado via trpc.workstation.list), input de foto com compressão canvas (max 1600px, JPEG q=0.8), preview + botão remover, textarea com contador, submit que faz upload + create + redirect
/maintenance/sent — Server Component que mostra o clientRequestId e o botão "Voltar ao início"
Build de produção limpo com 7 rotas