# Preparação para publicação Destino definido: Linux, domínio `investemoz.tempo.co.mz`. Os modelos Nginx, systemd e .env de produção estão em [deploy/linux](../../deploy/linux/README.md). Assumem `/var/www/investemoz`, utilizador `www-data` e PHP 8.5; adaptar os caminhos à distribuição e validar com nginx -t e systemd-analyze verify no servidor. Verificação local em 25/09/2026: suite PHP com 57 testes passou; os cinco testes operacionais foram repetidos após acrescentar a protecção transaccional da fila (26 verificações). Nenhum email real foi enviado. O diagnóstico confirmou ligação PostgreSQL, PostGIS e migrations aplicadas; produção, HTTPS, cookies seguros, desactivação de debug, remoção de public/hot do artefacto e correio real continuam como tarefas do servidor. Não foram alteradas estas definições de desenvolvimento. Não foi feita qualquer publicação nem activado o envio de emails. A conta pode ser configurada posteriormente em `/acesso-gestao`. ## Requisitos PHP compatível com composer.lock (>= 8.4.1), PDO PostgreSQL, PostgreSQL/PostGIS, Node compatível com package-lock.json para compilar assets, servidor HTTPS e processo permanente para a fila. Apontar o document root exclusivamente para `public`. Impedir acesso HTTP a `.env`, vendor, storage e restantes ficheiros. Dar escrita ao utilizador da aplicação apenas em storage e bootstrap/cache. ## Configuração do servidor Provisionar os segredos no servidor, sem os incluir no repositório: ```dotenv APP_ENV=production APP_DEBUG=false APP_URL=https://SEU-DOMINIO SESSION_SECURE_COOKIE=true DB_CONNECTION=pgsql QUEUE_CONNECTION=database PORTAL_NOTIFICATIONS_ENABLED=false PORTAL_NOTIFICATION_RECIPIENTS= ``` Definir APP_KEY, ligação PostgreSQL, PORTAL_MANAGER_EMAILS e correio SMTP com remetente autorizado. Manter a APP_KEY existente nas actualizações. Usar contas distintas para migrations e execução, conforme os privilégios definidos para o servidor. A configuração de proxy deve confiar apenas no proxy efectivamente usado. ## Instalação e actualização 1. Fazer backup PostgreSQL e dos ficheiros persistentes; ensaiar a recuperação numa instância separada. Guardar a versão anterior da aplicação. 2. Instalar dependências de produção com `composer install --no-dev --prefer-dist --optimize-autoloader`. 3. No ambiente de build, executar `npm ci` e `npm run build`. Publicar public/build; o artefacto de produção não deve incluir public/hot, node_modules nem .env local. 4. Na primeira instalação, gerar APP_KEY com `php artisan key:generate`. 5. Rever e executar `php artisan migrate --force`. Não executar migrate:fresh nem os seeders de demonstração em produção. 6. Executar `php artisan config:cache`, `php artisan route:cache` e `php artisan view:cache`. Reiniciar PHP/OPcache e `php artisan queue:restart`. 7. Executar `php artisan portal:readiness`. Corrigir os itens pendentes antes da publicação; o comando não apresenta credenciais nem altera registos. 8. Verificar `/up`, `/api/v1/home`, catálogo e login. Confirmar que utilizadores sem autorização recebem 403 nas rotas de gestão. Ensaiar emails com destinatário controlado antes de activar notificações públicas. ## Activação da biblioteca documental Para uma entrega que inclui o catálogo documental ou a análise antimalware, não usar uma migração global se existirem migrações pendentes não relacionadas. Fazer e validar primeiro um backup recuperável. Confirmar que a aplicação aponta para a base prevista e executar, nesta ordem, apenas as duas migrações desta entrega: ```sh php artisan migrate --path=database/migrations/2026_10_05_120000_extend_portal_document_catalogue.php --force php artisan migrate --path=database/migrations/2026_10_05_130000_add_document_malware_scanning.php --force php artisan portal:check-document-library-schema ``` O último comando tem de terminar com sucesso antes de disponibilizar o catálogo. As migrações mantêm os direitos anteriores como `unconfirmed` e as análises anteriores como `pending`; não marcar registos antigos como públicos ou limpos. Se a compatibilidade falhar, manter os controlos de publicação e análise e consultar o diagnóstico interno. O comando não altera dados. ## Notificações Definir PORTAL_NOTIFICATION_RECIPIENTS com emails da equipa separados por vírgulas. Activar PORTAL_NOTIFICATIONS_ENABLED apenas após testar SMTP. Esta opção é independente dos emails de verificação da conta enviados pelo Fortify. O registo de pedido e a inserção dos jobs usam a mesma transacção PostgreSQL. Manter DB_QUEUE_CONNECTION vazio (ligação por omissão) e after_commit=false na ligação database. Não usar uma base externa para jobs deste fluxo. Executar sob o supervisor do servidor: ```shell php artisan queue:work database --queue=default --sleep=3 --tries=3 --timeout=30 ``` O worker precisa de reiniciar automaticamente, guardar logs e ser reiniciado em cada release. Garantir timeout SMTP inferior ao timeout do worker e retry_after superior a 30 segundos. Consultar `php artisan queue:failed`; investigar a causa antes de repetir jobs com `php artisan queue:retry ID`. Uma repetição após entrega sem confirmação pode duplicar um email (entrega pelo menos uma vez). Desactivar a opção impede também o envio de jobs pendentes. Se os destinatários forem removidos, os respectivos jobs deixam de enviar. As notificações contêm apenas referência e ligação protegida; não incluem contactos nem mensagens. ## Histórico e recuperação `/management/history` mostra alterações efectuadas por gestores a partir desta versão. Os eventos e a alteração são gravados na mesma transacção. Reutiliza-se audit_events, protegido contra alterações e remoções; não há limpeza automática. Para entidades legadas bigint, o identificador fica em before_data/after_data.record_id; entity_id UUID fica nulo. Registam-se os campos alterados e valores operacionais permitidos, nunca textos livres, contactos ou palavras-passe. Este histórico cobre as acções de gestão, não alterações directas por SQL ou importações externas. Em incidente, desactivar notificações, colocar a aplicação em manutenção e reverter o código apenas se compatível com o esquema. Não executar rollback de migrations indiscriminadamente; recuperar backup só mediante plano validado. Monitorizar espaço em disco, jobs falhados, logs, HTTPS e backups. Testes PHPUnit devem usar exclusivamente bases descartáveis terminadas em `_test`.