From 1b2ede41e273474880c2e88cc1f30d2aa69b2f96 Mon Sep 17 00:00:00 2001 From: nala Date: Wed, 28 Oct 2026 20:49:30 +0200 Subject: [PATCH] fix(catalogue): include approved provincial corridor coverage and show territorial detail --- .../InvestmentDiscoveryController.php | 4 +- app/Services/InvestmentCatalogue.php | 44 +++++++++- app/Services/InvestmentCorridorContext.php | 9 +++ app/Services/OpportunityCorridorExplorer.php | 5 +- .../consolidated-review-matrix-2026-10-03.md | 12 +++ ...talogue-province-coverage-qa-20261028.json | 57 +++++++++++++ .../unification/traceability-and-manual.md | 12 +++ .../v2/auditoria-portal/matriz-requisitos.csv | 4 +- .../opportunity-corridor-groups.tsx | 11 +-- .../components/opportunity-search-filters.tsx | 5 ++ resources/js/pages/investment/catalogue.tsx | 2 +- resources/js/pages/investment/shared.tsx | 1 + .../Feature/CatalogueProvinceCoverageTest.php | 80 +++++++++++++++++++ 13 files changed, 232 insertions(+), 14 deletions(-) create mode 100644 docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json create mode 100644 tests/Feature/CatalogueProvinceCoverageTest.php diff --git a/app/Http/Controllers/InvestmentDiscoveryController.php b/app/Http/Controllers/InvestmentDiscoveryController.php index 9c7f3a4d..a1d19208 100644 --- a/app/Http/Controllers/InvestmentDiscoveryController.php +++ b/app/Http/Controllers/InvestmentDiscoveryController.php @@ -29,7 +29,7 @@ class InvestmentDiscoveryController extends Controller 'corridorGroups' => ($filters['view'] ?? '') === 'corridors' ? app(\App\Services\OpportunityCorridorExplorer::class)->groups($filters) : [], 'territorySelection' => app(InvestmentGeography::class)->selection($filters), 'guides' => app(\App\Services\SectorInvestment::class)->guides(\App\Models\Sector::where('slug', $filters['sector'] ?? '')->where('is_active', true)->whereNotNull('published_at')->first()), - 'results' => $catalogue->query($filters)->paginate(12)->withQueryString(), + 'results' => $catalogue->query($filters)->paginate(12)->withQueryString()->through(fn ($record) => $catalogue->presentLocation($record)), 'favourites' => $request->user() ? DB::table('opportunity_favourites')->where('user_id', $request->user()->id)->pluck('opportunity_id') : [], 'territorial' => $this->territorial($filters)]); } @@ -74,7 +74,7 @@ class InvestmentDiscoveryController extends Controller public function search(Request $request, InvestmentCatalogue $catalogue): JsonResponse { - return response()->json($catalogue->query($catalogue->filters($request))->paginate($request->integer('per_page', 12))->withQueryString()); + return response()->json($catalogue->query($catalogue->filters($request))->paginate($request->integer('per_page', 12))->withQueryString()->through(fn ($record) => $catalogue->presentLocation($record))); } public function references(Request $request, InvestmentCatalogue $catalogue): JsonResponse diff --git a/app/Services/InvestmentCatalogue.php b/app/Services/InvestmentCatalogue.php index d6fabb00..4db099fc 100644 --- a/app/Services/InvestmentCatalogue.php +++ b/app/Services/InvestmentCatalogue.php @@ -71,7 +71,9 @@ class InvestmentCatalogue } elseif (($filters['territory_basis'] ?? 'all') === 'context') { $query->whereNull('opportunities.primary_territory_id')->whereNotExists(fn ($l) => $l->selectRaw('1')->from('opportunity_locations')->whereColumn('opportunity_id', 'opportunities.id')); $query->where(fn ($q) => $q->whereExists(fn ($l) => $l->selectRaw('1')->from('opportunity_projects')->whereColumn('opportunity_id', 'opportunities.id')->whereIn('project_id', app(InvestmentRelations::class)->projectIds())) - ->orWhereExists(fn ($l) => $l->selectRaw('1')->from('opportunity_clusters')->whereColumn('opportunity_id', 'opportunities.id')->whereIn('cluster_id', $this->publicStructureIds('clusters', 'cluster_id')))); + ->orWhereExists(fn ($l) => $l->selectRaw('1')->from('opportunity_clusters')->whereColumn('opportunity_id', 'opportunities.id')->whereIn('cluster_id', $this->publicStructureIds('clusters', 'cluster_id'))) + ->orWhere(fn ($source) => $source->where('workflow_context->corridor_agribusiness->source_sha256', CorridorAgribusinessOpportunities::SOURCE_HASH) + ->whereIn('workflow_context->corridor_agribusiness->corridor', array_column(config('investment_corridors', []), 'name')))); } if (! empty($filters['opportunity_id'])) { $query->whereKey($filters['opportunity_id']); @@ -80,12 +82,13 @@ class InvestmentCatalogue $includeNational = filter_var($filters['include_national'] ?? false, FILTER_VALIDATE_BOOLEAN); if ($path !== []) { $ids = app(InvestmentGeography::class)->descendants($path[array_key_last($path)]->id); - $query->where(function ($territory) use ($ids, $includeNational, $filters): void { + $query->where(function ($territory) use ($ids, $includeNational, $filters, $path): void { $territory->whereIn('opportunities.primary_territory_id', $ids) ->orWhereExists(fn ($locations) => $locations->selectRaw('1')->from('opportunity_locations as territory_link') ->whereColumn('territory_link.opportunity_id', 'opportunities.id')->whereIn('territory_link.geo_location_id', $ids)); if (($filters['territory_basis'] ?? 'all') !== 'direct') { app(InvestmentRelations::class)->opportunityTerritories($territory, $ids); + if (count($path) === 1) $this->approvedCorridorProvince($territory, $path[0]->id); } if ($includeNational) { $territory->orWhere('opportunities.geography_scope', 'national'); @@ -162,6 +165,9 @@ class InvestmentCatalogue ->whereNull('target.deleted_at')->where('target.data_classification', 'public')); if (($filters['territory_basis'] ?? 'all') !== 'direct') { app(InvestmentRelations::class)->opportunityTerritories($matches, $locationIds ?? []); + if (app(InvestmentGeography::class)->publicReferences()->where('id', $filters['geo_location_id'])->where('location_type', 'province')->exists()) { + $this->approvedCorridorProvince($matches, $filters['geo_location_id']); + } } }); @@ -212,6 +218,38 @@ class InvestmentCatalogue }; } + private function approvedCorridorProvince($query, string $provinceId): void + { + $code = app(InvestmentGeography::class)->publicReferences()->where('id', $provinceId)->value('source_code'); + $names = []; + foreach (config('investment_corridors', []) as $entry) { + if (in_array($code, $entry['provinces'], true)) $names[] = $entry['name']; + } + if (!$names) return; + $query->orWhere(fn ($context) => $context->whereNull('opportunities.primary_territory_id') + ->whereNotExists(fn ($link) => $link->selectRaw('1')->from('opportunity_locations')->whereColumn('opportunity_id', 'opportunities.id')) + ->where('workflow_context->corridor_agribusiness->source_sha256', CorridorAgribusinessOpportunities::SOURCE_HASH) + ->whereIn('workflow_context->corridor_agribusiness->corridor', $names)); + } + + /** Public result presentation only; no editorial or territorial data is saved. */ + public function presentLocation(Opportunity $record): Opportunity + { + $geo = app(InvestmentGeography::class); + $paths = []; + $ids = array_filter([$record->primary_territory_id, ...$record->additionalTerritories()->pluck('geo_locations.id')->all()]); + foreach (array_unique($ids) as $id) { + $path = $geo->path($id); + if ($path) $paths[] = implode(' / ', array_column($path, 'name')); + } + if ($paths) $label = implode('; ', array_unique($paths)); + elseif ($provinces = app(InvestmentCorridorContext::class)->catalogueProvinces($record)) { + $label = implode(' / ', array_column($provinces, 'name')).' — contexto provincial do corredor; distrito e posto administrativo não indicados'; + } else $label = implode(' / ', array_filter([$record->province, $record->district])) ?: 'Localização não indicada'; + $record->setAttribute('territorial_summary', $label); + return $record; + } + /** @param array $territoryFilters * @return array */ public function references(bool $management = false, array $territoryFilters = []): array @@ -429,7 +467,7 @@ class InvestmentCatalogue $located = 0; foreach ($records as $record) { $properties = ['id' => $record->id, 'title' => $record->title, 'category' => $record->sector?->name, - 'location' => trim($record->province.' '.$record->district), 'url' => '/oportunidades/'.$record->slug.($filters === [] ? '' : '?'.http_build_query($filters))]; + 'location' => $this->presentLocation($record)->getAttribute('territorial_summary'), 'url' => '/oportunidades/'.$record->slug.($filters === [] ? '' : '?'.http_build_query($filters))]; foreach ($relations as $relation => $groups) { $properties[$relation] = ($groups->get($record->id) ?? collect())->pluck('name')->unique()->values()->all(); } diff --git a/app/Services/InvestmentCorridorContext.php b/app/Services/InvestmentCorridorContext.php index 7f4adcbd..da548fb7 100644 --- a/app/Services/InvestmentCorridorContext.php +++ b/app/Services/InvestmentCorridorContext.php @@ -14,6 +14,15 @@ final class InvestmentCorridorContext return null; } + /** Reuse Tempo's approved provincial context; never infer a district or master link. */ + public function catalogueProvinces(Opportunity $record): array + { + if ($record->primary_territory_id || $record->additionalTerritories()->exists()) return []; + if (data_get($record->workflow_context, 'corridor_agribusiness.source_sha256') !== CorridorAgribusinessOpportunities::SOURCE_HASH) return []; + $key = $this->key($record); + return $key ? $this->provinces($key) : []; + } + public function provinces(string $key): array { $entry = config('investment_corridors.'.$key); diff --git a/app/Services/OpportunityCorridorExplorer.php b/app/Services/OpportunityCorridorExplorer.php index d675a106..432222fe 100644 --- a/app/Services/OpportunityCorridorExplorer.php +++ b/app/Services/OpportunityCorridorExplorer.php @@ -35,8 +35,11 @@ final class OpportunityCorridorExplorer $path = collect($context['primary_territory_path'] ?? []); $province = $path->firstWhere('location_type', 'province')->name ?? $record->province; $district = $path->firstWhere('location_type', 'district')->name ?? $record->district; + $contextProvinces = app(InvestmentCorridorContext::class)->catalogueProvinces($record); + $provinceOptions = $province ? [$province] : array_column($contextProvinces, 'name'); $item = ['id' => $record->id, 'title' => $record->title, 'slug' => $record->slug, 'summary' => $record->summary, - 'province' => $province, 'district' => $district, 'chains' => array_values(array_unique($chains)), + 'province' => $province, 'district' => $district, 'provinces' => $provinceOptions, + 'territorial_summary' => $catalogue->presentLocation($record)->getAttribute('territorial_summary'), 'chains' => array_values(array_unique($chains)), 'stages' => $stages, 'maturity_label' => $record->maturity_label]; foreach ($corridors ?: ['other' => 'Outras localizações'] as $key => $name) { $groups[$key] ??= ['id' => $key, 'name' => $name, 'opportunities' => []]; diff --git a/docs/investmoz/consolidated-review-matrix-2026-10-03.md b/docs/investmoz/consolidated-review-matrix-2026-10-03.md index e005787f..c7788223 100644 --- a/docs/investmoz/consolidated-review-matrix-2026-10-03.md +++ b/docs/investmoz/consolidated-review-matrix-2026-10-03.md @@ -1739,3 +1739,15 @@ O delta instalado contém Área de trabalho no nível principal, destinos subord Pendente: conferência visual autenticada desktop/móvel/teclado/toque e percurso Gurué → consultar oferta → comparar ideia → guardar → recuperar no mesmo dossier. Último bloqueio conhecido: `The browser access host is unavailable`; uma aba aberta não restabelece o host. Não repetir as provas QA aceites nem reinstalar a base interna para resolver essa pendência. As 435 observações de Gurué não equivalem a 435 empresas únicas; listas internas, cobertura parcial e hipótese de investimento mantêm-se explícitas. L8 permanece parcial. Evidência: `docs/investmoz/unification/navigation-git-delivery-20261028.json`. O relatório QA anterior permanece como histórico do candidato antes da instalação. Actualizados os mesmos sete requisitos existentes, preservando o seu histórico; não foi criada outra matriz. +# Inventário antes da verificação — catálogo territorial, 28/10/2026 + +Preservar menus `6e8de43a`, dados, base interna, aprovações, configuração de corredores e históricos já aceites. Caso Maputo Província / Agronegócio reproduzido por leitura QA: zero resultados apesar de cinco oportunidades públicas do Corredor de Maputo, cujo âmbito provincial está aprovado desde 23/10 em `corridor-adaptive-context-20261023.json`. A consulta não inclui esse contexto; os cartões também não mostram todos os níveis territoriais disponíveis. Correcção delimitada nos requisitos existentes V2-07/V2-10, sem inferir distrito/posto administrativo onde a fonte não os indica. Conferência visual autenticada continua pendente; não há nova matriz nem reabertura de provas aceites. + + +## 28/10/2026 — correcção provincial do catálogo em QA, ainda sem instalação + +Caso da Tempo: Agronegócio / Maputo Província. A leitura QA reproduziu zero resultados para cinco oportunidades públicas do Corredor de Maputo. Reutilizada a decisão expressa de 23/10 que abrange Maputo Província e Maputo Cidade, antes disponível no percurso mas omitida na consulta. O filtro provincial passa a incluir esse contexto aprovado, mantendo sector e estado público, sem duplicar oportunidades nem atribuir distrito/posto administrativo ou coordenadas inexistentes. Uma localização explícita posterior prevalece sobre o contexto antigo. + +Os resultados apresentam a hierarquia territorial disponível; o contexto de corredor é identificado e os níveis não indicados continuam explícitos. Pesquisa/API, vista por corredores e lista sem coordenadas do mapa concordam. O atalho «Ver toda a província» elimina a necessidade de limpar vários níveis manualmente. Não foram criadas publicações, relações a mestres ou permissões. Provas QA: 4 testes/70 verificações, zero falhas, transacções revertidas; tipos, compilação QA e sintaxe PHP passaram. O inventário anterior foi registado antes dos testes. Menus 6e8de43a, base interna, históricos e aceitação anterior preservados; L8 permanece parcial. + +Relatório: `catalogue-province-coverage-qa-20261028.json`. Instalação pelo processo Git e conferência visual autenticada continuam pendentes. Não declarar auditados todos os outros menus por este delta. Cobertura actualizada nos requisitos existentes V2-07/V2-10; sem nova matriz. diff --git a/docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json b/docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json new file mode 100644 index 00000000..7252620b --- /dev/null +++ b/docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json @@ -0,0 +1,57 @@ +{ + "date": "2026-10-28", + "status": "QA_corrected_and_verified_not_installed", + "installed_baseline": "6e8de43ae7fec29b0766d95e209a8cb8baf0d88c", + "user_case": "Agronegócio / Maputo Província", + "reproduction": { + "QA_public_agribusiness": 37, + "Maputo_corridor_public_opportunities": 5, + "province_results_before": 0, + "province_results_after": 5 + }, + "cause": "The provincial catalogue ignored the corridor context already approved by Tempo; no records were deleted.", + "reused_decision": [ + "config/investment_corridors.php", + "docs/investmoz/unification/corridor-adaptive-context-20261023.json" + ], + "correction": [ + "Reuse approved corridor province context only at province level, with the accepted source hash and existing public publication decisions", + "Do not override an explicit primary/additional territory or infer district/post/coordinates", + "Display available province,district,administrative post,locality directly in results", + "Show both approved Maputo units as contextual coverage, not as two separate opportunities", + "Keep catalogue,API,corridor view and unlocated map list consistent", + "One action returns from district to whole province; no requirement to select every level" + ], + "QA": { + "tests": 4, + "assertions": 70, + "failures": 0, + "database": "proactive_investment_20261027_test", + "port": 55441, + "transactions_rolled_back": true, + "types": "passed", + "build": "passed", + "PHP_syntax": "passed" + }, + "preserved": [ + "Installed menus and accepted supply proofs", + "Originals,source data,territory IDs,publication states,permissions,private lists and histories", + "L8 unchanged,partial" + ], + "limitations": [ + "No active installation in this report", + "Real authenticated visual conference remains pending;last connector error The browser access host is unavailable", + "This fixes the shared investment catalogue and corridor view;it is not proof that every menu in the portal has been audited", + "Provincial corridor coverage is not a documented district site;unknown levels stay unknown" + ], + "existing_requirements": [ + "V2-07", + "V2-10" + ], + "restriction_origins": { + "territorial_behaviour": "Tempo current request", + "corridor_coverage": "Tempo express decision,23/10/2026", + "no_new_publication_or_roles": "existing approved scope", + "UI_summary_and_province_shortcut": "implementation choice" + } +} diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md index 941a2b40..586a2cea 100644 --- a/docs/investmoz/unification/traceability-and-manual.md +++ b/docs/investmoz/unification/traceability-and-manual.md @@ -7297,3 +7297,15 @@ O delta instalado contém Área de trabalho no nível principal, destinos subord Pendente: conferência visual autenticada desktop/móvel/teclado/toque e percurso Gurué → consultar oferta → comparar ideia → guardar → recuperar no mesmo dossier. Último bloqueio conhecido: `The browser access host is unavailable`; uma aba aberta não restabelece o host. Não repetir as provas QA aceites nem reinstalar a base interna para resolver essa pendência. As 435 observações de Gurué não equivalem a 435 empresas únicas; listas internas, cobertura parcial e hipótese de investimento mantêm-se explícitas. L8 permanece parcial. Evidência: `docs/investmoz/unification/navigation-git-delivery-20261028.json`. O relatório QA anterior permanece como histórico do candidato antes da instalação. Actualizados os mesmos sete requisitos existentes, preservando o seu histórico; não foi criada outra matriz. +# Inventário de preservação — consulta territorial, 28/10/2026 + +Antes das novas verificações: menus `6e8de43a` instalados, base interna e percurso proactivo preservados; conferência visual autenticada continua pendente. Reutilizam-se as provas anteriores. O caso relatado é Agronegócio / Maputo Província. Em leitura da QA isolada, as 37 oportunidades públicas incluem cinco do Corredor de Maputo; o filtro provincial devolve zero. A correspondência aprovada do corredor para Maputo Província e Maputo Cidade já existe em `config/investment_corridors.php` e `corridor-adaptive-context-20261023.json`, mas a pesquisa não a utiliza. Não se trata de eliminação dos registos. Os cartões mostram apenas província e omitem o detalhe territorial disponível. A correcção é de consulta/apresentação, sem criar localizações distritais não documentadas, relações a mestres, permissões ou novas publicações. Referência aos requisitos existentes V2-07/V2-10; a implementação transversal e a sessão real não ficam declaradas concluídas por este inventário. + + +## 28/10/2026 — correcção provincial do catálogo em QA, ainda sem instalação + +Caso da Tempo: Agronegócio / Maputo Província. A leitura QA reproduziu zero resultados para cinco oportunidades públicas do Corredor de Maputo. Reutilizada a decisão expressa de 23/10 que abrange Maputo Província e Maputo Cidade, antes disponível no percurso mas omitida na consulta. O filtro provincial passa a incluir esse contexto aprovado, mantendo sector e estado público, sem duplicar oportunidades nem atribuir distrito/posto administrativo ou coordenadas inexistentes. Uma localização explícita posterior prevalece sobre o contexto antigo. + +Os resultados apresentam a hierarquia territorial disponível; o contexto de corredor é identificado e os níveis não indicados continuam explícitos. Pesquisa/API, vista por corredores e lista sem coordenadas do mapa concordam. O atalho «Ver toda a província» elimina a necessidade de limpar vários níveis manualmente. Não foram criadas publicações, relações a mestres ou permissões. Provas QA: 4 testes/70 verificações, zero falhas, transacções revertidas; tipos, compilação QA e sintaxe PHP passaram. O inventário anterior foi registado antes dos testes. Menus 6e8de43a, base interna, históricos e aceitação anterior preservados; L8 permanece parcial. + +Relatório: `catalogue-province-coverage-qa-20261028.json`. Instalação pelo processo Git e conferência visual autenticada continuam pendentes. Não declarar auditados todos os outros menus por este delta. Cobertura actualizada nos requisitos existentes V2-07/V2-10; sem nova matriz. diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index 88ef11d0..607c8eb9 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -367,10 +367,10 @@ V2-03,"Mesmo dossier, pedido, conversa e tarefa interna; ciclo completo demonstr V2-04,Regras internas e recomendações explicáveis; evidência scoped com autoria/data/hash; aceitação distinta de tarefa,"backlog-mestre.md; § 3.2.3.1, p. 2472–2532; § 5.2, p. 7009–7190",Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. 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,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-04: Expandir consistência entre mercado, capacidade, recursos e calendário com fontes verificáveis; IA externa continua opcional",P2,V2-04: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-04,1,"[{""id"":""V2-04"",""pedido"":""Regras internas e recomendações explicáveis; evidência scoped com autoria/data/hash; aceitação distinta de tarefa"",""fontes"":[""backlog-mestre.md; § 3.2.3.1, p. 2472–2532; § 5.2, p. 7009–7190""],""aceitacao"":""Expandir consistência entre mercado, capacidade, recursos e calendário com fontes verificáveis; IA externa continua opcional"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""Balcão/orientação""}]",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.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 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.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",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: balcão. 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.,balcão,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/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; 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.",,, V2-05,Calculadores existentes preservados; fronteira entre explicação e cálculo determinístico mantida,"backlog-mestre.md; § 3.2.3.2, p. 2533–2576; § 3.2.1.5, p. 1746–2160",simuladores,/api/v1/questionnaires/{code}; /api/v1/simulation-drafts; /api/v1/simulation-drafts/claim; /api/v1/simulation-drafts/claim-preview; /api/v1/simulation-drafts/current; /api/v1/simulation-drafts/linkable-businesses; /api/v1/simulation-drafts/{id}; /api/v1/simulation-drafts/{id}/business-link; /api/v1/simulation-drafts/{id}/conversions; /api/v1/simulation-drafts/{id}/touch; /api/v1/simulations; /api/v1/simulations/history,"SimulationExecution, resultados/cenários/fontes, rascunhos e dossier existentes. 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,Cenário→cálculo→gravação→resultado/dossier correto→nova sessão→PDF/derivadas autorizadas. Sem aprovação/score inventado. Critério individual original preservado; cobertura atual ainda não individualizada.,"Regras financeiras/fiscais separadas; fonte oficial aceite, parâmetros/âmbito/período podem faltar; não substituir por0/taxa atual. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",V2-05: Reconciliar diplomas/artigos e parâmetros ausentes; nenhuma publicação documental ativa cálculos; não substituir desconhecidos por zero,P2,V2-05: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-05,1,"[{""id"":""V2-05"",""pedido"":""Calculadores existentes preservados; fronteira entre explicação e cálculo determinístico mantida"",""fontes"":[""backlog-mestre.md; § 3.2.3.2, p. 2533–2576; § 3.2.1.5, p. 1746–2160""],""aceitacao"":""Reconciliar diplomas/artigos e parâmetros ausentes; nenhuma publicação documental ativa cálculos; não substituir desconhecidos por zero"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""simuladores""}]",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.simulation_form_drafts: 22 registos; public.simulation_scenarios: 16 registos; public.simulations: 16 registos; public.simulation_tax_rules: 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.",Cenário→cálculo→gravação→resultado/dossier correto→nova sessão→PDF/derivadas autorizadas. Sem aprovação/score inventado. Critério individual original preservado; cobertura atual ainda não individualizada.,"SimulationExecution, resultados/cenários/fontes, rascunhos e dossier existentes","Regras financeiras/fiscais separadas; fonte oficial aceite, parâmetros/âmbito/período podem faltar; não substituir por0/taxa atual.",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: simuladores. 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.,simuladores,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/SimulationTaxParameterResolver.php; resources/js/components/simulation-form.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"SimulationExecutionTest, SimulationFormDraftTest, SimulationDraftContinuityTest, SimulationTaxRuleGovernanceTest; 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.",,, V2-06,Bolsa instalada constatada por leitura ativa; acesso e contexto compartilhados,"backlog-mestre.md; § 3.2.3.3, p. 2577–2609; § 3.5, p. 3374–3453",Bolsa/parcerias,/api/v1/partnerships; /api/v1/partnerships/source/{type}/{id}; /management/partnerships-install; /parcerias; /parcerias/candidaturas/{id}; /parcerias/criar; /parcerias/notificacoes/{id}/ler; /parcerias/painel; /parcerias/rascunhos; /parcerias/salas/{id}; /parcerias/salas/{id}/acordo; /parcerias/salas/{id}/documentos,"PartnershipExchange, salas, candidaturas, marcos, acesso/revogação documental. 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,"Candidatura/sala→documento autorizado→revogar→URL antigo negado na sessão corrente/nova, preservar proprietário/original. Critério individual original preservado; cobertura atual ainda não individualizada.","ACL da sala específica; autoria/membros/marcos e documentos privados, independente da ACL de oportunidade. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-06: Avaliar restantes propostas de indicadores, contratos e estados contra implementação real; acordos CTA/câmaras/associações dependem de decisões humanas",P2,V2-06: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-06,1,"[{""id"":""V2-06"",""pedido"":""Bolsa instalada constatada por leitura ativa; acesso e contexto compartilhados"",""fontes"":[""backlog-mestre.md; § 3.2.3.3, p. 2577–2609; § 3.5, p. 3374–3453""],""aceitacao"":""Avaliar restantes propostas de indicadores, contratos e estados contra implementação real; acordos CTA/câmaras/associações dependem de decisões humanas"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""Bolsa/parcerias""}]",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.portal_partnerships: 0 registos; public.partnership_rooms: 0 registos; public.partnership_interests: 0 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.","Candidatura/sala→documento autorizado→revogar→URL antigo negado na sessão corrente/nova, preservar proprietário/original. Critério individual original preservado; cobertura atual ainda não individualizada.","PartnershipExchange, salas, candidaturas, marcos, acesso/revogação documental","ACL da sala específica; autoria/membros/marcos e documentos privados, independente da ACL de oportunidade.",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: parcerias. 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.,parcerias,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/PartnershipExchange.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,PartnershipExchangeTest; 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.",,, -V2-07,Menu de gestão preserva rotas e permissões existentes,"backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. 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.,"28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-07: Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes",P2,V2-07: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-07,1,"[{""id"":""V2-07"",""pedido"":""Menu de gestão preserva rotas e permissões existentes"",""fontes"":[""backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339""],""aceitacao"":""Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",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.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 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.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",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: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,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/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; 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.",,, +V2-07,Menu de gestão preserva rotas e permissões existentes,"backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. 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.,"28/10:consulta provincial corrigida em QA,sem instalação;Maputo Agronegócio 0→5;histórico preservado. Histórico: 28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:falta entrega e conferência visual do delta provincial;outros menus não declarados integralmente auditados. Lacuna anterior: 28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-07: Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes",P2,V2-07: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-07,1,"[{""id"":""V2-07"",""pedido"":""Menu de gestão preserva rotas e permissões existentes"",""fontes"":[""backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339""],""aceitacao"":""Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",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.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 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.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",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: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:catalogue-province-coverage-qa-20261028.json;4testes/70verificações,tipos/build/PHP;contexto aprovado em23/10 reutilizado;sem novas publicações/permissões. Evidência anterior: 28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,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/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; 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.",,, V2-08,Projetos/clusters/zonas pesquisáveis e fichas navegáveis em QA; esquema territorial ativo constatado,"backlog-mestre.md; § 4.6.1, p. 3740–6267",cartografia/relações,/api/v1/geo/drafts; /api/v1/geo/search; /api/v1/geo/sources; /api/v1/geo/sources/{id}/transitions; /api/v1/geo/territories; /api/v1/geo/territories/{id}; /api/v1/geo/territories/{id}/transitions; /api/v1/geo/territories/{type}/{id}; /api/v1/geo/{collection}; /api/v1/investment/compare; /api/v1/investment/export; /api/v1/investment/favourites/{id},"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado. 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,"Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-08: Revisão documental de cada área, limites/polígonos oficiais, disponibilidade, capacidade e histórico; links territoriais existentes não certificam todas as correções propostas",P2,V2-08: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-08,1,"[{""id"":""V2-08"",""pedido"":""Projetos/clusters/zonas pesquisáveis e fichas navegáveis em QA; esquema territorial ativo constatado"",""fontes"":[""backlog-mestre.md; § 4.6.1, p. 3740–6267""],""aceitacao"":""Revisão documental de cada área, limites/polígonos oficiais, disponibilidade, capacidade e histórico; links territoriais existentes não certificam todas as correções propostas"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""cartografia/relaçõ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.geo_locations: 1990 registos; public.geo_geometries: 0 registos; public.project_locations: 28 registos; public.cluster_projects: 13 registos; public.opportunity_projects: 0 registos; public.opportunity_clusters: 0 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.","Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada.",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: território. 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.,território,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.",resources/js/components/investment-territory.tsx; app/Http/Controllers/InvestmentTerritoryController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentTerritoryTest, TerritorialRegistryTest, InvestmentTerritorialTraceabilityTest, InvestmentZoneTest; 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.",,, V2-09,"Nenhum score de sucesso, disponibilidade ou elegibilidade inventado","backlog-mestre.md; § 4.6.1.14–4.6.1.18, p. 4252–6267",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.","V2-09: Validar pesos, lacunas, condicionantes e saídas explicáveis; não executar seeds demonstrativos contra dados ativos",P2,V2-09: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-09,1,"[{""id"":""V2-09"",""pedido"":""Nenhum score de sucesso, disponibilidade ou elegibilidade inventado"",""fontes"":[""backlog-mestre.md; § 4.6.1.14–4.6.1.18, p. 4252–6267""],""aceitacao"":""Validar pesos, lacunas, condicionantes e saídas explicáveis; não executar seeds demonstrativos contra dados ativos"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""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.",,, -V2-10,Menus e preparação não limitados aos pilotos,"backlog-mestre.md; § 4.1–4.7, p. 3646–6994",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. 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.,"28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-10: Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva",P2,V2-10: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-10,1,"[{""id"":""V2-10"",""pedido"":""Menus e preparação não limitados aos pilotos"",""fontes"":[""backlog-mestre.md; § 4.1–4.7, p. 3646–6994""],""aceitacao"":""Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",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.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 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.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",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: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,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/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; 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.",,, +V2-10,Menus e preparação não limitados aos pilotos,"backlog-mestre.md; § 4.1–4.7, p. 3646–6994",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. 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.,"28/10:consulta provincial corrigida em QA,sem instalação;Maputo Agronegócio 0→5;histórico preservado. Histórico: 28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:falta entrega e conferência visual do delta provincial;outros menus não declarados integralmente auditados. Lacuna anterior: 28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-10: Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva",P2,V2-10: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-10,1,"[{""id"":""V2-10"",""pedido"":""Menus e preparação não limitados aos pilotos"",""fontes"":[""backlog-mestre.md; § 4.1–4.7, p. 3646–6994""],""aceitacao"":""Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",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.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 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.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",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: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:catalogue-province-coverage-qa-20261028.json;4testes/70verificações,tipos/build/PHP;contexto aprovado em23/10 reutilizado;sem novas publicações/permissões. Evidência anterior: 28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,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/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; 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.",,, V2-11,Inventário acessível atualizado: 248 ficheiros e 63 anexos incorporados; exemplares de formulários mantidos,"backlog-mestre.md; § 5.1; § 5.2 didática–5.6, p. 7007–7008 e 7191–7558",biblioteca,//; /Simulador; /api/v1/ai/documents; /api/v1/documents/recommendations; /api/v2/investment/admin/legal-sources; /api/v2/investment/admin/legal-sources/{id}/{action}; /apoio; /balcao-virtual; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /como-investir; /documentos; /documentos/{id},"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas. 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,Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"V2-11: Reconciliar todo o conteúdo do portal público, guias/árvores, autorização e atualização por ficheiro; inventário local não é crawl integral do site público",P2,V2-11: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-11,1,"[{""id"":""V2-11"",""pedido"":""Inventário acessível atualizado: 248 ficheiros e 63 anexos incorporados; exemplares de formulários mantidos"",""fontes"":[""backlog-mestre.md; § 5.1; § 5.2 didática–5.6, p. 7007–7008 e 7191–7558""],""aceitacao"":""Reconciliar todo o conteúdo do portal público, guias/árvores, autorização e atualização por ficheiro; inventário local não é crawl integral do site público"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""biblioteca""}]",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.documents: 4 registos; public.portal_resources: 4 registos; public.portal_resource_links: 19 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.",Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas",Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF.,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: documentos e legado. 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.,documentos e legado,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/PortalServicesController.php; app/Jobs/ScanDocumentForMalware.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"PortalServicesTest, DocumentLibrarySchemaCompatibilityTest, ImportDocumentBatchTest, ClamDScannerIntegrationTest; 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.",,, V2-12,"Validação interna não equivale a licença, aprovação, benefício fiscal ou ato administrativo","backlog-mestre.md; § 6, p. 7559–7687; § 3.2.1, p. 1453–2171 diff --git a/resources/js/components/opportunity-corridor-groups.tsx b/resources/js/components/opportunity-corridor-groups.tsx index 67a3b42e..32d721ad 100644 --- a/resources/js/components/opportunity-corridor-groups.tsx +++ b/resources/js/components/opportunity-corridor-groups.tsx @@ -2,7 +2,7 @@ import { Link } from '@inertiajs/react'; import { useState } from 'react'; import { button, card, input } from '@/pages/investment/shared'; -type Item = {id:number;title:string;slug:string;summary:string|null;province:string|null;district:string|null;chains:string[];stages:string[];maturity_label:string|null}; +type Item = {id:number;title:string;slug:string;summary:string|null;province:string|null;district:string|null;provinces?:string[];territorial_summary?:string;chains:string[];stages:string[];maturity_label:string|null}; export type CorridorGroup = {id:string;name:string;count:number;locations:string[];opportunities:Item[]}; type Props = {groups:CorridorGroup[];selected:number[];onSelect:(id:number,checked:boolean)=>void;onCompare:(ids:number[])=>void;onClear:()=>void}; @@ -10,10 +10,11 @@ function Group({group,selected,onSelect}: {group:CorridorGroup} & Pickr.province).filter((s):s is string=>!!s))].sort(); - const districts=[...new Set(group.opportunities.filter(r=>!province||r.province===province).map(r=>r.district).filter((s):s is string=>!!s))].sort(); + const provinceNames=(r:Item)=>r.provinces??(r.province?[r.province]:[]); + const provinces=[...new Set(group.opportunities.flatMap(provinceNames))].sort(); + const districts=[...new Set(group.opportunities.filter(r=>!province||provinceNames(r).includes(province)).map(r=>r.district).filter((s):s is string=>!!s))].sort(); const chains=[...new Set(group.opportunities.flatMap(r=>r.chains))].sort(); - const rows=group.opportunities.filter(r=>(!province||r.province===province)&&(!district||r.district===district)&&(!chain||r.chains.includes(chain))); + const rows=group.opportunities.filter(r=>(!province||provinceNames(r).includes(province))&&(!district||r.district===district)&&(!chain||r.chains.includes(chain))); return

{group.name}

{group.count} oportunidades publicadas

{group.locations.length ? 'Localizações identificadas: '+group.locations.join(' · ') : 'Abrangência territorial por indicar.'}

@@ -25,7 +26,7 @@ function Group({group,selected,onSelect}: {group:CorridorGroup} & Pick{rows.length} oportunidades com estes filtros

{rows.map(r=>

{r.title}

-

{[r.province,r.district].filter(Boolean).join(' / ')||'Localização por escolher'}

+

{r.territorial_summary||[r.province,r.district].filter(Boolean).join(' / ')||'Localização por escolher'}

Cadeia de valor: {r.chains.join(' · ')||'Por indicar'}

{r.summary && !r.stages.includes(r.summary) &&

{r.summary}

}

Etapas e actividades: {r.stages.join(' · ')||'Por indicar'}

{r.maturity_label}

diff --git a/resources/js/components/opportunity-search-filters.tsx b/resources/js/components/opportunity-search-filters.tsx index 3c371ff4..a4f6b6ea 100644 --- a/resources/js/components/opportunity-search-filters.tsx +++ b/resources/js/components/opportunity-search-filters.tsx @@ -222,6 +222,11 @@ export default function OpportunitySearchFilters({
Localização +

+ A província inclui as oportunidades dos seus distritos, postos administrativos e localidades. + Não é necessário escolher todos os níveis. O contexto provincial de um corredor é identificado nos resultados; não confirma uma implantação distrital. + {path.length > 1 && } +

{( [ 'province_id', diff --git a/resources/js/pages/investment/catalogue.tsx b/resources/js/pages/investment/catalogue.tsx index 643ef30d..602cca34 100644 --- a/resources/js/pages/investment/catalogue.tsx +++ b/resources/js/pages/investment/catalogue.tsx @@ -591,7 +591,7 @@ export default function Catalogue({

{r.sector?.name} ·{' '} - {r.province || 'Localização não indicada'} + {r.territorial_summary || [r.province, r.district].filter(Boolean).join(' / ') || 'Localização não indicada'}

withoutVite(); + } + + public function test_accepted_maputo_source_is_found_in_both_approved_provinces_without_becoming_a_district_site(): void + { + $c=app(InvestmentCatalogue::class); + $expected=Opportunity::published()->where('workflow_context->corridor_agribusiness->source_sha256',CorridorAgribusinessOpportunities::SOURCE_HASH) + ->where('workflow_context->corridor_agribusiness->corridor','Corredor de Maputo')->pluck('id')->all(); + $this->assertCount(5,$expected); + foreach([self::PROVINCE,'4aa31470-997e-5c63-8fe0-ff2f62586f56']as$province){ + foreach(['all','context']as$basis){ + $ids=$c->query(['sector'=>'agronegocio','province_id'=>$province,'territory_basis'=>$basis])->pluck('id')->all(); + foreach($expected as$id)$this->assertContains($id,$ids); + } + } + foreach($expected as$id)$this->assertNotContains($id,$c->query(['province_id'=>self::PROVINCE,'territory_basis'=>'direct'])->pluck('id')->all()); + $district=app(InvestmentGeography::class)->publicReferences()->where('parent_id',self::PROVINCE)->where('location_type','district')->first(); + $this->assertNotNull($district); + foreach($expected as$id)$this->assertNotContains($id,$c->query(['province_id'=>self::PROVINCE,'district_id'=>$district->id])->pluck('id')->all()); + $label=$c->presentLocation(Opportunity::findOrFail($expected[0]))->territorial_summary; + $this->assertStringContainsString('contexto provincial do corredor',$label); + $this->assertStringContainsString('distrito e posto administrativo não indicados',$label); + foreach($expected as$id)$this->assertContains($id,$c->query(['geo_location_id'=>self::PROVINCE])->pluck('id')->all()); + $this->assertSame([],array_intersect($expected,$c->query(['province_id'=>'059b02ca-7095-577a-8705-4d4c46896747'])->pluck('id')->all())); + } + + public function test_province_includes_its_descendants_with_full_location_and_excludes_private_and_other_provinces(): void + { + $geo=app(InvestmentGeography::class);$c=app(InvestmentCatalogue::class); + $district=$geo->publicReferences()->where('parent_id',self::PROVINCE)->where('location_type','district')->first(); + $post=$geo->publicReferences()->where('parent_id',$district->id)->where('location_type','admin_post')->first(); + $this->assertNotNull($post); + $make=fn($territory,$status='published')=>Opportunity::create(['sector_id'=>1,'reference'=>'SYNTHETIC-QA-'.Str::uuid(),'slug'=>'synthetic-'.Str::uuid(),'title'=>'SYNTHETIC QA province coverage','status'=>$status,'published_at'=>now()->subMinute(),'primary_territory_id'=>$territory,'geography_scope'=>'specific']); + $record=$make($post->id);$private=$make($post->id,'draft');$other=$make('059b02ca-7095-577a-8705-4d4c46896747'); + $ids=$c->query(['province_id'=>self::PROVINCE,'sector'=>'agronegocio'])->pluck('id')->all(); + $this->assertContains($record->id,$ids);$this->assertNotContains($private->id,$ids);$this->assertNotContains($other->id,$ids); + $label=$c->presentLocation($record)->territorial_summary; + foreach(['Maputo Província',$district->name,$post->name]as$name)$this->assertStringContainsString($name,$label); + } + + public function test_actual_territory_and_publication_decisions_override_old_corridor_context(): void + { + $c=app(InvestmentCatalogue::class); + $record=Opportunity::published()->where('workflow_context->corridor_agribusiness->corridor','Corredor de Maputo')->firstOrFail(); + $record->primary_territory_id='059b02ca-7095-577a-8705-4d4c46896747';$record->save(); + $this->assertNotContains($record->id,$c->query(['province_id'=>self::PROVINCE])->pluck('id')->all()); + $record->primary_territory_id=null;$record->status='draft';$record->save(); + $this->assertNotContains($record->id,$c->query(['province_id'=>self::PROVINCE])->pluck('id')->all()); + } + + public function test_public_search_and_corridor_view_agree_without_inventing_map_coordinates(): void + { + $filters=['province_id'=>self::PROVINCE,'sector'=>'agronegocio']; + $response=$this->getJson('/api/v1/investment/search?'.http_build_query($filters))->assertOk()->assertJsonPath('total',5); + foreach($response->json('data')as$row)$this->assertStringContainsString('contexto provincial do corredor',$row['territorial_summary']); + $groups=app(\App\Services\OpportunityCorridorExplorer::class)->groups($filters); + $this->assertCount(1,$groups);$this->assertSame(5,$groups[0]['count']); + foreach($groups[0]['opportunities']as$row){$this->assertContains('Maputo Província',$row['provinces']);$this->assertNull($row['district']);} + $map=app(InvestmentCatalogue::class)->map($filters); + $this->assertCount(5,$map['unlocated']);$this->assertSame([],$map['features']); + } +}