# Proposta revista SGF-IR-USABLE-401C-20261102 **Candidata utilizável ensaiada; instalação, activação e publicação NÃO executadas nem autorizadas.** Substitui a proposta de instalação técnica desactivada SGF-IR-INSTALL-5FAE-20261102, que não deve ser executada. Entrega para decisão posterior. O pacote instalado continua em **0.1.1**. ## Artefacto e destino proposto | Elemento | Valor vinculativo | | --- | --- | | Candidata | `OPERATIONAL-CANDIDATE-401ce31ae5f2dd20`, formato `tempo.operational-review.v1`, schema revisão **2**; sem nova versão comercial | | ZIP privado | `C:/laragon/www/compras/storage/app/private/candidate-archives/OPERATIONAL-CANDIDATE-401ce31ae5f2dd20.zip` | | SHA-256 ZIP | `59dbdc64c4d9f14dfb4025a6177b829d136a4e2cb633ca036b10b5ae3197e703` | | SHA-256 manifesto | `a6478223e17a5430652f0fcbf31a44a931ae2a99cd90b151c98d2df5df43c10b` | | Raiz futura | `C:/laragon/www/sgf-tempo`, ambiente `local` | | Base futura | **`sgf_tempo_dev`**, `127.0.0.1:55432` — não alterada nesta entrega | | Aplicação / migrador | `sgf_dev_app` / `sgf_dev_owner`, ligações distintas existentes; credenciais mantidas | | Bundle futuro | `packages/internal-requisitions`; não substitui `packages/purchasing/current.json` | | Preparação / backup futuros | `C:/laragon/data/sgf-tempo/install/SGF-IR-USABLE-401C-20261102` / `C:/laragon/data/sgf-tempo/backups/SGF-IR-USABLE-401C-20261102` | | Plano de código, só leitura | `d29833b1c48b9d666522d20d87040d5ad30370cf114c9a70f272cd041eea59e9` | | Plano de schema, só leitura | `169e6e863f28b67740f07b6e7cbc664fbe585a7760a83dccebc8d482ad8ab792` | Os dois planos passaram no destino sem escrita. Não se instalará a antiga candidata 5fae nem se activará esta candidata por consequência do ensaio. Não foi criado checkpoint nem publicado artefacto. ## O que fica utilizável na candidata Percurso administrativo e funcional integrado: ecrã nativo **Acessos** com catálogo/rótulos do servidor e opções limitadas aos direitos próprios; criação de centro por formulário; preparação de dotação; aprovação por outra identidade; configuração versionada de departamentos, intervenientes, limites e exigência orçamental; requisição de **consumíveis, serviços e outros**, edição de rascunho, submissão com uma reserva transaccional, aprovação independente e consulta/histórico. Não são necessárias fixtures ou inserções SQL para criar centros/dotações. O acesso inicia-se pelo módulo Compras e pelos links de requisições/preparação orçamental. O catálogo não concede direitos. A gestão normal continua a exigir autoridade administrativa, pertença e os direitos próprios de quem delega; a inicialização de autoridade continua explícita, nominativa e limitada ao âmbito configurado. Nenhum utilizador ou direito foi atribuído no destino. As dependências `cb_ui_commands` e `cb_consumption_sources` passam a integrar o pacote e a migração. Reutiliza-se o núcleo orçamental existente; a preparação/aprovação usa as APIs existentes. Movimentos orçamentais directos continuam bloqueados nesta composição: a reserva nasce da requisição, sem segundo motor nem forma alternativa de consumo. O catálogo inclui capacidades futuras que não ficam operacionais só por estarem listadas. ## Navegação e alterações locais Referência funcional: **`2a4169162bb4621a42a2ea1df627d52f860e7176`**. `fcf0ada22701337acd4c84b404207b8400f490a2` é documental. Os 19 ficheiros conferidos continuam byte a byte iguais no host ao inventário anterior; não houve instalação sobre o código aceite. Preservar Comercial, Compras, Stock, Oficinas, Financeiro e Contabilidade; **Início e Opções gerais/configuração permanecem separados**, conforme as permissões. Não existe compromisso de criar um menu literal único «Configuração». Contexto não concede direitos; associações antigas não são preenchidas. O manifesto da nova candidata prevê **nove sobreposições exactas**: Permissions, IdentityWorkflow, BudgetAdapter, BudgetWorkspace, AppServiceProvider, ModuleNavigation, `resources/js/app.jsx`, `resources/js/PurchasingHome.jsx` e `public/build/manifest.json`. A interface foi reconstruída numa cópia privada, com as dependências já instaladas. JS/CSS compilados e hashes viajam no próprio bundle; não se alteram dependências do host. As rotas estáticas servem exclusivamente os assets empacotados, inclusive antes da autenticação. O instalador recusa ficheiros locais divergentes e a recuperação inclui o manifesto anterior. Não usar reset/checkout/limpeza global nem sobrepor trabalho alheio. ## Schema e privilégios para decisão Migração aditiva transaccional **revisão 2**: sete tabelas do orçamento comum, duas dependências de interface (`cb_ui_commands`, `cb_consumption_sources`), seis tabelas `ir_*` e recibo `sgc_installations`: **16 tabelas novas, 87 → 103**. Amplia o campo/constraint do catálogo em `permission_grants`, sem modificar os registos. Cria constraints/triggers de integridade/imutabilidade; tabelas de negócio começam vazias. Recusa schema parcial ou recibo incompatível; não há `down` destrutivo. Não aplicar migrações genéricas de Compras autónomo. O migrador precisa de CONNECT, USAGE/CREATE no schema e propriedade dos objectos que altera (`permission_grants` e novos objectos/funções). O ensaio utilizou owner **NOSUPERUSER, NOCREATEDB, NOCREATEROLE, NOBYPASSRLS**. O runtime apenas CONNECT/USAGE e DML explícito; CREATE e ALTER foram efectivamente recusados. A leitura anterior do owner real confirmou propriedade e CREATE numa transacção read-only; não se alteraram credenciais ou privilégios reais. **Alteração SQL necessária, apenas proposta para decisão:** os defaults actuais do destino dão arwd em tabelas novas e rU nas sequências. Isso excede o mínimo. O plano `SqlPrivileges::plan('sgf_dev_app')` revoga privilégios herdados do runtime/PUBLIC **apenas nos 16 objectos novos**, e repõe: | Objectos | Runtime | | --- | --- | | cb_centres, cb_origins, cb_budget_entries, cb_audit, cb_ui_commands | SELECT, INSERT | | cb_budgets | SELECT, INSERT, UPDATE | | cb_budget_consumptions, cb_budget_reinforcements, cb_consumption_sources, sgc_installations | SELECT | | ir_requests, ir_steps, ir_policies | SELECT, INSERT, UPDATE | | ir_events, ir_commands, ir_policy_versions | SELECT, INSERT | | Sequências das tabelas de inserção | USAGE apenas | Sem DELETE/TRUNCATE, DDL, propriedade, superuser, concessões globais ou alteração dos DEFAULT PRIVILEGES. Objectos anteriores conservam ACLs. O plano é emitido por `sgf-internal-install.php privileges-plan sgf_dev_app`; **não é executado automaticamente** pela instalação. O ensaio reproduziu e reduziu os privilégios herdados, e comparou as ACLs das 87 tabelas anteriores. Catálogo reconhecido: `purchasing_requisitions.view/prepare/configure/approve.department_head/approve.procurement/approve.finance` e `purchasing_budget.view/create/approve/record/consume/reinforcement.propose/reinforcement.review`. **Concessões a utilizadores do destino: zero.** Para futura abertura são necessários âmbito/autoridade e responsáveis concretos aprovados, política e dotação configuradas pelas interfaces. A candidata resolve a preparação; não inventa a decisão empresarial nem importa os actores/valores sintéticos. ## Ensaio e recuperação [Prova consolidada](proofs/sgf-requisition-usable-candidate.json): **157 verificações integradas**, **17 verificações React/render/assets**, **54 verificações de aplicação/interrupção/recuperação de código**. As 87 comparações individuais de ACL estão incluídas nos 157 controlos; estes números não são uma nova suite global. Exportou-se apenas o schema actual do SGF, **zero linhas do destino**. Foram criadas bases e roles aleatórias restritas no cluster local de QA, com limpeza confirmada. Dados/contas/concessões usados no percurso são exclusivamente sintéticos. Verificado: DDL interrompida faz rollback; instalação vazia; autenticação/contexto/CSRF nativos; catálogo e delegação/recusa/revogação; centro idempotente; dotação com aprovação distinta; requisição com os três tipos suportados; submissão e reserva única; auto-aprovação recusada; decisão e histórico; módulo não contratado/desactivado recusado; código sucessor compatível aplicado e recuperado sem alterar qualquer tabela; backup custom efectivamente restaurado numa segunda base, **103 tabelas reconciliadas**, schema/triggers/decisão/origem/reserva preservados e leitura com runtime restrito. - **Código:** journal, hashes, cópia dos ficheiros/manifesto e bundle anterior; recuperação sob manutenção recusa alterações locais desconhecidas. Uma falha conserva manutenção. Actualização com mudança de contrato/schema é recusada e exige plano próprio. - **Schema:** transacção para falhas de DDL; depois do commit, manter schema aditivo compatível ou migração correctiva conferida. Recuperar código não remove tabelas nem inverte constraints. - **Dados:** dump real, restauro noutra base e reconciliação de todas as tabelas/sequências/schema/ACLs. O ensaio reconciliou os 103 conjuntos de linhas e a assinatura de constraints/triggers; o runtime voltou a ler decisão/reserva. Guardar bundles antigos não recupera dados. Não restaurar backup antigo por cima de operações posteriores sem reconciliação e decisão específica. As provas anteriores válidas de navegação (185/3220 + 8/90), isolamento/requisições/concorrência, núcleo comum e Compras são reutilizadas no seu âmbito. Não foram repetidas as suites globais. Build/SSR/HTTP não constituem revisão visual. ## Operação única proposta para futura decisão **Não executar agora.** Esta é a sequência técnica revista, e não uma ordem de instalação desactivada. A decisão futura terá de fixar também a abertura/configuração pretendida; sem destinatários/âmbitos aprovados não existe autorização implícita para concessões ou activação. 1. Conferir ZIP/manifesto e nove baselines; executar novamente só os planos read-only com os hashes acima. Qualquer divergência obriga a reconciliar a proposta antes de escrever. Extrair fora da raiz web, sem sobrepor tentativas anteriores. 2. Inventariar serviços/ambientes; preservar código local completo, estado Git, configurações/caches/uploads e ACLs em pasta privada. Parar apenas escritores do destino e colocar em manutenção. Não usar `sgf.ps1 stop`, não parar PostgreSQL nem demonstrações alheias. 3. Fazer backup fresco `before.dump` custom e hashes; restaurar numa base privada vazia `sgf_restore_ir_401c_pre`, comparar dados/schema/sequências/ACLs do corte real. A prova sintética desta entrega não substitui esse backup do dia. 4. Com ligação exclusiva `sgf_dev_owner`, executar `sgf-internal-install.php migrate `; conferir revisão 2, 16 tabelas novas, recibo e preservação de dados/acessos. Aplicar somente o mapa SQL novo se expressamente incluído na decisão; nenhuma concessão funcional a utilizadores por arrasto. 5. Fazer `prepared.dump`, restaurar em `sgf_restore_ir_401c_post` e conferir as 103 tabelas e contrato. Não avançar se restauro falhar. 6. Sob serviços escritores parados, executar `sgf-code-deploy.php apply --offline`. A CLI regista journal e mantém manutenção; conferir os nove overlays e os assets incluídos. Compras mantém 0.1.1. 7. Não criar caches globais de configuração/rotas/eventos neste host partilhado com demonstrações em ambientes diferentes. O instalador invalida caches conhecidos; preservar/reiniciar os serviços com os ambientes próprios. Não executar rebuild global por rotina. 8. Antes de qualquer abertura futura, aplicar somente a configuração/autoridade explicitamente decididas, usando interfaces e separação de identidades. Verificar isolamento tenant/empresa/unidade/módulo, direitos/revogação, guardas reais, rotas/assets e navegação aceite. Sem configuração autorizada, conservar guardas, sem declarar o destino utilizável. Restabelecer apenas serviços identificados e manutenção conforme estado inicial após verificações; guardar evidência privada. Em falha: manter manutenção, recuperar código pelo deployment id e conferir os ficheiros; conservar schema/dados. Para perda/corrupção, restaurar para base alternativa restrita, reconciliar e só depois decidir a troca. Nenhuma eliminação da base de destino ou reposição de dados automática faz parte desta proposta. ## Pendências e preservação final | Pendência | Estado/efeito | | --- | --- | | Duas tabelas da interface | Resolvidas na revisão 2 e comprovadas no schema reproduzido | | Administração dos direitos | Resolvida no ecrã nativo/catálogo/servidor, sem concessões no destino | | Centros/dotações | Preparação e aprovação independentes utilizáveis; valores reais continuam por configurar | | Equipamentos/peças | Fora do incremento, rejeitados por servidor; não bloqueiam consumíveis/serviços/outros; não disfarçar como outros | | Instalação/activação/privilégios SQL/autoridades reais | A decidir posteriormente; não executados nesta entrega | | Revisão visual | Pendente, separada; nenhuma tentativa pela via bloqueada | | Associações antigas | Continuam pendentes/sinalizadas, sem atribuição automática | | Volume/paginação | Pendente; sem alegar prova de carga ou paginação integral | Destino preservado por leitura final: **87 tabelas**, **89 concessões**, **2 pertenças**, **162 registos da auditoria de identidade**; fingerprints e guardas iguais aos anteriores, ponteiro Compras 0.1.1 intacto. Nenhuma publicação, instalação, activação, credencial ou privilégio do destino alterado. As alterações locais e o trabalho paralelo foram preservados. Hash SHA-256 do contrato de migra??o: `4ca4f5827c46e5ca29cb329c667df0b996ecbf5e318c0b157091c94e9d44ae92`. [Mapa SQL m?nimo exacto, proposta n?o executada](proofs/sgf-requisition-minimal-sql-plan.json). Integridade final: 49 ficheiros de suporte conferidos e 42 PHP verificados por lint; ZIP/manifesto inalterados. Snapshot do destino igual ao anterior.