Files
SGF/docs/PURCHASING_INSTALLATION_PROPOSAL.md
2026-11-02 20:29:34 +02:00

149 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SGF-IR-USABLE-401C-20261102 — proposta final sintética
**Estado: proposta para uma confirmação; NÃO executada.** Esta revisão substitui o destino/configuração da proposta anterior. A confirmação antiga 5fae não se aplica. Não instalar em sgf_tempo_dev nem alterar a demonstração 8039. O arquivo PURCHASING_INSTALLATION_PROPOSAL_401C_PRE_SYNTHETIC.md é histórico e não deve ser executado.
## Destino único proposto
| Elemento | Valor |
| --- | --- |
| Aplicação SGF de desenvolvimento | `C:/laragon/data/sgf-tempo/run/ir-usable-401c-20261102/app` |
| Ambiente / HTTP | `local`, `http://127.0.0.1:8041`, só loopback |
| Cluster PostgreSQL novo | `sgf_ir_401c_20261102`, dados em `C:/laragon/data/sgf-tempo/run/ir-usable-401c-20261102/postgres`, loopback **55441** |
| Base nova | `sgf_ir_dev_401c_20261102` |
| Migrador / runtime novos | `sgf_ir_owner_401c` / `sgf_ir_app_401c` |
| Credenciais | Novas, aleatórias e privadas fora do Git/raiz web; não alterar nem divulgar credenciais existentes |
| Backups privados | `C:/laragon/data/sgf-tempo/backups/SGF-IR-USABLE-401C-20261102` |
| Bundle na cópia | `packages/internal-requisitions` |
| Versão instalada de Compras | **0.1.1**, antes/depois, em original e cópia; candidata operacional separada |
A base real contém dados/configuração da Tempo e não é o destino desta operação. A instância sintética existente em 8039 já permite separação de empresas/unidades, mas a sua role é proprietária de users/permission_grants e tem CREATE no schema. Para preservar essa demonstração e garantir runtime sem propriedade/DDL, propõe-se nova base e cluster, sem alterar a role existente. Portas/pastas/nomes devem estar livres; se houver conflito, parar e rever a proposta, não escolher outro destino silenciosamente.
Fonte exclusivamente sintética: aplicação `C:/laragon/data/sgf-tempo/run/modular-regression-2576427d1939/development-app`, base `sgf_modules_dev_2576427d1939`, cluster 55439. Cópia consistente dos seus dados sintéticos com pg_dump e restauro sem owner/ACL no novo cluster; sem copiar linhas da Tempo ou de sgf_tempo_dev. Não copiar sessões, cookies, caches, credenciais, logs ou uploads indiscriminadamente. APP_KEY, cookie, storage e caches próprios; outbound mail/integrações externas desligados. Não arrancar workers/scheduler nem efectuar operações reais.
## Candidata e integridade
- Candidata: **OPERATIONAL-CANDIDATE-401ce31ae5f2dd20**, formato tempo.operational-review.v1, schema **revisão 2**. Não é release comercial 0.1.2.
- ZIP: `C:/laragon/www/compras/storage/app/private/candidate-archives/OPERATIONAL-CANDIDATE-401ce31ae5f2dd20.zip`.
- SHA-256 ZIP: `59dbdc64c4d9f14dfb4025a6177b829d136a4e2cb633ca036b10b5ae3197e703`.
- SHA-256 manifesto: `a6478223e17a5430652f0fcbf31a44a931ae2a99cd90b151c98d2df5df43c10b`.
- SHA-256 migração: `4ca4f5827c46e5ca29cb329c667df0b996ecbf5e318c0b157091c94e9d44ae92`.
Artefacto permanece inalterado. Os nove ficheiros de baseline da candidata foram conferidos por leitura na aplicação sintética existente: todos compatíveis. O código funcional modular continua identificado por **2a4169162bb4621a42a2ea1df627d52f860e7176**; fcf0ada é documental. Preservar seis módulos, Início e Opções gerais/configuração separados.
Na cópia nova, a identidade exacta da guarda TestingDatabaseGuard será adaptada de 55439/base/role antigas para 55441/base/role novas, sem aceitar curingas ou remover verificações. Registar hashes antes/depois; não adaptar guardas do original ou dos demais serviços para lhes abrir capacidades. Perfil de descoberta continua sintético, por user:tenant:company, sem conceder operações. Os antigos hashes de plano destinados a sgf_tempo_dev NÃO se aplicam: calcular novos planos vinculados à cópia/base exactas depois do provisionamento e antes de migrar; conferir destino, baseline e manifesto, sem trocar os hashes do artefacto.
## Contexto e valores de teste — todos sintéticos
Reutilizar, somente na cópia, o tenant **1** «Cliente de demonstração», empresa **1** «Empresa Horizonte — Demonstração» e unidade **1** «Unidade Central — Demonstração». Estes IDs são locais à base sintética, não identificam a Tempo. Preservar as empresas/unidades alternativas para testes de recusa; não lhes activar Compras internas.
| Configuração | Valor exacto proposto |
| --- | --- |
| Centro novo | `SYN-IR-401C`, exclusivamente empresa/unidade 1/1 |
| Departamento | `SYN-OPER`, centro e intervenientes associados explicitamente |
| Dotação | **50 000,00 MZN**, exercício **2026**, natureza `operating`, **inclui imposto** |
| Preparação / aprovação da dotação | Preparador sintético #1 / Revisor sintético #2, identidades distintas |
| Política inicial | Versão 1, enabled=true, budget_required=true, approval_includes_tax=true |
| Primeiro limite | **10 000,00 MZN** = 1 000 000 unidades menores |
| Segundo limite | **20 000,00 MZN** = 2 000 000 unidades menores |
| Motivo | «SINTÉTICO SGF-IR-401C — exercício de desenvolvimento; sem validade orçamental empresarial» |
Até 10 000 inclusive: responsável de departamento. Acima de 10 000 até 20 000 inclusive: departamento e Compras. Acima de 20 000: departamento, Compras e Financeiro, nessa ordem, por três aprovadores distintos e distintos do requerente. Sem auto-aprovação ou repetição do aprovador entre etapas. Nenhum limite representa uma decisão da Tempo.
O campo técnico rules_provisional é gravado como false pelo circuito existente ao guardar a política; significa configuração explícita desta política de teste, NÃO aprovação empresarial/fiscal real. Não alterar o motor ou inventar um valor não suportado para esse campo.
Exemplo de requisição: consumível 2 UN × 50,00 com imposto sintético de 16% = 116,00; serviço 1 UN × 25,00 a 0% = 25,00; outro 1 UN × 10,00 a 0% = 10,00. Base 135,00, imposto 16,00, total/reserva **151,00 MZN**, saldo disponível **49 849,00 MZN**. A taxa é um dado de ensaio, sem conclusão fiscal. Data pretendida: data local da execução +10 dias, registada na evidência. Equipamentos/peças rejeitados; não disfarçar como outros.
## Identidades e concessões exactas
Reutilizar #1 `gestor-modular-f40d500a09@example.test` (Desenvolvimento — Preparador), #2 `consulta-modular-f40d500a09@example.test` (Desenvolvimento — Revisor) e #3 `limitado-modular-f40d500a09@example.test` (Desenvolvimento — Consulta), preservando os seus direitos prévios na cópia. A origem e as contas reais permanecem intactas. #1 já possui access.manage no cenário modular; não remover esse direito histórico, mas não usá-lo como autoridade administrativa deste incremento.
Criar apenas na base nova três contas sintéticas: `admin-ir-401c@example.test`, `compras-ir-401c@example.test`, `financeiro-ir-401c@example.test`. IDs gerados serão registados e conferidos, não presumidos como 4/5/6. Senhas novas privadas, distintas; sem entrega em relatório. Cada conta nova: pertença só ao tenant/empresa 1/1, company.view nessa empresa e unit.view só na unidade 1. Administrador novo recebe também access.manage na empresa 1; as restantes contas novas não recebem administração.
Na tabela, R significa purchasing_requisitions e B significa purchasing_budget. Todas as concessões novas R/B são unitárias no âmbito **1:1:1**:
| Identidade | Direitos novos exactos |
| --- | --- |
| Preparador #1 | R.view, R.prepare; B.view, B.create, B.record |
| Revisor #2 / responsável de departamento | R.view, R.approve.department_head; B.view, B.approve, B.record |
| Consulta #3 | R.view, B.view |
| Compras novo | R.view, R.approve.procurement; B.view, B.record |
| Financeiro novo | R.view, R.approve.finance; B.view, B.record |
| Administrador novo | R.view, R.prepare, R.configure, R.approve.department_head, R.approve.procurement, R.approve.finance; B.view, B.create, B.approve, B.record |
Administrador recebe estes dez direitos porque a gestão nativa só permite delegar direitos próprios; não existe um direito separado de delegação. Portanto tem capacidade funcional acumulada, explicitamente declarada, mas não será utilizado para preparar/aprovar os exemplos. A separação do percurso é #1 → #2 → Compras novo → Financeiro novo; não alegar que o administrador é tecnicamente impedido de efectuar essas funções. B.record permite reserva/libertação pelo processo, inclusive rejeição; não concede movimentos directos, pagamentos ou consumo.
Não conceder B.consume, B.reinforcement.propose/review, unit.edit, direitos financeiros adicionais ou novos direitos noutras empresas/unidades. Não atribuir descoberta de desenvolvimento às contas novas por arrasto. #3 continua só de consulta. Não conceder novos direitos a #1/#2/#3 na origem 8039 nem a qualquer conta em sgf_tempo_dev.
Bootstrap: na base nova, criar/auditar as três identidades e permissões-base delimitadas; configurar temporariamente initialisation_scopes=["1:1:1"]; o novo administrador inicializa **apenas a sua própria autoridade** com os dez direitos enumerados, depois delega pelo ecrã Acessos os direitos exactos da tabela. Fechar initialisation_scopes=[] ao terminar. Registar concessões/auditoria e confirmar ausência de extras.
Membros da política: #1, #2, Compras novo e Financeiro novo associados a SYN-OPER; administrador/consulta sem papel aprovador na política. Centro criado pelo administrador; dotação preparada por #1 e aprovada por #2, pelas interfaces existentes. Sem SQL para fabricar centros, dotação ou decisão de requisição.
## Migração e mapa SQL mínimo incluídos na confirmação proposta
A fonte sintética tem **93 tabelas**, sem cb_*, ir_* ou sgc_installations (leitura confirmada). A migração revisão 2 adiciona **16**, resultando em **109 tabelas**, não 103. As provas anteriores 87→103 continuam válidas no seu âmbito; a instalação nova terá verificação própria 93→109.
Novas: cb_centres, cb_origins, cb_budgets, cb_budget_entries, cb_budget_consumptions, cb_budget_reinforcements, cb_audit, cb_ui_commands, cb_consumption_sources; ir_requests, ir_steps, ir_events, ir_commands, ir_policies, ir_policy_versions; sgc_installations. Alargar campo/constraint permission_grants, preservar dados; constraints/triggers/recibo. Não executar migrações genéricas de Compras ou down destrutivo.
Owner e runtime novos: NOSUPERUSER, NOCREATEDB, NOCREATEROLE, NOBYPASSRLS, sem filiação entre roles. Owner possui a base/objectos e executa DDL; runtime tem CONNECT/USAGE, sem propriedade ou CREATE/ALTER. No cluster novo, restringir PUBLIC/pg_hba para que as roles de aplicação/migração só se liguem à base nova; não alterar HBA/ACL de clusters existentes. Administração técnica do novo cluster é separada das contas funcionais.
Nos 93 objectos anteriores restaurados, repor para runtime apenas o mapa DML necessário já inventariado da ligação SGF sgf_dev_app (SELECT/INSERT/UPDATE/DELETE onde existente), USAGE das sequências e EXECUTE das funções exigidas. Não copiar propriedade/DDL da role sintética antiga; não GRANT ALL, TRUNCATE, administração ou DEFAULT PRIVILEGES globais. Conferir separadamente os seis objectos que excedem o schema 87 antes de lhes conceder acesso; começar sem privilégios runtime nesses seis se não forem dependências deste percurso. Qualquer dependência adicional exige revisão, não concessão silenciosa.
Nos **16 novos objectos**, aplicar o mesmo mapa mínimo anteriormente apresentado, emitido para **sgf_ir_app_401c** (não para sgf_dev_app):
| Tabelas | 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 |
REVOKE herdados runtime/PUBLIC só nos objectos novos antes do GRANT mínimo; sem DELETE/TRUNCATE de histórico ou DDL. O gerador e contrato são os mesmos; o JSON antigo com sgf_dev_app é referência histórica e não deve ser executado neste destino. A confirmação incluirá explicitamente este mapa para a role nova.
## Sequência única após confirmação — ainda não executar
1. Conferir artefacto, disponibilidade de caminhos/portas, fonte exclusivamente sintética e fingerprints dos originais/8039. Fazer snapshot consistente da fonte sintética e backup privado do seu código/configuração, sem alterar ou parar a origem.
2. Provisionar só cluster/base/roles/aplicação novos e restaurar a cópia sintética com owner novo. Isolar storage/sessões/credenciais/ligação. Aplicar apenas a adaptação de identidade exacta da guarda na cópia; registar hashes. Host novo começa em manutenção, operacional desactivado e sem servidor acessível externamente.
3. **Antes de qualquer migração da candidata**, fazer backup fresco do destino novo já restaurado (`before.dump`), código/configuração/ACLs/sequências e SHA-256. Restaurar efectivamente em `sgf_ir_restore_401c_pre` restrita no cluster novo; comparar as 93 tabelas, dados, schema, constraints/triggers/sequências e ACLs. Não migrar se falhar. A fonte sintética não substitui este backup do destino.
4. Recalcular os planos read-only para nova identidade exacta, validar nove baselines/manifesto e migrar com sgf_ir_owner_401c, backup e hashes conferidos. Aplicar mapa SQL mínimo à role nova. Conferir 93→109, recibo revisão 2 e preservação das linhas anteriores. Não usar os hashes de plano de sgf_tempo_dev.
5. Fazer prepared.dump e prova efectiva em `sgf_ir_restore_401c_post`, reconciliar 109 tabelas/contrato/ACLs. Aplicar código/assets com journal sob manutenção; manter ponteiro Compras 0.1.1. Sem caches globais partilhados; caches/sessões apenas desta cópia.
6. Activar a composição **apenas nesta aplicação/base sintéticas**: purchasing-operational.enabled=true; purchasing-internal.candidate_enabled=true; âmbito orçamental permitido apenas 1:1:1; modules.companies["1:1"] inclui Compras contratado/activo. Não activar empresas alternativas. Inicializar administrador/delegações exactamente como acima, fechar autoridade inicial, criar centro/dotação/política pela interface.
7. Verificar loopback, roles/DDL negado, permissões e isolamento entre empresa/unidade/módulo, CSRF/contexto/revogação; executar o exemplo 151 MZN com reserva única e aprovação por #2; testar recusas de auto-aprovação, tipos excluídos e saldo insuficiente sem escrita. Os percursos de múltiplas etapas usam as identidades distintas propostas. Reutilizar provas anteriores válidas; testes novos afectados pela identidade/configuração são necessários, sem repetir suites globais por rotina.
8. Fazer backup configurado, restaurar numa base de recuperação restrita e conferir origem/decisão/reserva. Retirar só a manutenção nova após checks; disponibilizar 8041 exclusivamente para desenvolvimento. Recomparar snapshots do original e 8039. Não tocar em serviços/dados de outras demonstrações nem parar clusters existentes.
## Recuperação e limites
Código: journal/backups dos nove overlays, manifesto e bundle anterior; rollback sob manutenção recusa divergências locais e não altera dados. Na nova instância, pode manter-se desactivado o percurso em falha sem afectar original/8039.
Schema: falha de DDL reverte transacção; após commit manter schema aditivo compatível ou aplicar correcção deliberada. Não executar down, apagar histórico ou supor que rollback de código remove schema.
Dados: usar before/prepared/configured.dump conforme o ponto de recuperação, restaurar em base alternativa restrita, reconciliar e reconfigurar ACLs mínimas. Troca da aplicação só para cópia conferida da própria base sintética; operações posteriores exigem reconciliação. Não sobrescrever sgf_tempo_dev, a base 8039 ou dados posteriores por automatismo. Guardar bundles não recupera dados.
Provas reutilizadas: 157 controlos integrados, 17 React/assets, 54 deployment, restauro efectivo de 103 tabelas da reprodução anterior, navegação 185/3220 + 8/90. Não são provas já executadas do novo cluster/destino proposto. Revisão visual permanece separada, sem nova tentativa pela via bloqueada. Associações antigas continuam sinalizadas e sem atribuição automática; volume/paginação pendentes. Sem equipamentos/peças, pagamentos, stock, emissão, contabilidade ou publicação no domínio.
## Texto da confirmação única proposta
«Confirmo SGF-IR-USABLE-401C-20261102 exclusivamente sintético: criar a cópia SGF no caminho indicado, cluster 55441/base sgf_ir_dev_401c_20261102 e roles separadas; reutilizar só as identidades/dados sintéticos da demonstração 8039 sem a alterar; aplicar a candidata 401ce31ae5f2dd20 e hashes indicados, migração revisão 2 e mapa SQL mínimo para sgf_ir_app_401c; configurar o centro, dotação fictícia de 50 000 MZN/2026, política/limites e concessões exactas desta proposta, com identidades distintas e autoridade inicial encerrada; efectuar backup fresco e restauros conferidos antes/depois, testes afectados e abertura apenas em loopback 8041. Preservar sgf_tempo_dev, Tempo, direitos públicos, alterações locais, navegação e Compras 0.1.1. Sem publicação; em divergência parar e recuperar no âmbito sintético.»
## Esclarecimento vinculativo do encerramento — ainda não autorizado
«Encerrar a autoridade inicial» terá DOIS efeitos obrigatórios: (1) configurar initialisation_scopes=[] e reiniciar apenas a instância nova para descarregar a configuração temporária; (2) revogar pelo circuito nativo auditado, exclusivamente de admin-ir-401c@example.test em 1:1:1, os seis direitos temporários abaixo, antes de abrir a demonstração:
- purchasing_requisitions.prepare;
- purchasing_requisitions.approve.department_head;
- purchasing_requisitions.approve.procurement;
- purchasing_requisitions.approve.finance;
- purchasing_budget.approve;
- purchasing_budget.record.
O administrador conservará SOMENTE: company.view e access.manage na empresa 1; unit.view, purchasing_requisitions.view, purchasing_requisitions.configure, purchasing_budget.view e purchasing_budget.create na unidade 1. Assim pode configurar política/centro e preparar dotações, mas não preparar/submeter requisições, aprovar dotações/requisições ou reservar/libertar pelo processo. Não é uma conta só de administração: B.create continua funcional e explícito. Se for necessária outra separação futura, exige decisão própria.
A revogação é individual via API/ecrã nativo, enquanto ainda detém cada direito a retirar, com motivo e auditoria. Não apagar grants por SQL para contornar auditoria. Verificar o conjunto final exacto e recusas por HTTP; se qualquer retirada/verificação falhar, conservar manutenção. Fechar scopes sozinho NÃO revoga direitos. Não retirar company.view/unit.view nem usar revogação em cascata. A autoridade inicial já auditada não é reaberta ou apagada.
Depois do encerramento, o administrador não poderá delegar nem revogar direitos que deixou de possuir pelo circuito normal; access.manage não contorna essa regra. Não haverá reatribuição temporária automática. Uma gestão futura desses direitos requer proposta explícita de autoridade compatível. Os direitos anteriormente delegados aos actores sintéticos mantêm-se. O access.manage histórico do preparador #1 na cópia permanece, conforme preservação anterior; este perfil não é usado como substituto administrativo deste incremento. Nada é revogado na demonstração 8039 ou no SGF real.
Plano SQL das identidades PostgreSQL: [novas roles/base](proofs/sgf-ir-401c-new-roles.sql), sem credenciais no ficheiro. Plano SQL final dos 16 objectos novos: [mapa dirigido a sgf_ir_app_401c](proofs/sgf-ir-401c-new-objects.sql), transaccional e condicionado a base/porta/migrador/revisão exactos. As contas funcionais continuam a ser criadas/delegadas/revogadas pelo bootstrap delimitado e circuito auditado, não recebem roles PostgreSQL individuais. Nenhuma alteração aos 93 objectos restaurados além do mapa DML anteriormente delimitado; os seis wc_* não recebem privilégios runtime. Os dois ficheiros SQL são propostas, não foram executados.
**Nenhuma das duas propostas está autorizada.** O texto de confirmação anterior só é válido se incluir também este esclarecimento e os planos SQL finais. Sem confirmação posterior do pacote completo, não provisionar, migrar, conceder, revogar, instalar ou activar. Preservar 8039 e sgf_tempo_dev intactos.