From 9a01426864a47dacd97db2b4da363aba86a94df6 Mon Sep 17 00:00:00 2001 From: nala Date: Sat, 14 Nov 2026 18:39:25 +0200 Subject: [PATCH] fix(offers): preserve description in authorised investment context --- app/Services/InvestorContext.php | 11 + .../unification/traceability-and-manual.md | 3 + .../v2/auditoria-portal/matriz-requisitos.csv | 2 +- .../ofertas-aceitacao-final-20261114.md | 14 +- .../ofertas-correcao-contexto-qa-20261114.md | 72 ++ .../focused.log | 1 + .../focused.xml | 9 + .../frontend-regression.log | 49 ++ .../integrated-report-input.json | 663 ++++++++++++++++++ .../location-analysis.json | 24 + .../phpstan.log | 1 + .../private-integrated-report.docx | Bin 0 -> 14783 bytes .../private-integrated-report.html | 3 + .../qa-result.json | 102 +++ .../regression.log | 1 + .../regression.xml | 35 + .../report-test.log | 9 + .../types.log | 3 + .../OfferInvestmentAcceptanceAuditTest.php | 123 +++- .../PrivateOfferConfidentialityTest.php | 10 + .../offer-investment-continuity.test.mjs | 94 +++ 21 files changed, 1219 insertions(+), 10 deletions(-) create mode 100644 docs/investmoz/v2/auditoria-portal/ofertas-correcao-contexto-qa-20261114.md create mode 100644 outputs/offers-investment-continuity-20261114/focused.log create mode 100644 outputs/offers-investment-continuity-20261114/focused.xml create mode 100644 outputs/offers-investment-continuity-20261114/frontend-regression.log create mode 100644 outputs/offers-investment-continuity-20261114/integrated-report-input.json create mode 100644 outputs/offers-investment-continuity-20261114/location-analysis.json create mode 100644 outputs/offers-investment-continuity-20261114/phpstan.log create mode 100644 outputs/offers-investment-continuity-20261114/private-integrated-report.docx create mode 100644 outputs/offers-investment-continuity-20261114/private-integrated-report.html create mode 100644 outputs/offers-investment-continuity-20261114/qa-result.json create mode 100644 outputs/offers-investment-continuity-20261114/regression.log create mode 100644 outputs/offers-investment-continuity-20261114/regression.xml create mode 100644 outputs/offers-investment-continuity-20261114/report-test.log create mode 100644 outputs/offers-investment-continuity-20261114/types.log create mode 100644 tests/frontend/offer-investment-continuity.test.mjs diff --git a/app/Services/InvestorContext.php b/app/Services/InvestorContext.php index f0da80d1..70239db0 100644 --- a/app/Services/InvestorContext.php +++ b/app/Services/InvestorContext.php @@ -193,6 +193,17 @@ final class InvestorContext $href = $published ? '/oportunidades/'.$o->slug : '/minhas-oportunidades/'.$o->id.'/view'; $version = $o->management_version; $fields = ['project_title' => $title, 'project_summary' => $draft['canonical']['executive_summary'] ?? $o->summary]; + if ($o->isPrivateOfferPreparation()) { + // Offers reuse Opportunity, but their preparation writes description, + // not the canonical executive summary. Keep this authorised private + // projection explicit: never copy private_offer (price/finances/contact). + $title = $draft['title'] ?? $o->title; + $summary = $fields['project_summary']; + $fields['project_title'] = $title; + $fields['project_summary'] = is_string($summary) && trim($summary) !== '' + ? $summary : ($draft['description'] ?? null); + $href = '/minhas-oportunidades/ofertas/'.$o->id; + } if ($o->sector) { $fields['sector_id'] = (string) $o->sector_id; $fields['sector'] = $o->sector->name; diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md index be8b9e05..f2cf5020 100644 --- a/docs/investmoz/unification/traceability-and-manual.md +++ b/docs/investmoz/unification/traceability-and-manual.md @@ -10202,3 +10202,6 @@ Estado: cinco fases preparadas em QA; F1-F4 aceites tecnicamente com ressalvas, # Auditoria de aceitação Ofertas — 14/11/2026, antes de instalar Referência: `../v2/auditoria-portal/ofertas-aceitacao-final-20261114.md`. Candidata `528a2597`; commits e hashes F1–F5 conferidos, JUnit aceite 59 testes/780 asserções confirmado sem o apresentar como nova execução. Nova regressão dos componentes nativos: 14/227 aprovada. Novo teste de integração: 2/11, um aprovado e uma falha na reutilização da descrição da Oferta pelo contexto de investimento; recuperação financeira privada e isolamento passaram. A aceitação integral permanece bloqueada: falta demonstrar Oferta → dossier → viabilidade em função da localização → relatório → recuperação. Publicação efectiva não implementada/activada; NDA real, visual/móvel, imagens e entrega real de email mantêm os estados específicos do relatório. Plano de instalação preparado, zero novas migrações no delta, schema do destino e reversão compatível por conferir. Nenhuma instalação ou alteração funcional efectuada nesta auditoria. RF-MN-003 actualizado sem alterar os restantes requisitos. +# Correcção Ofertas → contexto de investimento — QA, 14/11/2026 + +Após `ed2fd86f`, foi autorizada exclusivamente a correcção da continuidade. `InvestorContext` passa a recuperar a descrição da Oferta quando não existe resumo, mantendo a mesma Opportunity, os identificadores e a autorização privada. Resumo existente e edições deliberadas no dossier prevalecem. Não se copiam dados empresariais confidenciais, contactos ou preço privado; NDA/autorização do vendedor não concedem acesso ao contexto privado. A prova sintética percorre criação, submissão, revisão/aprovação, projecção pública isolada de teste, contexto/dossier, localização, pressupostos financeiros declarados, gravação/recuperação e relatórios HTML/Word. Não representa publicação real nem rentabilidade garantida. Recibo e resultados em `../v2/auditoria-portal/ofertas-correcao-contexto-qa-20261114.md` e `outputs/offers-investment-continuity-20261114/qa-result.json`; RF-MN-003 e matriz final actualizados. Mantêm-se pendências jurídicas, visuais, de imagens e email real. Sem instalação, activação pública, migrações ou alteração de dados operacionais; aguarda nova autorização para instalar. diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index f47a49f7..a81eb32b 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -163,7 +163,7 @@ RF-MIN-005,"Controlar cessão, mudança de controlo e aprovações.",upgrade v4 RF-MIN-006,Pesquisar e corresponder oportunidades mineiras.,upgrade v4 SHA f0b9815…; p. 3275; requirements-audit.csv,oportunidades,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /investidor/terra-duat; /investidor/terra-duat/novo; /investidor/terra-duat/{id}; /investidor/terra-duat/{id}/actualizacoes; /investidor/terra-duat/{id}/documentos; /investidor/terra-duat/{id}/documentos/{attachment}; /investidor/terra-duat/{id}/editar; /investidor/terra-duat/{id}/imprimir; /investidor/terra-duat/{id}/solicitar-apoio; /management/opportunities,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","RF-MIN-006: Filtros incluem recurso, fase, título, localização, valor, modalidade e infra-estrutura; recomendação é explicável e revista por gestor.",P2,RF-MIN-006: Relatório 25/09 conservado; estado histórico não promove conclusão,RF-MIN-006,1,"[{""id"":""RF-MIN-006"",""pedido"":""Pesquisar e corresponder oportunidades mineiras."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 3275; requirements-audit.csv""],""aceitacao"":""Filtros incluem recurso, fase, título, localização, valor, modalidade e infra-estrutura; recomendação é explicável e revista por gestor."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""oportunidades""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.opportunities: 6 registos; public.opportunity_images: tabela ausente; public.opportunity_documents: tabela ausente; public.opportunity_location_drafts: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources","030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: oportunidades. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,oportunidades,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/OpportunityManagement.php; app/Services/OpportunityResources.php; resources/js/pages/management/opportunity-draft.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"OpportunityManagementTest, OpportunityResourcesTest, OpportunityOriginReviewTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RF-MN-001,Registar utilizadores singulares e colectivos com verificação de contactos.,upgrade v4 SHA f0b9815…; p. 2957; requirements-audit.csv | portal do investidor\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 573 | portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3409 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 580 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2214 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3409,CRM/solicitações,//; /Simulador; /api/v1/documents/recommendations; /api/v1/investment/submissions; /api/v1/investment/submissions/{id}; /api/v1/investment/submissions/{id}/attachments; /api/v1/investment/submissions/{id}/attachments/{attachment}; /api/v1/investment/submissions/{id}/submit; /apoio; /balcao-virtual; /como-investir; /documentos,"investors/contacts/leads/tasks, OpportunityContacts, acompanhamento interno existente. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Converter sem duplicar, tarefa/responsável/próxima ação recuperáveis; corrigir apenas falha comprovada. Critério individual original preservado; cobertura atual ainda não individualizada.",Relações mestre/contexto e autorizações; não depende de CRM externo. C131 sóQA. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RF-MN-001: Conta só é activada após confirmação do correio electrónico ou telefone; tentativas e falhas ficam registadas. | MASTER-471012ab-0051: Registar utilizadores singulares e colectivos com verificação de contactos. | MASTER-e1169a77-0201: Registar utilizadores singulares e colectivos com verificação de contactos. | MASTER-f70ce307-0057: Registar utilizadores singulares e colectivos com verificação de contactos. | MASTER-51b8f0ad-0137: Registar utilizadores singulares e colectivos com verificação de contactos. | MASTER-edece80c-0201: Registar utilizadores singulares e colectivos com verificação de contactos.,P2,RF-MN-001: Relatório 25/09 conservado; estado histórico não promove conclusão | MASTER-471012ab-0051: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-e1169a77-0201: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0057: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0137: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0201: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,RF-MN-001 | MASTER-471012ab-0051 | MASTER-e1169a77-0201 | MASTER-f70ce307-0057 | MASTER-51b8f0ad-0137 | MASTER-edece80c-0201,6,"[{""id"":""RF-MN-001"",""pedido"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 2957; requirements-audit.csv""],""aceitacao"":""Conta só é activada após confirmação do correio electrónico ou telefone; tentativas e falhas ficam registadas."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-471012ab-0051"",""pedido"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""fontes"":[""portal do investidor\\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 573""],""aceitacao"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-e1169a77-0201"",""pedido"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3409""],""aceitacao"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-f70ce307-0057"",""pedido"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 580""],""aceitacao"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-51b8f0ad-0137"",""pedido"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2214""],""aceitacao"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-edece80c-0201"",""pedido"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3409""],""aceitacao"":""Registar utilizadores singulares e colectivos com verificação de contactos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.interest_requests: 4 registos; public.leads: 0 registos; public.investors: 3 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Converter sem duplicar, tarefa/responsável/próxima ação recuperáveis; corrigir apenas falha comprovada. Critério individual original preservado; cobertura atual ainda não individualizada.","investors/contacts/leads/tasks, OpportunityContacts, acompanhamento interno existente",Relações mestre/contexto e autorizações; não depende de CRM externo. C131 sóQA.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: acompanhamento. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,acompanhamento,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/CrmController.php; app/Services/DeclaredOriginStatistics.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InterestSubmissionTest, InvestmentWorkspaceTest, PortalOriginCompatibilityTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RF-MN-002,"Gerir perfis, representantes, funções e organizações.",upgrade v4 SHA f0b9815…; p. 2961; requirements-audit.csv,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.","outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | 02/11/2026: profile-json preserva erros por campo e reautenticacao em falhas HTML/419 e rejeita JSON invalido; contexto de investimento rejeita falso sucesso HTTP 200 e liberta keepalive, sem repetir escritas. 26 testes focados, TypeScript e build aprovados. Prova local parcial; sem dados/permissoes/publicacao. | Retoma 02/11/2026: profileJson GET independente de cookie CSRF malformado; POST recusa antes do transporte com mensagem de recuperacao. Preservadas validacao e credenciais. 14 testes focados aprovados, incluindo separadores de cookie sem espaco; sem mudanca de direitos.",Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",RF-MN-002: Uma organização pode ter vários utilizadores; cada acção identifica o utilizador e a função.,P2,RF-MN-002: Relatório 25/09 conservado; estado histórico não promove conclusão,RF-MN-002,1,"[{""id"":""RF-MN-002"",""pedido"":""Gerir perfis, representantes, funções e organizações."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 2961; requirements-audit.csv""],""aceitacao"":""Uma organização pode ter vários utilizadores; cada acção identifica o utilizador e a função."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, -RF-MN-003,"Criar, guardar, editar e submeter ofertas e procuras.",upgrade v4 SHA f0b9815…; p. 2965; requirements-audit.csv | portal do investidor\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 581 | portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3417 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 588 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2222 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3417,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle; /ofertas; /ofertas/{id}; /api/v1/offers; /api/v1/offers/{id}; /api/v1/offers/map; /api/v1/offers/export; /minhas-oportunidades/ofertas/{id}/recursos; /minhas-oportunidades/ofertas/{id}/confidencialidade; /minhas-oportunidades/ofertas/{id}/confidencial; /minhas-oportunidades/ofertas/{id}/nda; /minhas-oportunidades/ofertas/{id}/operacoes; /minhas-oportunidades/ofertas/{id}/denunciar; /minhas-oportunidades/ofertas/{id}/denuncias; /minhas-oportunidades/ofertas/{id}/destaque-administrativo,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual. | 14/11/2026 - Ofertas F1: oportunidades como cadastro principal; criar, guardar, recuperar, editar e submeter em privado; autorizacao existente, CRM e localizacao reutilizados; sem menu, publicacao ou instalacao. | 14/11/2026 F2 autorizada: circuito editorial privado no workflow e Dashboard existentes; revisao/atribuicao/rejeicao/correccao/reenvio/aprovacao interna; decisoes por snapshot/hash/ciclo, tarefas, auditoria e notificacoes. Sem publicacao ou instalacao. | 14/11/2026 F3 autorizada: consulta read-only da projeccao publica separada, filtros por categoria/localizacao/preco/moeda, grelha/lista/mapa administrativo e CSV. Barreira efectiva fechada; apenas amostras sinteticas em QA isolado podem ser consumidas por injeccao de teste. | 14/11/2026 F4 autorizada, campos propostos confirmados: particularidades opcionais de empresas/imoveis no mesmo rascunho; seis fotografias activas com edicao/retirada/restauro; originais cifrados e scan existente; comprovativos exclusivamente para validadores internos com ambito/MFA. NDA e autorizacao expressa do vendedor vinculados a versao/hash, revogacao e auditoria; exemplar juridico real pendente, configuracao nula. Sem publicacao ou instalacao. | 14/11/2026 F5 autorizada em QA: retirada imediata pelo dono, novo ciclo/v4 e aprovacao antes da reactivacao; validade congelada por versao, prazo configuravel nulo por defeito, expiracao independente de NDA/cron; denuncias cifradas com origem versionada, tarefas e Dashboard existentes; planos administrativos de destaque sem efeitos comerciais. Publicacao e instalacao bloqueadas.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.","outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | QA: PrivateOfferPreparationTest.php; regressao 35 testes/548 assercoes e passagem final focada 16/172 (grupos sobrepostos, nao somar). outputs/offers-private-phase1-20261114/qa-result.json. | F2 QA: 35 testes/499 assercoes; final focado 11/160; complemento contribuidores 1/14 e HTML compilado 1/10 aprovados, grupos sobrepostos. tests/Feature/PrivateOfferEditorialTest.php; outputs/offers-private-phase2-20261114/qa-result.json. | F3 QA: tests/Feature/OfferPublicCatalogueTest.php; outputs/offers-public-phase3-20261114/qa-result.json; sem instalacao ou publicacao real. | F4: tests/Feature/PrivateOfferConfidentialityTest.php; outputs/offers-private-phase4-20261114/qa-result.json. Cinco casos territoriais desbloqueados com fixture sintetico guardado em transaccao QA; sem dados operacionais. | F5: tests/Feature/PrivateOfferOperationsTest.php; outputs/offers-private-phase5-20261114/qa-result.json. Matriz de aceitacao das cinco fases no relatorio ofertas-fase5-fecho-qa-20261114.md; provas sinteticas e regressao afectada, sem testes gerais de outros modulos.",Parcial - Ofertas F1-F4 tecnicamente aceites com ressalvas; F5 implementada em QA para apreciacao; cinco fases nao instaladas; publicacao efectiva bloqueada,"Dependencias para uso publico: exemplar/versao/aprovacao do NDA; tipos juridicos de comprovativos; prazo/politica final de validade; avisos juridicos, visual/movel, GD/WebP e email real F2. Politica comercial/destaque activo nao definidos e nao activados. Publicacao/instalacao exigem autorizacao expressa. Procuras permanece por implementar.",Autorizacao expressa para Fase 3 e para instalacao; designacoes operacionais e configuracao de entrega reais apenas quando aplicaveis. Sem novos papeis ou permissoes por inferencia.,"RF-MN-003: Rascunho persiste; submissão bloqueia campos essenciais e gera número de protocolo. | MASTER-471012ab-0052: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-e1169a77-0202: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-f70ce307-0058: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-51b8f0ad-0138: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-edece80c-0202: Criar, guardar, editar e submeter ofertas e procuras.",P2,RF-MN-003: Relatório 25/09 conservado; estado histórico não promove conclusão | MASTER-471012ab-0052: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-e1169a77-0202: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0058: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0138: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0202: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,RF-MN-003 | MASTER-471012ab-0052 | MASTER-e1169a77-0202 | MASTER-f70ce307-0058 | MASTER-51b8f0ad-0138 | MASTER-edece80c-0202,6,"[{""id"":""RF-MN-003"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 2965; requirements-audit.csv""],""aceitacao"":""Rascunho persiste; submissão bloqueia campos essenciais e gera número de protocolo."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""governação/outros""},{""id"":""MASTER-471012ab-0052"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 581""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-e1169a77-0202"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3417""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-f70ce307-0058"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 588""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-51b8f0ad-0138"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2222""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-edece80c-0202"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3417""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]","QA - preparacao, revisao e historico privados; filtros e acesso pelo Dashboard existente; visual manual pendente",QA - operacoes autenticadas /minhas-oportunidades/ofertas e /{id}/revisao; MFA/ambito/conflitos verificados no servidor; publicacao recusada,"QA - cadastro Oportunidades, tarefas/auditoria/notificacoes nativos; snapshots e hashes por ciclo; sem tabelas ou migracoes novas","QA - recuperar oferta, correccao, decisao e versoes anteriores; conflitos, rollback e indisponibilidade sem downgrade | F4: guardar/recuperar particularidades; fotografias e provas no recurso existente; historico de aceitacao/autorizacao/retirada/revogacao por exemplar e versao, sem substituir dados ou decisoes. | F5: retirada sem perda de conteudo; revalidacao no mesmo identificador; historico de ciclos, expiracao, denuncias e planos administrativos com conflitos/etags.","QA - aprovacao interna privada distinta de publicacao; versao publica nativa anterior preservada | F3: projecao publica anterior preservada durante edicao/rejeicao da nova revisao; sem contacto, anexos ou coordenadas do negocio; moeda sem conversao. | F4: dados empresariais reservados so depois de NDA + autorizacao expressa do vendedor; comprovativos nunca entregues ao interessado. | F5: sem reexposicao de publicacao/grants antigos ao reactivar; exclusao uniforme em listas/filtros/mapas/API/CSV; validade opcional visivel quando definida; destaques administrativos privados.",Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,Auditoria antes da instalacao: ancestralidade F1-F5 e hashes do recibo 528a2597 confirmados; JUnit original 59/780 sem erros. Nova regressao nativa 14/227 aprovada. Teste integrado novo 2/11: 1 falha na reutilizacao da descricao no contexto de investimento.,"Corrigir perda da descricao; demonstrar Oferta -> dossier -> viabilidade territorial -> relatorio -> recuperacao, preservando confidencialidade e edicoes. Publicador efectivo ausente; NDA aprovado, comprovativos, prazo, visual/movel, imagens e email real pendentes.","Opportunity, PortalProfileAccess, OpportunityProfileWorkflow, OpportunityWorkflowTasks, documents/recursos, auditoria, Dashboard, filtros/mapa/API/CSV existentes; sem cadastro paralelo.","Decisoes juridicas concretas, processamento de imagens, conferencia visual/email e continuidade funcional. Destino/schema/reversao de homologacao ainda por conferir; sem instalacao autorizada nesta auditoria.","Exclusivamente auditoria final e plano de instalacao. Sem correccoes funcionais, publicacao, migracoes operacionais, dados reais ou mne.",Aceitacao tecnica parcial com ressalvas; aceitacao integral bloqueada por falha reproduzida e percurso integrado nao demonstrado.,Sem nova estimativa temporal nesta entrega; testes sobrepostos nao devem ser somados. Historico de estimativas conservado nas colunas anteriores.,docs/investmoz/v2/auditoria-portal/ofertas-fase5-fecho-qa-20261114.md; outputs/offers-private-phase5-20261114/qa-result.json; provas aceites F1-F4 referenciadas na matriz de aceitacao das cinco fases.; docs/investmoz/v2/auditoria-portal/ofertas-aceitacao-final-20261114.md; outputs/offers-final-acceptance-20261114/receipt-verification.json; native-integration.xml; investment-acceptance.xml,governação e demais cláusulas,14/11/2026 - auditoria final antes da instalacao; aprovado/ressalvas/bloqueado/nao verificado separados,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +RF-MN-003,"Criar, guardar, editar e submeter ofertas e procuras.",upgrade v4 SHA f0b9815…; p. 2965; requirements-audit.csv | portal do investidor\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 581 | portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3417 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 588 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2222 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3417,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle; /ofertas; /ofertas/{id}; /api/v1/offers; /api/v1/offers/{id}; /api/v1/offers/map; /api/v1/offers/export; /minhas-oportunidades/ofertas/{id}/recursos; /minhas-oportunidades/ofertas/{id}/confidencialidade; /minhas-oportunidades/ofertas/{id}/confidencial; /minhas-oportunidades/ofertas/{id}/nda; /minhas-oportunidades/ofertas/{id}/operacoes; /minhas-oportunidades/ofertas/{id}/denunciar; /minhas-oportunidades/ofertas/{id}/denuncias; /minhas-oportunidades/ofertas/{id}/destaque-administrativo,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual. | 14/11/2026 - Ofertas F1: oportunidades como cadastro principal; criar, guardar, recuperar, editar e submeter em privado; autorizacao existente, CRM e localizacao reutilizados; sem menu, publicacao ou instalacao. | 14/11/2026 F2 autorizada: circuito editorial privado no workflow e Dashboard existentes; revisao/atribuicao/rejeicao/correccao/reenvio/aprovacao interna; decisoes por snapshot/hash/ciclo, tarefas, auditoria e notificacoes. Sem publicacao ou instalacao. | 14/11/2026 F3 autorizada: consulta read-only da projeccao publica separada, filtros por categoria/localizacao/preco/moeda, grelha/lista/mapa administrativo e CSV. Barreira efectiva fechada; apenas amostras sinteticas em QA isolado podem ser consumidas por injeccao de teste. | 14/11/2026 F4 autorizada, campos propostos confirmados: particularidades opcionais de empresas/imoveis no mesmo rascunho; seis fotografias activas com edicao/retirada/restauro; originais cifrados e scan existente; comprovativos exclusivamente para validadores internos com ambito/MFA. NDA e autorizacao expressa do vendedor vinculados a versao/hash, revogacao e auditoria; exemplar juridico real pendente, configuracao nula. Sem publicacao ou instalacao. | 14/11/2026 F5 autorizada em QA: retirada imediata pelo dono, novo ciclo/v4 e aprovacao antes da reactivacao; validade congelada por versao, prazo configuravel nulo por defeito, expiracao independente de NDA/cron; denuncias cifradas com origem versionada, tarefas e Dashboard existentes; planos administrativos de destaque sem efeitos comerciais. Publicacao e instalacao bloqueadas.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.","outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | QA: PrivateOfferPreparationTest.php; regressao 35 testes/548 assercoes e passagem final focada 16/172 (grupos sobrepostos, nao somar). outputs/offers-private-phase1-20261114/qa-result.json. | F2 QA: 35 testes/499 assercoes; final focado 11/160; complemento contribuidores 1/14 e HTML compilado 1/10 aprovados, grupos sobrepostos. tests/Feature/PrivateOfferEditorialTest.php; outputs/offers-private-phase2-20261114/qa-result.json. | F3 QA: tests/Feature/OfferPublicCatalogueTest.php; outputs/offers-public-phase3-20261114/qa-result.json; sem instalacao ou publicacao real. | F4: tests/Feature/PrivateOfferConfidentialityTest.php; outputs/offers-private-phase4-20261114/qa-result.json. Cinco casos territoriais desbloqueados com fixture sintetico guardado em transaccao QA; sem dados operacionais. | F5: tests/Feature/PrivateOfferOperationsTest.php; outputs/offers-private-phase5-20261114/qa-result.json. Matriz de aceitacao das cinco fases no relatorio ofertas-fase5-fecho-qa-20261114.md; provas sinteticas e regressao afectada, sem testes gerais de outros modulos.",Parcial - Ofertas F1-F4 tecnicamente aceites com ressalvas; F5 implementada em QA para apreciacao; cinco fases nao instaladas; publicacao efectiva bloqueada,"Dependencias para uso publico: exemplar/versao/aprovacao do NDA; tipos juridicos de comprovativos; prazo/politica final de validade; avisos juridicos, visual/movel, GD/WebP e email real F2. Politica comercial/destaque activo nao definidos e nao activados. Publicacao/instalacao exigem autorizacao expressa. Procuras permanece por implementar.",Autorizacao expressa para Fase 3 e para instalacao; designacoes operacionais e configuracao de entrega reais apenas quando aplicaveis. Sem novos papeis ou permissoes por inferencia.,"RF-MN-003: Rascunho persiste; submissão bloqueia campos essenciais e gera número de protocolo. | MASTER-471012ab-0052: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-e1169a77-0202: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-f70ce307-0058: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-51b8f0ad-0138: Criar, guardar, editar e submeter ofertas e procuras. | MASTER-edece80c-0202: Criar, guardar, editar e submeter ofertas e procuras.",P2,RF-MN-003: Relatório 25/09 conservado; estado histórico não promove conclusão | MASTER-471012ab-0052: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-e1169a77-0202: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0058: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0138: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0202: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,RF-MN-003 | MASTER-471012ab-0052 | MASTER-e1169a77-0202 | MASTER-f70ce307-0058 | MASTER-51b8f0ad-0138 | MASTER-edece80c-0202,6,"[{""id"":""RF-MN-003"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 2965; requirements-audit.csv""],""aceitacao"":""Rascunho persiste; submissão bloqueia campos essenciais e gera número de protocolo."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""governação/outros""},{""id"":""MASTER-471012ab-0052"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 581""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-e1169a77-0202"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3417""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-f70ce307-0058"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 588""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-51b8f0ad-0138"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2222""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-edece80c-0202"",""pedido"":""Criar, guardar, editar e submeter ofertas e procuras."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3417""],""aceitacao"":""Criar, guardar, editar e submeter ofertas e procuras."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]","QA - preparacao, revisao e historico privados; filtros e acesso pelo Dashboard existente; visual manual pendente",QA - operacoes autenticadas /minhas-oportunidades/ofertas e /{id}/revisao; MFA/ambito/conflitos verificados no servidor; publicacao recusada,"QA - cadastro Oportunidades, tarefas/auditoria/notificacoes nativos; snapshots e hashes por ciclo; sem tabelas ou migracoes novas","QA - recuperar oferta, correccao, decisao e versoes anteriores; conflitos, rollback e indisponibilidade sem downgrade | F4: guardar/recuperar particularidades; fotografias e provas no recurso existente; historico de aceitacao/autorizacao/retirada/revogacao por exemplar e versao, sem substituir dados ou decisoes. | F5: retirada sem perda de conteudo; revalidacao no mesmo identificador; historico de ciclos, expiracao, denuncias e planos administrativos com conflitos/etags.","QA - aprovacao interna privada distinta de publicacao; versao publica nativa anterior preservada | F3: projecao publica anterior preservada durante edicao/rejeicao da nova revisao; sem contacto, anexos ou coordenadas do negocio; moeda sem conversao. | F4: dados empresariais reservados so depois de NDA + autorizacao expressa do vendedor; comprovativos nunca entregues ao interessado. | F5: sem reexposicao de publicacao/grants antigos ao reactivar; exclusao uniforme em listas/filtros/mapas/API/CSV; validade opcional visivel quando definida; destaques administrativos privados.",Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,Correcao QA autorizada apos ed2fd86f: InvestorContext projecta descricao da Oferta quando resumo ausente; mesma Opportunity e mesmo dossier. Prova controlada submissao/revisao/aprovacao -> publicacao sintetica isolada -> contexto/localizacao -> hipotese financeira -> HTML/Word -> recuperacao; dados NDA nao transferidos.,"Mantem publicador operacional bloqueado, NDA real/exemplar/versao, comprovativos juridicos, prazo final, conferencia visual/movel, processamento de derivadas e email real. A simulacao por custos declarados nao certifica rentabilidade nem todos os cenarios fiscais.","Opportunity, PortalProfileAccess, OpportunityProfileWorkflow, OpportunityWorkflowTasks, documents/recursos, auditoria, Dashboard, filtros/mapa/API/CSV existentes; sem cadastro paralelo.","Decisoes juridicas, processamento de imagens, visual/email. Instalacao depende de nova autorizacao; sem alteracao operacional ou mne.","Autorizacao exclusiva para corrigir continuidade em QA. Publicacao efectiva, novas funcionalidades, migracoes operacionais e instalacao proibidas nesta passagem.","Correcao implementada em QA, sem instalacao; provas afectadas e saldo de aceitacao no recibo de continuidade.",Sem nova estimativa temporal nesta entrega; testes sobrepostos nao devem ser somados. Historico de estimativas conservado nas colunas anteriores.,docs/investmoz/v2/auditoria-portal/ofertas-fase5-fecho-qa-20261114.md; outputs/offers-private-phase5-20261114/qa-result.json; provas aceites F1-F4 referenciadas na matriz de aceitacao das cinco fases.; docs/investmoz/v2/auditoria-portal/ofertas-aceitacao-final-20261114.md; outputs/offers-final-acceptance-20261114/receipt-verification.json; native-integration.xml; investment-acceptance.xml; docs/investmoz/v2/auditoria-portal/ofertas-correcao-contexto-qa-20261114.md; outputs/offers-investment-continuity-20261114/qa-result.json,governação e demais cláusulas,14/11/2026 - correcao da continuidade Ofertas/contexto e prova integrada QA; pendencias de publicacao e verificacoes restantes preservadas,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RF-MN-004,"Aplicar campos condicionais por tipo de pessoa, modalidade e fase.",upgrade v4 SHA f0b9815…; p. 2969; requirements-audit.csv,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","RF-MN-004: Campos aparecem e tornam-se obrigatórios conforme regras da matriz, sem perda de dados válidos.",P2,RF-MN-004: Relatório 25/09 conservado; estado histórico não promove conclusão,RF-MN-004,1,"[{""id"":""RF-MN-004"",""pedido"":""Aplicar campos condicionais por tipo de pessoa, modalidade e fase."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 2969; requirements-audit.csv""],""aceitacao"":""Campos aparecem e tornam-se obrigatórios conforme regras da matriz, sem perda de dados válidos."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RF-MN-005,"Validar formatos, intervalos, dependências, duplicados e consentimentos.",upgrade v4 SHA f0b9815…; p. 2973; requirements-audit.csv | portal do investidor\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 589 | portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3425 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 596 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2230 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3425,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","RF-MN-005: O sistema impede submissão inválida e apresenta mensagem associada ao campo e orientação de correcção. | MASTER-471012ab-0054: Validar formatos, intervalos, dependências, duplicados e consentimentos. | MASTER-e1169a77-0204: Validar formatos, intervalos, dependências, duplicados e consentimentos. | MASTER-f70ce307-0060: Validar formatos, intervalos, dependências, duplicados e consentimentos. | MASTER-51b8f0ad-0140: Validar formatos, intervalos, dependências, duplicados e consentimentos. | MASTER-edece80c-0204: Validar formatos, intervalos, dependências, duplicados e consentimentos.",P2,RF-MN-005: Relatório 25/09 conservado; estado histórico não promove conclusão | MASTER-471012ab-0054: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-e1169a77-0204: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0060: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0140: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0204: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,RF-MN-005 | MASTER-471012ab-0054 | MASTER-e1169a77-0204 | MASTER-f70ce307-0060 | MASTER-51b8f0ad-0140 | MASTER-edece80c-0204,6,"[{""id"":""RF-MN-005"",""pedido"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 2973; requirements-audit.csv""],""aceitacao"":""O sistema impede submissão inválida e apresenta mensagem associada ao campo e orientação de correcção."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""governação/outros""},{""id"":""MASTER-471012ab-0054"",""pedido"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""fontes"":[""portal do investidor\\upgrade do portal de investimentos.docx; SHA 471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f; w:p 589""],""aceitacao"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-e1169a77-0204"",""pedido"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 3425""],""aceitacao"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-f70ce307-0060"",""pedido"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 596""],""aceitacao"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-51b8f0ad-0140"",""pedido"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 2230""],""aceitacao"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-edece80c-0204"",""pedido"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 3425""],""aceitacao"":""Validar formatos, intervalos, dependências, duplicados e consentimentos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global. diff --git a/docs/investmoz/v2/auditoria-portal/ofertas-aceitacao-final-20261114.md b/docs/investmoz/v2/auditoria-portal/ofertas-aceitacao-final-20261114.md index 71b5f9c5..f5f6742a 100644 --- a/docs/investmoz/v2/auditoria-portal/ofertas-aceitacao-final-20261114.md +++ b/docs/investmoz/v2/auditoria-portal/ofertas-aceitacao-final-20261114.md @@ -4,6 +4,8 @@ **Decisão: aprovação técnica parcial com ressalvas; aceitação integral bloqueada.** As provas das cinco fases são válidas para os comportamentos que demonstram. Não demonstram uma publicação operacional nem a continuidade completa Oferta → dossier → viabilidade territorial. Foi reproduzida uma perda de reutilização da descrição nessa fronteira. +**Actualização posterior à auditoria `ed2fd86f`:** a correcção autorizada em QA está documentada em [Ofertas → Investimento](ofertas-correcao-contexto-qa-20261114.md). O saldo actualizado nas linhas abaixo substitui apenas o estado desses critérios; conserva-se a prova original da falha. O percurso controlado com hipóteses de localização e relatório foi demonstrado; publicação operacional e restantes dependências não foram activadas. + ## Evidência e limites - Confirmada a ancestralidade dos commits F1 `1f2990e4`, plano `6e302db6`, F2 `91c18573`, F3 `7691cab3`, F4 `e431de8b` e F5 `528a2597`. @@ -30,23 +32,23 @@ | Denúncias e tratamento no Dashboard, auditoria e destaques administrativos | aprovado com ressalvas | F5 cobre isolamento, fundamento cifrado, tarefas existentes, versões e responsável. Destaque só rascunho/arquivo, sem promoção/pagamentos. Visual pendente. | | Isolamento de utilizadores, páginas, APIs, anexos, mapas e CSV | aprovado com ressalvas | Suites F1–F5 e regressão nativa; leitura pública limitada à projecção, comprovativos internos, sem originais externos. Não equivale a teste de intrusão independente nem validação visual. | | Preservação da versão pública durante edição | aprovado com ressalvas | Contrato sintético de Ofertas e nova regressão nativa aprovados; não existe ainda versão pública operacional de Ofertas para demonstrar o percurso real. | -| Escrever uma vez: recuperar a descrição no contexto de investimento | bloqueado | Novo teste reproduz `project_summary` ausente embora `description` esteja guardada. `InvestorContext::reference` lê resumo canónico/`summary`, sem aproveitar a descrição da Oferta. | -| Reutilização de valores financeiros autorizados na viabilidade, por localização e factores do negócio | não verificado | Os campos privados são recuperáveis, mas não foi localizado um contrato específico que os leve ao simulador, explicite pressupostos territoriais e preserve alterações deliberadas. Não inferir viabilidade a partir de receita/caixa/preço. Falta prova integrada e decisão de mapeamento quando necessária. | -| Consulta da Oferta → acção no mesmo dossier → simulação → relatório → recuperação | bloqueado | Detalhe público apenas liga a regresso/denúncia e mapa; consulta normal fechada. O contexto nativo admite referências privadas autorizadas, mas não demonstra este percurso completo de aquisição/investimento. | +| Escrever uma vez: recuperar a descrição no contexto de investimento | aprovado | Correcção QA específica da transformação; descrição recuperada, resumo existente e alterações deliberadas preservados, sem truncar a origem nem duplicar registos. Prova e recibo no relatório de correcção. | +| Contexto territorial e hipóteses económicas autorizadas até à viabilidade | aprovado com ressalvas | Localização persistida até ao rascunho, custos de renda/transporte declarados pelo investidor, cálculo e comparação sensível aos custos. Valores empresariais confidenciais não são transferidos; não constitui conclusão automática sobre rentabilidade nem valida todos os cenários fiscais. | +| Percurso controlado QA Oferta → mesmo dossier → simulação → relatório → recuperação | aprovado com ressalvas | Criação/submissão/revisão/aprovação reais no teste, projecção pública sintética isolada, referência privada autorizada, rascunho/resultados no dossier e exportadores HTML/Word existentes. Abertura pública operacional continua bloqueada e visual pendente. | | Restantes oportunidades, pesquisa e recursos afectados | aprovado com ressalvas | Nova regressão 14/227 passou. Não constitui declaração de ausência de defeitos em todo o portal ou em serviços externos não ensaiados. | | Desktop/móvel e acessibilidade funcional | não verificado | Última evidência do conector: `The browser access host is unavailable`; não foi repetido o ciclo de reinícios. HTML compilado não substitui conferência visual. | | Entrega real de notificações por email | não verificado | Serviço existente e permissões foram testados com transporte de teste; SMTP/fila/recepção real não ensaiados. Não foram enviados emails operacionais. | ## Bloqueantes e ressalvas para decisão -1. **Integração funcional:** corrigir e repetir o teste da descrição; demonstrar, sem exposição pública, o percurso de contexto/dossier/viabilidade/relatório/recuperação. Definir o mapeamento autorizado de dados económicos e pressupostos da localização antes de transportar informação confidencial; preservar proveniência, moeda e escolhas deliberadas. Não confundir preço de aquisição com investimento total nem dados históricos com previsão. +1. **Integração funcional — corrigida em QA na passagem autorizada posterior:** o teste da descrição e a prova controlada contexto/dossier/viabilidade/relatório/recuperação passaram. A projecção limita-se a campos comuns autorizados; dados económicos confidenciais não são transferidos. Moeda e custos do investimento são hipóteses explícitas, sem confundir preço de aquisição com investimento total ou dados históricos com previsão. Qualquer novo contrato de transferência confidencial continua fora desta correcção. 2. **Publicação:** implementar e testar um publicador controlado, se autorizado em nova instrução. A aceitação do consumidor sintético não autoriza remover as barreiras existentes. Instalação privada de avaliação e abertura pública são decisões separadas. 3. **Jurídico:** faltam exemplar/versão/referência de aprovação do NDA, tipos admissíveis de comprovativo imobiliário, política final de validade e condições/avisos aplicáveis à divulgação. Não são motivos para invalidar as provas técnicas já aceites; bloqueiam os comportamentos dependentes. 4. **Imagens:** comprovar processamento seguro e derivadas numa instalação compatível, incluindo scan, metadados, acesso e limite de seis. Não instalar extensões nem declarar galeria pronta nesta auditoria. 5. **Visual e correio:** realizar conferência real desktop/móvel e entrega de email autorizada em ambiente de teste. Permanecem não verificados, sem solicitar que o utilizador repita autenticações nesta passagem. 6. **Reversão:** um retorno cego à F4 é inseguro como plano: a versão F4 de `PrivateOfferConfidentiality::approvedHash` não verifica `OfferAvailability`, enquanto a F5 o faz. Uma retirada de ciclo zero pode conservar o mesmo hash editorial. A reversão deve preservar a recusa de leitura de ofertas retiradas/expiradas e os históricos; não assumir que repor código antigo mantém as novas protecções. -Não foram corrigidas estas lacunas porque a instrução autoriza exclusivamente auditoria e preparação do plano. O teste falhado fica explícito como critério de aceitação por satisfazer; não foi convertido numa aprovação por caracterização da falha. +Na auditoria original não foram corrigidas lacunas por estar autorizada exclusivamente a auditoria. A falha histórica foi conservada; a autorização posterior permitiu a correcção delimitada agora comprovada, sem alterar os restantes bloqueios. ## Plano de instalação controlada — não executado @@ -61,4 +63,4 @@ Não foram corrigidas estas lacunas porque a instrução autoriza exclusivamente ## Resultado e próxima acção -Auditoria documental, hashes e regressões delimitadas concluídos com achados. **O módulo não está integralmente aceite para o percurso de investimento solicitado.** Próxima acção recomendada: autorizar a correcção da continuidade Oferta → contexto/dossier e a sua prova de viabilidade, mantendo os bloqueios públicos; depois concluir as verificações dependentes e submeter o pacote à autorização de homologação. Nenhuma instalação efectuada. +Auditoria original concluída com achados; a continuidade Oferta → contexto/dossier e a prova controlada de viabilidade/relatório foram corrigidas em QA por autorização posterior. **O módulo mantém ressalvas e bloqueios de publicação operacional, jurídicos e verificações pendentes.** Próxima acção: apreciar o recibo de correcção e as dependências restantes antes de qualquer autorização de homologação. Nenhuma instalação efectuada. diff --git a/docs/investmoz/v2/auditoria-portal/ofertas-correcao-contexto-qa-20261114.md b/docs/investmoz/v2/auditoria-portal/ofertas-correcao-contexto-qa-20261114.md new file mode 100644 index 00000000..cc943ac9 --- /dev/null +++ b/docs/investmoz/v2/auditoria-portal/ofertas-correcao-contexto-qa-20261114.md @@ -0,0 +1,72 @@ +# Ofertas → Investimento — correcção da continuidade em QA + +14/11/2026. Base: auditoria `ed2fd86f`, preservando F1–F5 até `528a2597`. Autorização exclusiva para investigar/corrigir a continuidade e demonstrá-la em QA. Sem instalação, publicação efectiva, alterações operacionais, migrações ou intervenção em `mne`. + +## Causa e correcção + +A reprodução antes da alteração confirmou o resultado anterior: dois testes, um aprovado e um falhado; o contexto não tinha `project_summary`. A descrição estava correctamente persistida em `Opportunity.description`, no mesmo identificador. A autorização já permitia ao dono consultar a Oferta. A perda ocorria na **transformação/recuperação**: `InvestorContext::reference('opportunity:…')` só projectava `canonical.executive_summary` ou `summary`, enquanto a preparação privada das Ofertas escreve `description`. + +O adaptador existente passa a usar a descrição guardada como alternativa para `project_summary`, **apenas para Ofertas privadas já autorizadas**, conservando qualquer resumo existente não vazio. O título vem dos valores correntes da mesma preparação e a referência aponta para a rota específica da Oferta. Não se criam registos, fontes, relações ou contratos paralelos. Não se trunca a descrição, não se grava uma cópia na Oportunidade e não se altera a origem ao confirmar dados no dossier. + +O reconciliador existente continua a apresentar prévia e confirmação, com versões, hash, proveniência e preservação de edições deliberadas. O teste integrado confirma que um resumo deliberadamente alterado no dossier não é substituído numa nova prévia da mesma Oferta. + +## Campos e confidencialidade + +| Informação | Continuidade autorizada | +| --- | --- | +| Identificador/chave da Oportunidade, versão, hash, título e referência | Contrato existente `opportunity:`; mesmo cadastro e dossier, sem duplicação. | +| Descrição | Alternativa para resumo apenas no contexto privado autorizado; resumo existente prevalece. Descrição longa preservada. Não é uma autorização de divulgação pública. | +| Referências administrativas e sector comum já cadastrado | Contratos existentes preservados; a localização do ensaio mantém o mesmo identificador até ao contexto e ao rascunho financeiro. Não se deduz cobertura, disponibilidade ou benefício fiscal. | +| Moeda, custos e pressupostos do investimento | Declarações explícitas do investidor no percurso existente. A moeda/preço da Oferta não se convertem automaticamente em moeda/investimento total do projecto. | +| `private_offer.business`, receitas, fluxo de caixa, preço privado, contacto, razões e comprovativos | Não são copiados pelo adaptador para o contexto, relatórios ou exportações. Os campos de sector guardados dentro da informação empresarial confidencial também não são promovidos ao sector comum por inferência. | +| Informação pública sintética | Apenas projecção pública separada e expressamente construída no teste. A descrição privada e os valores empresariais não passam para essa projecção. | +| Leitura por NDA e autorização do vendedor | Mantém o âmbito próprio: não concede acesso à referência privada do contexto. Novo teste confirma recusa 404 mesmo depois das duas condições satisfeitas; revogação e demais testes F4 permanecem válidos. | + +Não se introduziu um novo percurso de transferência de dados confidenciais. Qualquer futura reutilização desses dados precisa de autorização e contrato próprios; esta correcção não alarga direitos de consulta ou exportação. + +## Prova integrada reproduzível + +`OfferInvestmentAcceptanceAuditTest` usa exclusivamente `offers_phase1_20261114_test`, loopback:55441, com guardas e rollback existentes. Cria Oferta de empresa e referência provincial sintéticas, grava/recupera, associa contacto autorizado, submete, efectua revisão/aprovação por outra conta e conserva `status=draft`/`published_at=null`. + +O mesmo teste comprova catálogo normal vazio e injecta `OfferPublicCatalogue(true)` exclusivamente no contentor do teste, sujeito à guarda real da base isolada. A projecção aprovada/publicada sintética tem resumo público próprio; não se altera qualquer interruptor de publicação operacional. A referência privada continua sujeita a `PortalProfileAccess`. + +O dono selecciona a mesma Oportunidade num dossier, confere a prévia e confirma. Descrição e referência provincial chegam ao prefill existente do simulador. O investidor declara moeda e pressupostos de renda/transporte para esse local; guarda o rascunho financeiro, recupera-o e devolve os resultados com confirmação da revisão do contexto. Uma nova autenticação da mesma conta recupera o mesmo dossier e rascunho; outra conta é recusada. O teste confirma uma Oportunidade e um dossier, sem duplicações. + +O teste frontend consome o JSON produzido pela prova PHP, recupera o snapshot e executa os calculadores existentes: receita mensal sintética 10.000, renda 2.000 e transporte 1.000 produzem saldo operacional estimado de 7.000 MZN; custos alternativos expressamente declarados de 5.000 e 3.000 produzem 2.000 MZN. Custos fixos 3.000, preço unitário 100 e custo variável 50 dão ponto de equilíbrio de 60 unidades. Estas hipóteses demonstram sensibilidade aos custos do local; **não atribuem uma tarifa provincial, uma margem real da empresa ou rentabilidade garantida**. Receita histórica confidencial da Oferta não é usada como previsão. + +O mesmo teste gera o relatório privado HTML e Word pelo exportador existente, reabre o Word e verifica descrição/localização, recuperação do snapshot e ausência dos valores confidenciais e contacto. Os artefactos são sintéticos, não documentos de negócio nem uma aceitação visual. + +Durante a preparação da prova, a referência provincial inicial não tinha a proveniência exigida pelo catálogo público; foi corrigida apenas a fixture isolada, reutilizando o contrato de `OpportunitySearchFixture`. O pedido do simulador foi ajustado à lista de campos já aceite e à confirmação da revisão de contexto. Nenhuma guarda foi desactivada para passar o ensaio. + +## Ficheiros e verificação + +- Produto: `app/Services/InvestorContext.php`, projecção delimitada de descrição/título/referência. +- Testes PHP: `OfferInvestmentAcceptanceAuditTest.php`, persistência, resumo existente, descrição longa, dossier/rascunho/resultados e isolamento; `PrivateOfferConfidentialityTest.php`, acesso por NDA sem concessão de acesso ao contexto privado. +- Teste frontend: `tests/frontend/offer-investment-continuity.test.mjs`, cálculo com pressupostos territoriais declarados e relatório real com reabertura do Word. +- Documentação: matriz RF-MN-003, manual e matriz final de aceitação existentes; este recibo explica a correcção sem apagar a prova histórica da falha. + +Resultados e comandos finais: `outputs/offers-investment-continuity-20261114/qa-result.json`. Não somar passagens sobrepostas nem apresentar os 59/780 históricos como executados novamente nesta correcção. + +| Verificação final | Resultado | +| --- | --- | +| Continuidade Oferta/contexto e percurso integrado | 4 testes / 62 asserções aprovados | +| Confidencialidade, incluindo NDA sem acesso ao contexto privado | 11 / 161 aprovados | +| Percursos existentes de investimento/dossiers | 4 / 192 aprovados | +| Gestão nativa de Oportunidades e versão pública | 3 / 46 aprovados | +| **Passagem PHP integrada** | **22 testes / 461 asserções; zero erros/falhas** | +| Regressão frontend de plano financeiro e relatórios | 41 testes aprovados | +| Prova frontend ligada ao JSON da passagem PHP final | 1 teste aprovado; HTML e Word gerados/reabertos | +| PHPStan completo, TypeScript e Pint | Aprovados; zero erros PHPStan | +| Lint/formatação do novo teste frontend; diferenças Git | Aprovados | + +Comando PHP final: `php vendor/bin/phpunit tests/Feature/OfferInvestmentAcceptanceAuditTest.php tests/Feature/PrivateOfferConfidentialityTest.php tests/Feature/InvestorPathTest.php tests/Feature/OpportunityManagementTest.php --log-junit outputs/offers-investment-continuity-20261114/regression.xml`, com a configuração sintética/guardada acima. Frontend: `node --test tests/frontend/investor-dossier-report.test.mjs tests/frontend/business-financial-plan.test.mjs`, seguido de `node --test tests/frontend/offer-investment-continuity.test.mjs`. Análise: `php vendor/bin/phpstan analyse --no-progress --memory-limit=1G`, `npm.cmd run types:check`, Pint nos três ficheiros PHP e `vp fmt --check`/`vp lint` no novo teste. A compilação QA anterior é reutilizada porque não mudou código frontend do produto; os testes PHP preservaram os assets existentes. + +## Saldo para aceitação + +**Corrigido em QA:** descrição na fronteira Oferta/contexto, preservação de resumo e edições deliberadas, recuperação no mesmo dossier, ensaio de localização/pressupostos → cálculo → relatórios HTML/Word → recuperação, sem passagem de dados financeiros confidenciais. + +**Mantém-se bloqueado:** publicação efectiva operacional; NDA real enquanto faltar o exemplar aprovado; decisões jurídicas/prazo definitivos identificados na auditoria. A injecção de projecção sintética não substitui esse fecho. + +**Por verificar:** conferência visual desktop/móvel, processamento de derivadas de imagens/galeria no ambiente compatível e entrega real de email. A simulação demonstrada é uma análise controlada com hipóteses declaradas, não uma prova de todos os cenários fiscais e factores de rentabilidade do portal. + +Nenhuma instalação efectuada ou autorizada por este recibo. A eventual instalação aguarda nova autorização expressa, com o plano de cópia/restauro e reversão compatível já documentado. diff --git a/outputs/offers-investment-continuity-20261114/focused.log b/outputs/offers-investment-continuity-20261114/focused.log new file mode 100644 index 00000000..cb07957b --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/focused.log @@ -0,0 +1 @@ +{"tool":"phpunit","result":"passed","tests":4,"passed":4,"assertions":55,"duration_ms":25651} diff --git a/outputs/offers-investment-continuity-20261114/focused.xml b/outputs/offers-investment-continuity-20261114/focused.xml new file mode 100644 index 00000000..8121e35d --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/focused.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/outputs/offers-investment-continuity-20261114/frontend-regression.log b/outputs/offers-investment-continuity-20261114/frontend-regression.log new file mode 100644 index 00000000..e0d55c82 --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/frontend-regression.log @@ -0,0 +1,49 @@ +✔ financial forecast reconciles revenue, finance sources, working capital and monthly cash (25.013875ms) +✔ opening payable installments reduce cash without changing profit and retain unpaid balances (4.962292ms) +✔ opening payable schedule caps cent rounding at the remaining balance (0.817417ms) +✔ monthly unit schedules drive revenue, costs, inventory and scenario volume (11.337458ms) +✔ monthly unit schedules must match the horizon and contain valid quantities (2.604459ms) +✔ monthly prices and unit costs affect revenue, consumption and scenarios (4.282666ms) +✔ monthly money schedules cover the horizon and reject invalid amounts (2.09225ms) +✔ monthly operating and payroll expense schedules remain separate from payments (3.289125ms) +✔ monthly operating schedules require full horizon, exact cents and current snapshot version (18.074292ms) +✔ losses and negative closing cash remain visible instead of being clamped to zero (3.032334ms) +✔ principal repayments affect cash but are excluded from profit expenses (2.658625ms) +✔ depreciation allocation reconciles exactly over useful life (1.653209ms) +✔ missing currency, products, invalid numbers and invalid horizons are explicit errors (1.136708ms) +✔ versioned plan snapshots restore assumptions and reject unsupported or oversized data (3.091333ms) +✔ business plan serializer refuses snapshots above the server storage limit (0.349541ms) +✔ sales invoicing and receipts follow an optional declared collection lag (0.986292ms) +✔ scheduled collection percentage keeps unpaid invoices in receivables with exact rounding (0.648709ms) +✔ sales recovery applies only to overdue invoices and never exceeds open balances (1.041541ms) +✔ opening receivables affect cash only when a month and collection percentage are declared (0.967791ms) +✔ opening receivable installments reconcile to the initial balance across months (1.622958ms) +✔ opening receivable installments cap independently rounded cents at the available balance (2.369541ms) +✔ inventory purchases, consumption, closing stock and stock shortfall reconcile independently of payments (0.385875ms) +✔ inventory lead time separates monthly orders, receipts, shortages and goods still in transit (0.667ms) +✔ monthly inventory purchase schedule reconciles variable orders, lead times, receipts and transit (1.319042ms) +✔ monthly variable purchase payments affect cash independently from inventory orders and profit (0.722625ms) +✔ product inventory schedules reconcile independently and do not transfer stock between products (6.993292ms) +✔ supplier payment terms drive purchase cash flow and expose amounts due beyond the horizon (2.183292ms) +✔ supplier order installments reconcile exact cents, cash dates and unallocated balances (0.841625ms) +✔ business assumptions survive the existing encrypted-draft snapshot split and restore (0.779958ms) +✔ presentation currency conversion requires and reports its rate, date, and declared source (1.636458ms) +✔ CSV marks presentation currency conversion as an unverified user planning assumption (1.087958ms) +✔ business plan export carries its assumptions, formulas, period, currency, and matching result (0.447959ms) +✔ business plan CSV preserves declared monthly product schedules (0.446125ms) +✔ CSV export exposes the sales collection assumption and outstanding receivable (0.320583ms) +✔ business plan CSV neutralizes formula-like labels and preserves negative financial values (0.323792ms) +✔ financial scenarios expose user-declared changes without creating tax values (5.431667ms) +✔ one dossier groups stage evidence, SWOT, fiscal and all preserved APIEX versions without modifying sources (5.195167ms) +✔ cross-dossier or cross-opportunity preparation is rejected and an ambiguous scope requires selection (1.404625ms) +✔ financial results from a different opportunity do not enter the consolidated report or its index (0.736833ms) +✔ the consolidated report reuses loan, break-even, financing and budget outputs with currency and historical state (14.746791ms) +✔ the existing Word and print exporters retain dossier identity, pending stages, source and history, escaping active HTML (131.861583ms) +ℹ tests 41 +ℹ suites 0 +ℹ pass 41 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 964.394334 diff --git a/outputs/offers-investment-continuity-20261114/integrated-report-input.json b/outputs/offers-investment-continuity-20261114/integrated-report-input.json new file mode 100644 index 00000000..6b0e0a0b --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/integrated-report-input.json @@ -0,0 +1,663 @@ +{ + "path": { + "funding_selections": [], + "preparation_action": null, + "private_investment": null, + "case": { + "id": "f71a2833-c182-43ba-862d-234e4b64739b", + "title": "Synthetic acquisition acceptance", + "version": 5, + "closed": false + }, + "journey_id": "a0851462-2b7f-47dc-bb0f-59c2a5004e36", + "definition_id": "61000919-0000-4000-8000-000000000001", + "definition_version": 1, + "source_sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364", + "phases": { + "1": "Ideia e viabilidade", + "2": "Formaliza\u00e7\u00e3o e dossier", + "3": "Licenciamento e terra", + "4": "Financiamento", + "5": "Execu\u00e7\u00e3o e acompanhamento" + }, + "steps": [ + { + "code": "S01", + "phase": 1, + "title": "Sistematizar a ideia", + "branch": null, + "sequence": 1, + "dependencies": [], + "source_paragraph": 22, + "id": "9f12bd89-308a-4e94-9cc3-df4822dea011", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + }, + { + "code": "S02", + "phase": 1, + "title": "An\u00e1lise preliminar", + "branch": null, + "sequence": 2, + "dependencies": [], + "source_paragraph": 23, + "id": "369a3135-119c-42d2-83d2-6b5e3ff9e659", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S03", + "phase": 1, + "title": "Decis\u00e3o sobre a viabilidade", + "branch": null, + "sequence": 3, + "dependencies": [], + "source_paragraph": 24, + "id": "0480e4d9-2265-4921-8338-83a0f728d49f", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S04", + "phase": 1, + "title": "Estruturar o investimento", + "branch": null, + "sequence": 4, + "dependencies": [], + "source_paragraph": 25, + "id": "882503f7-e30d-4c8d-b7ca-fb157bda2dc7", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S05", + "phase": 2, + "title": "Constitui\u00e7\u00e3o e registo", + "branch": null, + "sequence": 5, + "dependencies": [], + "source_paragraph": 26, + "id": "c3c87f28-f26a-42d0-80e9-74b412ae2ca5", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + }, + { + "code": "S06", + "phase": 2, + "title": "Preparar o dossier", + "branch": null, + "sequence": 6, + "dependencies": [], + "source_paragraph": 27, + "id": "57865d31-78f3-4961-a065-49efd4ff15e8", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + }, + { + "code": "S07", + "phase": 2, + "title": "Submeter quando aplic\u00e1vel", + "branch": null, + "sequence": 7, + "dependencies": { + "submit": [ + "S06" + ] + }, + "source_paragraph": 28, + "id": "18dd4fa9-c309-4031-88eb-f4c27ab69e47", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": { + "submit": [ + "S06" + ] + }, + "context_review_required": false + }, + { + "code": "S08", + "phase": 3, + "title": "Licenciamento pr\u00e9vio", + "branch": null, + "sequence": 8, + "dependencies": [], + "source_paragraph": 29, + "id": "65d81f1c-da8d-4f2b-af0d-a6a049cbe54b", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S09", + "phase": 3, + "title": "Necessidade de terra", + "branch": null, + "sequence": 9, + "dependencies": [], + "source_paragraph": 30, + "id": "b1a99d72-5ca6-4cb1-8a0a-7e35f1890392", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + }, + { + "code": "S10", + "phase": 3, + "title": "Regulariza\u00e7\u00e3o da terra", + "branch": "land_needed", + "sequence": 10, + "dependencies": [], + "source_paragraph": 31, + "id": "162637cf-d578-4a75-87b9-369996834843", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "undetermined", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + }, + { + "code": "S11", + "phase": 3, + "title": "Confirmar regulariza\u00e7\u00e3o aplic\u00e1vel", + "branch": null, + "sequence": 11, + "dependencies": [], + "source_paragraph": 32, + "id": "2c7d86f2-7426-4c6c-8ed4-cae8b6e68c99", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + }, + { + "code": "S12", + "phase": 4, + "title": "Necessidade e estrutura de financiamento", + "branch": null, + "sequence": 12, + "dependencies": [], + "source_paragraph": 33, + "id": "7bdb6b9b-324d-49e2-a133-5865b423c830", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S13", + "phase": 4, + "title": "Dilig\u00eancia e negocia\u00e7\u00e3o financeira", + "branch": "external_funding", + "sequence": 13, + "dependencies": [], + "source_paragraph": 34, + "id": "60bdbf70-8bbb-4771-abda-4f82b3f3e53e", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "undetermined", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S14", + "phase": 4, + "title": "Decis\u00e3o do financiador", + "branch": "external_funding", + "sequence": 14, + "dependencies": [], + "source_paragraph": 35, + "id": "69a00105-ed81-4679-a0de-536b995d6b3e", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "undetermined", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S15", + "phase": 4, + "title": "Fecho e desembolso", + "branch": "external_funding", + "sequence": 15, + "dependencies": { + "execute": [ + "S14" + ] + }, + "source_paragraph": 36, + "id": "4b70d527-bdfd-4792-9fd9-a3cc7c397f28", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "undetermined", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": { + "execute": [ + "S14" + ] + }, + "context_review_required": true + }, + { + "code": "S16", + "phase": 5, + "title": "Implementa\u00e7\u00e3o", + "branch": null, + "sequence": 16, + "dependencies": [], + "source_paragraph": 37, + "id": "9c838949-2537-4d81-b848-adf20be1b789", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + }, + { + "code": "S17", + "phase": 5, + "title": "Inspec\u00e7\u00f5es, testes e licen\u00e7a de opera\u00e7\u00e3o", + "branch": null, + "sequence": 17, + "dependencies": [], + "source_paragraph": 38, + "id": "8864abd3-fc9a-40f8-ad5f-22a84d87e10a", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": true + }, + { + "code": "S18", + "phase": 5, + "title": "In\u00edcio de opera\u00e7\u00e3o", + "branch": null, + "sequence": 18, + "dependencies": { + "operate": [ + "S17" + ] + }, + "source_paragraph": 39, + "id": "dc259b0e-2c14-422d-8309-dbd817f17ca4", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": { + "operate": [ + "S17" + ] + }, + "context_review_required": false + }, + { + "code": "S19", + "phase": 5, + "title": "Acompanhamento recorrente", + "branch": null, + "sequence": 19, + "dependencies": [], + "source_paragraph": 40, + "id": "22afbc5a-daec-473b-bd69-d90605d6d604", + "version": 1, + "state": "not_started", + "saved_state": "not_started", + "applicability": "applicable", + "reason": "", + "detail": { + "state": "not_started" + }, + "preparation_allowed": true, + "action_gaps": [], + "context_review_required": false + } + ], + "facts": { + "land_needed": "unknown", + "external_funding": "unknown", + "viability": "unknown" + }, + "fact_reasons": [], + "context_opportunity": null, + "opportunity_options": [], + "fintech": null, + "canWrite": true, + "canReview": false, + "next": { + "code": "S01", + "title": "Sistematizar a ideia", + "action": "Preparar", + "href": "#S01" + }, + "investment_context": { + "opportunity_choices": [], + "preparation_documents": [], + "preparation_snapshot": null, + "revision": 1, + "selection": { + "opportunity": { + "key": "opportunity:4", + "kind": "opportunity", + "id": "4", + "title": "Synthetic acquisition acceptance", + "version": 5, + "href": "\/minhas-oportunidades\/ofertas\/4", + "fields": { + "project_title": "Synthetic acquisition acceptance", + "project_summary": "Existing company description to reuse once in investment preparation.", + "province": "Synthetic province", + "province_id": "22fd440c-f744-4647-86a6-348c01c194d7", + "location": "Synthetic province" + }, + "documents": [], + "visibility": "private", + "state": "approved", + "sha256": "b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e" + } + }, + "fields": { + "project_title": "Synthetic acquisition acceptance", + "investment_regime": "general", + "special_zone_id": "", + "currency": "MZN", + "project_summary": "Existing company description to reuse once in investment preparation.", + "province": "Synthetic province", + "province_id": "22fd440c-f744-4647-86a6-348c01c194d7", + "location": "Synthetic province" + }, + "provenance": { + "project_title": { + "kind": "dossier", + "id": "f71a2833-c182-43ba-862d-234e4b64739b", + "version": 2 + }, + "currency": { + "kind": "process_declaration", + "actor_id": 8, + "context_revision": 1 + }, + "project_summary": { + "key": "opportunity:4", + "kind": "opportunity", + "id": "4", + "title": "Synthetic acquisition acceptance", + "version": 5, + "href": "\/minhas-oportunidades\/ofertas\/4", + "documents": [], + "visibility": "private", + "state": "approved", + "sha256": "b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e" + }, + "province": { + "key": "opportunity:4", + "kind": "opportunity", + "id": "4", + "title": "Synthetic acquisition acceptance", + "version": 5, + "href": "\/minhas-oportunidades\/ofertas\/4", + "documents": [], + "visibility": "private", + "state": "approved", + "sha256": "b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e" + }, + "province_id": { + "key": "opportunity:4", + "kind": "opportunity", + "id": "4", + "title": "Synthetic acquisition acceptance", + "version": 5, + "href": "\/minhas-oportunidades\/ofertas\/4", + "documents": [], + "visibility": "private", + "state": "approved", + "sha256": "b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e" + }, + "location": { + "key": "opportunity:4", + "kind": "opportunity", + "id": "4", + "title": "Synthetic acquisition acceptance", + "version": 5, + "href": "\/minhas-oportunidades\/ofertas\/4", + "documents": [], + "visibility": "private", + "state": "approved", + "sha256": "b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e" + } + }, + "review_steps": { + "S02": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S03": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S04": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S08": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S12": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S13": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S14": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S15": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + }, + "S17": { + "revision": 1, + "reason": "O contexto mudou; reveja os pressupostos e a evid\u00eancia aplic\u00e1vel." + } + }, + "dependency_hash": "1311d8539ea6a08237003a36712145618834461dd63b510658b5419e95af46dd", + "updated_at": "2026-11-14T16:35:56+00:00", + "updated_by": 8, + "requirements_assessment": { + "version": "context-requirements-20261023", + "requirements": [], + "fiscal_notice": "Localiza\u00e7\u00e3o, corredor, cluster ou projecto \u00e2ncora n\u00e3o activam benef\u00edcios fiscais. O simulador mant\u00e9m as condi\u00e7\u00f5es, fonte, per\u00edodo e \u00e2mbito pr\u00f3prios; condi\u00e7\u00f5es ausentes permanecem indeterminadas." + }, + "complements": [] + }, + "results": [ + { + "id": "a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8", + "source_key": "3b31db9e28c3d4b33f05812d6292408541b24e06f720861cbea1350cd9b0b1c2", + "draft_id": "38f76a31-44ea-4815-b523-d99046475518", + "draft_version": 1, + "snapshot_sha256": "aa09f1d3ea78bbc8eccd5336548bd39466946799030e5459fe1b42e89587d87b", + "financial_snapshot": "{\"version\":1,\"data\":{\"budgetPeriod\":\"Mensal\",\"loan\":{\"principal\":\"100000\",\"rate\":\"0\",\"months\":\"24\",\"rateType\":\"nominal\",\"periodMonths\":\"1\",\"gracePeriods\":\"0\",\"upfrontFee\":\"0\",\"recurringFee\":\"0\"},\"breakEven\":{\"fixed\":\"3000\",\"price\":\"100\",\"variable\":\"50\"},\"funding\":{\"total\":\"100000\",\"secured\":\"30000\"},\"incomes\":[{\"label\":\"Synthetic scenario revenue\",\"amount\":\"10000\"}],\"expenses\":[{\"label\":\"Declared rent at synthetic province\",\"amount\":\"2000\"},{\"label\":\"Declared transport at synthetic province\",\"amount\":\"1000\"}]}}", + "context_opportunity": null, + "currency": "MZN", + "engine": "financial-calculators:v1", + "kind": "local_calculation_inputs", + "context_state": "current", + "context_revision": 1, + "context_dependency_hash": "1311d8539ea6a08237003a36712145618834461dd63b510658b5419e95af46dd", + "recorded_at": "2026-11-14T16:35:59+00:00" + } + ], + "requests": [], + "documents": [], + "fiscal_reports": [], + "land_report": null, + "preparation_report": null, + "company_reports": [], + "zone_contexts": [], + "sector_contexts": [], + "sector_references": [], + "content_sources": [], + "tasks": [], + "services": [], + "tools": { + "funding": "\/fundos?kind=institution&location_mode=physical&context=f71a2833-c182-43ba-862d-234e4b64739b", + "simulator": "\/simulador-fiscal?context=f71a2833-c182-43ba-862d-234e4b64739b&draft=38f76a31-44ea-4815-b523-d99046475518", + "preparation": null, + "company": "\/investimentos\/f71a2833-c182-43ba-862d-234e4b64739b\/forma-juridica", + "desk": "\/balcao-virtual\/dossiers\/f71a2833-c182-43ba-862d-234e4b64739b", + "guidance": "\/balcao-virtual\/dossiers\/f71a2833-c182-43ba-862d-234e4b64739b\/orientacao", + "library": "\/documentos?context=f71a2833-c182-43ba-862d-234e4b64739b", + "opportunities": "\/oportunidades?context=f71a2833-c182-43ba-862d-234e4b64739b", + "territory": "\/zonas?context=f71a2833-c182-43ba-862d-234e4b64739b", + "partners": "\/parcerias\/painel?context=f71a2833-c182-43ba-862d-234e4b64739b", + "land": "\/investidor\/terra-duat\/novo?context=f71a2833-c182-43ba-862d-234e4b64739b" + } + }, + "saved": { + "project_title": "Synthetic acquisition acceptance", + "currency": "MZN", + "project_summary": "Existing company description to reuse once in investment preparation.", + "province_id": "22fd440c-f744-4647-86a6-348c01c194d7", + "journey_type": "investor", + "purpose": "simulate_only", + "context_applicability_snapshot": "{\"version\":1,\"context_revision\":1,\"consumer_opportunity\":null,\"portfolio_origin\":null,\"zone\":null,\"provenance\":{\"project_title\":{\"kind\":\"dossier\",\"id\":\"f71a2833-c182-43ba-862d-234e4b64739b\",\"version\":2},\"currency\":{\"kind\":\"process_declaration\",\"actor_id\":8,\"context_revision\":1},\"project_summary\":{\"key\":\"opportunity:4\",\"kind\":\"opportunity\",\"id\":\"4\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5,\"href\":\"\\\/minhas-oportunidades\\\/ofertas\\\/4\",\"documents\":[],\"visibility\":\"private\",\"state\":\"approved\",\"sha256\":\"b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e\"},\"province\":{\"key\":\"opportunity:4\",\"kind\":\"opportunity\",\"id\":\"4\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5,\"href\":\"\\\/minhas-oportunidades\\\/ofertas\\\/4\",\"documents\":[],\"visibility\":\"private\",\"state\":\"approved\",\"sha256\":\"b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e\"},\"province_id\":{\"key\":\"opportunity:4\",\"kind\":\"opportunity\",\"id\":\"4\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5,\"href\":\"\\\/minhas-oportunidades\\\/ofertas\\\/4\",\"documents\":[],\"visibility\":\"private\",\"state\":\"approved\",\"sha256\":\"b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e\"},\"location\":{\"key\":\"opportunity:4\",\"kind\":\"opportunity\",\"id\":\"4\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5,\"href\":\"\\\/minhas-oportunidades\\\/ofertas\\\/4\",\"documents\":[],\"visibility\":\"private\",\"state\":\"approved\",\"sha256\":\"b175039f4c49e40278436403a6aea19f218e03c3d9cb602583f0394caecd1f4e\"}},\"opportunity_choices\":[],\"complements\":[],\"requirements_assessment\":{\"version\":\"context-requirements-20261023\",\"requirements\":[],\"fiscal_notice\":\"Localiza\u00e7\u00e3o, corredor, cluster ou projecto \u00e2ncora n\u00e3o activam benef\u00edcios fiscais. O simulador mant\u00e9m as condi\u00e7\u00f5es, fonte, per\u00edodo e \u00e2mbito pr\u00f3prios; condi\u00e7\u00f5es ausentes permanecem indeterminadas.\"},\"path\":{\"definition_id\":\"61000919-0000-4000-8000-000000000001\",\"definition_version\":1,\"source_sha256\":\"aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364\",\"steps\":[{\"code\":\"S10\",\"title\":\"Regulariza\u00e7\u00e3o da terra\",\"state\":\"not_started\",\"applicability\":\"undetermined\",\"reason\":\"\",\"context_review_required\":false},{\"code\":\"S13\",\"title\":\"Dilig\u00eancia e negocia\u00e7\u00e3o financeira\",\"state\":\"not_started\",\"applicability\":\"undetermined\",\"reason\":\"\",\"context_review_required\":true},{\"code\":\"S14\",\"title\":\"Decis\u00e3o do financiador\",\"state\":\"not_started\",\"applicability\":\"undetermined\",\"reason\":\"\",\"context_review_required\":true},{\"code\":\"S15\",\"title\":\"Fecho e desembolso\",\"state\":\"not_started\",\"applicability\":\"undetermined\",\"reason\":\"\",\"context_review_required\":true}]},\"land_preparation\":{\"need\":\"unknown\",\"reason\":\"\"},\"field_provenance\":{\"project_title\":{\"kind\":\"dossier\",\"version\":2},\"currency\":{\"kind\":\"process_declaration\",\"context_revision\":1},\"project_summary\":{\"kind\":\"opportunity\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5},\"province\":{\"kind\":\"opportunity\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5},\"province_id\":{\"kind\":\"opportunity\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5},\"location\":{\"kind\":\"opportunity\",\"title\":\"Synthetic acquisition acceptance\",\"version\":5}},\"preparation\":null,\"fields\":{\"investment_regime\":\"general\",\"currency\":\"MZN\"},\"notice\":\"Refer\u00eancias e declara\u00e7\u00f5es para prepara\u00e7\u00e3o; sem reconhecimento autom\u00e1tico de elegibilidade ou benef\u00edcio.\"}", + "financial_tools_snapshot": "{\"version\":1,\"data\":{\"budgetPeriod\":\"Mensal\",\"loan\":{\"principal\":\"100000\",\"rate\":\"0\",\"months\":\"24\",\"rateType\":\"nominal\",\"periodMonths\":\"1\",\"gracePeriods\":\"0\",\"upfrontFee\":\"0\",\"recurringFee\":\"0\"},\"breakEven\":{\"fixed\":\"3000\",\"price\":\"100\",\"variable\":\"50\"},\"funding\":{\"total\":\"100000\",\"secured\":\"30000\"},\"incomes\":[{\"label\":\"Synthetic scenario revenue\",\"amount\":\"10000\"}],\"expenses\":[{\"label\":\"Declared rent at synthetic province\",\"amount\":\"2000\"},{\"label\":\"Declared transport at synthetic province\",\"amount\":\"1000\"}]}}" + } +} \ No newline at end of file diff --git a/outputs/offers-investment-continuity-20261114/location-analysis.json b/outputs/offers-investment-continuity-20261114/location-analysis.json new file mode 100644 index 00000000..e08825ee --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/location-analysis.json @@ -0,0 +1,24 @@ +{ + "scope": "Synthetic investor-declared costs at the selected location; no automatic profitability or fiscal entitlement", + "province_id": "22fd440c-f744-4647-86a6-348c01c194d7", + "budget": { + "incomeTotal": "10000.00", + "expenseTotal": "3000.00", + "operatingBalance": "7000.00", + "status": "estimated" + }, + "breakEven": { + "contributionPerUnit": "50.00", + "breakEvenUnits": "60", + "breakEvenRevenue": "6000.00", + "status": "estimated" + }, + "alternative": { + "incomeTotal": "10000.00", + "expenseTotal": "8000.00", + "operatingBalance": "2000.00", + "status": "estimated" + }, + "source_offer": "opportunity:4", + "case_id": "f71a2833-c182-43ba-862d-234e4b64739b" +} \ No newline at end of file diff --git a/outputs/offers-investment-continuity-20261114/phpstan.log b/outputs/offers-investment-continuity-20261114/phpstan.log new file mode 100644 index 00000000..1b1222c3 --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/phpstan.log @@ -0,0 +1 @@ +{"tool":"phpstan","result":"passed","errors":0} diff --git a/outputs/offers-investment-continuity-20261114/private-integrated-report.docx b/outputs/offers-investment-continuity-20261114/private-integrated-report.docx new file mode 100644 index 0000000000000000000000000000000000000000..1aaabe8bd33ec355d8b0c2f714e6020f28a5e1c8 GIT binary patch literal 14783 zcmc(GWmKHY((d3A2oRj$?ykWhxJz(%cMTrg-QC>+1b5fq?(V@|F4@`H$<8_7UHAU_ zdaZY6)|!5*tGlbax}NG+S_}jf8t}c0`BHo3HtDjXgZS>7- z|EUQ1m#oNjZw)XY03Zt#0KoirMLkPhdvkpYJ8CC$GwScq(wJe3PF#2&&F*y#-F#z= z4|w(Rkv64^5V%f{*$H6nc_zy(1-Dhjke6-N5DB-8xC+UZoO+t8u9ngj^fXG~1>#G( z6tjjkZYrOLKVAZP=Tvk$HeV{Ue$uE2>ua$-{s5tJx2V)sF^-l`**gPyYe=Mx;u3C8A6j@e-t5!mmor1F7Wtzyc+-W+o5wELg-o>s-2 zI!(G*W%jbSO9b(96 z65oK-&<8yv5~bEC7dJe5tI+h7@{Rz7QTISSOlmn4py{s62RJ{+`N!~?(rV^#A_4$b zWk3LgpTqb2z#XNkS`x6t^|nH1b^}A@=@;5nQTC$S9UhC*jH6b6qz`VA`4H1(_o0&S z^XA|L*YUXyH_yjwygtAq5)61k?-Wa-)Mx*aWW7NPWgDT~GZBn0)Mav%PjDU_dXe@m zcN+q$(df}Z!6!M}n2e@AzGWv)tZapkw@c?ATLokCGKJg_K1a_J$<=VXKTh4YAzENo zNJqC}H6{4)jYq<*q_bn$9NYCfZ`zrFhWMLUVb_z?6i$z2j7cBIfXQQlF2?c&R&rSh zjKXiwIVx|c373zVypy;mkLu7DW0QoQxMYt|)kZ^T^=`q~ig=IhfgGkx&XtCZ^dvfJ#eB@TEHi*E5~orUA?|Bp zEMW!*rDT)L6s3IGM02{=v^~g}9=ml*EPfcYsVloFO~-XT)x`EUZ3<-P)A30MUvx?1 zm|C7|9ZucC6?B(WKlWVNs^AVkTT6na9+_;9329Rhek(7koxH-UW{FFTJb4zF(!IeM z7~Vn)C6$T7a#a;;>*is~8Vi+oi$k*adAUypaTaxmo|}*0c}`OG+;%dgiTy59l0jlD7H}FKpOdD>;&p4ca}=s#%)jV-wDQMy+_#z77!3Yrt;X%15cy z%Zxc6kIm;N3xd7dXJ{MZjB}l+5IC&){n`clnZ4Tm)T@B$`{p=B%Nq6)hJE|j3qk}g zYBLX@5}uSQ5sA9XLBhgV{(=Mwt`Hg+5XpVj@+^<}sg_BPHD&LDxk95)5(_;=WZ^PT zmDjD2p$KNgF(dMQ)DvVUZfWu`_|6G}gt#2Z9-MjbwMee>V*)lmZ9kuMwUbb9Pqd`O zzAA!h@wX++=aw9?^aIEak$TCt&HBl?&`Ckoq!WW7)1jY7Y_C`-<;_5ID7*rz$w-7* z^G$jd%;*@-WzdAb8H7wipF}=AGtsBr99P%^IrH;fekjkw)FQObZ>1B+Q=2ojU)u=a zwR=mCYG(5l6RIl3zl~-x-uVl%g?{4H}B*XxtkNQ=n6( zl&P5XL~aF2KQXvDuqNhrRaW2%FlwtC4`-i0)>oA{;!TMp9lP{oDQfMfxo#=j-*@D4 zwTjlT%u_lI8`L-%(Ad9`OH{KX4MHhS_^O6#1-_CK3$?@G@0SEV^9WytN=`wgBCB3( zDi;25p*Zg<^rV^5a-pv$y1kFl-?&-4Tq{3N=id;dmF!!`|M0?L9Us^ z<-8@@MC@4YWeInKZ_xRt)J8`i$0jGe!+RF}MQv1$Ea#V06b#G07Kp14x{2toeV7@( zOctZI+c2B!xACtZ=Gn%oRWjNnGDcE#O1C(zfBg2bZ}q~`4`$?J>JAxf)(2r@q<5|= zp&bO$p+}Q_I$`F>{TKw~pG)z%e1+%U(~5-8R9Hi(BCqBFGePf`dbO0W(v}U9YZ1U4 z$9v9w2rn#GqKdZd&KFyM=TFt^ENs29$W^cy;X&F7PH#qAy$tV1`c<$r2hBC15Uqt) zi48ZuI|V>r32c&1wRC z)!gQd)De_~R#hf?AqRZ+$kcSQw3K1)Bq-7Mh9dZ)437PDev37@eeJzDSB}BgH1NIw zd`O@&H>^|cWC{Lbt6@wxYsmEF_(P^Ch6m7GD>@;rW1e z)YS0pVEA=Bn`;$mUJt|#)?UIjQ*B`Q`f{MC0rD&sSj<>wU!QL*={H3gs&a0EMEQn4 z8>FnS)G)$(qEyx?C#X>>`J<4jStv3XjuqI74>=^8*`I@g<}SbuSu53l9XfUEzj<@k9dvS^U18I!;lIr^5I*gg+=<(|YA&-jl z3gLyQQ3V5F3&F()s}ElnHV59qL9V%-M`~B;;ys8PqaP@Js-j#$|wF&VvsJ&f^V9*TMKWn!roq_@v$AN=W?%HBc3N9UI^Jua2&~xo+$h za)=Th@kq5!5$2i2HxmO|;Oh7SJVI-RtvuVJ!@ToJJrnSZJKB8-)ffk^+<1+_1#cQ2 zQS;JD=7e~>pM*~OzysbUw!m^6FZSlqvgr+Nll`&MhJVx2TSK&Wl3z%*hxD}+VW^`~ zNvsF)kv}_rV{*m4S`VutXYCv{UP@5(e6G5zBV2)u9QlUt5!u?eLVto`}=Td*HjKnIC zdL6}D6?$=f`>z&6nA158k0%e=&R2uA2wi=vpoLWk&B=s=7e}I$X$mo9pFjm<~029(!c0KHW!4VfO^l_R=P_cBP)nJ+?LDXo`74LE8?Vpg!ho~ zybL}k-x2UV=0@KU6H<5_&$~8W6;#p8kPFQ-Ctg~?3!^_8^1EW}@8yzUc@*7-CR^K@ z4rD^8gIp9UTLS^Qo^Tn%*h%LMUuCcbqa~(JTYI&!9^k9-dD6J^!b>V}{oROzKHVD# z#=_#RNaS=M=C=s9WPVzsDVTmcNng8azVNCWp;)nr`vLnMc`~q0Gkm3m*Kh?Zr!~ac zKI}|!gAZiTNXAd7DsR9eeEC_*XxYXL#|GMJqmAjnGt_5}>96rF z%dcQz3qQx5ixLsS2Ocx&NPz>bK0!GQ(LV>6(Ct+E6jOfi+b)2qUu3&#OH$qX}{YKeAZ=@x| z(>StujEEgR@X4<@t9@LlS1>XSEH=6djZx6v@GpPEXN8Mch$|`Dc){o0Q(|{q(DjGb z?+z5h+SsLct8N>)Sd|94(SxD$*;!WiVA|%!f}=NlUB~0c37t-0FPl8W6?)NYb2obo z!?xonRK9Q04FxXo&ZxRa&C-Pk)yDq25EDb5wDOtihj_Zi&y4(C$5l=NvqE{S+iVo&%mL#st;^i?A@x!kY)wO0zi7%yD*5(h+J)w>yS<+d zCssehXa|MV+mNl$ip(wGZ=rh`(rG(1&fI18fpp*p%TJl_-LaNn?g*k z(yj3l#xM&d`n<7Vw9Tcn}9cRBCQ=t2)W!8BlhH=qFSju4N=?Ul6m>=_hH+`2;zCjkvr*DK*R0B_j2mu*M zUyZmTSaEMFyruKG9TxdjxXr?wKK7obyfeQPx=cI33{4rU(5_zIV_&)}STLDs&dxT-pJ6+6NPUX#9$G6kC|3Nj@n3)+9cQ>)_#4=cnqemk zG;uNUr|796np$8tIqcAD=v_YDsB2-D7^J{~UuYc4CaWwQPv;@bOtSQk#{?bCBJ(!O zm1c~d;5grQQur`++(|0E^07yLJXTO@%|?wGrPWwxI+j~3RU7so()8)rM88BdZ+UM) zQ2Py44<~vQlk+*&XrhZVx=F!_Zn>$J)|BTWUqc0c$~F}Q>O_1 zhlZdiA#n@1fyQ?b{Z@h}M#3qOE_zf?5n~9D;|K3=JzQZx4#hKM zOyrvrOUL`xoDOiaoLbkOOPyD$&^~j7X3X|aNVXnN)`ZUE>>TOO#IRdxY@S(Bp_#eeVY0$3DN)NgI);Xu5gk>~}HZb3PJaf3{O)k`*gtE+w zlSMg%tRQ$%ymh4N^D3p(?Uc>uN*?B~ww?@}v&f6%$W8jx8%Zb;{_#DQ9C`S8aa`OZ zs_db$>O!d(;8&E2;_ER|$ZD4u2Z}ck>&=)>y@hG&Vlo;f8=*7g_e)HI=}U*jkz?$d z=-vU;-fseo-rGUJr*fEUycd^^e|3&~dzcw3yq~(lDj*xr8+aClkv}*VU8}{t%t)0j z>@-mw^I40=vzdp9!};?4M>-(}+|EI1DRd_UI`o19XB{s+29zF{d%q>A%8dxEop&*{ z3~l|%FYWH%UJBTe+%dp;VwvzU$*>I)kQs2;MXs@r3#)@#I8m z7IG$XaulN0Uj}ey>aOGvk_3AoXWw`tVJF4-Yg=4;HYtb{fvhbU3l&&{=ld5)k^3b# z&xwdy2FPuD!0xY#5l4Pbthq?ADNGq{-wV=mGXE%r0WT^q4&}Srm+Q<% zI@VFb;OEhC(Wtx+7rn%RX=`lrE}tnunCm%_R)U~v%`?g1*!mlaHL|UJ)}#`oRekM{ zg`$IUyEb#4bUG70#3FlPKdJ`J7<&>-xhxO=;S@tfTE~G#>k>OJB!8j12K50)Bhd>=^lduB45Cx#ioX-7t+ATsbIDzv%D7O?BBsXZ`A7e?sMTkWskwcUFLgyd{D~)nBhD|6DI!rr|EtPAMSo8Jy z#xYN2E#*%$Y-}WMFjTrZoMH&gztX{!qn|F-m79V0n(Wo1n@-0z6e4Np0mJ1AAm!C{ z3$1gvcK?E5T^R;Hqr=*u4nNSw5w#qHVl$w?DUAiMzz$pesn|fLhaUisa+P zkRj%z!HptEpO0f2#CmYlt{Lv2-}+|mH_%tGlQ=0f_W;V%@0{d-8?opjmenWYBlkGR zFU3m?{TW(^F`!?M+%VW4-;l)93k*ag0ob5S)uUu3_iZ}z@eadQ5_&&qR{^O2m_E@{ zlD=&Jd7su7^?h)!>Y5brCL1HkmJUp-O%D?DV8jb@F3BP!zzDe0K(dRGCS0mm?HBgO zn01G^^(*B8?WpT_(buoznwV_M{7CKzpZRG;Q9>tU>wBAa*c9^8)uSK%>g#AYFH_{o zueO(C?wLa&_@N-S;x``s#Bie1BX+jK;?urNP1WXz(>>;Fdx^PzrPV*HAlH$SiuL!I z72@W9pGK&V4=+CRR-B3{mo~3g!sm;ekV`IuC|D*iX9j@IIWAkU+bd{P34L5~53~CQ z{GJQ{Z9;_NYr4RbEVWRYEoQ4eEBvdy(5yS5!n5NJf&C@IFY<`K&Cu+z)!)AI&loFm z9;DcuREU==YLOXTUQo8ao#EQsHZqHr=@AxTfdvM>{!|#cc}?46 z_Hl@-8G@xNmC1uko`xln1~;v7Q_<@u;=MB{Zo7Qgan%@$>&y#Yl09#bXbbnuuVN5; z4zKnc*!Q}*-Jc+SuFwBWOF+G>&leh8+Q!oA&x}Js7FK-COU8lkWhsBB%>SvTYiXnZ zeIe&Ysam|nL-MQr9&vG;8m6>)+gBz z)z*bgVzPV(o|69UVP{q%&tGXv*1q-Bijlm1U8b=o``e+{@S77l1&G zKuKSPTS%NNIQTIh{KO5};*OLu1pYxKS<_wpqN4I~Nsk#%W%0gRCr}E6^T;}V?-Esf4-L(Edw-5v&&jF= zf+3J|*Fx8?mB!0O0SS_)OOSga4;si7(Urk~Hi3e7+v;n=SRT zX`{r6POh7PExqQbFBfnDguL5+z3b&L#=1D}sEs=uml3;cO+zaKKEX|-*Wee)-gUOI z(VV+sk8df?AXVk!#7}tXG#WRC(x8DPY|0n%`&01KlWJ!M-;(D=@0F}Kt)q%@nI;c@ zsV_+O^B}v@pdA@~GFopfAPGQAXKhh!@qmmewzyN?O3;^)v=T>cDZ?2vQIVt63( zE{5_}2Dd^V^rWYnm0{%piH-k$`&juTBd3R+NDfKemo$T3jxBl+$<4zRORzKh_=E_C4l7L zyoR2!?L3oO?rDbA{x&G~`ZWwV4y+~?5}v$`h#TKG8ADS%8APzsQ(n91^G~+>@0JPN zj>SDZo)5RV^^Pd>gF_piOdi_wUNdv2X7yK0SK`|!*X|xz@4B7#pwE=>?~R!XKU)`F zkcPP!;k10Z()5s=;tJ{Etk%@*ibR*p=dA8UwKm`}fji0$W@R|FPglXx>`FxUbu+QI zL7yji`TB@3-+O9Z6Lfvt8d{X`WJcZTeQy(oLkUc(xoXJ0=xn#+cM#X4yCAsMTydv- zx9POA(ssoC(>(ukrviU5&;OPf#mSC}+kW|P8J{)Y6hPNMV1TKRoeadys`6rI>%VP;q@-Zj#nqMHJ3iE!zYK%R%k%c-`77uAV@wPzE$#Ge=>AC)ON8*g2F8OCDCcW% z45AL9>m0Ipt#tu_Rlt4iE3L!PLaF}Lbp6!ies00F$cSuhl|qSzqM0W0$-CE$T}?}U z`|Y<$|4h0MOaut_@Gj+w?=K@6_Tdk%7w!iYR!?i<{?Qxn%IMK$ zKe?0FsGX9`b0|3`3vQJpS3{Oh8!`sAr~EY{aGRsMpY#u6h%$1?WM;tb&u%yNQ`F5^ z_%)nGKNUONYU#IQd@~=ZkA@{(n}#MrHzaS36SS85K}B+Kpy1IAcy#RO-wOgrC(AnoZ`$KOGJmbJpS0`5XZ_1l`%d z3LRvhIOxQ}cZJ_mBJ>J7CD|%uf$sCKD{>BJ_YN<&z*t?;v`yzT?IejC!ZC7$I%I!C ziSt9PypnKNOJbK8Dnmd~!X$N2vmmor(WBpNHhLwf#FBP;4$b38ORPe}2x_eN z%~cj-_U(>gs0txnXnIuWMkSSFf!QnGS0+21R`qTkkJ@E=YMqcvPhdY6@DKl@@7+3>sK3H~WJ9FD`Oj=@p zSv}A9ohh;fv2WP3S!B1x>q9V`MVxy?PFddtD}E^!65W^oV5qMsatOE9+dflVdqKli z@z@k?*y?{+cm@0KF04PK&PTtf{(X=6ZmRzrgS4%z{;j{yp?T4($nom8)<;YJ+wO0DFgZ|^=zppimm+j!Mh-@lm_A|S!$$+HN*$G$YBhY>n=cXrL^D=ClrMHE=&qPn*IMDXJ$8!p53aOb9UkL-dl5Y1}~_;lz?Qk!fauLx-8f#>4=bn0yA%)1Y7CRw;s zGde_5v-z4sUb~-Hu7JEB?5Hi)F4ka=w(51=33lfa-2}Z9zT~qM2n7tb!YbpdIy?5F zL>JRT;JrAoTk=>K7rlHI2pFUsYvS;LZo&e`ej#3KR;N1K^)Tw|wzpK`X!x=uNG5;{ zQ{x@R7O~FGJAkni(U^%q9*Uk~{N?I$jP!9g0WCkEIPQbnVkzp(<7O_ZHp`cA1$PoPwLA zaUa33UKL3re4%VFB6+lw2un}N8SGrn@tnbR`z|5|kbVTs-gY1CGP zd*YDaTp8syQe13&I(~ttjOaN!oFsX?K{8USU4FMqB?smlV50G!2(u*-|DE8530K%X zqD2%Z)+jGSYBQHayf@T1V<$z`W5UNfMEYk&Z@CYwDmTNL|2E&>{Q=gC`TpS#{;`3- z9OnO`N8lC>3vGX~(x?|J{pW&?zJ=aD3J%9CSZv_J`@LLh;%X0Tm>LM02*y@uE>2p4 z$Uy5YXv1y0+CFl0g&g_vA%>ZynJz!k@+pz7#PZ1`wz|U^Di3##o+ywOQ`Fc2?DqU# z`!ssdY+9XK+!z-!J)`;m*)rE^hpLC7q4HNI+MvDtky(dPYKXy&eIyLndU zM;X=NSAxw=>2ucEmUL=^rxCPbrdDIbrV|_Np=0eKjBQ{-J@;~uj)^C+oy3dU$}b-F z?f{Bw0ga6%Y^|7#4tf29M&a8`pF?htOij+LO`hoK7Lt^kypndp*+IgZN#%X0#47eh zo>il>QAzgBDr${Zef7h@tUzn^lp_R~XXn<=H}Be2d*}cd737dji^i5Edg*8TT_hrNs*>| zv&*gp7kOlT#X0Qki&Uas5wXj_xX3qa=PqCeC&F!-JrOs1I~8J$d;lEh(zUN;Bu+-c zf3H6R*}E%Ab}ebApgm7^mI32zg{FEGZ|WK+*zVwWfuo*P>xZQx?aEdTaSa5ng0f0? zwH2c`y!oK36NxhxiD2Ew+S6e=JQoNS8hny3dY)C+y=CkfTnku9nMv_qeb+jA;an}W zh^e&E$mLaIc{W(weLlodv$_YSBE!YJ3(WD><~`M5!T#KhYL)f6FjlkI5es~>pNW@E zd{1x0KJs$r1J#xkSX7=ea|~xf(3Dn|P9wuajFN-Y1Rz-oB|hW}WL%CWY>cL45#6LO zq9~W>nLsqn`Pud#W~Y0kF^%;ypZqVR#&6Eh!cJaW$LudwBXw-aq5~HR;zSW|k)kFs z)VO4sQp};1698QE{&oJ^>SQfW=@--W&?RK}v*#^Wvuj1G!(PzOyA&-d1}W&}(k}$t z&Gk&LPA9s+UX9(ZM7O2ijeBi#4AY%3WiDrI2KjQ=Y#d*N35>9cj;ZTi37u!i9(owC z9&74?FQ1WqHN=5gQy|A6^pjQx1@v^yhi$AW^pJ2j4bY9KfHaJS@eFm1F={lsx6^j?^aay0J(-J*#WvmlqR)JH8jKa6Yek6z2wM8 z!zv~jc@9bhigytBKCpin03LS$lh493t3x)Gyt3{1ZE3050Xgj2< zIab`$&yE74Hva$kmfwc-e{T{0XBhdjK008-?v;0x< zug||?rz2$v%LPIBM+(qyp)Ev%0dHpS0+MF~5h%!PFl8ugN{QlU)#t}bg(aJjNFz`< z8F?%@kpw^(dAv35bYTdMCUC~^$iy1Q=_?T%A*BaBht*pW-BJ=$-SWy-Truf)0w6`4 zC#@-F2Fm#H!^4d?9Ty=w+YR5A5g@Q#_n zSW>qhF!p*w+pe&*Vf-BsiUtfqJga(H9K;sJlcdM~+=n=sS;7qE9l12MWYJsJaYRN1 ztZU|v_Dp>Tish1NO&rc=_x%(3BvS6F<;@ngAd%$@&5wJ@9%&wX504Asmg#P$y<%9; z+wtYg52rhgixl3|jx@_nuBUhR<$@nt4~n-G1#t-@`;4EtUt z9_N_u$q3`GwA2aPExLIUEX*&(QeH=+9i+{xIe_SlE*d7-oQS-SiC*52azv!cU(=pwBX&iMOq9KoD@ttW$M8I=4Nv-69kwPIwHf#T@U0uH6I{ z_-S+ijW3VDkr#|P3W8w`9Vi}};RvxO^(jHvxT>DS0DOsk*5J^1MYn47J+weR^Cq=b z8G(!IJS=WVX^Jt@?(EksBr&8Ex3Ut#x_bU`x^1AW4m<9g_oMD=R?EnOn~2M-(ltmuTQ-=0yGZ1uI%1sPN+!= zBfyuT$X)M=QX&tH;>6{mS*>DGHRfOl;DZ-P`zARYwYMRIs&WwPESDWC8)>1!9_T{v z!{EFG*G5`wM|pJl4sp!+8f_la-4m9r7MA&nq1OO1WcHN-WC6X|5sJi{Mv;b8`l>Dy z7CM$Ade~g#F~srRW@saUdq!%h`-~2!$If%H33k+SyP%~0q874_(xN14RNcG1;3RCq zF|KyoP08JhJ((ilW=1{c2>1&*J@*-C`mhW6{n~uU78FNp&Gidiu(S^uoKE zxv^LEnEOIdXcE@}G&_UnteQLyN04PL8RV>xxIOwY!e;`mY}dzPB-?LlqE&afCNxCq zdV6opa&7KR5MgWdU(nDPf5smaDze@6{4iU;!MHo$u2xiH) zkfNBs3Jx7;REnuCS-sulxqG>H{S{riTl+&e`!Q$&p)F3nNK1$hYWJk;UC|cV!sRQm zI$plwchNoyp+MLK#S^G0XATQ#r$w=XrW>DSHB`PKQPK;I&{?#qfT%meXX89TK+|-h zxeZiX0-a}v9TYlOaOZsO;w!@L!}Zs%Jwx-6M_8l9(3v|Z)EbLY&7CLrXxNfEp%0=^ zrzpRnOzL5w9V~^We68i)w%g3hj#?MngL`)Dwz5@PHFV=# zF7`b}Wm2kA=ls?D+bu^NG#n3RqeLVJeEJH4WhliZ@Digi2}$U)P^d*rG?$g zTNs-1&Q|)i>ffn>8ihg0PFnbfSW?BwIx8N?nyt1CNX!9Z4 zou`tGZ(2(%gr=fZd51VcsEanA8je`T_&Q(-hQKjE$2y|XaScHhuYWqO?96J`KyfUS z|3pCaIW}_Tj&}YE_gs3KO}kL-29L*xRdkJ=uIJg#;9LzVLP0)>G*Nx?Lxx#|lza|> z4v~(VISpf`h6t;`&cw&PCS-VE*jnl;lrgo$Z3B(^Uc<6N=HR^&i8*XXcpM-WBA-Wa zj6=fPC0xh@?e`t8If^(x>Yc=nw&|?1!BG}@D&UZ)=cmbGt}}{62=&YD@v@tfHv^;& z9)~T~cqKNcvnppexd*X{eLk3b$Wh}cE7Xozlt69 zzbxc84*b6g`ja^SB?#l?%=*_v{U+j9pMU88Cms6>4UG5OOzHkZ&i*OjPcrnEfbQP~ z{7sGiiT;y`{Dt36!}PeuNWXMe$?$^IGA-$JoJ@&EIXu9E+& zBL*+t?VlL=kDmPJg8KI^7(ns2sGl*{zgN|tQP;0NRQ?Relatório — Synthetic acquisition acceptance

InvesteMoz
Relatório consolidado do projecto

Synthetic acquisition acceptance
Gerado em 14/11/2026, 14:00:00
Versão/revisão: Dossier f71a2833-c182-43ba-862d-234e4b64739b · v5 · contexto v1 · oportunidade contexto comum

Documento privado. O portal não publica nem partilha este conteúdo.

Relatório privado de preparação; não comprova licenciamento, aprovação ou financiamento.

Os actos externos só valem pelo respectivo documento e entidade. Pendências e versões históricas permanecem identificadas.

O índice referencia os originais; não incorpora automaticamente os seus anexos nem envia dados a entidades externas.

Investimento e localização em preparação

Dados guardados no contexto seleccionado; não representam aprovação ou validação externa.

CampoConteúdoClassificação / origem
ProjectoSynthetic acquisition acceptancePreparação do investimento. Contexto v1
DescriçãoExisting company description to reuse once in investment preparation.Preparação do investimento. Contexto v1
ProvínciaSynthetic provincePreparação do investimento. Contexto v1
LocalizaçãoSynthetic provincePreparação do investimento. Contexto v1
MoedaMZNPreparação do investimento. Contexto v1

Identificação e índice dos relatórios

Dossier: f71a2833-c182-43ba-862d-234e4b64739b

Oportunidade: Contexto comum do dossier

Gerado em 2026-11-14T12:00:00Z; versão do dossier 5.

CampoConteúdoClassificação / origem
S01 — Sistematizar a ideiaSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S01
S02 — Análise preliminarSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S02
S03 — Resultado de viabilidade financeiraResultado guardado; versão 1; 2026-11-14T16:35:59+00:00Consultar resultado. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#resultados-financeiros
S04 — Estruturar o investimentoSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S04
S05 — Constituição e registoSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S05
S06 — Preparar o dossierSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S06
S07 — Submeter quando aplicávelSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S07
S08 — Licenciamento prévioSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S08
S09 — Necessidade de terraSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S09
S10 — Regularização da terraSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S10
S11 — Confirmar regularização aplicávelSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S11
S12 — Necessidade e estrutura de financiamentoSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S12
S13 — Diligência e negociação financeiraSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S13
S14 — Decisão do financiadorSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S14
S15 — Fecho e desembolsoSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S15
S16 — ImplementaçãoSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S16
S17 — Inspecções, testes e licença de operaçãoSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S17
S18 — Início de operaçãoSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S18
S19 — Acompanhamento recorrenteSem relatório ou documento associado; versão 1; data não registadaConsultar etapa. /investimentos/f71a2833-c182-43ba-862d-234e4b64739b#S19

Etapas, resultados e pendências

A situação de uma etapa não significa que o respectivo relatório ou acto externo tenha sido produzido.

CampoConteúdoClassificação / origem
S01 — Sistematizar a ideiaPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 1: Ideia e viabilidade
S02 — Análise preliminarPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 1: Ideia e viabilidade
S03 — Decisão sobre a viabilidadePor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 1: Ideia e viabilidade
S04 — Estruturar o investimentoPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 1: Ideia e viabilidade
S05 — Constituição e registoPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 2: Formalização e dossier
S06 — Preparar o dossierPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 2: Formalização e dossier
S07 — Submeter quando aplicávelPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 2: Formalização e dossier
S08 — Licenciamento prévioPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 3: Licenciamento e terra
S09 — Necessidade de terraPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 3: Licenciamento e terra
S10 — Regularização da terraPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 3: Licenciamento e terra
S11 — Confirmar regularização aplicávelPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 3: Licenciamento e terra
S12 — Necessidade e estrutura de financiamentoPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 4: Financiamento
S13 — Diligência e negociação financeiraPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 4: Financiamento
S14 — Decisão do financiadorPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 4: Financiamento
S15 — Fecho e desembolsoPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 4: Financiamento
S16 — ImplementaçãoPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 5: Execução e acompanhamento
S17 — Inspecções, testes e licença de operaçãoPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 5: Execução e acompanhamento
S18 — Início de operaçãoPor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 5: Execução e acompanhamento
S19 — Acompanhamento recorrentePor iniciar; versão 1. Sem fundamento adicional registado. Pendente. Fase 5: Execução e acompanhamento

Viabilidade e relatórios fiscais

Resultados recuperados das entradas guardadas pelo motor existente; impostos destinam-se à simulação de viabilidade.

CampoConteúdoClassificação / origem
Plano financeiro — Periodicidade do orçamentoMensalEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarada pelo utilizador
Empréstimo educativo — Capital pressuposto100000 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Empréstimo educativo — Taxa anual pressuposta0% (nominal anual)Estimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarada pelo utilizador; não é taxa de produto
Empréstimo educativo — Prazo pressuposto24 mesesEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Empréstimo educativo — Método e pressupostos substituídosSaldo decrescente; capital 100000 MZN; taxa 0% nominal anual (dividida pelos períodos do ano); prazo 24 meses; periodicidade 1 meses; carência 0 períodos; comissão inicial 0 MZN; comissão periódica 0 MZN. Montantes a duas casas decimais; juros e prestação arredondados à unidade monetária mínima, metade para cima; última prestação ajusta o saldo residual.Estimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Cronograma do simulador; taxa declarada, sem correspondência a produto
Empréstimo educativo — Prestação do primeiro período4166.67 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Empréstimo educativo — Juros totais estimados0.00 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Empréstimo educativo — Estado/erro do cálculoCalculado pelo cronograma do simuladorEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Ponto de equilíbrio — Fórmula e valores substituídos3000 / (100 − 50); unidades arredondadas para cimaEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Custos fixos ÷ margem de contribuição unitária; pressupostos declarados
Ponto de equilíbrio — Unidades estimadas60Estimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Ponto de equilíbrio — Vendas correspondentes6000.00 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Ponto de equilíbrio — Estado/erro do cálculoCalculado pelo simuladorEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Financiamento — Investimento total pressuposto100000 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Financiamento — Montante já mobilizado pressuposto30000 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Financiamento — Fórmula e valores substituídos100000 − 30000Estimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Investimento total declarado − financiamento mobilizado declarado
Financiamento — Diferença por financiar70000.00 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Financiamento — Estado/erro do cálculoCalculado pelo simuladorEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Orçamento — Fórmula e valores substituídos10000.00 − 3000.00Estimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Receitas declaradas − despesas declaradas; valores ausentes não são zero
Orçamento — Receitas declaradas10000.00 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Orçamento — Despesas declaradas3000.00 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Orçamento — Saldo operacional estimado7000.00 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Orçamento — Estado/erro do cálculoCalculado pelo simuladorEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Estimativa matemática baseada em pressupostos declarados; não é oferta de crédito nem resultado oficial
Orçamento — Receita declarada: Synthetic scenario revenue10000 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Orçamento — Despesa declarada: Declared rent at synthetic province2000 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador
Orçamento — Despesa declarada: Declared transport at synthetic province1000 MZNEstimativa guardada. Resultado a18f1c7a-73bd-41d1-a28b-6c19b1bf3fb8; rascunho 38f76a31-44ea-4815-b523-d99046475518, versão 1; 2026-11-14T16:35:59+00:00; Declarado pelo utilizador

Análise SWOT

Análise SWOT ainda não produzida neste âmbito.

Preparação documental APIEX e actos externos

Preparação APIEX ainda não disponível neste âmbito.

Documentos associados ao dossier

Consulte os originais no dossier. Os controlos de acesso e disponibilidade mantêm-se em cada descarga.

Documentos comuns não comprovam a sua aplicabilidade a todas as oportunidades; confira a associação à etapa e ao pedido.

InvesteMoz · Relatório privado · Dossier f71a2833-c182-43ba-862d-234e4b64739b · v5 · contexto v1 · oportunidade contexto comum
\ No newline at end of file diff --git a/outputs/offers-investment-continuity-20261114/qa-result.json b/outputs/offers-investment-continuity-20261114/qa-result.json new file mode 100644 index 00000000..a40f1c42 --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/qa-result.json @@ -0,0 +1,102 @@ +{ + "base": "ed2fd86f", + "phase5_preserved": "528a2597", + "environment": { + "database": "offers_phase1_20261114_test", + "host": "127.0.0.1", + "port": 55441, + "fixtures": "synthetic only" + }, + "cause": "Transformation: description persisted, project_summary read only canonical/summary. Existing identifiers and permissions preserved.", + "php_suites": [ + { + "name": "Tests\\Feature\\OfferInvestmentAcceptanceAuditTest", + "tests": 4, + "assertions": 62, + "errors": 0, + "failures": 0 + }, + { + "name": "Tests\\Feature\\PrivateOfferConfidentialityTest", + "tests": 11, + "assertions": 161, + "errors": 0, + "failures": 0 + }, + { + "name": "Tests\\Feature\\InvestorPathTest", + "tests": 4, + "assertions": 192, + "errors": 0, + "failures": 0 + }, + { + "name": "Tests\\Feature\\OpportunityManagementTest", + "tests": 3, + "assertions": 46, + "errors": 0, + "failures": 0 + } + ], + "php_totals": { + "tests": 22, + "assertions": 461, + "errors": 0, + "failures": 0 + }, + "frontend_regression": { + "tests": 41, + "passed": 41 + }, + "integrated_frontend_report": { + "tests": 1, + "passed": 1, + "artifacts": [ + "private-integrated-report.html", + "private-integrated-report.docx", + "location-analysis.json" + ] + }, + "static": { + "phpstan": "full analysis passed, zero errors", + "types": "tsc --noEmit passed", + "pint": "affected PHP passed", + "frontend_lint_format": "new mjs passed", + "build": "unchanged frontend product sources: accepted QA build reused; no rebuild", + "git_diff_check": "passed" + }, + "field_policy": "Common authorised title/description/administrative references only; no private_offer financial/contact/price/proof transfer. NDA grant does not grant private context access.", + "publication": "default consumer closed; injected synthetic consumer guarded by actual isolated database", + "matrix": "RF-MN-003 only; other rows unchanged", + "pending": [ + "real NDA and legal decisions", + "effective public writer/activation", + "desktop/mobile visual acceptance", + "image processing derivatives", + "real email delivery" + ], + "installations": false, + "operational_migrations": false, + "mne_changes": false, + "accepted_59_780_repeated": false, + "source_sha256": { + "app/Services/InvestorContext.php": "cdae33a63d796b7e9862c949711b2c83f2482990d3d77806591a594214313fff", + "tests/Feature/OfferInvestmentAcceptanceAuditTest.php": "d91112cfccc08f45afb9a6c317ead1a5d03f97221a606ad123ca590a4b401b5b", + "tests/Feature/PrivateOfferConfidentialityTest.php": "5beb77c609baf3c78768bfbe0906b5d5b8701cd3266ca9ead8c3198a30fb5bc6", + "tests/frontend/offer-investment-continuity.test.mjs": "b37acc9d1dbf900aa8a5555666142bc088e73245b60c5aa8f6d0f7baa1a7655a" + }, + "evidence_sha256": { + "focused.log": "0943af2982f42d60848e480008f0e045ebda4da944d16408be0ae944b94428bc", + "focused.xml": "e57322452c4e009e40dc0b3d5bbfa1da1c3add6afb74a8006143efbc904ee2cb", + "frontend-regression.log": "ddbeb6fe3365cb70fd4c0e5eafaf4d7919ead5910415f6aed9167acfb43e315d", + "integrated-report-input.json": "60d8d8f46821da56f47183f57e6869cb64160cf5f5c2fdd03eab2acdd24c5014", + "location-analysis.json": "83729ad333ace4507e3827b97f84905327083682fb83eecbb05847e4f59a5dff", + "phpstan.log": "c10f74fb840de989bba7e9c2dfee7f8419b5d2ac0cc0daf18a4a187f6530aa43", + "private-integrated-report.docx": "df76a52f6f1d1ee990702aefa8b4c3d3604de2305be840be88c77fc3dbdf546e", + "private-integrated-report.html": "3221f94d4df400f4edf5e9b262dbf4a13d6f80d6b6fd58b6f8a09ed384141367", + "regression.log": "13480527b87e724e7c9687131ee0d0f611f1c9a6ac719612440dcfac8ccfd543", + "regression.xml": "2785f34fb05e01b945fb1b7a61ba3e9d6c061d5c7d3cf09b189188b58a1b2e37", + "report-test.log": "71d866136fca227770e0c73347750f6597224c9420672c6ab9dfcebd9f80c60d", + "types.log": "b59cdb3ff539a29c8ae6c37772ecc1a93a5266c49959d408f16b17487b7ac755" + } +} diff --git a/outputs/offers-investment-continuity-20261114/regression.log b/outputs/offers-investment-continuity-20261114/regression.log new file mode 100644 index 00000000..bdd3f91d --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/regression.log @@ -0,0 +1 @@ +{"tool":"phpunit","result":"passed","tests":22,"passed":22,"assertions":461,"duration_ms":135835} diff --git a/outputs/offers-investment-continuity-20261114/regression.xml b/outputs/offers-investment-continuity-20261114/regression.xml new file mode 100644 index 00000000..703e8a56 --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/regression.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/outputs/offers-investment-continuity-20261114/report-test.log b/outputs/offers-investment-continuity-20261114/report-test.log new file mode 100644 index 00000000..2f7f6867 --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/report-test.log @@ -0,0 +1,9 @@ +✔ persisted synthetic offer crosses the dossier boundary into location assumptions, calculation and private report (130.377542ms) +ℹ tests 1 +ℹ suites 0 +ℹ pass 1 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 596.953708 diff --git a/outputs/offers-investment-continuity-20261114/types.log b/outputs/offers-investment-continuity-20261114/types.log new file mode 100644 index 00000000..dc5a08e5 --- /dev/null +++ b/outputs/offers-investment-continuity-20261114/types.log @@ -0,0 +1,3 @@ + +> types:check +> tsc --noEmit diff --git a/tests/Feature/OfferInvestmentAcceptanceAuditTest.php b/tests/Feature/OfferInvestmentAcceptanceAuditTest.php index fb019c1b..004f3341 100644 --- a/tests/Feature/OfferInvestmentAcceptanceAuditTest.php +++ b/tests/Feature/OfferInvestmentAcceptanceAuditTest.php @@ -5,17 +5,21 @@ namespace Tests\Feature; use App\Models\Opportunity; use App\Models\User; use App\Services\InvestorContext; +use App\Services\OfferPublicCatalogue; +use App\Services\OpportunityManagement; use App\Services\PortalProfileAdministration; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Str; use Tests\TestCase; -/** Acceptance audit only: no change to the product's contracts or access rules. */ +/** Synthetic acceptance regression for the existing investment-context boundary. */ final class OfferInvestmentAcceptanceAuditTest extends TestCase { use RefreshDatabase; - private function prepare(): array + private function prepare(array $location = []): array { $this->withoutVite(); config(['portal.profile_access_enabled' => true]); @@ -28,7 +32,7 @@ final class OfferInvestmentAcceptanceAuditTest extends TestCase 'title' => 'Synthetic acquisition acceptance', 'description' => 'Existing company description to reuse once in investment preparation.', 'private_offer' => ['price_mode' => 'amount', 'amount' => '120000.00', 'currency' => 'MZN', 'business' => ['revenue' => '60000.00', 'cash_flow' => '20000.00', 'currency' => 'MZN']], - 'reason' => 'Synthetic final acceptance integration audit only.']; + 'reason' => 'Synthetic final acceptance integration audit only.', ...$location]; $record = $this->actingAs($owner)->postJson('/minhas-oportunidades/ofertas/rascunhos', $payload)->assertCreated()->json('record'); return [$owner, $record, $payload]; @@ -42,6 +46,10 @@ final class OfferInvestmentAcceptanceAuditTest extends TestCase $this->assertSame($payload['title'], $reference['fields']['project_title']); $this->assertSame($payload['description'], $reference['fields']['project_summary'] ?? null, 'Write once/read always: the existing description must not disappear at the investment-context boundary.'); + $this->assertSame('/minhas-oportunidades/ofertas/'.$record['id'], $reference['href']); + $this->assertArrayNotHasKey('private_offer', $reference); + $this->assertArrayNotHasKey('revenue', $reference['fields']); + $this->assertArrayNotHasKey('currency', $reference['fields']); } public function test_native_context_options_do_not_disclose_another_owners_private_offer(): void @@ -55,4 +63,113 @@ final class OfferInvestmentAcceptanceAuditTest extends TestCase $this->assertNotContains('opportunity:'.$record['id'], array_column(app(InvestorContext::class)->options(), 'key')); $this->getJson('/minhas-oportunidades/ofertas/'.$record['id'])->assertForbidden(); } + + public function test_private_description_is_not_truncated_and_does_not_replace_an_existing_summary(): void + { + [$owner, $record, $payload] = $this->prepare(); + $description = str_repeat('Synthetic complete description. ', 400); + $this->postJson('/minhas-oportunidades/ofertas/'.$record['id'].'/guardar', [ + 'etag' => $record['etag'], 'description' => $description, 'reason' => $payload['reason'], + ])->assertOk(); + $this->assertSame(trim($description), app(InvestorContext::class)->reference('opportunity:'.$record['id'])['fields']['project_summary']); + DB::table('opportunities')->where('id', $record['id'])->update(['summary' => 'Deliberate existing summary']); + $this->assertSame('Deliberate existing summary', app(InvestorContext::class)->reference('opportunity:'.$record['id'])['fields']['project_summary']); + $this->assertSame(trim($description), Opportunity::findOrFail($record['id'])->description); + } + + public function test_approved_offer_continues_in_same_dossier_location_analysis_saved_result_and_report_input(): void + { + Mail::fake(); + config(['editorial_workflow.enabled' => true, 'investor-path.enabled' => true, 'suitecrm.enabled' => false, 'investmoz_ai.enabled' => false]); + $country = (string) Str::uuid(); + $province = (string) Str::uuid(); + foreach ([[$country, 'country', null], [$province, 'province', $country]] as [$id, $type, $parent]) { + DB::table('geo_locations')->insert(['id' => $id, 'code' => 'SYNTHETIC-'.$id, 'name' => 'Synthetic '.$type, + 'location_type' => $type, 'parent_id' => $parent, 'data_classification' => 'public', + // Same isolated reference contract as OpportunitySearchFixture; never an operational import. + 'source_system' => 'cartografia-workbook', + 'external_id' => '964a187ad32ea553b9e112cd159caa90b900050c42b7329594a75bcd798a96ff:'.$id]); + } + [$owner, $record, $payload] = $this->prepare(['province_id' => $province]); + $contact = (string) Str::uuid(); + DB::table('contacts')->insert(['id' => $contact, 'full_name' => 'Synthetic private contact', 'source_system' => 'portal-user-contact', 'external_id' => 'user:'.$owner->id]); + $url = '/minhas-oportunidades/ofertas/'.$record['id']; + $this->postJson($url.'/guardar', ['etag' => $record['etag'], 'private_offer' => [...$payload['private_offer'], 'contact_id' => $contact], 'reason' => $payload['reason']])->assertOk(); + $this->postJson($url.'/submeter', ['etag' => app(OpportunityManagement::class)->etag(Opportunity::findOrFail($record['id'])), 'confirm' => true])->assertOk()->assertJsonPath('record.state', 'submitted'); + $reviewer = User::factory()->withTwoFactor()->create(); + app(PortalProfileAdministration::class)->insertGrant((string) Str::uuid(), User::factory()->create(), [ + 'user_id' => $reviewer->id, 'role' => 'validator', 'responsibilities' => ['validation_coordinator'], + 'opportunity_types' => ['business_sale'], 'source' => 'synthetic-acceptance-audit', + ]); + $this->actingAs($reviewer)->withSession(['portal.mfa_actor' => $reviewer->id, 'portal.mfa_at' => time(), 'portal.access_revision' => (int) $reviewer->fresh()->portal_access_revision]); + foreach (['start_review', 'approve'] as $action) { + $this->postJson($url.'/revisao', ['etag' => app(OpportunityManagement::class)->etag(Opportunity::findOrFail($record['id'])), + 'action' => $action, 'reason' => 'Synthetic independent review for investment continuity.'])->assertOk(); + } + $offer = Opportunity::findOrFail($record['id']); + $public = ['title' => 'Synthetic public acquisition', 'summary' => 'Approved synthetic public summary only.', 'category' => 'business_sale', + 'province_id' => $province, 'district_id' => null, 'price_mode' => 'negotiable', 'amount' => null, 'currency' => null]; + $hash = OfferPublicCatalogue::projectionHash($public); + $context = $offer->workflow_context; + $context['offer_publication'] = ['contract' => OfferPublicCatalogue::CONTRACT, 'qa_fixture' => true, 'revision' => 1, 'payload' => $public, + 'approval' => ['state' => 'approved', 'hash' => $hash, 'actor_id' => $reviewer->id, 'at' => now()->subMinutes(2)->toIso8601String()], + 'publication' => ['state' => 'published', 'hash' => $hash, 'actor_id' => User::factory()->create()->id, 'at' => now()->subMinute()->toIso8601String()]]; + $offer->forceFill(['workflow_context' => $context])->save(); + $this->getJson('/api/v1/offers')->assertOk()->assertJsonPath('results.total', 0); + $this->app->instance(OfferPublicCatalogue::class, new OfferPublicCatalogue(true)); + $response = $this->getJson('/api/v1/offers/'.$offer->id)->assertOk()->assertJsonPath('data.summary', $public['summary']); + $this->assertStringNotContainsString($payload['description'], $response->getContent()); + $this->assertStringNotContainsString('60000.00', $response->getContent()); + $this->assertNull($offer->fresh()->published_at); + $this->actingAs($owner); + $case = $this->postJson('/investimentos', ['title' => $payload['title'], 'client_key' => (string) Str::uuid(), 'reuse_consent' => true])->assertCreated()->json('id'); + $view = $this->getJson('/investimentos/'.$case.'/contexto')->assertOk()->json(); + $body = ['version' => $view['case']['version'], 'selection' => ['opportunity' => 'opportunity:'.$offer->id], 'declarations' => ['currency' => 'MZN']]; + $plan = $this->postJson('/investimentos/'.$case.'/contexto/previa', $body)->assertOk()->json(); + $this->assertSame($payload['description'], $plan['fields']['project_summary']); + $this->postJson('/investimentos/'.$case.'/contexto/confirmar', [...$body, 'preview_hash' => $plan['preview_hash'], 'operation_key' => (string) Str::uuid(), 'confirm' => true])->assertOk(); + $view = $this->getJson('/investimentos/'.$case.'/contexto')->assertOk()->json(); + $prefill = $view['prefill']['simulator']; + $this->assertSame($province, $prefill['province_id']); + $this->assertSame($payload['description'], $prefill['project_summary']); + $this->assertStringNotContainsString('60000.00', json_encode($view, JSON_THROW_ON_ERROR)); + $financial = ['version' => 1, 'data' => ['budgetPeriod' => 'Mensal', + 'loan' => ['principal' => '100000', 'rate' => '0', 'months' => '24', 'rateType' => 'nominal', 'periodMonths' => '1', 'gracePeriods' => '0', 'upfrontFee' => '0', 'recurringFee' => '0'], + 'breakEven' => ['fixed' => '3000', 'price' => '100', 'variable' => '50'], 'funding' => ['total' => '100000', 'secured' => '30000'], + 'incomes' => [['label' => 'Synthetic scenario revenue', 'amount' => '10000']], + 'expenses' => [['label' => 'Declared rent at synthetic province', 'amount' => '2000'], ['label' => 'Declared transport at synthetic province', 'amount' => '1000']]]]; + $draft = $this->postJson('/api/v1/simulation-drafts', ['context' => $case, 'personal_snapshot' => [], + 'economic_snapshot' => [...array_intersect_key($prefill, array_flip(['purpose', 'journey_type', 'project_title', 'project_summary', 'currency', 'province_id', 'context_applicability_snapshot'])), + 'financial_tools_snapshot' => json_encode($financial, JSON_THROW_ON_ERROR)]], + ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id'); + $saved = $this->getJson('/api/v1/simulation-drafts/'.$draft.'?context='.$case)->assertOk()->json('data.economic_snapshot'); + $this->assertSame($payload['description'], $saved['project_summary']); + $path = $this->getJson('/investimentos/'.$case)->assertOk()->json(); + $this->postJson('/investimentos/'.$case.'/resultados', ['version' => $path['case']['version'], 'draft_id' => $draft, 'draft_version' => 1, + 'context_revision' => $path['investment_context']['revision'], 'context_reviewed' => true])->assertOk(); + auth()->logout(); + $this->actingAs(User::findOrFail($owner->id)); + $path = $this->getJson('/investimentos/'.$case)->assertOk()->json(); + $this->assertSame($draft, $path['results'][0]['draft_id']); + $this->assertSame($payload['description'], $path['investment_context']['fields']['project_summary']); + $this->assertSame(1, Opportunity::count()); + $this->assertSame(1, DB::table('desk_cases')->count()); + $this->assertStringNotContainsString('60000.00', json_encode($path, JSON_THROW_ON_ERROR)); + $output = base_path('outputs/offers-investment-continuity-20261114'); + if (! is_dir($output)) { + mkdir($output, 0777, true); + } + file_put_contents($output.'/integrated-report-input.json', json_encode(['path' => $path, 'saved' => $saved], JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)); + $body = ['version' => $path['case']['version'], 'selection' => ['opportunity' => 'opportunity:'.$offer->id], + 'declarations' => ['project_summary' => 'Deliberate investment-specific summary']]; + $plan = $this->postJson('/investimentos/'.$case.'/contexto/previa', $body)->assertOk()->json(); + $this->assertSame('Deliberate investment-specific summary', $plan['fields']['project_summary']); + $this->postJson('/investimentos/'.$case.'/contexto/confirmar', [...$body, 'preview_hash' => $plan['preview_hash'], 'operation_key' => (string) Str::uuid(), 'confirm' => true])->assertOk(); + $view = $this->getJson('/investimentos/'.$case.'/contexto')->assertOk()->json(); + $this->postJson('/investimentos/'.$case.'/contexto/previa', ['version' => $view['case']['version'], + 'selection' => ['opportunity' => 'opportunity:'.$offer->id]])->assertOk()->assertJsonPath('fields.project_summary', 'Deliberate investment-specific summary'); + $this->assertSame($payload['description'], $offer->fresh()->description); + $this->actingAs(User::factory()->create())->getJson('/investimentos/'.$case)->assertForbidden(); + $this->getJson('/api/v1/simulation-drafts/'.$draft.'?context='.$case)->assertNotFound(); + } } diff --git a/tests/Feature/PrivateOfferConfidentialityTest.php b/tests/Feature/PrivateOfferConfidentialityTest.php index 188725be..ee38f993 100644 --- a/tests/Feature/PrivateOfferConfidentialityTest.php +++ b/tests/Feature/PrivateOfferConfidentialityTest.php @@ -5,6 +5,7 @@ namespace Tests\Feature; use App\Jobs\ScanDocumentForMalware; use App\Models\Opportunity; use App\Models\User; +use App\Services\InvestorContext; use App\Services\OpportunityManagement; use App\Services\PortalProfileAdministration; use App\Services\PrivateOfferConfidentiality; @@ -19,6 +20,7 @@ use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; +use Symfony\Component\HttpKernel\Exception\HttpException; use Tests\Support\CleanScannerFixture; use Tests\TestCase; @@ -238,6 +240,14 @@ final class PrivateOfferConfidentialityTest extends TestCase $data = $this->login($interested)->getJson($url.'/confidencial')->assertOk()->assertJsonPath('business.revenue', '789.01')->getContent(); $this->assertStringNotContainsString('PRIVATE-CONTACT-CANARY', $data); $this->assertStringNotContainsString('PRIVATE-DESCRIPTION-CANARY', $data); + // NDA permission is a bounded read, not permission to copy the private + // Opportunity into another investment context or its downstream reports. + try { + app(InvestorContext::class)->reference('opportunity:'.$record->id); + $this->fail('An NDA grant must not grant private investment-context access.'); + } catch (HttpException $error) { + $this->assertSame(404, $error->getStatusCode()); + } $this->login($this->actor())->getJson($url.'/confidencial')->assertForbidden(); $this->login($owner)->postJson($url.'/confidencialidade', $this->command($record, $nda, 'revoke', ['interested_user_id' => $interested->id]))->assertOk(); $this->login($interested)->getJson($url.'/confidencial')->assertForbidden(); diff --git a/tests/frontend/offer-investment-continuity.test.mjs b/tests/frontend/offer-investment-continuity.test.mjs new file mode 100644 index 00000000..56367ba7 --- /dev/null +++ b/tests/frontend/offer-investment-continuity.test.mjs @@ -0,0 +1,94 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync, writeFileSync } from 'node:fs'; +import JSZip from 'jszip'; +import { + calculateBudget, + calculateBreakEven, + restoreFinancialToolsSnapshot, +} from '../../resources/js/lib/financial-calculators.ts'; +import { createInvestorDossierReport } from '../../resources/js/lib/investor-dossier-report.ts'; +import { + createProjectDossierPrintHtml, + generateProjectDossierDocx, +} from '../../resources/js/lib/project-dossier-report.ts'; + +await test('persisted synthetic offer crosses the dossier boundary into location assumptions, calculation and private report', async () => { + // Produced by the guarded PHP integration test, never by an operational export. + const directory = new URL( + '../../outputs/offers-investment-continuity-20261114/', + import.meta.url, + ); + const { path, saved } = JSON.parse( + readFileSync( + new URL('integrated-report-input.json', directory), + 'utf8', + ), + ); + assert.equal(path.case.title, 'Synthetic acquisition acceptance'); + assert.equal( + path.investment_context.fields.project_summary, + saved.project_summary, + ); + assert.equal(path.investment_context.fields.province_id, saved.province_id); + const data = restoreFinancialToolsSnapshot( + path.results[0].financial_snapshot, + ); + assert.ok(data); + assert.deepEqual( + data, + restoreFinancialToolsSnapshot(saved.financial_tools_snapshot), + ); + const budget = calculateBudget( + data.incomes.map((row) => row.amount), + data.expenses.map((row) => row.amount), + ); + const breakEven = calculateBreakEven( + data.breakEven.fixed, + data.breakEven.price, + data.breakEven.variable, + ); + assert.equal(budget.operatingBalance, '7000.00'); + assert.equal(breakEven.breakEvenUnits, '60'); + // An explicit alternative location-cost assumption, not an inferred provincial tariff. + const alternative = calculateBudget( + data.incomes.map((row) => row.amount), + ['5000', '3000'], + ); + assert.equal(alternative.operatingBalance, '2000.00'); + assert.deepEqual( + data.expenses.map((row) => row.amount), + ['2000', '1000'], + ); + const report = createInvestorDossierReport(path, '2026-11-14T12:00:00Z'); + const html = await createProjectDossierPrintHtml(report, [], false); + assert.ok(html.includes(saved.project_summary)); + assert.ok(html.includes('Synthetic province')); + assert.ok(!html.includes('60000.00')); + assert.ok(!html.includes('Synthetic private contact')); + const docx = await generateProjectDossierDocx(report, [], false); + const bytes = Buffer.from(await docx.arrayBuffer()); + const zip = await JSZip.loadAsync(bytes); + const xml = await zip.file('word/document.xml').async('string'); + assert.ok(xml.includes(saved.project_summary)); + assert.ok(xml.includes('Synthetic province')); + assert.ok(!xml.includes('60000.00')); + writeFileSync(new URL('private-integrated-report.html', directory), html); + writeFileSync(new URL('private-integrated-report.docx', directory), bytes); + writeFileSync( + new URL('location-analysis.json', directory), + JSON.stringify( + { + scope: 'Synthetic investor-declared costs at the selected location; no automatic profitability or fiscal entitlement', + province_id: saved.province_id, + budget, + breakEven, + alternative, + source_offer: path.investment_context.selection.opportunity.key, + case_id: path.case.id, + }, + null, + 2, + ), + ); +});