361 lines
75 KiB
Markdown
361 lines
75 KiB
Markdown
# Transferência de Compras e actualizações do SGF
|
|
|
|
## Decisão de instalação — proposta sem execução, 02/11/2026
|
|
|
|
O âmbito escolhido pelo proprietário é **decidir a instalação, sem a executar**. A [decisão concreta](PURCHASING_INSTALLATION_DECISION.md) identifica projecto/base efectivos, candidata/hashes, schema/catálogos, bloqueantes e backup/restauro/recuperação. Os planos de leitura de código/schema passaram e o ZIP foi reconferido. O [inventário do destino](proofs/sgf-installation-decision-inventory.json) foi obtido em transacção PostgreSQL READ ONLY; nenhuma suite foi repetida.
|
|
|
|
**Recomendação: não instalar esta candidata como percurso operacional ainda.** O destino `C:\laragon\www\sgf-tempo`, base `sgf_tempo_dev` em `127.0.0.1:55432`, tem 87 tabelas e usa `sgf_dev_app`, sem CREATE/ALTER necessários. Faltam a execução migradora/mapa de privilégios mínimos runtime e a preparação operacional de centros/dotações: não existem tabelas `cb_*`, a interface candidata apenas selecciona centros existentes e a interface orçamental actual depende de duas tabelas ausentes do schema candidato. As provas isoladas com role proprietária/cadastros preparados não cobriam esses aspectos do destino. Preservar o ZIP aprovado como evidência e resolver essas lacunas antes de propor a operação executável; novos bytes exigem novos hashes/provas.
|
|
|
|
**Catálogo administrativo:** implementado/testado na candidata, ainda não instalado; não é falta de implementação, mas não constitui direitos já atribuídos. **Equipamentos/peças:** fora do recorte básico de consumíveis/serviços/outros, não são o seu bloqueio. Há uma concessão de administração da empresa no destino; a regra de dois administradores permanece pendente para entrega/activação, sem criar conta ou atribuir direitos por conveniência. A eventual instalação técnica desactivada é diferente de abrir o percurso aos utilizadores.
|
|
|
|
**Navegação modular: tecnicamente aceite em 02/11/2026**, conforme [registo próprio do SGF](../../sgf-tempo/docs/MODULAR_NAVIGATION_DELIVERY.md). Manter separadas revisão visual/recargas, associações antigas e volume/paginação. Essa aceitação não autoriza instalar a candidata, alterar direitos públicos ou publicar. O SGF continua em **0.1.1**. Não foram executados `migrate`, `apply`, `cache`, backups, concessões, manutenção ou paragem/reinício de serviços.
|
|
|
|
## Reconciliação com a entrega modular do SGF — 02/11/2026
|
|
|
|
A conferência documental posterior encontrou uma entrega própria de navegação modular no SGF: [implementação e estado](../../sgf-tempo/docs/MODULAR_NAVIGATION_DELIVERY.md), [conclusão técnica](../../sgf-tempo/docs/MODULAR_NAVIGATION_COMPLETION.md) e [conferência de 02/11/2026](../../sgf-tempo/docs/proofs/modular-navigation-recheck-20261102.json). Portanto, **a indicação anterior «sem resultado apresentado» fica sucedida por «entrega técnica documentada, com encerramento pendente»**. Não repetir implementação ou testes já registados com base naquele estado histórico.
|
|
|
|
Segundo essa entrega, os módulos são Comercial, Compras, Stock, Oficinas, Financeiro e Contabilidade; Início e Opções gerais estão separados do módulo activo. A entrega regista 185 testes/3.220 asserções de regressão, 8 testes/90 asserções focados e três perfis sintéticos num ambiente próprio. A conferência registada comparou 184 ficheiros com a cópia validada, confirmou hashes de JUnit e preservação de concessões/pertenças/auditoria/guarda/ponteiro, sem repetir testes ou provisionamento. Esta retoma de Compras **leu e reconciliou essas provas**, não executou novamente essa conferência nem as suites. Instância isolada documentada: `http://127.0.0.1:8039`.
|
|
|
|
Continuam separados: [revisão visual pendente](../../sgf-tempo/docs/MODULAR_NAVIGATION_VISUAL_REVIEW.md), incluindo recargas de páginas autónomas; reconciliação humana das associações antigas; avaliação de volume/paginação antes de implantação. A interface usa «Opções gerais», não um submenu único literalmente chamado «Configuração». Não declarar aceitação visual, cobertura operacional dos módulos em preparação ou disponibilização comercial integral.
|
|
|
|
Esta entrega modular não instala a candidata de requisições nem substitui as suas provas de código/schema/caches. A integração candidata continua preparada e verificada no âmbito descrito abaixo; o SGF de destino permanece em 0.1.1. **Não houve instalação, activação, alteração de código/permissões ou nova tentativa de navegador nesta reconciliação.** A decisão de instalar continua separada, conforme instrução do proprietário.
|
|
|
|
## Actualização entre bundles e caches nativos — 02/11/2026
|
|
|
|
**Concluído neste incremento candidato:** transição de código entre bundles já instalados, reversão para o anterior e compilação/recuperação dos caches Laravel nativos. **32 controlos novos aprovados**, sem repetir as suites anteriores. Prova e hashes em [proofs/sgf-update-cache-delivery.json](proofs/sgf-update-cache-delivery.json). A candidata é `OPERATIONAL-CANDIDATE-5fae7cf7f99c42ba`, com [ZIP de revisão](../storage/app/private/candidate-archives/OPERATIONAL-CANDIDATE-5fae7cf7f99c42ba.zip); SHA-256 do ZIP `d14a3261d5aaab80f96250af781c700ab53376021f4638e3aee43c15ff37ceed` e do manifesto `b1ec47f7a9ad87e0b232bac41e402d4a00ee5f03f00a79b93effc692ce8b39a2`. Não foi publicado no canal, instalado ou activado no destino. SGF mantém **0.1.1**.
|
|
|
|
As pendências históricas de transição entre versões e ensaio dos caches padrão, registadas nas secções seguintes, são sucedidas por este resultado. Não se altera o âmbito das provas anteriores nem se declara concluída a reorganização modular do SGF.
|
|
|
|
### Transição com proveniência local
|
|
|
|
`plan` reconhece a versão de código seleccionada pelo registo privado `storage/app/private/module-deployments/current.json`, distinto do ponteiro `packages/purchasing/current.json` que permanece intacto. Confere o journal, os bytes e o manifesto do bundle instalado; rejeita alterações locais, conteúdo extra, bundle sem proveniência, mudança de baseline/composição dos ficheiros nativos ou diferenças nos ficheiros de preparação do schema/catálogo. A transição implementada cobre código sob o **mesmo contrato de schema**. Alterar esse contrato exige plano/revisão de migração próprios; não executa uma migração implicitamente.
|
|
|
|
`apply` guarda o bundle anterior na instalação, troca o código sob manutenção/serviços parados e actualiza atomicamente o registo privado da versão seleccionada. `rollback` repõe o bundle, ficheiros nativos e proveniência anteriores, sem depender da pasta de Compras, base de desenvolvimento ou ficheiros da origem. Recusa reversão fora de ordem e replay de uma versão que já não está seleccionada. Uma nova tentativa depois de uma reversão recebe outro ID; os journals anteriores permanecem preservados. A repetição de uma reversão já concluída não volta a alterar código/caches da versão anterior.
|
|
|
|
O registo privado é criado pela rotina actual. Uma cópia antiga/manual de bundle, sem esse registo, não é adoptada automaticamente: exige reconciliação explícita da proveniência. Este requisito preserva os ficheiros existentes e não atribui direitos funcionais. Continua a não haver outorga automática, alteração do perfil ou importação de dados de desenvolvimento.
|
|
|
|
### Compilação nativa e recuperação de caches
|
|
|
|
A CLI tem agora a acção `cache`, que usa o mesmo PHP fixado para executar **`config:cache`, `route:cache` e `event:cache` no próprio host**, com manutenção/serviços parados. Arquiva os caches anteriores em armazenamento privado, invalida-os antes de arrancar Artisan e regista comandos/resultado/hashes dos ficheiros produzidos, incluindo resultados parciais quando uma compilação falha. Assim, um `config.php` truncado não impede a CLI de o preservar e reconstruir a configuração a partir das fontes actuais. Os logs e cópias compiladas ficam privados e não são incluídos no ZIP cliente.
|
|
|
|
Se tiver havido compilação registada, a reversão invalida esses caches e conserva-os em arquivo privado; não repõe silenciosamente valores compilados antigos sobre configuração posterior. Depois de repor o bundle anterior, executar `cache` para o ID dessa versão e reiniciar os seus serviços antes de reabrir. Se não tiver havido recompilação, mantém-se a reposição exacta dos caches anteriores já ensaiada. Alterações aos caches após a compilação registada continuam a bloquear uma reversão cega e exigem reconciliação. Caches com caminhos personalizados continuam fora do contrato actual e são recusados antes de aplicação/recuperação.
|
|
|
|
```text
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-code-deploy.php" plan "<raiz-SGF>" "<candidata>" <manifest-sha256>
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-code-deploy.php" apply "<raiz-SGF>" "<candidata>" <manifest-sha256> <target-codigo-sha256> "<operador>" --offline
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-code-deploy.php" cache "<raiz-SGF>" <deployment-id-seleccionado> "<operador>" --offline
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-code-deploy.php" rollback "<raiz-SGF>" <deployment-id-a-reverter> "<operador>" --offline
|
|
```
|
|
|
|
Para uma actualização: conferir a origem aprovada, os hashes e o plano; preservar o destino e parar os serviços em manutenção; aplicar o bundle; compilar os caches para o ID devolvido; reiniciar apenas os serviços dessa instalação e conferir o seu arranque; reabrir só pela decisão de activação separada. Para reverter: parar serviços em manutenção, reverter o ID seleccionado, compilar os caches da versão anterior reposta e reiniciar/conferir antes de reabrir. Dados/schema/permissões não são restaurados por estes comandos. A preparação de schema continua no executor separado, apenas quando houver uma migração prevista e ensaiada.
|
|
|
|
### Âmbito exacto das novas provas
|
|
|
|
Ensaiada transição real entre a candidata anterior `10dce6cd57fa1f31` e a nova, recuperação de falha entre preservação/troca dos bundles, reversão e nova tentativa com histórico distinto. Confirmadas recusas de origem desconhecida, schema divergente, alteração local/conteúdo extra e reversão fora de ordem. A segunda cópia inclui aplicação e dependências, sem `.env` ou dados reais; para acelerar o ensaio, as dependências imutáveis usam hardlinks **apenas para uma cópia descartável anterior**, nunca para o vendor do SGF de destino. Não se executam comandos Composer que alterem essas dependências.
|
|
|
|
Na cópia isolada foram executados os três comandos de cache nativos, falha injectada após `config:cache`, recuperação de cache inválido pela CLI e reinícios efectivos do servidor PHP local de teste. A rota em cache manteve autenticação (401 para anónimo), manutenção manteve bloqueio (503) e o host voltou a responder após reversão, sem a rota retirada (404) e com healthcheck 200. Os reinícios cobrem o servidor de teste, **não certificam todos os gestores de serviços de clientes**. Nenhum serviço, base, direito público ou ponteiro do SGF de destino foi alterado. Nenhuma contratação para terceiros foi incluída.
|
|
|
|
O ZIP contém código/manifesto locais com integridade conferida, sem base, credenciais, documentos, cache de cliente ou dependências copiadas de desenvolvimento. Pode ser transportado e extraído para uma pasta de preparação no cliente; conferir hashes e executar as ferramentas pelo PHP do próprio SGF. Não extrair directamente sobre a raiz do host. A aprovação do canal de confiança e a decisão de instalar/activar continuam separadas; a preparação do ZIP não é publicação ou autorização de implantação.
|
|
|
|
## Aplicação e reversão offline do código — 02/11/2026
|
|
|
|
Implementadas `integrations/sgf/operational/CodeDeployment.php` e CLI `scripts/sgf-code-deploy.php`, incluídas na candidata `OPERATIONAL-CANDIDATE-10dce6cd57fa1f31`. **42 controlos novos aprovados** com PHP 8.4.27 fixado do SGF, apenas sobre cópias descartáveis de ficheiros; sem abrir bases, reiniciar serviços ou repetir suites anteriores. Ver [proofs/sgf-code-deploy-delivery.json](proofs/sgf-code-deploy-delivery.json). O SGF instalado continua em **0.1.1** e nenhuma aplicação/reversão foi executada nesse destino.
|
|
|
|
A rotina distingue `plan` read-only, `apply` e `rollback`. Confere manifesto e conteúdo, hashes anteriores dos ficheiros do host e impressão do destino, mantém lock exclusivo e prepara cópias anteriores em `storage/app/private/module-deployments/<id>`. O journal durável é escrito antes de começar a substituir código; cada ficheiro é preparado e trocado por rename no seu directório e o bundle é preparado separadamente antes da troca. **Isto não é uma transacção de filesystem sobre todos os ficheiros:** a consistência visível exige manutenção e serviços de escrita parados durante toda a implantação/recuperação. Uma interrupção deixa o journal para recuperação explícita, sem reabrir o serviço automaticamente.
|
|
|
|
`apply` exige manutenção Laravel baseada em `storage/framework/down` e `--offline`, que é a declaração do operador de que parou web/workers/schedulers responsáveis por escritas. A rotina não detecta nem termina processos. Guarda os caches padrão `config.php`, `events.php`, `packages.php`, `services.php` e `routes*.php` existentes em `bootstrap/cache`, invalida-os e preserva outros ficheiros. Os backups de configuração compilada podem conter segredos e ficam exclusivamente no armazenamento privado local, com permissões restritas do sistema; não integram o artefacto distribuído. Caches configurados por `APP_*_CACHE` fora das localizações padrão são recusados antes da aplicação: não são apagados nem presumidos cobertos.
|
|
|
|
`rollback` confere código, backup e caches antes de restaurar; recusa alterações locais desconhecidas e caches recriados, em vez de sobrescrever trabalho ou configuração posterior. Repõe os bytes anteriores dos ficheiros/caches e retira o bundle para arquivo privado de diagnóstico. Recupera igualmente aplicação interrompida a meio dos ficheiros ou depois da troca do bundle. Não apaga schema, dados, recibos de negócio, permissões ou operações posteriores. Conserva o ponteiro `packages/purchasing/current.json` e deixa manutenção activa. A existência de `restart_required=true` é uma obrigação operacional, não prova de reinício automático.
|
|
|
|
### Sequência de implantação, após decisão separada
|
|
|
|
1. Produzir/conferir a candidata e manifesto por canal de confiança. Executar `plan` de schema e `plan` de código e registar as duas impressões de destino. Conferir o destino e preservar dados/documentos/configuração. A rotina de código não substitui o backup/restauro de PostgreSQL.
|
|
2. Entrar em manutenção pelo procedimento do host (`artisan down`, driver de ficheiro) e parar os serviços de escrita daquela instalação. Não usar comandos de demonstração que também parem outras instalações. Não executar `apply` com serviços em funcionamento.
|
|
3. Executar a preparação de schema `sgf-internal-install.php migrate`, com backup/manifesto/destino conferidos, conforme secção própria. Nenhuma concessão é atribuída por essa preparação.
|
|
4. Executar `sgf-code-deploy.php apply` com o hash do manifesto, impressão do plano de código, operador nominativo e `--offline`. Registar `deployment_id`. A rotina confere e aplica apenas código/bundle e invalida caches conhecidos; não activa configuração comercial nem concede direitos.
|
|
5. Mantendo a manutenção, conferir os ficheiros e o journal, configurar explicitamente o destino/âmbitos e os acessos aprovados pelo percurso administrativo, e reiniciar os processos persistentes pelo gestor de serviços daquela instalação para descartar código/opcache antigo. A atribuição administrativa que requer HTTP terá de usar uma janela controlada depois do arranque; não contornar os middlewares nem inserir concessões por SQL para evitar essa etapa. Remover a manutenção e abrir aos utilizadores só depois de conferir a instalação e da decisão de activação. Estas acções de serviços/configuração/abertura são do operador e não são executadas pela CLI.
|
|
6. Em falha de código, manter/parar novamente os serviços em manutenção, executar `rollback` com o ID registado, conferir a reposição, reiniciar os serviços e só então decidir reabrir. Se houver código ou caches alterados depois da aplicação, a rotina recusa a recuperação: preservar esses estados e reconciliar explicitamente antes de tentar novamente. Não executar `down` de migrações nem restaurar backup de dados por efeito de rollback de código.
|
|
|
|
CLI pelo PHP fixado do host; exemplos com parâmetros, **não executados no SGF de destino**:
|
|
|
|
```text
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-code-deploy.php" plan "<raiz-SGF>" "<candidata>" <manifest-sha256>
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-code-deploy.php" apply "<raiz-SGF>" "<candidata>" <manifest-sha256> <target-codigo-sha256> "<operador>" --offline
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-code-deploy.php" rollback "<raiz-SGF>" <deployment-id> "<operador>" --offline
|
|
```
|
|
|
|
**Limites exactos:** esta versão cobre primeira instalação sobre o baseline conferido e recusa um bundle já existente ou ficheiros nativos divergentes. Ainda não implementa transição entre versões do novo bundle; o updater anterior de código 0.1.1 conserva apenas o seu âmbito já demonstrado. Os controlos de caches deste incremento verificam invalidação e restauro byte a byte dos ficheiros padrão, não regeneração de todos os caches em Laravel nem automação de gestores de serviços. A prova HTTP anterior de 27 controlos mantém o seu âmbito; não foi repetida sobre cada combinação de caches. Não declarar disponibilização comercial completa nem aceitar actualizações futuras sem a respectiva transição/compatibilidade. A reorganização modular permanece entrega distinta.
|
|
|
|
## Arranque e integração HTTP em cópia isolada — 02/11/2026
|
|
|
|
Preparada a candidata `OPERATIONAL-CANDIDATE-4b25f81932efd69d`, preservando os artefactos anteriores. A composição já inclui sobreposição do provider nativo para carregar o bundle local e registar as rotas, sem registo manual de rotas pelo harness HTTP. O bundle fica em `packages/internal-requisitions`, com classes e ficheiros próprios; a sobreposição do SGF reconhece `purchasing_requisitions.view` como autorização de descoberta do módulo Compras, sem conceder direitos nem substituir o catálogo/controlo funcional.
|
|
|
|
`RuntimeContext` é acrescentado às rotas do bundle **depois** dos middlewares nativos de sessão/autenticação/empresa. Confere opção operacional habilitada, destino/schema/âmbito, módulos adquiridos e habilitados, selecção explícita de Compras e geração de contexto nos APIs. A atribuição inicial permanece no âmbito de Administração: não exige um direito funcional de requisição que ainda não foi outorgado, mas exige módulo adquirido, âmbito habilitado e os controlos nominativos/administrativos já implementados. Não cria autoridade a partir da selecção do módulo. A composição desactivada recusa a execução das rotas.
|
|
|
|
O ensaio `scripts/sgf-composition-proof.php` usa uma instalação descartável com código, dependências e packages **copiados**, provider/configuração/rotas do próprio SGF e bootstrap nativo, sem `.env`, contas, documentos ou dados empresariais copiados. Usa base `sgc_composition_<12hex>` e role próprias, ambiente `production`, sessões privadas e acesso HTTP loopback com login/CSRF reais. A preparação de dados sintéticos e a activação ocorrem exclusivamente nessa cópia/base; não são passos aplicados ao SGF de destino. O router de teste só entrega o pedido ao kernel: não regista rotas, não substitui autenticação e não carrega classes da instalação original.
|
|
|
|
Resultados efectivos, caminho do artefacto e verificações em [proofs/sgf-composition-delivery.json](proofs/sgf-composition-delivery.json). A prova verifica o incremento de composição/HTTP, incluindo autoridade inicial, administração nativa, contexto, submissão/reserva/aprovação/consulta e revogação; não repete as suites anteriores nem declara revisão visual por navegador. Os resultados históricos seguintes conservam o seu âmbito.
|
|
|
|
**Resultado final: 27 controlos novos aprovados.** Confirmados provider e adaptador efectivamente carregados da cópia isolada; `plan` aceite pelo verificador de integridade do novo bundle; acesso anónimo e CSRF bloqueados; autoridade inicial sem direitos funcionais prévios; atribuição pela administração nativa; selecção explícita de Compras; recusa de token antigo, modalidade diferente, revogação, módulo não adquirido e composição desactivada; rascunho → submissão com uma reserva existente → aprovação por outra identidade → consulta com três versões/eventos. Base e role descartáveis removidas. Nenhum registo de dados ou direito do SGF de destino alterado.
|
|
|
|
**Limites de entrega:** esta composição ainda não foi aplicada ao destino. Falta a rotina operacional de aplicação atómica das sobreposições/código, preservação/reversão dos ficheiros do host e gestão dos caches/reinício de serviços. O ensaio usa configuração sem cache; não declara validada a activação com cache de rotas/configuração pré-existente. As alterações de configuração da prova foram seguidas de reinício do serviço PHP. `plan`/`migrate` continuam a preparar/conferir schema, sem aplicar estas sobreposições ou activar rotas. Não substituir esse procedimento por extracção cega do bundle. SGF de destino mantém **0.1.1**, sem schema, permissões, provider ou rotas alterados. Activação continua dependente da decisão separada. A reorganização modular posterior é uma entrega distinta, não concluída por este incremento.
|
|
|
|
## Objectivo e estado em 01/11/2026
|
|
|
|
O foco autorizado pelo proprietário é transferir as capacidades de Compras para o SGF e levar as melhorias seguintes por versões verificáveis. Não é sincronizar bases de desenvolvimento nem manter duas implementações. O SGC autónomo conserva todas as suas funcionalidades; no SGF, Pessoas e contratações destina-se apenas ao uso interno. Cada cliente recebe as capacidades adquiridas, com configuração e permissões próprias.
|
|
|
|
**Implementado neste incremento:** mecanismo de publicação/instalação/actualização/reversão e primeira capacidade realmente extraída e executada no SGF: projecção de reposição de stock. **A transferência integral dos processos, ecrãs, identidade e dados de negócio ainda não está concluída.**
|
|
|
|
**Conferência antes de ampliar, 01/11/2026:** a prioridade passa a ser esta matriz e a delimitação de instalação/reversão, conforme pedido posterior do proprietário. SGF local activo em `0.1.1`. O núcleo económico começou a ser preparado antes desse pedido; a transferência em curso foi interrompida antes de nova activação. Existe candidata `0.1.2` no canal, sem instalação no SGF. Código preparado na origem não conta como capacidade transferida.
|
|
|
|
**Actualização posterior autorizada:** percurso de requisição interna implementado como candidata de revisão `IR-CANDIDATE-bfa807e2b3c4fae7`, testada sem activar o destino. A matriz abaixo distingue essa implementação candidata da capacidade instalada. Ver detalhes, recuperação e limites na secção do percurso escolhido.
|
|
|
|
## Fonte única e fronteira dos dois hosts
|
|
|
|
`packages/purchasing` em Compras é a fonte canónica. `App\Services\ReplenishmentProjection` passou a fachada de compatibilidade; os consumidores actuais conservam a assinatura e usam o motor comum `Tempo\Purchasing\Supply\ReplenishmentProjection`. O SGF carrega os mesmos bytes de uma pasta de versão instalada. Não há chamada HTTP a Compras, procura da pasta vizinha, segundo algoritmo ou alteração das dependências instaladas.
|
|
|
|
As diferenças concretas que impedem uma cópia directa da aplicação permanecem: SGF usa tenant/empresa fiscal/unidade e concessões/contexto próprios, enquanto Compras usa tenant/departamento e perfis; ambos têm classes `App` e tabelas-base com significados diferentes. Os frontends e versões de PHP/Brick Math também diferem. Não copiar os controladores, tabelas `users`/`tenants` ou histórias de migração de um host para o outro. Extrair capacidades e adaptar contexto/acesso explicitamente.
|
|
|
|
## Matriz de integração conferida
|
|
|
|
Estados: **Transferido** identifica a capacidade exacta instalada e executada no SGF; **Parcialmente transferido** identifica componentes comuns existentes, com lacunas no percurso; **Pendente** identifica capacidades ainda não incorporadas no SGF. A presença de um menu, cálculo ou classe não comprova transferência do processo completo. Capacidades excluídas do SGF são identificadas à parte.
|
|
|
|
| Processo/capacidade | Estado | Núcleo e persistência | Adaptadores de identidade/acesso e integração | Ecrãs e percurso no SGF | Evidência/lacuna determinante |
|
|
| --- | --- | --- | --- | --- | --- |
|
|
| Publicação, instalação e actualização de código do pacote | **Transferido** | Artefactos imutáveis, hashes, lock, histórico e ponteiro local; sem schema | CLI local e prova com PHP do host; sem alteração de direitos | CLI implementada; painel de updates não implementado | `0.1.0/0.1.1`, retry e rollback de código conferidos; migrações e canal remoto assinado pendentes |
|
|
| Cálculo de projecção de reposição | **Transferido** | Mesmo motor de consumo manual, média racional, reservas/entregas e lotes; sem persistência própria | Carregamento local independente do checkout de Compras; não concede acesso a dados | Sem novo ecrã; capacidade de cálculo instalada | Pacote activo `0.1.1`, dois testes SGF e prova de cliente independente |
|
|
| Orçamento de Compras no núcleo comum | **Parcialmente transferido** | `packages/budget-control` comum anterior; mesmo motor de reserva | Composição operacional candidata com destino/schema/âmbito explícitos; adaptador instalado continua QA | Interface anterior e candidata de requisições; arranque/rotas operacionais ainda não integrados | 20 controlos novos de preparação; restauro em production/base fora do prefixo QA verificado; sem instalação/activação no destino |
|
|
| Preparação de schema da integração | **Parcialmente transferido — candidata não instalada** | Migração transaccional, contrato do orçamento, registo imutável de revisão/hashes/operadores/backup | CLI `plan`/`migrate` local ao host, sem cópia de dados sintéticos ou concessões | Sem ecrã ou activação implícita; CLI de preparação não substitui instalação de código/rotas | Prova nova `sgf-operational-delivery.json`; destino 0.1.1 preservado |
|
|
| Aplicação/actualização/reversão do código da nova integração | **Parcialmente transferido — candidata não instalada** | Journal/backups e registo privado da versão, lock, preservação do bundle anterior; sem efeitos de dados/schema | CLI `plan/apply/cache/rollback`, com proveniência e contrato de schema iguais; serviços parados pelo operador | Transição, falhas e reversão ensaiadas; caches nativos compilados e servidor isolado reiniciado; nenhuma abertura automática no cliente | 32 controlos novos em `sgf-update-cache-delivery.json`, além das provas anteriores; caches personalizados e migrações futuras exigem plano próprio; destino 0.1.1 |
|
|
| Factura conferida → obrigação a fornecedor | **Parcialmente transferido** | Núcleo comum de obrigações anterior, com origem única | Adaptador SGF e API no âmbito sintético; sem passagem automática de tabelas/IDs de Compras | Consulta/decisão do percurso anterior; sem workflow integral de recepção/conferência de facturas de Compras | `SupplierPayables` conserva guarda de ensaio; fornecedor de histórico SGF não concluído conforme entregas anteriores |
|
|
| Pagamentos e afectações a fornecedores | **Parcialmente transferido** | Núcleo comum e entregas anteriores preservados | Adaptadores/autorizações delimitados nas respectivas entregas; não representam migração de contas ou histórico de cliente | Percurso anterior existe no âmbito documentado; integração completa com novas origens de Compras pendente | `SUPPLIER_SETTLEMENT_DELIVERY.md` e limites de histórico/origens; não afirmar financeiro integral |
|
|
| Identidade, empresa/unidade, perfis e módulos adquiridos | **Parcialmente transferido** | Fundações próprias existentes nos dois hosts; não se fundiram tabelas-base | SGF mantém tenant/empresa fiscal/unidade/concessões; correspondência explícita com o contexto Purchasing por concluir | Sessão/contexto SGF existentes; selector SGC não foi incorporado automaticamente | Sem associação por igualdade de nome, email ou ID; parametrização comercial e permissões continuam distintas |
|
|
| Navegação modular do SGF, entrega própria | **Tecnicamente aceite — 02/11/2026** | Seis módulos, Início/Opções gerais separados; não equivale a todos os processos comerciais concluídos | Provas SGF próprias de contexto, autorização e perfis sintéticos; sem outorga adicional por escolha de módulo | Revisão visual/recargas, associações antigas e volume/paginação mantêm pendências próprias | Aceitação expressa em `MODULAR_NAVIGATION_DELIVERY/COMPLETION`; 185 testes/3.220 asserções preservados; não autoriza a instalação da candidata |
|
|
| Requisição interna: rascunho, submissão, aprovação independente e consulta | **Parcialmente transferido — candidata; não activa** | Motor único `InternalRequisitions`, adaptadores dos dois hosts; recibos, versões e histórico; reserva existente na mesma transacção | Contexto interno, empresa/unidade, autorização renovada e identidade independente; composição no provider e associação do novo direito de consulta ao módulo preparadas | Ecrãs e percurso integrados na cópia isolada pelo arranque nativo; nenhuma rota/menu novo activo no destino | Provas anteriores preservadas; novo ensaio de composição HTTP em `sgf-composition-delivery.json`; aplicação operacional do código/caches e equipamentos/peças pendentes; destino 0.1.1 |
|
|
| Planeamento de compras | **Pendente** | Itens, marcos e associação a requisições permanecem em Compras | Adaptar unidades, centros, intervenientes e vínculos de origem no SGF | Planeamento e acompanhamento de marcos SGF do roteiro de Compras pendentes | Não gerar requisições duplicadas nem inferir reserva/decisão a partir de um plano |
|
|
| Fornecedores, documentos e dados bancários | **Pendente** | Cadastros/versionamento de Compras ainda não extraídos | Definir correspondências autorizadas de fontes e permissões, sem fundir entidades por nome | Cadastro, validações e consulta SGF de todo o percurso pendentes | Preservar fotografias utilizadas e validação bancária independente |
|
|
| Cotações, descontos e comparação económica | **Pendente** | Descontos e pontuação foram preparados na origem/candidata `0.1.2`; SGF activo não contém estas classes | Elegibilidade, conflitos, avaliações autorizadas e decisão continuam no host; adaptador do processo SGF não implementado | Recepção de cotações, grelha, empates, recomendação e decisão SGF pendentes | Testes locais não equivalem a transferência. Candidata não instalada; nenhuma adjudicação automática |
|
|
| Abertura, admissibilidade, qualificação, recomendação e adjudicação | **Pendente** | Serviços/snapshots permanecem em Compras | Traduzir contexto, atribuições, impedimentos e versões sem alterar decisões concluídas | Actas, avaliações, decisões e ordens ainda não incorporadas | Necessita persistência e percurso completo por etapa, não simples ligação de menus |
|
|
| Ordens, recepções, inventário físico e lotes | **Pendente** | O cálculo de reposição está transferido; movimentos, ledger físico, decisões e reversões não | Adaptar origens únicas, armazéns/artigos, separação de funções e âmbito empresarial | Guias, recepções, saídas, transferências, contagens e lotes SGF de Compras pendentes | Não duplicar efeitos físicos ou confundir projecção com stock disponível |
|
|
| Fornecimento habitual, sugestões e importações | **Parcialmente transferido** | Apenas o motor de projecção incorporado; acordos, políticas versionadas, conversões e logística pendentes | Fontes, decisões, cadastros e vínculos aos processos SGF ainda por adaptar | Calendário, sugestão → requisição e importação operacional SGF pendentes | Um cálculo disponível não completa o workflow de abastecimento |
|
|
| Equipamentos, peças, manutenção e investimento | **Pendente** | Serviços/cadastros de Compras ainda não incorporados | Correspondência de activos/peças/unidades e regras aprovadas por definir tecnicamente | Ecrãs/percursos de Compras no SGF pendentes | Preservar origens e não repetir consumo físico/custo |
|
|
| Avaliação de fornecedores, melhoria e contraditório | **Pendente** | Versionamento, decisões e evidências permanecem em Compras | Adaptadores de intervenientes, conflitos e autorização independente pendentes | Preparação, revisão, acompanhamento e relatórios SGF pendentes | Não alterar avaliações antigas nem confundir qualificação com desempenho |
|
|
| Relatórios de Compras e sínteses factuais | **Pendente** | Projecções autorizadas de Compras ainda não extraídas | Reutilizar âmbito efectivo e versões do processo no SGF | Relatórios individuais/consolidados do roteiro de Compras pendentes | Não substituir por relatórios financeiros SGF de outro âmbito; núcleo factual independente de IA |
|
|
| Venda de mercadorias e ligação ao comercial SGF | **Pendente** | A opção de contexto não é um percurso completo de retalho/grosso demonstrado em Compras | Reutilizar responsabilidades de stock/facturação SGF, sem criar motores ou efeitos concorrentes | Percurso conjunto por módulos adquiridos ainda por demonstrar | Não confundir aquisição para revenda com venda efectuada nem declarar emissão fiscal transferida |
|
|
| Pessoas: recrutamento e prestadores internos | **Pendente** | Processos e versões ainda em Compras; fronteira técnica de RH apenas preparada | Adaptar perfis/atribuições e integração futura com RH; apenas contrato formalizado pode desencadear ligação | Candidaturas, avaliações, decisões e formalização/RH no SGF pendentes | RH ainda não implementado; selecção aprovada/rascunho não criam vínculo |
|
|
|
|
**Fora do âmbito SGF:** recrutamento e contratação de prestadores por conta de terceiros. Mantêm-se no SGC autónomo; não são uma pendência a implementar no SGF. Não transferir candidaturas automaticamente para Compras, vendas ou RH.
|
|
|
|
### Percurso escolhido e candidata de requisições internas
|
|
|
|
O proprietário autorizou **requisição interna → submissão → aprovação independente → consulta do processo**, usando a reserva orçamental existente. A implementação está preparada separadamente para revisão. **O SGF continua em 0.1.1; nem a candidata económica 0.1.2 nem esta integração foram activadas.** Não foram publicados pacotes nem alterados direitos públicos.
|
|
|
|
O motor `packages/purchasing/src/InternalRequisitions.php` é usado pelo adaptador autónomo `app/Services/InternalRequisitionPort.php` e pela candidata `integrations/sgf/internal-requisitions`. Conserva as regras de valores, limites, reserva antes da submissão e decisão por identidade diferente do requerente e dos decisores anteriores. O adaptador SGF reutiliza `CompanyContext`, `Permissions` e `BudgetAdapter`; não copia utilizadores, empresas ou o motor orçamental.
|
|
|
|
A candidata inclui rascunho/edição, listagem, submissão, decisão e consulta com histórico, além de parametrização versionada de centros/departamentos/intervenientes/limites. Apenas centros e pessoas autorizados do host podem ser associados. A configuração habilita a opção interna; não atribui permissões. O servidor volta a validar direitos e contexto em cada operação, incluindo repetições, e projecta as acções disponíveis para os ecrãs. Chave de operação, hash do conteúdo, versão esperada, locks e transacção única preservam origem e impedem duplicação de requisições/reservas em retry e concorrência. Uma falha mantém a transacção anterior; uma resposta perdida admite a repetição da mesma operação.
|
|
|
|
Os artefactos de revisão são produzidos por `php scripts/build-internal-requisition-candidate.php`. O manifesto, hashes e caminhos estão em [proofs/internal-requisitions-candidate.json](proofs/internal-requisitions-candidate.json). `runtime.zip` contém código e schema explicitamente não instaláveis pelo updater actual; `verification.zip` contém as provas. Não levam bases, dados sintéticos, credenciais, dependências ou concessões. O caminho do SGF serve apenas para preparar/verificar; o runtime candidato utiliza ficheiros locais e serviços do próprio host. A futura instalação exige uma entrega compatível com schema, separada da activação do ponteiro de código.
|
|
|
|
**Limitações da candidata:** SGF suporta neste recorte consumíveis, serviços e outros; equipamentos/peças e respectivas validações técnicas continuam apenas no percurso autónomo. Fornecedores, cotações, ordens e recepções não foram incorporados por arrasto. As rotas/ecrãs só são carregados pelo bootstrap explícito das provas; não há novo menu activo no destino. A integração do catálogo privado de permissões na administração comercial, a instalação/migração operacional e a parametrização comercial integral permanecem pendentes. A guarda isolada do adaptador orçamental SGF foi preservada. Não há integração de contratações para terceiros nem activação de RH.
|
|
|
|
### Classificação das pendências para decidir a instalação
|
|
|
|
**Incremento posterior de preparação dos acessos:** o catálogo e a autoridade inicial já têm implementação candidata em `integrations/sgf/access`, preparada separadamente em `ACCESS-CANDIDATE-a69f06e21747228a`. Prova [proofs/sgf-access-delivery.json](proofs/sgf-access-delivery.json): **24 controlos novos**, em PostgreSQL descartável, sem repetir as suites aprovadas da requisição. O SGF instalado continua com o catálogo anterior. As classificações abaixo mantêm-se bloqueantes **até integrar e instalar** esta preparação com o orçamento/schema/arranque operacionais; não significam ausência de implementação candidata.
|
|
|
|
Conferência de código posterior à entrega, sem repetir testes aprovados e sem alterar a candidata congelada ou a instalação SGF. **A candidata comprova o percurso em ensaio isolado; ainda não é uma entrega operacional instalável.**
|
|
|
|
| Pendência | Classificação para este percurso | Impacto e condição de resolução |
|
|
| --- | --- | --- |
|
|
| Equipamentos/peças e validações técnicas | **Fora do âmbito** do percurso básico entregue | O adaptador SGF aceita `consumable`, `service` e `other`. Estas requisições podem completar rascunho → submissão/reserva → aprovação → consulta sem equipamentos/peças. Uma necessidade de equipamento/peça continua sem percurso SGF suportado; não deve ser disfarçada como `other`. A classificação não declara suporte a todos os tipos de requisição. |
|
|
| Catálogo administrativo das novas permissões e sua gestão | **Bloqueante para este percurso em utilização operacional** | `Permissions::UNIT` contém apenas `unit.view` e `unit.edit`; `IdentityWorkflow::accessList/changeAccess` filtra/valida esse catálogo. Os direitos `purchasing_requisitions.*` não podem ser atribuídos/revogados pela administração normal. As concessões directas dos testes foram apenas sintéticas e não constituem configuração comercial entregue. |
|
|
| Autoridade inicial para gerir/outorgar os novos direitos | **Bloqueante para este percurso em utilização operacional** | `changeAccess` exige que quem concede já possua o direito concedido. Acrescentar nomes ao catálogo não resolve a atribuição inicial: é necessária entrega nominativa, explícita e auditada da autoridade aprovada pela empresa, sem outorga automática aos perfis actuais. A listagem e revogação de direitos derivados da unidade também devem abranger o catálogo integrado. |
|
|
| Adaptador orçamental operacional | **Bloqueante para este percurso em utilização operacional** | `BudgetAdapter::guard()` exige ambiente `budget-testing`, PostgreSQL local e base `budget_core_sgf_<12hex>`. O adaptador de requisições chama essa guarda inclusive na consulta/configuração. Não basta copiar ficheiros ou permitir requisições sem orçamento. Substituir a composição exclusiva de ensaio por composição operacional configurada, mantendo autorização, isolamento e motor comum; não renomear base real nem mudar o ambiente para contornar a guarda. Os direitos orçamentais necessários também não integram o catálogo administrativo actual. |
|
|
| Instalação/migração, arranque e encaminhamento das rotas | **Bloqueante para este percurso em utilização operacional** | `Schema::install` e bootstrap existem, mas só foram compostos no harness isolado. Falta instalador operacional com pré-condições, registo de migração e recuperação, composição local e registo controlado de rotas. O updater actual recusa esta candidata; não é possível instalar o percurso com o comando habitual de update de código. |
|
|
| Fornecedores, cotações, ordens, recepções e contratações para terceiros | **Fora do âmbito** desta entrega | Não são necessários para terminar a requisição no estado aprovado e consultá-la; contratação para terceiros permanece excluída do SGF. |
|
|
|
|
**Direitos que a instalação deve permitir gerir, sem os conceder implicitamente:** por empresa/unidade, `purchasing_requisitions.view`, `.prepare`, `.configure`, `.approve.department_head`, `.approve.procurement` e `.approve.finance`. Mantêm-se `company.view`, pertença à empresa e `unit.view` como condições do contexto. Submeter com reserva exige ainda `purchasing_budget.record`; rejeitar com libertação também usa esse direito existente. Preparação/aprovação da dotação usa os direitos do orçamento existente e deve ter responsáveis expressamente configurados. Só os escalões aplicáveis à política precisam de decisores, sempre com identidades distintas do requerente e dos decisores anteriores. Não é necessário conceder todos os direitos a todos os utilizadores.
|
|
|
|
#### Implementação candidata do catálogo e autoridade inicial
|
|
|
|
`php scripts/prepare-sgf-access.php <raiz-SGF>` lê os dois ficheiros de identidade do host e produz uma sobreposição de revisão em `storage/app/private/candidates/ACCESS-CANDIDATE-<hash>`, com manifesto e hashes antes/depois. **Não escreve na pasta SGF**, não aplica schema nem concede direitos. Recusa preparar uma alteração se os pontos esperados no host divergirem, exigindo reconciliação do trabalho em curso. A candidata original `IR-CANDIDATE-bfa807e2b3c4fae7` não foi reescrita.
|
|
|
|
Na sobreposição, o catálogo unitário inclui os direitos de requisição e orçamento existentes; a criação de unidades continua a outorgar **apenas** `unit.view`/`unit.edit`. A administração nativa passa a listar/atribuir/revogar os novos direitos, conservando a exigência de o administrador possuir o direito que outorga. A atribuição unitária exige consulta da unidade pelo destinatário. Revogar a consulta da unidade confere autoridade sobre todos os direitos derivados afectados antes de os remover numa transacção; uma recusa não elimina parcialmente acessos.
|
|
|
|
`InitialAuthority.php` resolve a atribuição inicial como operação explícita. Exige administrador autenticado com `access.manage`, consulta/pertença ao contexto e uma lista de âmbitos habilitados pela futura composição de instalação (`purchasing-access.initialisation_scopes`, chaves `tenant:company:unit`; vazia por omissão). Só admite como destinatários administradores nominativos já autorizados nessa empresa/unidade. Escolhem-se os direitos e um fundamento, sem selecção automática de todos os direitos. Não atribui perfis de desenvolvimento. A concessão e a auditoria nativa `purchasing.access_initialised` são atómicas, serializadas pela empresa. Uma falha de auditoria desfaz as concessões. Uma repetição exacta não concede de novo nem recupera direitos entretanto revogados; outra inicialização é recusada, seguindo-se a gestão normal de acessos. Revogar a autoridade administrativa bloqueia também a consulta do ecrã e a repetição da operação.
|
|
|
|
As rotas candidatas em `integrations/sgf/access/routes.php` oferecem o ecrã `/purchasing/internal-requisitions/access-initialisation` e a operação `/api/internal-requisitions/access-initialisation`, com os middlewares nativos de autenticação, sessão e empresa. O ecrã mostra o contexto, permite escolher um destinatário nominativo e os direitos e envia CSRF/token de contexto/chave estável de operação. **Estas rotas não estão registadas no destino.** A prova nova verificou serviços nativos, persistência, autorização e renderização do ecrã; não declara ensaio HTTP completo ou revisão visual deste novo ecrã. A composição de instalação deverá ligar estas rotas ao módulo autorizado e retirar a habilitação de inicialização depois da entrega, preservando a auditoria.
|
|
|
|
Próxima dependência concreta: preparar a composição orçamental operacional e o instalador rastreável, incorporar esta sobreposição ao pacote SGF específico e conferir a sua integração HTTP. Não activar o módulo, a candidata de acessos ou 0.1.2 por consequência desta implementação.
|
|
|
|
### Procedimento de instalação: estado exacto e sequência obrigatória
|
|
|
|
**Incremento posterior — composição orçamental e preparação de schema:** implementados em candidata separada `integrations/sgf/operational` e `scripts/sgf-internal-install.php`. Já existe executor de **preparação de schema**, com `plan` e `migrate`; continua sem existir comando completo de instalação/activação de código e rotas. Esta actualização sucede à ausência de executor registada na primeira conferência, preservando o âmbito das provas anteriores. Ver [proofs/sgf-operational-delivery.json](proofs/sgf-operational-delivery.json). Nenhum destes comandos foi executado na base da instalação SGF de destino.
|
|
|
|
`php scripts/prepare-sgf-operational.php <raiz-SGF>` lê o host e produz `OPERATIONAL-CANDIDATE-<hash>`, com manifesto, sobreposições de identidade/orçamento e ficheiros de suporte locais. Não escreve no SGF nem publica um pacote. A sobreposição orçamental conserva o motor e autorizações existentes; acrescenta composição operacional habilitada explicitamente, sem depender de `APP_ENV=budget-testing` ou de um nome de base QA. A guarda exige impressão do destino real (configuração e endereço/porta PostgreSQL efectivos), schema/versão de migração conferidos e âmbito `tenant:company:unit` autorizado em `purchasing-operational.scopes`. `purchasing-operational.enabled` é falso por omissão e `purchasing-operational.target` deve coincidir com o destino conferido. A guarda de ensaio anterior permanece para a composição QA, sem se tornar uma autorização operacional alternativa.
|
|
|
|
A preparação exige fundação de identidade existente; cria o schema orçamental vazio se ausente, ou confere o schema completo existente contra o contrato estrutural aceite, conservando registos e dotação aprovada. Schema parcial ou incompatível é recusado. Estende os valores unitários aceites pelo constraint de permissões sem conceder direitos. Aplica o schema de requisições e grava `sgc_installations` imutável, revisão 1, assinatura estrutural, hash da migração, backup, operador nominativo de implantação e role PostgreSQL executante. Usa lock transaccional de instalação e DDL transaccional. Repetição com a mesma migração/schema reconhece a preparação anterior; alterações divergentes são recusadas sem sobrescrever. **Não há `down` nem eliminação de dados no executor.** A revisão actual não é mecanismo genérico para futuras migrações; estas exigem novo plano compatível e revisão própria.
|
|
|
|
Procedimento da CLI **na candidata**, pelo PHP fixado do host, apenas depois da decisão de instalação e preservação do destino:
|
|
|
|
```text
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-internal-install.php" plan "<raiz-SGF>"
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "<raiz-SGF>/scripts/sgf.ps1" php "<candidata>/scripts/sgf-internal-install.php" migrate "<raiz-SGF>" <target-sha256> "<backup.dump>" <backup-sha256> "<operador-nominativo>" <manifest-sha256>
|
|
```
|
|
|
|
`plan` só lê/verifica: integridade dos ficheiros da candidata, compatibilidade dos ficheiros do host com hashes antes/depois, identidade do destino, hash do manifesto e existência do registo de preparação. O campo `schema_prepared` informa a existência da tabela de registo; não substitui a conferência integral feita por `migrate`/guarda operacional. Conferir o manifesto/hashes com a referência de entrega por canal de confiança. `migrate` exige correspondência do destino e do manifesto, ficheiro de backup existente e SHA-256 coincidente; lê o índice com `pg_restore --list` antes de escrever. O cliente PostgreSQL deve estar no PATH ou indicado por `PG_RESTORE_BINARY`. Conferir o índice não prova recuperação: manter o restauro/reconciliação já aceites e o ensaio adicional da preparação operacional registado na prova. Nenhuma credencial deve ser passada nos argumentos ou copiada para o manifesto; usa-se a ligação configurada do próprio host.
|
|
|
|
**Prova deste incremento:** `OPERATIONAL-CANDIDATE-29687a1c9bc0e0b5`, 20 controlos novos aprovados, incluindo CLI real, backup custom válido, recusa de backup não conferido, schema vazio/existente/parcial/incompatível, falha injectada, recuperação da transacção, repetição sem novo registo, ausência de concessões e preservação do orçamento aprovado. Após backup/restauro para outra base descartável fora de `budget_core_sgf_*`, a mesma composição passou em `production`, conferindo schema/registo de preparação, reserva existente e revogação preservada. Este ensaio verifica o novo registo/schema operacional; não repete nem substitui as suites já aprovadas da requisição. As duas bases e role restrita foram removidas; o backup sintético não integra a entrega. Os caminhos e resultados estão em [proofs/sgf-operational-delivery.json](proofs/sgf-operational-delivery.json). Os ficheiros de código/ponteiro e dados do SGF instalado não foram alterados.
|
|
|
|
Após `migrate`, o estado é **preparado, não activado**: não altera o ponteiro 0.1.1, providers/rotas, concessões, dados de demonstração ou configuração de activação. O código/sobreposições candidatos ainda precisam de aplicação controlada, composição de arranque e integração HTTP antes de propor a activação. A configuração comercial por empresa/unidade e a atribuição explícita de acessos continuam obrigatórias. Isto não entrega fornecedores, consumo de facturas, pagamentos, equipamentos/peças ou reorganização modular do SGF.
|
|
|
|
**Não há neste momento um comando operacional completo para instalar esta candidata.** Os passos abaixo distinguem o que existe do que falta implementar; não são autorização para os executar no destino. A decisão de instalação continua separada. Não usar `purchasing:transfer`, `purchasing-release.php install`, os scripts de prova ou as fixtures para instalar esta integração numa empresa. O pacote `runtime.zip` é um artefacto de revisão, não deve ser extraído sobre a raiz do SGF: inclui também adaptações `app/*` de Compras que não pertencem ao host SGF.
|
|
|
|
1. **Identificar e conferir — disponível:** fixar a candidata `IR-CANDIDATE-bfa807e2b3c4fae7`, o manifesto e os hashes em `proofs/internal-requisitions-candidate.json`; conferir o ZIP e cada ficheiro contra o manifesto. Registar raiz/destino, PHP do wrapper SGF, versão de aplicação/dependências, servidor/base/empresa/unidade e estado do ponteiro `packages/purchasing/current.json` (actualmente 0.1.1). Confirmar que os pré-requisitos de identidade e orçamento correspondem à composição pretendida. Nenhum comando desta etapa migra ou concede direitos.
|
|
2. **Preparar a entrega operacional — bloqueado pelas implementações identificadas acima:** produzir pacote SGF separado e versionado apenas com os ficheiros comuns necessários e adaptadores/ecrãs do host; incluir migração rastreável, composição operacional do orçamento, catálogo/gestão dos direitos e mecanismo de autoridade inicial. Conservar os hashes da candidata como referência; uma alteração de código origina outro artefacto, sem sobrescrever o congelado. A migração 46 de Compras não se aplica à base SGF. Não copiar tabelas base nem fixtures de Compras.
|
|
3. **Preservar o destino — procedimento necessário antes de qualquer futura escrita:** suspender tráfego de escrita e workers, aguardar transacções em curso, registar instante de corte, arquivar código/configuração de implantação e ponteiro/histórico; preservar documentos/ficheiros e contas. Fazer backup integral PostgreSQL da base conferida, não apenas das tabelas `ir_*`, pois o orçamento e as concessões também são afectados. Guardar o arquivo, hash e identidade do destino fora do pacote distribuído. Não incluir segredos no registo de implantação.
|
|
4. **Aplicar schema e preparar código sem expor rotas — executor de schema agora em candidata:** usar a CLI `plan`/`migrate` descrita acima, sem outorgar acessos. O wrapper transaccional regista revisão, confere repetições e recusa divergências; não executar `Schema::install` isoladamente. Preparar os ficheiros num directório local de versão, sem sobrepor os `app/*` de Compras nem trocar para 0.1.2. A aplicação das sobreposições e o arranque/activação do código continuam separados e pendentes.
|
|
5. **Configurar acessos e política — bloqueado pelo catálogo/autoridade inicial:** pelos mecanismos administrativos auditados, atribuir explicitamente os direitos aprovados a pessoas nominativas e ao âmbito correcto; garantir requerente e aprovadores distintos, e responsáveis da dotação. Depois configurar centros existentes, referências de departamento, intervenientes, limites, inclusão de imposto e exigência de orçamento. Nenhum nome ou ID de outra instalação é uma correspondência automática. Não inserir concessões por SQL como solução de entrega.
|
|
6. **Activar — depende de decisão separada e das etapas anteriores concluídas:** registar arranque/rotas locais do módulo e abrir o percurso apenas para contextos/módulos adquiridos e utilizadores autorizados; reiniciar serviços persistentes pelo procedimento do host. Conferir o estado aplicado, acessos efectivos e a consulta do processo no destino, sem repetir as suites já aprovadas. Registar versão, schema, configuração, autoria e instante da activação. Só então reabrir escritas/workers. Não existe nesta entrega comando que concretize esta etapa; nenhum destes passos foi executado na instalação SGF.
|
|
|
|
### Procedimento de recuperação por tipo de falha
|
|
|
|
Os ensaios aceites sustentam DDL transaccional e backup/restauro isolado; não equivalem a um instalador de recuperação automática de cliente. Não repetir os testes para esta classificação.
|
|
|
|
| Situação | Acção exacta |
|
|
| --- | --- |
|
|
| Falha de preparação, antes de escrever no destino | Abandonar a preparação; conservar o código/ponteiro 0.1.1 e a base intactos. Não há migração ou reversão de dados a executar. |
|
|
| Excepção durante a transacção de schema | Fazer rollback da transacção; conferir ausência de tabelas/alterações parciais e igualdade com o inventário prévio. Se a ligação se perder durante o commit, primeiro inspeccionar schema e registo de revisão; não pressupor rollback nem repetir `Schema::install` às cegas. Manter o módulo desactivado até esclarecer o estado. |
|
|
| Código não arranca após schema confirmado, antes de novas operações | Retirar o novo registo de rotas/arranque e regressar ao código/configuração anterior arquivados; reiniciar os serviços. Manter o schema aditivo e os dados, incluindo auditoria. O ponteiro 0.1.1 não reverte alterações do host. Não executar `down`, truncar `ir_*`, estreitar a coluna de permissões ou remover direitos/histórico por arrasto. |
|
|
| Falha numa submissão/decisão ou resposta perdida | Conservar a identidade/contexto e repetir exactamente a mesma chave, versão e conteúdo; o recibo devolve o efeito já confirmado ou a transacção recomeça sem reserva duplicada. Se houver conflito de versão/conteúdo ou revogação, consultar o processo com identidade autorizada; não gerar uma nova origem para contornar o erro. |
|
|
| Corrupção/dados ou schema incompatíveis após operações novas | Suspender escritas/workers; preservar também uma cópia do estado que falhou e operações posteriores ao corte. Restaurar o backup numa **nova base vazia**, nunca por cima da base em uso. Conferir tabelas/dados, schema/constraints/triggers e consulta de origens/versões/reservas. Reconciliar explicitamente as operações posteriores ao backup e a configuração/autorização actual, incluindo revogações; um backup antigo não deve reabrir acessos revogados. Só apontar a aplicação à base recuperada após conferência e decisão registada. Conservar a base anterior para diagnóstico. |
|
|
|
|
Forma dos comandos PostgreSQL usados na prova aceite, a adaptar ao destino conferido e à autenticação administrativa local, **não executados nesta conferência**:
|
|
|
|
```text
|
|
pg_dump --format=custom --file=<arquivo-backup.dump> --dbname=<base-origem-conferida>
|
|
pg_restore --list <arquivo-backup.dump>
|
|
createdb --owner=<proprietario-autorizado> <nova-base-vazia-de-recuperacao>
|
|
pg_restore --no-owner --no-privileges --exit-on-error --dbname=<nova-base-vazia-de-recuperacao> <arquivo-backup.dump>
|
|
```
|
|
|
|
O restauro da prova usou uma role restrita proprietária da nova base. `--no-owner --no-privileges` não restaura roles/grants PostgreSQL: estes devem ser preservados no inventário administrativo e repostos explicitamente no ambiente de recuperação. As permissões funcionais da aplicação são dados da base e também exigem reconciliação temporal. `pg_restore --list` só lê o índice; a prova de recuperação aceite é o restauro efectivo com reconciliação das 22 tabelas e consulta posterior já registados. Os comandos não restauram documentos externos, `.env`, dependências ou código; estes têm cópias/procedimentos próprios. Não há comando único entregue para fazer a troca operacional da base.
|
|
|
|
### Entrega distinta da reorganização modular do SGF
|
|
|
|
Esta entrega é **a integração candidata de requisições internas**. Extrair um motor e preparar um adaptador não comprova a reorganização modular do SGF pedida posteriormente. **Essa reorganização continua pendente, sem resultado apresentado nesta entrega**, e deve ter inventário, alterações e resultado próprios. Não a contar como concluída na matriz nem usar esta classificação como autorização para a executar por arrasto.
|
|
|
|
### Dados/schema: ensaio separado da reversão de código
|
|
|
|
- **Compras:** migração aditiva `2026_11_01_000046_add_requisition_command_versions.php`, sobre a base que já contém a migração 45. Acrescenta versão do processo e recibos imutáveis de comando; não reclassifica nem apaga dados. O caminho autónomo anterior continua utilizável sem instalar os recibos; o ecrã só envia chaves/versões quando o schema está preparado. `down` recusa apagar recibos já existentes. Nenhuma migração foi aplicada à base persistente de desenvolvimento.
|
|
- **SGF:** `Schema.php` acrescenta as tabelas `ir_*`, alarga o comprimento de `permission_grants.permission` e estende a condição de âmbito com os direitos privados da candidata. Conserva a condição anterior e os seus registos, sem conceder direitos. Políticas e histórico são versionados e imutáveis; snapshots submetidos e origem não são reescritos. A instalação foi ensaiada em PostgreSQL descartável já com identidades, concessões e orçamento sintéticos.
|
|
- **Falha/compatibilidade:** DDL transaccional com falha injectada preserva schema/dados anteriores e permite nova tentativa. Foi ensaiada uma evolução aditiva compatível com a candidata anterior. Isto não comprova compatibilidade com futuras alterações destrutivas.
|
|
- **Recuperação:** backup/restauro para outra base isolada, reconciliação de dados, colunas, constraints e triggers e consulta do processo restaurado. O backup de ensaio é sintético e não faz parte do pacote cliente. Uma recuperação real exige parar escritas e reconciliar operações posteriores ao backup; não há restauro automático sobre operações novas.
|
|
- **Código:** o updater continua limitado a código sem migrações. Voltar ao código 0.1.1 não remove tabelas nem restaura dados, e essa versão não apresenta o novo percurso. Não executar `down` nem recuperar uma base antiga como efeito implícito de rollback do ponteiro.
|
|
|
|
As provas e os resultados efectivos deste incremento constam de [proofs/internal-requisitions-sgf.json](proofs/internal-requisitions-sgf.json). As provas históricas abaixo conservam o respectivo âmbito. Ecrãs foram verificados por HTTP, modelo de acções, tipos/lint e compilação; não houve revisão visual por navegador.
|
|
|
|
| Verificação da candidata congelada | Resultado |
|
|
| --- | --- |
|
|
| Integração SGF pelo PHP 8.4.27 do host, PostgreSQL descartável | 43 controlos; 2 origens, 2 requisições e 2 reservas, incluindo save/submit/decide concorrentes em processos separados |
|
|
| Adaptador autónomo e regressão de compras/orçamento em PostgreSQL descartável | 46 testes / 339 asserções |
|
|
| Regressão completa de Compras em SQLite isolado | 883 testes: 881 aprovados, 2 ignorados; 8.950 asserções; resultado final em [proofs/internal-requisitions-validation.json](proofs/internal-requisitions-validation.json) |
|
|
| Recuperação de dados/schema | 22 tabelas reconciliadas; constraints/triggers/colunas conferidos; consulta restaurada preserva origem e versão 3 |
|
|
| Modelo dos ecrãs congelados, limites monetários exactos, envelopes de retry e headers | 23 controlos Node; sem navegador |
|
|
| PHPStan dirigido, TypeScript, lint/formatação e build frontend | Aprovados; sem erros PHPStan ou avisos lint nos ficheiros verificados |
|
|
| Activação e permissões no SGF de destino | Ponteiro 0.1.1 preservado; candidata recusada pelo updater normal; nenhuma concessão aplicada |
|
|
|
|
## Percurso de actualização
|
|
|
|
### Separação entre preparação e instalação cliente
|
|
|
|
| Etapa | Acesso necessário | Dependência de Compras na instalação cliente |
|
|
| --- | --- | --- |
|
|
| Produzir ZIP validado (`publish-purchasing.php`) | Fonte Compras e canal de saída; não precisa de pasta SGF | Nenhuma depois de produzido o artefacto |
|
|
| Coordenar prova/instalação no SGF de desenvolvimento (`transfer-purchasing.php`) | Pastas locais de Compras/SGF, wrapper e canal | É uma ferramenta de desenvolvimento, não o instalador obrigatório do cliente |
|
|
| Conferir/instalar no cliente (`purchasing-release.php`) | SGF do próprio cliente com dependências e ferramentas de arranque, ZIP e SHA-256 aprovado | Não usa pasta, base, sessão ou serviço de Compras |
|
|
| Executar a capacidade instalada | Loader, versão seleccionada e dependências locais do SGF | Não consulta a origem nem sincroniza dados com ela |
|
|
|
|
Conferido por dois meios: teste em pasta cliente sintética com a pasta de origem renomeada para indisponível; e execução no SGF `0.1.1` verificando que todos os ficheiros PHP carregados pertencem ao próprio host. A segunda prova não arranca a aplicação nem liga à base. Isto comprova a independência do pacote actual, não a preparação completa de todos os futuros módulos de cliente.
|
|
|
|
No desenvolvimento, a partir de Compras:
|
|
|
|
```text
|
|
composer purchasing:transfer -- C:/laragon/www/sgf-tempo C:/laragon/data/sgc-releases/purchasing
|
|
```
|
|
|
|
O comando usa o wrapper e o PHP fixado pelo SGF, sem substituir versões. Executa regressões da capacidade e do mecanismo; verifica que a origem não mudou durante os testes; prova uma fotografia imutável; publica essa mesma fotografia; compara com a versão instalada; prova a candidata com o PHP/dependências do SGF; instala se for mais recente. Sem alterações no pacote, não gera versão nem reinstala código. O exemplo de caminho é do ambiente local, não dependência do runtime ou do formato distribuído.
|
|
|
|
Para apenas produzir uma versão validada, usar `composer purchasing:publish -- <canal>`. O comando `scripts/purchasing-release.php publish` é a primitiva técnica sem execução de testes; a publicação normal usa o percurso validado anterior.
|
|
|
|
O canal contém `catalog.json` e ZIPs imutáveis. Há numeração patch automática por alteração dos bytes; `source_sha256` identifica o conjunto exacto de ficheiros. O manifesto individual contém SHA-256 por ficheiro e contrato/capacidades do módulo. A validação rejeita ficheiros extra, ausentes, alterados, caminhos inválidos, entradas duplicadas e arquivos excessivos.
|
|
|
|
Na instalação cliente, distribuir o ZIP, os artefactos de arranque e a referência SHA-256 por canal de confiança. Não é necessário o checkout de Compras:
|
|
|
|
```text
|
|
php scripts/purchasing-release.php check <raiz-SGF> <versao.zip> <sha256-manifesto>
|
|
php scripts/purchasing-release.php install <raiz-SGF> <versao.zip> <sha256-manifesto>
|
|
php scripts/purchasing-release.php status <raiz-SGF>
|
|
php scripts/purchasing-release.php rollback <raiz-SGF>
|
|
```
|
|
|
|
O SHA-256 confere integridade contra a referência aprovada; não autentica sozinho um canal remoto. Não há download ou activação a partir de URLs arbitrários. Um catálogo remoto assinado e verificação de assinatura ainda não integram esta entrega.
|
|
|
|
## Preservação e recuperação
|
|
|
|
Cada versão ocupa `packages/purchasing/releases/<versão>`; `current.json` é o ponteiro local. A instalação valida a versão actual antes de actualizar, prepara a candidata separadamente, regista histórico e troca o ponteiro atomicamente sob lock. Não apaga a versão anterior. Uma alteração local ao código instalado bloqueia a actualização em vez de a sobrescrever. Versão igual com conteúdo diferente e downgrade implícito são recusados. A reversão explícita confere os bytes anteriores e não recalcula nem apaga dados.
|
|
|
|
`current.json`, locks e histórico são estado da instalação e não credenciais/contas distribuídas. O SGF pode arrancar sem este módulo opcional instalado; depois da instalação, o provider carrega o pacote verificado. O histórico é local e não deve ser transplantado de uma empresa para outra.
|
|
|
|
O formato actual **recusa pacotes com alterações de schema ou concessões**. Os comandos de instalação/prova do primeiro incremento não abriram bases nem executaram migrações, seeds, alterações de contas, permissões, stock, finanças ou contratos. A nova candidata de requisições ensaiou persistência apenas em bases sintéticas descartáveis, conforme secção própria, sem alargar o contrato do updater. Serviços persistentes devem ser reiniciados pelo procedimento operacional depois de actualizar; o instalador não termina processos.
|
|
|
|
### Alcance exacto da reversão
|
|
|
|
| Elemento | Cobertura actual |
|
|
| --- | --- |
|
|
| Código do pacote e versão seleccionada | Reversão explícita para a versão anterior, depois de conferir integridade; histórico local e troca de ponteiro |
|
|
| Dependências PHP/Composer e frontend do host | Não são substituídas nem revertidas por este mecanismo |
|
|
| Dados empresariais, schema, configuração e permissões | Não são alterados nem revertidos pelo actual contrato |
|
|
| Migrações de dados/schema | Fora do updater; na candidata interna, DDL falhada, compatibilidade aditiva e backup/restauro em base isolada ensaiados separadamente; sem down/restauro automático |
|
|
|
|
O manifesto exige `database_changes=false` e o formato não aceita pastas de migração/seed; isso delimita o contrato distribuído actual, não torna PHP futuro uma sandbox. Uma capacidade com persistência exige antes um contrato de migração com autoria/versão, schema compatível, aplicação idempotente, auditoria, destino conferido e backup/restauro ensaiados em isolamento. Deve distinguir reversão de código compatível, correcção por migração seguinte e eventual restauro de dados com plano de reconciliação. Não executar automaticamente `down`, apagar históricos ou restaurar um backup antigo sobre novas operações. A estratégia concreta terá de acompanhar o percurso escolhido.
|
|
|
|
## Provas e limites
|
|
|
|
**Conferência adicional antes de ampliar:** seis testes do mecanismo/29 asserções, incluindo execução em cliente com origem indisponível; prova SGF em PHP 8.4.27, versão activa `0.1.1`, todos os ficheiros carregados no próprio host e nenhuma ligação à base. Ver `proofs/purchasing-client-independence.json`. As provas do primeiro incremento abaixo mantêm o seu âmbito histórico. A candidata `0.1.2` contém preparação económica, mas não foi instalada; não contar os testes dessa preparação como prova do processo económico no SGF.
|
|
|
|
- Compras: 86 testes/566 asserções no percurso de publicação (reposição, histórico, lotes, coordenação, sugestões, estornos, contagens e cinco testes do mecanismo).
|
|
- SGF: dois testes/11 asserções, executados com o wrapper e PHP 8.4.27, sem base; execução real do pacote e resultados de consumo manual, média racional e lotes.
|
|
- Publicação `0.1.0` e actualização `0.1.1` instaladas localmente. A segunda versão acrescenta documentação do contrato de distribuição; o algoritmo transferido permaneceu igual.
|
|
- Reversão real `0.1.1 → 0.1.0` e reactivação `0.1.1` conferidas, sem dados/permissões alterados.
|
|
- Cinco testes do instalador cobrem publicação sem duplicação, nova versão, retry, rollback/reactivação, código local alterado, manifesto errado, conteúdo adulterado, path traversal, ficheiro ausente, segredo na origem e pedido de alteração de schema.
|
|
- Fachada e motor comum passaram análise PHP dirigida. Fonte do mecanismo e artefactos SGF conferidos em `packages/module-updates/runtime-manifest.json`.
|
|
|
|
**Limitação central:** este mecanismo actualiza as capacidades já extraídas para o pacote; não transfere automaticamente melhorias ainda confinadas aos controladores/serviços/ecrãs de Compras. Continuar a migração pela matriz acima, sem declarar todo o SGF actualizado só porque a versão do pacote mudou. Não há publicação no domínio ou conclusão de integração de RH nesta entrega.
|
|
|
|
## Candidata utilizável de requisições — 02/11/2026
|
|
|
|
Esta secção actualiza a matriz para a candidata `OPERATIONAL-CANDIDATE-401ce31ae5f2dd20`, schema revisão 2, e substitui apenas as lacunas administrativas/orçamentais identificadas na proposta anterior. A distribuição instalada mantém **0.1.1**; não houve instalação/activação/publicação.
|
|
|
|
| Capacidade | Candidata / prova | Destino |
|
|
| --- | --- | --- |
|
|
| Dependências da interface orçamental | cb_ui_commands e cb_consumption_sources incluídas, estruturas existentes reutilizadas; 16 tabelas novas no total | Não migrado |
|
|
| Administração de direitos | Acessos React usa catálogo/rótulos do servidor, filtro por direito próprio e unidade; servidor valida delegação/revogação | Sem concessões |
|
|
| Centros e dotações | Formulário de centro, preparação pela API comum, aprovação independente; sem fixtures necessárias | Sem dados novos |
|
|
| Requisição básica | Consumível/serviço/outro → submissão e reserva única → aprovação distinta → consulta/histórico | Não activado |
|
|
| Equipamentos/peças | Rejeitados; fora do incremento | Não activado |
|
|
| Privilégios mínimos | Roles separadas, CREATE/ALTER negados ao runtime; mapa restringe ACLs herdadas só em objectos novos | Apenas proposta; não aplicada |
|
|
| Recuperação | Sucessor de código + rollback sem alterações de dados; dump restaurado e 103 tabelas reconciliadas, schema/decisão/reserva preservados | Sem restauro/mudança |
|
|
| Navegação | Código funcional 2a4169162bb4621a42a2ea1df627d52f860e7176 preservado; Início/Opções gerais separados | 19 hashes inalterados |
|
|
|
|
Provas afectadas: **157 controlos integrados + 17 React/render/assets + 54 aplicação/interrupção/recuperação de código**. Não são testes de carga ou revisão visual. As suites anteriores válidas são reutilizadas; as 87 comparações de ACL integram os 157 controlos. Bases/roles sintéticas removidas. Ver [prova consolidada](proofs/sgf-requisition-usable-candidate.json) e [proposta única revista](PURCHASING_INSTALLATION_PROPOSAL.md), com hashes/recuperação de código, schema e dados separados.
|
|
|
|
Pendências mantidas: revisão visual sem nova tentativa pela via bloqueada; associações antigas sem atribuição automática; volume/paginação; decisão posterior de instalação, mapa SQL e configuração/autoridades do destino. A candidata não inclui pagamentos/recepções/ordens/stock ou direitos reais por arrasto.
|
|
|
|
## Revisão da proposta para desenvolvimento sintético — 02/11/2026
|
|
|
|
A proposta SGF-IR-USABLE-401C-20261102 foi completada, sem execução: destino novo em C:/laragon/data/sgf-tempo/run/ir-usable-401c-20261102/app, HTTP8041, cluster55441/base sgf_ir_dev_401c_20261102, owner/runtime novos separados. Origem exclusivamente sintética 8039 preservada; as nove baselines são compatíveis. Fonte contém 93 tabelas (incluindo seis wc_* fora deste incremento), portanto migração nova será 93→109, não 87→103. Perfis #1/#2/#3 reutilizados somente na cópia; três contas sintéticas novas de administração/Compras/Financeiro propostas. Dotação fictícia 50 000 MZN/2026, limites 10 000/20 000, concessões exactas na proposta. Mapa SQL mínimo dirigido à role nova, não sgf_dev_app. Nenhum provisionamento, concessão, migração ou activação executados. Provas antigas reutilizadas sem declarar o destino novo testado. Ver PURCHASING_INSTALLATION_PROPOSAL.md e proofs/sgf-ir-synthetic-installation-proposal.json. A versão anterior da proposta ficou arquivada e não deve ser executada.
|
|
|
|
## Execução autorizada em 8039 — 02/11/2026
|
|
|
|
Concluída/conferida exclusivamente na demonstração existente 8039/base sgf_modules_dev_2576427d1939/55439/contexto1:1:1: 14 direitos (8/4/2), centro SINTETICO-REPRO/OPER, dotação 10 000 MZN/2026 por #1 aprovada por #2 e requisição de 100 MZN com reserva única e aprovação independente. Direitos/contas anteriores preservados, sem GRANT/REVOKE SQL ou novas contas. A proposta8041 permanece adiada. Ver SGF_REQUISITIONS_8039_DELIVERY.md e provas associadas. Consulta #3 tem listagem acessível mas 404 no registo de outro autor pela visibilidade existente; nenhuma ampliação de direitos/código foi feita. Backup anterior conferido; restauro efectivo deste backup não é declarado nesta passagem. SGF real/Tempo e 0.1.1 preservados; revisão visual/associações antigas/volume-paginação separados.
|