diff --git a/.gitattributes b/.gitattributes index 4da48a8f..918cc013 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,8 @@ * text=auto eol=lf +# Preserve the exact bytes pinned by EconomicReferenceCatalog::MANIFEST_SHA256. +database/data/economic-references-lot-01.json text eol=crlf + *.blade.php diff=html *.css diff=css *.html diff=html diff --git a/README.md b/README.md index fd5b8db8..de49b35f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ -# Portal do Investidor — esqueleto Laravel +# Portal do Investidor — InvesteMoz + +## Executar esta plataforma no Windows + +Consulte [Execução local](deploy/local/README.md). Com Docker Desktop iniciado, +execute `./deploy/local/start.ps1`. Depois da preparação, `composer run dev` +inicia a plataforma em http://127.0.0.1:8000. + +O ambiente local usa uma base PostgreSQL/PostGIS de demonstração isolada. +Não execute os exemplos históricos de criação de um projecto novo sobre esta +instalação ou sobre dados existentes. + +## Referência histórica do pacote inicial Estes ficheiros correspondem ao domínio de **sectores**, **oportunidades** e **manifestações de interesse** do Portal do Investidor. Foram desenhados diff --git a/app/Console/Commands/CheckDevelopmentEnvironment.php b/app/Console/Commands/CheckDevelopmentEnvironment.php new file mode 100644 index 00000000..240becbd --- /dev/null +++ b/app/Console/Commands/CheckDevelopmentEnvironment.php @@ -0,0 +1,51 @@ += 8.4.1' => version_compare(PHP_VERSION, '8.4.1', '>='), + 'Driver PostgreSQL activo' => extension_loaded('pdo_pgsql'), + 'APP_KEY definida' => filled(config('app.key')), + 'Base PostgreSQL configurada' => config('database.default') === 'pgsql', + 'Cache de vistas gravável' => is_dir(config('view.compiled') ?: '') && is_writable(config('view.compiled') ?: ''), + 'Sessões e logs graváveis' => is_writable(storage_path('framework/sessions')) && is_writable(storage_path('logs')), + 'Dependências frontend instaladas' => is_file(base_path('node_modules/.bin/vp')) || is_file(base_path('node_modules/.bin/vp.cmd')), + ]; + + if ($checks['Driver PostgreSQL activo'] && $checks['Base PostgreSQL configurada']) { + try { + DB::selectOne('SELECT 1'); + $checks['Ligação à base de dados'] = true; + $checks['Extensão PostGIS instalada'] = (bool) DB::selectOne("SELECT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'postgis') AS installed")->installed; + $checks['Tabelas principais instaladas'] = collect(['migrations', 'users', 'sectors', 'opportunities', 'sessions', 'cache', 'jobs']) + ->every(fn (string $table): bool => Schema::hasTable($table)); + } catch (\Throwable) { + $checks['Ligação à base de dados'] = false; + } + } + + foreach ($checks as $label => $passed) { + $this->line(($passed ? '[OK] ' : '[FALHA] ').$label); + } + + if (in_array(false, $checks, true)) { + $this->error('Arranque interrompido. Consulte deploy/local/README.md e corrija os itens acima.'); + + return self::FAILURE; + } + + return self::SUCCESS; + } +} diff --git a/app/Http/Controllers/EditorialArticleController.php b/app/Http/Controllers/EditorialArticleController.php index 09842258..b3eda649 100644 --- a/app/Http/Controllers/EditorialArticleController.php +++ b/app/Http/Controllers/EditorialArticleController.php @@ -25,6 +25,11 @@ class EditorialArticleController extends Controller : response()->view('management.editorial-installation', ['plan' => $installation->preview($request->user()), 'operationKey' => (string) \Illuminate\Support\Str::uuid(), 'receipt' => $receipt])->header('Cache-Control', 'private, no-store'); } + public function showMfa(Request $request) + { + return $this->confirmMfa($request); + } + public function confirmMfa(Request $request) { $actor = $request->user(); diff --git a/app/Support/IsolatedQaDatabase.php b/app/Support/IsolatedQaDatabase.php new file mode 100644 index 00000000..6b529b59 --- /dev/null +++ b/app/Support/IsolatedQaDatabase.php @@ -0,0 +1,23 @@ +environment('testing') || config('database.default') !== 'pgsql' + || ! in_array($connection['host'], ['127.0.0.1', 'localhost'], true) + || (string) $connection['port'] !== '55441' || ! empty($connection['url']) + || ! str_ends_with($connection['database'], '_test')) { + return false; + } + + $identity = DB::selectOne('SELECT current_database() AS database, inet_server_port() AS port'); + + return $identity->database === $connection['database'] && (int) $identity->port === 55441; + } +} diff --git a/bootstrap/app.php b/bootstrap/app.php index 8b20e633..a4b2495e 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -19,7 +19,7 @@ use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Symfony\Component\HttpFoundation\Response; -return Application::configure(basePath: dirname(__DIR__)) +$app = Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', api: __DIR__.'/../routes/api.php', @@ -106,3 +106,7 @@ return Application::configure(basePath: dirname(__DIR__)) return $response; }); })->create(); + +(require __DIR__.'/storage.php')($app->basePath(), $app->storagePath()); + +return $app; diff --git a/bootstrap/storage.php b/bootstrap/storage.php new file mode 100644 index 00000000..e6786d87 --- /dev/null +++ b/bootstrap/storage.php @@ -0,0 +1,17 @@ +$table->text('editorial_draft')->nullable()); } public function down(): void diff --git a/database/migrations/2026_10_16_140000_add_investment_zone_operational_details.php b/database/migrations/2026_10_16_140000_add_investment_zone_operational_details.php index 91159479..40d5bc67 100644 --- a/database/migrations/2026_10_16_140000_add_investment_zone_operational_details.php +++ b/database/migrations/2026_10_16_140000_add_investment_zone_operational_details.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { - if(!config('investment-zone-details.authenticated_installation')){throw new RuntimeException('Use a instalação autenticada nominal L1.');} + if(!config('investment-zone-details.authenticated_installation') && !\App\Support\IsolatedQaDatabase::allowsSchemaChanges()){throw new RuntimeException('Use a instalação autenticada nominal L1.');} if(!Schema::hasColumn('investment_zones','editorial_draft') || !DB::table('migrations')->where('migration','2026_10_16_130000_add_investment_zone_editorial_draft')->exists()){throw new RuntimeException('Instale/verifique primeiro a base 130000.');} Schema::table('investment_zones',fn(Blueprint $table)=>$table->jsonb('operational_details')->nullable()); } diff --git a/database/migrations/2026_10_16_150000_create_investor_navigation_preferences.php b/database/migrations/2026_10_16_150000_create_investor_navigation_preferences.php index f58cb54a..0f773e52 100644 --- a/database/migrations/2026_10_16_150000_create_investor_navigation_preferences.php +++ b/database/migrations/2026_10_16_150000_create_investor_navigation_preferences.php @@ -8,7 +8,7 @@ return new class extends Migration { public function up(): void { - if (! config('investor-context.authenticated_installation')) { + if (! config('investor-context.authenticated_installation') && ! \App\Support\IsolatedQaDatabase::allowsSchemaChanges()) { throw new RuntimeException('Use a ação autenticada nominal de instalação do contexto.'); } Schema::create('investor_navigation_preferences', function (Blueprint $t) { diff --git a/database/migrations/2026_10_18_160000_add_portal_editorial_content.php b/database/migrations/2026_10_18_160000_add_portal_editorial_content.php index c785fb4b..d557490d 100644 --- a/database/migrations/2026_10_18_160000_add_portal_editorial_content.php +++ b/database/migrations/2026_10_18_160000_add_portal_editorial_content.php @@ -9,7 +9,7 @@ return new class extends Migration { public function up(): void { - if (!config('editorial.authenticated_installation')) { throw new RuntimeException('Use a instalação editorial autenticada.'); } + if (!config('editorial.authenticated_installation') && !\App\Support\IsolatedQaDatabase::allowsSchemaChanges()) { throw new RuntimeException('Use a instalação editorial autenticada.'); } Schema::table('portal_resources', fn (Blueprint $t) => $t->jsonb('editorial_content')->nullable()); } diff --git a/deploy/local/README.md b/deploy/local/README.md new file mode 100644 index 00000000..95e23f63 --- /dev/null +++ b/deploy/local/README.md @@ -0,0 +1,86 @@ +# Execução local no Windows + +Ambiente de demonstração novo autorizado em 19/10/2026. PostgreSQL/PostGIS +isolado em `127.0.0.1:55441`, base `investmoz_local_test`, volume Docker +`investmoz-local-qa_postgres-qa`. Não contém os dados do portal activo. +O MySQL existente não serve este esquema PostgreSQL e é preservado. + +## Arrancar + +Inicie Docker Desktop. Na raiz do projecto: + +```powershell +./deploy/local/start.ps1 +``` + +Com a base já iniciada e preparada, basta: + +```powershell +composer run dev +``` + +Abra http://127.0.0.1:8000. O comando inicia Laravel, o worker da fila e Vite. +Use Ctrl+C para terminar. A base conserva os dados entre arranques. + +O script de arranque executa estes passos, parando no primeiro erro: + +```powershell +docker compose --env-file .env -f deploy/local/compose.yaml up -d --wait +php tools/local-qa-bootstrap.php +composer run dev +``` + +O preparador verifica configuração e identidade real da base antes de migrar. +Só admite `investmoz_local_test`, TCP local e porta real 55441, sem DB_URL nem +configuração em cache. Executa migrations em `testing`, como exigem as guardas +existentes. Só cria os dados iniciais quando sectores e utilizadores estão vazios; +um novo arranque não redefine contas. Nunca usa `migrate:fresh`. + +As quatro migrations mais recentes também admitem QA com identidade verificada +por `IsolatedQaDatabase`. A alternativa de instalação autenticada no activo é +preservada. A excepção QA é uma escolha técnica consistente com as migrations +anteriores, sem activar funcionalidades ou publicar dados. + +Conta do seeder existente, exclusivamente para esta demonstração: +`test@example.com` / `password`. Não é um administrador do portal. +As regras existentes de autenticação, MFA e instalação autenticada mantêm-se. + +## Dependências e configuração + +- PHP >= 8.4.1, com `pdo_pgsql` e `pgsql` activos no PHP do terminal. +- Node 24, Composer, dependências de `composer.lock` e `package-lock.json`. +- Docker Desktop com contentores Linux. +- `.env` local com PostgreSQL, porta 55441, base e utilizador do Compose e + `DB_PASSWORD` privado. A chave da aplicação existente deve ser preservada. +- O primeiro build obtém as fontes configuradas de fonts.bunny.net; precisa de rede. + +O bootstrap cria as pastas de cache, vistas, sessões e logs antes da configuração +Laravel. `php artisan portal:dev-check` verifica os requisitos essenciais sem +alterar registos nem mostrar credenciais. Falhas interrompem `composer run dev` +antes de iniciar os três processos. + +```powershell +php artisan portal:dev-check +php artisan wayfinder:generate --with-form +npm run types:check +npm run build +``` + +Os testes que usam RefreshDatabase devem usar outra base `investmoz_test` no +mesmo servidor QA; nunca a base de demonstração nem o activo. `tests/TestCase.php` +mantém as guardas e o bloqueio contra testes concorrentes. + +## Origem e limites + +Origem: pedido expresso de correcção e configuração local e escolha do responsável +por uma base nova de demonstração em 19/10/2026. Portas, Compose, pastas automáticas +e verificação de arranque são escolhas técnicas, sem novas regras organizacionais. +Aplicam-se as decisões Tempo de 12/10/2026 e a separação QA/activo de AGENTS.md. +Não constitui implantação em produção nem aceitação funcional global da matriz +existente em `docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv`. + +Não remover o volume Docker para actualizar. O `.env` anterior e o `php.ini` +anterior à activação PostgreSQL foram conservados em `storage/app/private/`. +O correio local usa o canal log. Integrações externas e serviços opcionais precisam +das configurações próprias já previstas no projecto; este arranque não lhes +atribui autorização, publicação ou credenciais. diff --git a/deploy/local/VERIFICACAO-20261019.md b/deploy/local/VERIFICACAO-20261019.md new file mode 100644 index 00000000..dfefb259 --- /dev/null +++ b/deploy/local/VERIFICACAO-20261019.md @@ -0,0 +1,62 @@ +# Verificação local — 19/10/2026 + +Pedido: identificar e corrigir o arranque, configurar a plataforma e testar. +O responsável escolheu uma base nova de demonstração local. + +## Plano executado e causas corrigidas + +1. Reproduzido `Please provide a valid cache path`: faltavam as pastas + `storage/framework`. O bootstrap agora cria as pastas antes da configuração. +2. Substituída a configuração local MySQL incompatível por PostgreSQL/PostGIS + QA em `investmoz_local_test:55441`; activados `pdo_pgsql` e `pgsql` no PHP + usado pelo terminal. Configurações anteriores preservadas privadamente. +3. Preparado Docker Desktop e um contentor/volume próprios, ligado só a + `127.0.0.1`. O MySQL existente não foi removido nem alterado. +4. Aplicadas as 88 migrations e os seeders existentes. Quatro migrations + recentes não admitiam QA: passaram a reconhecer exclusivamente o alvo real + isolado, mantendo a alternativa autenticada para o activo. Guardas testadas + contra ambiente de produção, host/porta/base/URL indevidos e identidade real + diferente da configuração. Nenhuma flag foi apresentada como autenticação. +5. Completadas as dependências JavaScript em falta (`docx`, `jszip`) e separado + o destino GET da confirmação MFA editorial, evitando uma propriedade + duplicada no TypeScript gerado. O fluxo MFA existente foi preservado. +6. Corrigida a distribuição do manifesto económico: o hash existente corresponde + a CRLF, enquanto o checkout convertia o ficheiro para LF. Repostos os bytes + que correspondem ao SHA-256 já fixado, sem alterar conteúdo ou hash esperado; + `.gitattributes` preserva CRLF para esse ficheiro específico. +7. Criada a ligação `public/storage`, acrescentada a verificação prévia de + `composer run dev` e documentado o arranque repetível. + +## Resultado observado + +- `composer check-platform-reqs`: passou. +- `composer validate --no-check-publish`: válido; aviso preexistente sobre + versão exacta de `opis/json-schema`. +- Wayfinder com `--with-form`: passou. +- `npm run types:check`: passou. +- `npm run build`: passou, 2481 módulos; avisos de tamanho de chunks e + optimização opcional de fontes não interrompem o build. +- PHPUnit seleccionado: **13 testes, 39 asserções, todos passaram**, na base + separada `investmoz_test:55441`. Inclui login, página inicial, guardas QA, + criação idempotente das pastas e integridade do manifesto. +- Pint dos novos componentes PHP: passou. `git diff --check`: passou. +- Segundo `local-qa-bootstrap.php`: nada por migrar, dados e contas preservados, + seed omitido. `migrate:status`: 88 migrations aplicadas. +- `composer run dev`: Laravel em 8000, Vite em 5173 e fila a funcionar. +- HTTP 200: saúde, início, login, registo, catálogo, página de sector e APIs + públicas de início, sectores e pesquisa. Vite client: 200. +- Chrome: início, catálogo, sector, login, registo e painel após autenticação + renderizados; **zero erros JavaScript e zero respostas 5xx observadas**. + Provas: `outputs/local-startup-20261019/browser.json`, `home.png`, `dashboard.png`. + +Origem das alterações: pedido expresso e opção do responsável por demonstração; +pastas, Compose, portos e excepção de migração em QA são escolhas técnicas. +Aplicam-se as decisões Tempo de 12/10/2026 e a separação QA/activo em AGENTS.md. +Referência na matriz existente: `MASTER-e1169a77-0376`, apenas como prova do +ambiente local. Não encerra os critérios globais da cláusula. + +O catálogo novo pode apresentar colecções vazias: os dados do portal activo não +foram importados. A conta local é `test@example.com` / `password`; não recebe +privilégios administrativos. As integrações externas, o envio real de correio, +o scan de uploads e a aceitação funcional integral não foram demonstrados por +este ensaio de arranque. Mantêm-se as configurações e autorizações próprias. diff --git a/deploy/local/compose.yaml b/deploy/local/compose.yaml new file mode 100644 index 00000000..ca62aa2d --- /dev/null +++ b/deploy/local/compose.yaml @@ -0,0 +1,21 @@ +name: investmoz-local-qa +services: + postgres: + image: postgis/postgis:17-3.5 + command: ['postgres', '-p', '55441'] + restart: unless-stopped + environment: + POSTGRES_DB: investmoz_local_test + POSTGRES_USER: investmoz_test + POSTGRES_PASSWORD: '${DB_PASSWORD:?Configure DB_PASSWORD in the local .env first}' + ports: + - '127.0.0.1:55441:55441' + volumes: + - postgres-qa:/var/lib/postgresql/data + healthcheck: + test: ['CMD-SHELL', 'pg_isready -p 55441 -U investmoz_test -d investmoz_local_test'] + interval: 5s + timeout: 5s + retries: 20 +volumes: + postgres-qa: diff --git a/deploy/local/start.ps1 b/deploy/local/start.ps1 new file mode 100644 index 00000000..525b631a --- /dev/null +++ b/deploy/local/start.ps1 @@ -0,0 +1,13 @@ +$ErrorActionPreference = 'Stop' +$projectRoot = (Resolve-Path (Join-Path $PSScriptRoot '../..')).Path +Push-Location $projectRoot +try { + docker compose --progress plain --env-file .env -f deploy/local/compose.yaml up -d --wait --wait-timeout 120 + if ($LASTEXITCODE -ne 0) { throw 'Inicie Docker Desktop e verifique o serviço PostgreSQL QA.' } + php tools/local-qa-bootstrap.php + if ($LASTEXITCODE -ne 0) { throw 'Preparação QA interrompida; veja a mensagem acima.' } + composer run dev + if ($LASTEXITCODE -ne 0) { throw 'Arranque interrompido; veja a mensagem acima.' } +} finally { + Pop-Location +} diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index 9cef5b65..7288fbdd 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -690,7 +690,7 @@ MASTER-e1169a77-0372,"Usar 00-plan.md como orquestrador: seleccionar os prompts MASTER-e1169a77-0373,Qualquer teste obrigatório falha,portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7182 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7182,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.",MASTER-e1169a77-0373: Qualquer teste obrigatório falha | MASTER-edece80c-0373: Qualquer teste obrigatório falha,P2,MASTER-e1169a77-0373: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0373: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0373 | MASTER-edece80c-0373,2,"[{""id"":""MASTER-e1169a77-0373"",""pedido"":""Qualquer teste obrigatório falha"",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7182""],""aceitacao"":""Qualquer teste obrigatório falha"",""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-0373"",""pedido"":""Qualquer teste obrigatório falha"",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7182""],""aceitacao"":""Qualquer teste obrigatório falha"",""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.",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." MASTER-e1169a77-0374,"Registar aprovações técnica, negócio e segurança",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7192 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7192,negócios,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /api/v1/existing-business/listings; /api/v1/existing-business/listings/{id}; /api/v1/existing-business/listings/{id}/objects; /api/v1/existing-business/listings/{id}/objects/{object}; /api/v1/existing-business/listings/{id}/transitions; /api/v1/existing-business/listings/{id}/verifications; /api/v1/existing-business/reviews; /api/v1/simulation-drafts/linkable-businesses; /api/v1/simulation-drafts/{id}/business-link; /investidor/negocios,"ExistingBusinessDrafts/Policy, anúncio público, InterestSubmission e filtros 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.,Sem evidência suficiente,Negócio→revisão/publicação→interesse→origem→estatística única→recuperação; preparar caso existente autorizado sem forçar estado. Critério individual original preservado; cobertura atual ainda não individualizada.,Políticas legadas próprias e docs/mandatos; QA18445zero anúncios publicados; notificaçõesOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"MASTER-e1169a77-0374: Registar aprovações técnica, negócio e segurança | MASTER-edece80c-0374: Registar aprovações técnica, negócio e segurança",P2,MASTER-e1169a77-0374: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0374: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0374 | MASTER-edece80c-0374,2,"[{""id"":""MASTER-e1169a77-0374"",""pedido"":""Registar aprovações técnica, negócio e segurança"",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7192""],""aceitacao"":""Registar aprovações técnica, negócio e segurança"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""negócios""},{""id"":""MASTER-edece80c-0374"",""pedido"":""Registar aprovações técnica, negócio e segurança"",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7192""],""aceitacao"":""Registar aprovações técnica, negócio e segurança"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""negócios""}]",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.existing_businesses: 2 registos; public.existing_business_revisions: 2 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.",Negócio→revisão/publicação→interesse→origem→estatística única→recuperação; preparar caso existente autorizado sem forçar estado. Critério individual original preservado; cobertura atual ainda não individualizada.,"ExistingBusinessDrafts/Policy, anúncio público, InterestSubmission e filtros atuais",Políticas legadas próprias e docs/mandatos; QA18445zero anúncios publicados; notificaçõesOFF.,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: negócios. 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.,negócios,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/ExistingBusinessController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"ExistingBusinessFoundationTest, ExistingBusinessIntakeTest, ExistingBusinessWizardTest; 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." MASTER-e1169a77-0375,"Os conteúdos desta secção constituem modelos históricos não normativos. A transposição para o repositório deve usar exclusivamente A.31 e requer adaptação ao código-fonte real, revisão humana, testes, controlo de versão, segurança e aprovação formal.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7246 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7246,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.","MASTER-e1169a77-0375: Os conteúdos desta secção constituem modelos históricos não normativos. A transposição para o repositório deve usar exclusivamente A.31 e requer adaptação ao código-fonte real, revisão humana, testes, controlo de versão, segurança e aprovação formal. | MASTER-edece80c-0375: Os conteúdos desta secção constituem modelos históricos não normativos. A transposição para o repositório deve usar exclusivamente A.31 e requer adaptação ao código-fonte real, revisão humana, testes, controlo de versão, segurança e aprovação formal.",P2,MASTER-e1169a77-0375: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0375: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0375 | MASTER-edece80c-0375,2,"[{""id"":""MASTER-e1169a77-0375"",""pedido"":""Os conteúdos desta secção constituem modelos históricos não normativos. A transposição para o repositório deve usar exclusivamente A.31 e requer adaptação ao código-fonte real, revisão humana, testes, controlo de versão, segurança e aprovação formal."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7246""],""aceitacao"":""Os conteúdos desta secção constituem modelos históricos não normativos. A transposição para o repositório deve usar exclusivamente A.31 e requer adaptação ao código-fonte real, revisão humana, testes, controlo de versão, segurança e aprovação formal."",""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-0375"",""pedido"":""Os conteúdos desta secção constituem modelos históricos não normativos. A transposição para o repositório deve usar exclusivamente A.31 e requer adaptação ao código-fonte real, revisão humana, testes, controlo de versão, segurança e aprovação formal."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7246""],""aceitacao"":""Os conteúdos desta secção constituem modelos históricos não normativos. A transposição para o repositório deve usar exclusivamente A.31 e requer adaptação ao código-fonte real, revisão humana, testes, controlo de versão, segurança e aprovação formal."",""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.",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." -MASTER-e1169a77-0376,"# InvestMoz Upgrade\n\nmodelo inicial — adaptar e rever\n\n## Pré-requisitos\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\n\n## Ordem\n1. Validar manifest/project.yaml e contratos.\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\n3. Validar schemas e importar CSV por lotes idempotentes.\n4. Executar reconciliação, testes e revisão de segurança.\n5. Abrir PR com evidências; não fazer deploy automático.\n\n## Comandos de validação\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f ""$f""; done\npython -m json.tool imports/schemas/projects.schema.json\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\nnpx @asyncapi/cli validate events/asyncapi.yaml\nsha256sum $(find . -type f | sort)\n\n## Aviso\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7272 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7272,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.","MASTER-e1169a77-0376: # InvestMoz Upgrade\n\nmodelo inicial — adaptar e rever\n\n## Pré-requisitos\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\n\n## Ordem\n1. Validar manifest/project.yaml e contratos.\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\n3. Validar schemas e importar CSV por lotes idempotentes.\n4. Executar reconciliação, testes e revisão de segurança.\n5. Abrir PR com evidências; não fazer deploy automático.\n\n## Comandos de validação\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f ""$f""; done\npython -m json.tool imports/schemas/projects.schema.json\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\nnpx @asyncapi/cli validate events/asyncapi.yaml\nsha256sum $(find . -type f | sort)\n\n## Aviso\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging. | MASTER-edece80c-0376: # InvestMoz Upgrade\n\nmodelo inicial — adaptar e rever\n\n## Pré-requisitos\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\n\n## Ordem\n1. Validar manifest/project.yaml e contratos.\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\n3. Validar schemas e importar CSV por lotes idempotentes.\n4. Executar reconciliação, testes e revisão de segurança.\n5. Abrir PR com evidências; não fazer deploy automático.\n\n## Comandos de validação\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f ""$f""; done\npython -m json.tool imports/schemas/projects.schema.json\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\nnpx @asyncapi/cli validate events/asyncapi.yaml\nsha256sum $(find . -type f | sort)\n\n## Aviso\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging.",P2,MASTER-e1169a77-0376: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0376: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0376 | MASTER-edece80c-0376,2,"[{""id"":""MASTER-e1169a77-0376"",""pedido"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7272""],""aceitacao"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""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-0376"",""pedido"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7272""],""aceitacao"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""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.",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." +MASTER-e1169a77-0376,"# InvestMoz Upgrade\n\nmodelo inicial — adaptar e rever\n\n## Pré-requisitos\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\n\n## Ordem\n1. Validar manifest/project.yaml e contratos.\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\n3. Validar schemas e importar CSV por lotes idempotentes.\n4. Executar reconciliação, testes e revisão de segurança.\n5. Abrir PR com evidências; não fazer deploy automático.\n\n## Comandos de validação\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f ""$f""; done\npython -m json.tool imports/schemas/projects.schema.json\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\nnpx @asyncapi/cli validate events/asyncapi.yaml\nsha256sum $(find . -type f | sort)\n\n## Aviso\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging.","portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7272 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7272",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. | [Arranque local 19/10/2026] Pedido expresso Tempo e escolha de base nova de demonstra??o; decis?es AGENTS.md 12/10/2026 aplicadas. Compose/portas/pastas autom?ticas/guarda QA s?o escolhas t?cnicas. Prova limitada a investmoz_local_test:55441 e testes em investmoz_test:55441; activo preservado, sem fecho global. deploy/local/VERIFICACAO-20261019.md; outputs/local-startup-20261019/browser.json.","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.","MASTER-e1169a77-0376: # InvestMoz Upgrade\n\nmodelo inicial — adaptar e rever\n\n## Pré-requisitos\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\n\n## Ordem\n1. Validar manifest/project.yaml e contratos.\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\n3. Validar schemas e importar CSV por lotes idempotentes.\n4. Executar reconciliação, testes e revisão de segurança.\n5. Abrir PR com evidências; não fazer deploy automático.\n\n## Comandos de validação\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f ""$f""; done\npython -m json.tool imports/schemas/projects.schema.json\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\nnpx @asyncapi/cli validate events/asyncapi.yaml\nsha256sum $(find . -type f | sort)\n\n## Aviso\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging. | MASTER-edece80c-0376: # InvestMoz Upgrade\n\nmodelo inicial — adaptar e rever\n\n## Pré-requisitos\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\n\n## Ordem\n1. Validar manifest/project.yaml e contratos.\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\n3. Validar schemas e importar CSV por lotes idempotentes.\n4. Executar reconciliação, testes e revisão de segurança.\n5. Abrir PR com evidências; não fazer deploy automático.\n\n## Comandos de validação\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f ""$f""; done\npython -m json.tool imports/schemas/projects.schema.json\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\nnpx @asyncapi/cli validate events/asyncapi.yaml\nsha256sum $(find . -type f | sort)\n\n## Aviso\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging.",P2,"MASTER-e1169a77-0376: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0376: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas","MASTER-e1169a77-0376 | MASTER-edece80c-0376",2,"[{""id"":""MASTER-e1169a77-0376"",""pedido"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7272""],""aceitacao"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""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-0376"",""pedido"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7272""],""aceitacao"":""# InvestMoz Upgrade\\n\\nmodelo inicial — adaptar e rever\\n\\n## Pré-requisitos\\n- PostgreSQL 15+ com PostGIS e pgcrypto disponíveis.\\n- Cliente psql, validador JSON Schema, validador OpenAPI/AsyncAPI e utilitário SHA-256.\\n- Branch de trabalho, fixtures anonimizadas e ambiente development/test.\\n\\n## Ordem\\n1. Validar manifest/project.yaml e contratos.\\n2. Executar database/sql/001_extensions.sql e depois os scripts 010–110 por ordem numérica.\\n3. Validar schemas e importar CSV por lotes idempotentes.\\n4. Executar reconciliação, testes e revisão de segurança.\\n5. Abrir PR com evidências; não fazer deploy automático.\\n\\n## Comandos de validação\\npsql -v ON_ERROR_STOP=1 -f database/sql/001_extensions.sql\\nfor f in database/sql/*.sql; do psql -v ON_ERROR_STOP=1 -f \""$f\""; done\\npython -m json.tool imports/schemas/projects.schema.json\\nnpx @redocly/cli lint openapi/investmoz-v1.yaml\\nnpx @asyncapi/cli validate events/asyncapi.yaml\\nsha256sum $(find . -type f | sort)\\n\\n## Aviso\\nNão usar segredos ou dados reais. Executar somente em development/test antes de staging."",""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.","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. | [Arranque local 19/10/2026] Pedido expresso Tempo e escolha de base nova de demonstra??o; decis?es AGENTS.md 12/10/2026 aplicadas. Compose/portas/pastas autom?ticas/guarda QA s?o escolhas t?cnicas. Prova limitada a investmoz_local_test:55441 e testes em investmoz_test:55441; activo preservado, sem fecho global. deploy/local/VERIFICACAO-20261019.md; outputs/local-startup-20261019/browser.json.","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." MASTER-e1169a77-0377,"Não copiar nem executar estes blocos históricos. Materializar exclusivamente os artefactos e caminhos normativos de A.31, validar a sintaxe, calcular SHA-256, colocar sob controlo de versão, abrir PR e executar apenas em development/test antes de staging.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7319 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7319,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.","MASTER-e1169a77-0377: Não copiar nem executar estes blocos históricos. Materializar exclusivamente os artefactos e caminhos normativos de A.31, validar a sintaxe, calcular SHA-256, colocar sob controlo de versão, abrir PR e executar apenas em development/test antes de staging. | MASTER-edece80c-0377: Não copiar nem executar estes blocos históricos. Materializar exclusivamente os artefactos e caminhos normativos de A.31, validar a sintaxe, calcular SHA-256, colocar sob controlo de versão, abrir PR e executar apenas em development/test antes de staging.",P2,MASTER-e1169a77-0377: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0377: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0377 | MASTER-edece80c-0377,2,"[{""id"":""MASTER-e1169a77-0377"",""pedido"":""Não copiar nem executar estes blocos históricos. Materializar exclusivamente os artefactos e caminhos normativos de A.31, validar a sintaxe, calcular SHA-256, colocar sob controlo de versão, abrir PR e executar apenas em development/test antes de staging."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7319""],""aceitacao"":""Não copiar nem executar estes blocos históricos. Materializar exclusivamente os artefactos e caminhos normativos de A.31, validar a sintaxe, calcular SHA-256, colocar sob controlo de versão, abrir PR e executar apenas em development/test antes de staging."",""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-0377"",""pedido"":""Não copiar nem executar estes blocos históricos. Materializar exclusivamente os artefactos e caminhos normativos de A.31, validar a sintaxe, calcular SHA-256, colocar sob controlo de versão, abrir PR e executar apenas em development/test antes de staging."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7319""],""aceitacao"":""Não copiar nem executar estes blocos históricos. Materializar exclusivamente os artefactos e caminhos normativos de A.31, validar a sintaxe, calcular SHA-256, colocar sob controlo de versão, abrir PR e executar apenas em development/test antes de staging."",""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.",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." MASTER-e1169a77-0378,As secções históricas contêm modelos não normativos; a criação física no repositório deve seguir exclusivamente A.31 e ser realizada pela equipa técnica ou pelo Codex sob revisão humana.,portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7320 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7320,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.",MASTER-e1169a77-0378: As secções históricas contêm modelos não normativos; a criação física no repositório deve seguir exclusivamente A.31 e ser realizada pela equipa técnica ou pelo Codex sob revisão humana. | MASTER-edece80c-0378: As secções históricas contêm modelos não normativos; a criação física no repositório deve seguir exclusivamente A.31 e ser realizada pela equipa técnica ou pelo Codex sob revisão humana.,P2,MASTER-e1169a77-0378: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0378: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0378 | MASTER-edece80c-0378,2,"[{""id"":""MASTER-e1169a77-0378"",""pedido"":""As secções históricas contêm modelos não normativos; a criação física no repositório deve seguir exclusivamente A.31 e ser realizada pela equipa técnica ou pelo Codex sob revisão humana."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7320""],""aceitacao"":""As secções históricas contêm modelos não normativos; a criação física no repositório deve seguir exclusivamente A.31 e ser realizada pela equipa técnica ou pelo Codex sob revisão humana."",""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-0378"",""pedido"":""As secções históricas contêm modelos não normativos; a criação física no repositório deve seguir exclusivamente A.31 e ser realizada pela equipa técnica ou pelo Codex sob revisão humana."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7320""],""aceitacao"":""As secções históricas contêm modelos não normativos; a criação física no repositório deve seguir exclusivamente A.31 e ser realizada pela equipa técnica ou pelo Codex sob revisão humana."",""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.",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." MASTER-e1169a77-0379,Controlos obrigatórios das migrations.,portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7340 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7340,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.",MASTER-e1169a77-0379: Controlos obrigatórios das migrations. | MASTER-edece80c-0379: Controlos obrigatórios das migrations.,P2,MASTER-e1169a77-0379: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0379: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0379 | MASTER-edece80c-0379,2,"[{""id"":""MASTER-e1169a77-0379"",""pedido"":""Controlos obrigatórios das migrations."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 7340""],""aceitacao"":""Controlos obrigatórios das migrations."",""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-0379"",""pedido"":""Controlos obrigatórios das migrations."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 7340""],""aceitacao"":""Controlos obrigatórios das migrations."",""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.",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." @@ -1707,7 +1707,7 @@ MASTER-f167d915-0004,"5. Ligações institucionais de apoio: disponibilizar, no MASTER-f167d915-0005,"Princípio de incorporação: o Balcão Virtual não será uma aplicação isolada. Será incluído no mesmo domínio funcional do Portal do Investidor, partilhando cabeçalho, menus, sessão, perfis, design system, gestão de utilizadores, observabilidade e processos de publicação. A implementação deverá evitar autenticação duplicada, cadastros paralelos e componentes que já existam no portal.",..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 30,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.","MASTER-f167d915-0005: Princípio de incorporação: o Balcão Virtual não será uma aplicação isolada. Será incluído no mesmo domínio funcional do Portal do Investidor, partilhando cabeçalho, menus, sessão, perfis, design system, gestão de utilizadores, observabilidade e processos de publicação. A implementação deverá evitar autenticação duplicada, cadastros paralelos e componentes que já existam no portal.",P2,MASTER-f167d915-0005: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-f167d915-0005,1,"[{""id"":""MASTER-f167d915-0005"",""pedido"":""Princípio de incorporação: o Balcão Virtual não será uma aplicação isolada. Será incluído no mesmo domínio funcional do Portal do Investidor, partilhando cabeçalho, menus, sessão, perfis, design system, gestão de utilizadores, observabilidade e processos de publicação. A implementação deverá evitar autenticação duplicada, cadastros paralelos e componentes que já existam no portal."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 30""],""aceitacao"":""Princípio de incorporação: o Balcão Virtual não será uma aplicação isolada. Será incluído no mesmo domínio funcional do Portal do Investidor, partilhando cabeçalho, menus, sessão, perfis, design system, gestão de utilizadores, observabilidade e processos de publicação. A implementação deverá evitar autenticação duplicada, cadastros paralelos e componentes que já existam no portal."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""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." MASTER-f167d915-0006,"URL e navegação recomendadas: disponibilizar o módulo através de uma rota própria no Portal do Investidor, por exemplo “/balcao-virtual”, acessível pelo menu principal e pela área autenticada. As rotas internas dos formulários, pedidos e painéis devem permanecer sob o mesmo domínio e respeitar os mecanismos de autorização já existentes.",..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 31,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.","MASTER-f167d915-0006: URL e navegação recomendadas: disponibilizar o módulo através de uma rota própria no Portal do Investidor, por exemplo “/balcao-virtual”, acessível pelo menu principal e pela área autenticada. As rotas internas dos formulários, pedidos e painéis devem permanecer sob o mesmo domínio e respeitar os mecanismos de autorização já existentes.",P2,MASTER-f167d915-0006: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-f167d915-0006,1,"[{""id"":""MASTER-f167d915-0006"",""pedido"":""URL e navegação recomendadas: disponibilizar o módulo através de uma rota própria no Portal do Investidor, por exemplo “/balcao-virtual”, acessível pelo menu principal e pela área autenticada. As rotas internas dos formulários, pedidos e painéis devem permanecer sob o mesmo domínio e respeitar os mecanismos de autorização já existentes."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 31""],""aceitacao"":""URL e navegação recomendadas: disponibilizar o módulo através de uma rota própria no Portal do Investidor, por exemplo “/balcao-virtual”, acessível pelo menu principal e pela área autenticada. As rotas internas dos formulários, pedidos e painéis devem permanecer sob o mesmo domínio e respeitar os mecanismos de autorização já existentes."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""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." MASTER-f167d915-0007,"A validação pública do portal confirma uma plataforma activa com navegação, conteúdos, área de entrada, dados de mercado, notícias, explorador de activos, carteira, perfil do investidor e simuladores. A reutilização técnica definitiva depende de acesso ao repositório, configuração, base de dados e ambientes; por isso, os itens abaixo distinguem o que pode ser assumido como disponível do que deve ser comprovado na Fase 0.",..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 42,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.","MASTER-f167d915-0007: A validação pública do portal confirma uma plataforma activa com navegação, conteúdos, área de entrada, dados de mercado, notícias, explorador de activos, carteira, perfil do investidor e simuladores. A reutilização técnica definitiva depende de acesso ao repositório, configuração, base de dados e ambientes; por isso, os itens abaixo distinguem o que pode ser assumido como disponível do que deve ser comprovado na Fase 0.",P2,MASTER-f167d915-0007: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-f167d915-0007,1,"[{""id"":""MASTER-f167d915-0007"",""pedido"":""A validação pública do portal confirma uma plataforma activa com navegação, conteúdos, área de entrada, dados de mercado, notícias, explorador de activos, carteira, perfil do investidor e simuladores. A reutilização técnica definitiva depende de acesso ao repositório, configuração, base de dados e ambientes; por isso, os itens abaixo distinguem o que pode ser assumido como disponível do que deve ser comprovado na Fase 0."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 42""],""aceitacao"":""A validação pública do portal confirma uma plataforma activa com navegação, conteúdos, área de entrada, dados de mercado, notícias, explorador de activos, carteira, perfil do investidor e simuladores. A reutilização técnica definitiva depende de acesso ao repositório, configuração, base de dados e ambientes; por isso, os itens abaixo distinguem o que pode ser assumido como disponível do que deve ser comprovado na Fase 0."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""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." -MASTER-f167d915-0008,"Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação.",..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 44,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.,Sem evidência suficiente,"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.","MASTER-f167d915-0008: Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação.",P2,MASTER-f167d915-0008: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-f167d915-0008,1,"[{""id"":""MASTER-f167d915-0008"",""pedido"":""Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 44""],""aceitacao"":""Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""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.,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." +MASTER-f167d915-0008,"Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação.","..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 44",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. | [Identidade Tempo 19/10/2026] Pedido expresso: importar header/footer de tempo-dashboard, remover marca InvesteMoz da navega??o e organizar Descoberta/Realiza??o/Suporte. AGENTS.md 12/10/2026: propriet?rio e regras Tempo preservados. Radix, CSS responsivo e tradu??es institucionais s?o escolhas t?cnicas. S? ambiente local investmoz_local_test:55441; sem migra??es ou implanta??o activa nesta altera??o visual. Prova: outputs/tempo-shell-20261019/analysis-and-plan.json; verification.json; header.png; footer.png; mobile-320.png. Quatro p?ginas 200; cinco larguras 320?1440 sem overflow; teclado/Escape/foco, idioma, login/logout sem erros JS. N?o encerra aceita??o global da cl?usula.","Sem evidência suficiente","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.","MASTER-f167d915-0008: Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação.",P2,"MASTER-f167d915-0008: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas",MASTER-f167d915-0008,1,"[{""id"":""MASTER-f167d915-0008"",""pedido"":""Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 44""],""aceitacao"":""Navegação e identidade visual Observável no portal público. Reutilizar cabeçalho, menus, grelha, tipografia, cores, componentes e padrões responsivos. Inventário de componentes, design tokens e regras de navegação."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""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.","outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | [Identidade Tempo 19/10/2026] Pedido expresso: importar header/footer de tempo-dashboard, remover marca InvesteMoz da navega??o e organizar Descoberta/Realiza??o/Suporte. AGENTS.md 12/10/2026: propriet?rio e regras Tempo preservados. Radix, CSS responsivo e tradu??es institucionais s?o escolhas t?cnicas. S? ambiente local investmoz_local_test:55441; sem migra??es ou implanta??o activa nesta altera??o visual. Prova: outputs/tempo-shell-20261019/analysis-and-plan.json; verification.json; header.png; footer.png; mobile-320.png. Quatro p?ginas 200; cinco larguras 320?1440 sem overflow; teclado/Escape/foco, idioma, login/logout sem erros JS. N?o encerra aceita??o global da cl?usula.",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." MASTER-f167d915-0009,"Área de entrada e sessão Existe ponto de entrada público; implementação interna não verificada. Reutilizar autenticação e sessão existentes, sem criar credenciais paralelas. Fluxo de login/logout, recuperação, MFA, duração de sessão e mecanismo de autorização.",..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 45,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.","MASTER-f167d915-0009: Área de entrada e sessão Existe ponto de entrada público; implementação interna não verificada. Reutilizar autenticação e sessão existentes, sem criar credenciais paralelas. Fluxo de login/logout, recuperação, MFA, duração de sessão e mecanismo de autorização.",P1,MASTER-f167d915-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-f167d915-0009,1,"[{""id"":""MASTER-f167d915-0009"",""pedido"":""Área de entrada e sessão Existe ponto de entrada público; implementação interna não verificada. Reutilizar autenticação e sessão existentes, sem criar credenciais paralelas. Fluxo de login/logout, recuperação, MFA, duração de sessão e mecanismo de autorização."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 45""],""aceitacao"":""Área de entrada e sessão Existe ponto de entrada público; implementação interna não verificada. Reutilizar autenticação e sessão existentes, sem criar credenciais paralelas. Fluxo de login/logout, recuperação, MFA, duração de sessão e mecanismo de autorização."",""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.",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." MASTER-f167d915-0010,"Frontend e design system Interface funcional confirmada; stack e biblioteca não verificados. Reutilizar componentes existentes; criar apenas componentes específicos de formulários, timeline, filas e validação. Stack frontend, biblioteca, convenções, acessibilidade e cobertura de testes.",..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 47,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.,"MASTER-f167d915-0010: Frontend e design system Interface funcional confirmada; stack e biblioteca não verificados. Reutilizar componentes existentes; criar apenas componentes específicos de formulários, timeline, filas e validação. Stack frontend, biblioteca, convenções, acessibilidade e cobertura de testes.",P2,MASTER-f167d915-0010: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-f167d915-0010,1,"[{""id"":""MASTER-f167d915-0010"",""pedido"":""Frontend e design system Interface funcional confirmada; stack e biblioteca não verificados. Reutilizar componentes existentes; criar apenas componentes específicos de formulários, timeline, filas e validação. Stack frontend, biblioteca, convenções, acessibilidade e cobertura de testes."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 47""],""aceitacao"":""Frontend e design system Interface funcional confirmada; stack e biblioteca não verificados. Reutilizar componentes existentes; criar apenas componentes específicos de formulários, timeline, filas e validação. Stack frontend, biblioteca, convenções, acessibilidade e cobertura de testes."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""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." MASTER-f167d915-0011,"Base de dados Não verificável externamente. Reutilizar a instância e padrões existentes, criando schema/tabelas próprias e relações controladas com utilizadores e organizações. SGBD, migrations, convenções, volumes, backups, índices, auditoria e política de dados.",..\..\..\..\..\..\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 49,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.","MASTER-f167d915-0011: Base de dados Não verificável externamente. Reutilizar a instância e padrões existentes, criando schema/tabelas próprias e relações controladas com utilizadores e organizações. SGBD, migrations, convenções, volumes, backups, índices, auditoria e política de dados.",P2,MASTER-f167d915-0011: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-f167d915-0011,1,"[{""id"":""MASTER-f167d915-0011"",""pedido"":""Base de dados Não verificável externamente. Reutilizar a instância e padrões existentes, criando schema/tabelas próprias e relações controladas com utilizadores e organizações. SGBD, migrations, convenções, volumes, backups, índices, auditoria e política de dados."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\0ad28475-97cc-4263-b611-022f3de5bebc\\Pasted text.txt; SHA f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37; linha 49""],""aceitacao"":""Base de dados Não verificável externamente. Reutilizar a instância e padrões existentes, criando schema/tabelas próprias e relações controladas com utilizadores e organizações. SGBD, migrations, convenções, volumes, backups, índices, auditoria e política de dados."",""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.",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." diff --git a/public/images/logo/logo-vermelho.png b/public/images/logo/logo-vermelho.png new file mode 100644 index 00000000..16f48707 Binary files /dev/null and b/public/images/logo/logo-vermelho.png differ diff --git a/resources/css/app.css b/resources/css/app.css index 7015d586..ba4fc620 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -7,6 +7,295 @@ @custom-variant dark (&:is(.dark *)); +/* Institutional shell adapted from Tempo; page content keeps its own theme. */ +.tempo-header { + position: relative; + z-index: 40; + background: #090909; + color: #fff; +} +.tempo-logo-link { + display: inline-flex; + align-items: center; + border-radius: 0.25rem; +} +.tempo-nav-trigger { + display: flex; + min-height: 44px; + align-items: center; + gap: 0.5rem; + padding: 0.6rem 0.75rem; + border-radius: 0.5rem; + font-size: 0.875rem; + font-weight: 600; + color: #eee; + transition: + color 0.2s, + background 0.2s; +} +.tempo-nav-trigger:hover, +.tempo-nav-trigger[data-state='open'] { + background: #ffffff0d; + color: #fff; +} +.tempo-nav-trigger[data-current-group] { + color: #fff; + box-shadow: inset 0 -2px #ed1c24; +} +.tempo-nav-trigger[data-state='open'] > svg { + transform: rotate(180deg); +} +@media (max-width: 640px) { + .tempo-nav-trigger { + gap: 0.25rem; + padding-inline: 0.25rem; + font-size: 0.75rem; + } + .tempo-nav-trigger > svg { + width: 12px; + height: 12px; + } +} +.tempo-utility-button { + display: flex; + min-height: 40px; + align-items: center; + gap: 0.4rem; + padding: 0.4rem; + border-radius: 0.5rem; + font-size: 0.75rem; + color: #e2e8f0; +} +.tempo-utility-button:hover { + background: #ffffff10; +} +.tempo-header-social { + display: flex; + width: 30px; + height: 40px; + align-items: center; + justify-content: center; + color: var(--social-color); + transition: + transform 0.2s, + opacity 0.2s; + border-radius: 0.4rem; +} +.tempo-header-social:hover { + transform: translateY(-2px); + opacity: 0.8; +} +.tempo-login-button { + display: inline-flex; + min-height: 40px; + align-items: center; + gap: 0.5rem; + border: 1px solid #ffffff50; + border-radius: 0.4rem; + padding: 0.5rem 0.85rem; + font-size: 0.8rem; + font-weight: 600; + color: #fff; + transition: + background 0.2s, + border-color 0.2s; +} +.tempo-login-button:hover { + background: #ed1c24; + border-color: #ed1c24; +} +.tempo-header-actions { + order: 2; + display: flex; + align-items: center; + gap: 0.5rem; + margin-left: auto; +} +.tempo-interest-button { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 40px; + padding: 0.5rem 0.75rem; + border: 1px solid #ed1c24; + border-radius: 0.4rem; + background: #ed1c24; + color: white; + font-size: 0.75rem; + font-weight: 600; + white-space: nowrap; + transition: background 0.2s; +} +.tempo-interest-button:hover { + background: #c9151c; +} +.tempo-panel-summary { + order: 4; + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + width: 100%; + min-height: 44px; + padding-block: 0.5rem; + border-top: 1px solid #ffffff1a; + font-size: 0.75rem; +} +.tempo-panel-summary a { + color: #fff; + text-underline-offset: 3px; +} +.tempo-panel-summary a:hover { + text-decoration: underline; +} +.tempo-panel-summary span { + color: #cbd5e1; + font-size: 0.6875rem; + white-space: nowrap; +} +@media (max-width: 480px) { + .tempo-header-actions { + flex-direction: column; + align-items: flex-end; + padding-block: 0.65rem; + } +} +@media (min-width: 1280px) { + .tempo-header-actions { + order: 6; + margin-left: 0; + } + .tempo-header-inner .tempo-nav-trigger { + padding-inline: 0.5rem; + font-size: 0.8125rem; + } + .tempo-panel-summary { + order: 0; + flex-direction: column; + align-items: flex-start; + justify-content: center; + gap: 0.1rem; + width: auto; + min-width: 102px; + border-top: 0; + border-left: 1px solid #ffffff1a; + padding-left: 0.75rem; + } +} +.tempo-header :is(a, button):focus-visible { + outline: 2px solid #fff; + outline-offset: 4px; +} +.tempo-dropdown { + z-index: 60; + border: 1px solid #e2e8f0; + border-radius: 0.8rem; + background: #fff; + color: #0f172a; + box-shadow: 0 18px 50px #00000026; + transform-origin: var(--radix-dropdown-menu-content-transform-origin); + animation-duration: 160ms; +} +.tempo-menu-item { + min-height: 42px; + gap: 0.5rem; + border-radius: 0.4rem; + padding: 0.6rem 0.7rem; + font-size: 0.8125rem; + white-space: normal; + line-height: 1.5; +} +.tempo-menu-item[data-highlighted], +.tempo-menu-item:focus, +.tempo-menu-item[aria-current='page'] { + background: #fef2f2; + color: #b91c1c; + outline: none; +} +.tempo-footer { + margin-top: 2rem; + background: #050505; + color: #fff; +} +.tempo-footer-heading { + margin-bottom: 1.4rem; + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.15em; + text-transform: uppercase; +} +.tempo-footer-link { + display: inline-flex; + align-items: baseline; + gap: 0.35rem; + font-size: 0.8125rem; + line-height: 1.5; + color: #e2e8f0; + transition: + color 0.2s, + transform 0.2s; +} +.tempo-footer-link > svg { + align-self: center; + color: #ed1c24; + flex-shrink: 0; +} +.tempo-footer-link:hover { + color: #fb7185; + transform: translateX(3px); +} +.tempo-contact-link { + display: flex; + align-items: center; + gap: 0.7rem; + transition: color 0.2s; +} +.tempo-contact-link:hover { + color: #fb7185; +} +.tempo-contact-icon { + display: flex; + width: 36px; + height: 36px; + flex-shrink: 0; + align-items: center; + justify-content: center; + border: 1px solid #ffffff12; + border-radius: 0.65rem; + background: #ffffff08; +} +.tempo-footer-social { + display: flex; + width: 40px; + height: 44px; + align-items: center; + justify-content: center; + border: 1px solid #ffffff15; + border-radius: 0.65rem; + color: #fff; + transition: + color 0.2s, + border-color 0.2s, + transform 0.2s; +} +.tempo-footer-social:hover { + color: var(--social-color); + border-color: var(--social-color); + transform: translateY(-3px); +} +.tempo-footer :is(a, button):focus-visible { + outline: 2px solid #fb7185; + outline-offset: 4px; +} +@media (prefers-reduced-motion: reduce) { + .tempo-header *, + .tempo-footer *, + .tempo-dropdown { + animation-duration: 0ms !important; + transition-duration: 0ms !important; + } +} + @theme { --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, diff --git a/resources/js/components/app-logo.tsx b/resources/js/components/app-logo.tsx index 4845632e..e8fa317e 100644 --- a/resources/js/components/app-logo.tsx +++ b/resources/js/components/app-logo.tsx @@ -1,20 +1,11 @@ -import { usePage } from '@inertiajs/react'; - -import AppLogoIcon from '@/components/app-logo-icon'; - export default function AppLogo() { - const { name } = usePage().props; - return ( - <> -
- -
-
- - {name} - -
- + Tempo ); } diff --git a/resources/js/components/portal-grouped-menu.tsx b/resources/js/components/portal-grouped-menu.tsx index bc927a19..789e0c57 100644 --- a/resources/js/components/portal-grouped-menu.tsx +++ b/resources/js/components/portal-grouped-menu.tsx @@ -1,16 +1,32 @@ -import { useNavigationContext } from '@/components/navigation-context'; -import type { ProfileAccess } from '@/types/profile-access'; import { Link, router, usePage } from '@inertiajs/react'; -import { LogOut } from 'lucide-react'; -import { logout } from '@/routes'; -import { useEffect, useId, useRef, useState } from 'react'; -import type { OpportunityManagementAccess } from '@/types/opportunity-management'; +import { ChevronDown, LogOut, UserRound } from 'lucide-react'; +import { useState } from 'react'; +import { useNavigationContext } from '@/components/navigation-context'; +import { TempoSocialLinks, useTempoUi } from '@/components/tempo-brand'; +import { + TempoLanguageSelector, + TempoWeather, +} from '@/components/tempo-header-tools'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; import { portalNavigation, currentNavigationGroup, currentNavigationItem, - type PortalNavItem, } from '@/lib/portal-navigation'; +import type { PortalNavItem } from '@/lib/portal-navigation'; +import type { ProfileAccess } from '@/types/profile-access'; +import type { OpportunityManagementAccess } from '@/types/opportunity-management'; +import { logout } from '@/routes'; export function PortalGroupedMenu() { const { props, url } = usePage<{ @@ -23,10 +39,10 @@ export function PortalGroupedMenu() { educationEnabled?: boolean; aiEnabled?: boolean; legacyContentEnabled?: boolean; - portalOperator?: string | null; profileAccess?: ProfileAccess | null; opportunityManagement?: OpportunityManagementAccess | null; }>(); + const { t, language, requestCount } = useTempoUi(); const navigation = useNavigationContext(); const groups = portalNavigation({ context: navigation.view @@ -44,159 +60,77 @@ export function PortalGroupedMenu() { }); const current = currentNavigationGroup(groups, url); const currentItem = currentNavigationItem(groups, url); - const [open, setOpen] = useState(null); - const [branch, setBranch] = useState(null); - const [offset, setOffset] = useState(0); const [loggingOut, setLoggingOut] = useState(false); - const root = useRef(null); - const id = useId(); - useEffect(() => { - const position = () => { - const button = open - ? document.getElementById(`${id}-${open}-button`) - : null; - if (!button || window.innerWidth < 640) { - setOffset(0); - return; - } - const rect = button.getBoundingClientRect(); - const width = Math.min(288, window.innerWidth - 32); - setOffset( - Math.max( - 16, - Math.min(rect.left, window.innerWidth - width - 16), - ) - rect.left, - ); - }; - position(); - window.addEventListener('resize', position); - return () => window.removeEventListener('resize', position); - }, [open, id]); - useEffect(() => { - const outside = (event: PointerEvent) => { - if ( - event.target instanceof Node && - !root.current?.contains(event.target) - ) { - setOpen(null); - setBranch(null); - } - }; - document.addEventListener('pointerdown', outside); - return () => document.removeEventListener('pointerdown', outside); - }, []); - const close = () => { - setOpen(null); - setBranch(null); - }; const items = (children: PortalNavItem[]) => - children.map((item) => ( -
  • - {item.children ? ( - <> - - {branch === item.id && ( -
      - {items(item.children)} -
    - )} - - ) : ( + children.map((item) => + item.children ? ( + + + {t(item.label)} + + + {items(item.children)} + + + ) : ( + - {item.label} + {t(item.label)} - )} -
  • - )); + + ), + ); + const accountGroups = groups.filter( + (group) => + !['home', 'discovery', 'realization', 'support'].includes(group.id), + ); return ( -
    { - if (event.key !== 'Escape') return; - event.preventDefault(); - if (branch) { - document.getElementById(`${id}-${branch}-button`)?.focus(); - setBranch(null); - } else if (open) { - document.getElementById(`${id}-${open}-button`)?.focus(); - close(); - } - }} - > -
    -
    - - InvesteMoz - -

    - Iniciativa privada e independente de apoio ao - investimento. Orientação e acompanhamento internos; - decisões oficiais cabem às instituições competentes. - {props.portalOperator && ( - <> Operador: {props.portalOperator}. - )} -

    -
    - {props.auth?.user && ( - - )} -
    ); diff --git a/resources/js/components/tempo-brand.tsx b/resources/js/components/tempo-brand.tsx new file mode 100644 index 00000000..e346620c --- /dev/null +++ b/resources/js/components/tempo-brand.tsx @@ -0,0 +1,288 @@ +import { createContext, useContext, useEffect, useState } from 'react'; +import { Facebook, Instagram, Linkedin, Youtube } from 'lucide-react'; +import type { CSSProperties, ReactNode } from 'react'; + +export const tempoSocialLinks = [ + { + name: 'Facebook', + href: 'https://www.facebook.com/revistatempo.mz/', + icon: Facebook, + color: '#1877f2', + }, + { + name: 'Instagram', + href: 'https://www.instagram.com/revistatempo.mz/', + icon: Instagram, + color: '#e1306c', + }, + { + name: 'LinkedIn', + href: 'https://www.linkedin.com/company/revistatempo/', + icon: Linkedin, + color: '#38a5df', + }, + { + name: 'YouTube', + href: 'https://www.youtube.com/@RevistaTempoMz/', + icon: Youtube, + color: '#ff3333', + }, +]; + +const menuTranslations = [ + ['O meu painel', 'My dashboard', 'Mon espace', 'Mi panel'], + [ + 'Manifestar interesse', + 'Express interest', + 'Manifester un intérêt', + 'Manifestar interés', + ], + [ + 'pedido recebido', + 'request received', + 'demande reçue', + 'solicitud recibida', + ], + [ + 'pedidos recebidos', + 'requests received', + 'demandes reçues', + 'solicitudes recibidas', + ], + [ + 'Porquê investir em Moçambique', + 'Why invest in Mozambique', + 'Pourquoi investir au Mozambique', + 'Por qué invertir en Mozambique', + ], + [ + 'Oportunidades de investimento', + 'Investment opportunities', + 'Opportunités d’investissement', + 'Oportunidades de inversión', + ], + [ + 'Sectores de investimento', + 'Investment sectors', + 'Secteurs d’investissement', + 'Sectores de inversión', + ], + ['Localizações', 'Locations', 'Localisations', 'Ubicaciones'], + [ + 'Iniciar investimento', + 'Start an investment', + 'Démarrer un investissement', + 'Iniciar una inversión', + ], + [ + 'Incentivos e simulador fiscal', + 'Incentives and tax simulator', + 'Incitations et simulateur fiscal', + 'Incentivos y simulador fiscal', + ], + ['Licenciamento', 'Licensing', 'Autorisations', 'Licencias'], + ['Acesso à terra', 'Land access', 'Accès à la terre', 'Acceso a la tierra'], + [ + 'Serviços ao investidor', + 'Investor services', + 'Services aux investisseurs', + 'Servicios al inversor', + ], + [ + 'Acompanhamento do projecto', + 'Project follow-up', + 'Suivi du projet', + 'Seguimiento del proyecto', + ], + [ + 'Apoio ao investidor', + 'Investor support', + 'Assistance aux investisseurs', + 'Apoyo al inversor', + ], + [ + 'Dossiers e percursos', + 'Investment files and journeys', + 'Dossiers et parcours', + 'Expedientes y recorridos', + ], + [ + 'Perfil e empresas', + 'Profile and companies', + 'Profil et entreprises', + 'Perfil y empresas', + ], + [ + 'Pedidos e tarefas de acompanhamento', + 'Requests and follow-up tasks', + 'Demandes et tâches de suivi', + 'Solicitudes y tareas de seguimiento', + ], + [ + 'Manifestações e favoritos', + 'Expressions of interest and favourites', + 'Manifestations d’intérêt et favoris', + 'Manifestaciones de interés y favoritos', + ], + ['Notificações', 'Notifications', 'Notifications', 'Notificaciones'], + ['A minha atividade', 'My activity', 'Mes activités', 'Mi actividad'], + [ + 'As minhas parcerias', + 'My partnerships', + 'Mes partenariats', + 'Mis alianzas', + ], + ['Os meus negócios', 'My businesses', 'Mes entreprises', 'Mis negocios'], +]; +const translatedMenu = (column: number) => + Object.fromEntries(menuTranslations.map((row) => [row[0], row[column]])); + +const translations: Record> = { + en: { + ...translatedMenu(1), + Descoberta: 'Discover', + Realização: 'Invest', + Suporte: 'Support', + Entrar: 'Sign in', + 'A minha área': 'My account', + 'Terminar sessão': 'Sign out', + Contactos: 'Contacts', + Navegação: 'Navigation', + Início: 'Home', + Oportunidades: 'Opportunities', + Sectores: 'Sectors', + Legislações: 'Legislation', + 'Guia do investidor': 'Investor guide', + Contacto: 'Contact', + 'Política de Privacidade': 'Privacy Policy', + 'Termos de Uso': 'Terms of Use', + 'Todos os direitos reservados.': 'All rights reserved.', + 'Siga a Revista Tempo para actualizações exclusivas.': + 'Follow Revista Tempo for exclusive updates.', + 'Número de registo': 'Registration number', + 'A minha conta e atividade': 'My account and activity', + 'Área de trabalho': 'Workspace', + }, + fr: { + ...translatedMenu(2), + Descoberta: 'Découvrir', + Realização: 'Investir', + Suporte: 'Assistance', + Entrar: 'Connexion', + 'A minha área': 'Mon compte', + 'Terminar sessão': 'Déconnexion', + Contactos: 'Contacts', + Navegação: 'Navigation', + Início: 'Accueil', + Oportunidades: 'Opportunités', + Sectores: 'Secteurs', + Legislações: 'Législation', + 'Guia do investidor': 'Guide de l’investisseur', + Contacto: 'Contact', + 'Política de Privacidade': 'Politique de confidentialité', + 'Termos de Uso': 'Conditions d’utilisation', + 'Todos os direitos reservados.': 'Tous droits réservés.', + 'Siga a Revista Tempo para actualizações exclusivas.': + 'Suivez Revista Tempo pour des actualités exclusives.', + 'Número de registo': 'Numéro d’enregistrement', + 'A minha conta e atividade': 'Mon compte et mes activités', + 'Área de trabalho': 'Espace de travail', + }, + es: { + ...translatedMenu(3), + Descoberta: 'Descubrir', + Realização: 'Invertir', + Suporte: 'Soporte', + Entrar: 'Entrar', + 'A minha área': 'Mi cuenta', + 'Terminar sessão': 'Cerrar sesión', + Contactos: 'Contactos', + Navegação: 'Navegación', + Início: 'Inicio', + Oportunidades: 'Oportunidades', + Sectores: 'Sectores', + Legislações: 'Legislación', + 'Guia do investidor': 'Guía del inversor', + Contacto: 'Contacto', + 'Política de Privacidade': 'Política de privacidad', + 'Termos de Uso': 'Términos de uso', + 'Todos os direitos reservados.': 'Todos los derechos reservados.', + 'Siga a Revista Tempo para actualizações exclusivas.': + 'Siga Revista Tempo para recibir novedades exclusivas.', + 'Número de registo': 'Número de registro', + 'A minha conta e atividade': 'Mi cuenta y actividad', + 'Área de trabalho': 'Área de trabajo', + }, +}; + +const TempoUi = createContext({ + language: 'pt', + setLanguage: (_language: string) => {}, + t: (text: string) => text, + requestCount: 0, + registerSubmittedInterest: () => {}, +}); + +export function TempoUiProvider({ children }: { children: ReactNode }) { + const [language, setCurrentLanguage] = useState('pt'); + const [requestCount, setRequestCount] = useState(0); + useEffect(() => { + try { + const saved = localStorage.getItem('tempo-navigation-language'); + if (saved && ['pt', 'en', 'fr', 'es'].includes(saved)) + setCurrentLanguage(saved); + } catch { + /* Navigation remains usable without browser storage. */ + } + }, []); + const setLanguage = (next: string) => { + setCurrentLanguage(next); + try { + localStorage.setItem('tempo-navigation-language', next); + } catch { + /* Optional persistence. */ + } + }; + return ( + translations[language]?.[text] ?? text, + requestCount, + registerSubmittedInterest: () => + setRequestCount((count) => count + 1), + }} + > + {children} + + ); +} + +export const useTempoUi = () => useContext(TempoUi); + +export function TempoSocialLinks({ footer = false }: { footer?: boolean }) { + return ( +
    + {tempoSocialLinks.map(({ name, href, icon: Icon, color }) => ( + + + ))} +
    + ); +} diff --git a/resources/js/components/tempo-footer.tsx b/resources/js/components/tempo-footer.tsx new file mode 100644 index 00000000..061601e2 --- /dev/null +++ b/resources/js/components/tempo-footer.tsx @@ -0,0 +1,136 @@ +import { Link } from '@inertiajs/react'; +import { ChevronRight, Mail, MapPin, Phone } from 'lucide-react'; +import { TempoSocialLinks, useTempoUi } from '@/components/tempo-brand'; + +const navigation = [ + ['/', 'Início'], + ['/apoio', 'Contacto'], +]; + +export function TempoFooter() { + const { t, language } = useTempoUi(); + return ( +
    +
    +
    + + Tempo + +
    +
    +
    +
    +

    {t('Contactos')}

    +
    + {[ + ['+258868010880', '+258 86 801 0880'], + ['+258833219644', '+258 83 321 9644'], + ].map(([number, label]) => ( + + + + + {label} + + + ))} + + + + + comercial@tempo.co.mz + + +
    +
    + + +
    +

    Social

    +

    + {t( + 'Siga a Revista Tempo para actualizações exclusivas.', + )} +

    + +
    +
    +
    +
    +

    + © {new Date().getFullYear()}{' '} + Tempo.{' '} + {t('Todos os direitos reservados.')} +

    +

    {t('Número de registo')}: 13/GABINFO-DE/: 2003

    +
    +
    +
    + ); +} diff --git a/resources/js/components/tempo-header-tools.tsx b/resources/js/components/tempo-header-tools.tsx new file mode 100644 index 00000000..10ea7063 --- /dev/null +++ b/resources/js/components/tempo-header-tools.tsx @@ -0,0 +1,141 @@ +import { useEffect, useState } from 'react'; +import { ChevronDown, CloudSun, Globe, MapPin } from 'lucide-react'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import { useTempoUi } from '@/components/tempo-brand'; + +type Weather = { temp: number; description: string; humidity?: number }; + +export function TempoWeather() { + const { language } = useTempoUi(); + const [weather, setWeather] = useState(null); + const [loading, setLoading] = useState(true); + useEffect(() => { + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), 8000); + fetch(`https://teste-info.tempo.co.mz/api/weather?lang=${language}`, { + signal: controller.signal, + credentials: 'omit', + }) + .then((response) => (response.ok ? response.json() : null)) + .then((data: { current?: Weather } | null) => { + if (data?.current && Number.isFinite(data.current.temp)) + setWeather(data.current); + }) + .catch(() => { + /* No guessed temperatures when the source is unavailable. */ + }) + .finally(() => { + clearTimeout(timer); + setLoading(false); + }); + return () => { + clearTimeout(timer); + controller.abort(); + }; + }, [language]); + return ( + + + + +

    + Maputo, Moçambique +

    + {weather ? ( + <> +

    + {Math.round(weather.temp)}°C +

    +

    + {weather.description} +

    + {weather.humidity !== undefined && ( +

    + Humidade: {weather.humidity}% +

    + )} + + ) : ( +

    + {loading + ? 'A consultar a temperatura…' + : 'Temperatura temporariamente indisponível.'} +

    + )} +

    + Meteorologia · Tempo +

    +
    +
    + ); +} + +export function TempoLanguageSelector() { + const { language, setLanguage } = useTempoUi(); + return ( + + + + + + Navegação institucional + + {[ + ['pt', 'Português'], + ['en', 'English'], + ['fr', 'Français'], + ['es', 'Español'], + ].map(([code, name]) => ( + setLanguage(code)} + className={`tempo-menu-item ${language === code ? 'bg-red-50 text-red-700' : ''}`} + > + + {code} + + {name} + + ))} + + + ); +} diff --git a/resources/js/layouts/portal-navigation.tsx b/resources/js/layouts/portal-navigation.tsx index 196123c7..2985a8d8 100644 --- a/resources/js/layouts/portal-navigation.tsx +++ b/resources/js/layouts/portal-navigation.tsx @@ -1,6 +1,8 @@ import { Link, usePage } from '@inertiajs/react'; import { createContext, useContext } from 'react'; import { PortalGroupedMenu } from '@/components/portal-grouped-menu'; +import { TempoUiProvider } from '@/components/tempo-brand'; +import { TempoFooter } from '@/components/tempo-footer'; import type { ReactNode } from 'react'; import { NavigationContextProvider, @@ -99,80 +101,85 @@ export default function PortalNavigation({ ? 'Definições da conta' : 'Detalhes'); return ( - - -
    - {portalShell && (
    - +
    )} - {children} -
    - +
    + +
    + +
    +
    + ); } diff --git a/resources/js/lib/portal-navigation.ts b/resources/js/lib/portal-navigation.ts index 663a5cb1..624b7eda 100644 --- a/resources/js/lib/portal-navigation.ts +++ b/resources/js/lib/portal-navigation.ts @@ -440,11 +440,11 @@ export function currentNavigationItem( export function portalNavigation(access: PortalNavAccess): PortalNavItem[] { const previous = legacyPortalNavigation(access); return uniqueNavigationDestinations([ + link('home', 'Início', '/'), { id: 'discovery', label: 'Descoberta', children: [ - link('home', 'Início', '/'), link( 'why', 'Porquê investir em Moçambique', diff --git a/resources/js/pages/PortalInvestidor.tsx b/resources/js/pages/PortalInvestidor.tsx index 80355427..ca04dee6 100644 --- a/resources/js/pages/PortalInvestidor.tsx +++ b/resources/js/pages/PortalInvestidor.tsx @@ -1,6 +1,7 @@ import { createContext, useContext, useRef, useState } from 'react'; import { router } from '@inertiajs/react'; import { PortalMenu } from '@/layouts/portal-navigation'; +import { useTempoUi } from '@/components/tempo-brand'; import { ProvinceSelect } from '@/components/investment-territory'; import { MATURITY_LEVELS } from '@/lib/investment-maturity'; import CountrySelect, { type Country } from '@/components/country-select'; @@ -94,48 +95,6 @@ function QueryStatus({ /* Componentes */ /* ------------------------------------------------------------------ */ -function TopBar({ - onNavigate, - requestCount, -}: { - onNavigate: (view: View) => void; - requestCount: number; -}) { - return ( - - ); -} - function Hero({ query, setQuery, @@ -1048,23 +1007,6 @@ function Field({ ); } -function Footer() { - return ( -
    -
    -

    INVESTE Moçambique

    -

    - Portal do Investidor — conheça as oportunidades de - investimento em Moçambique e manifeste o seu interesse.{' '} - - Acesso à gestão - -

    -
    -
    - ); -} - /* ------------------------------------------------------------------ */ /* App */ /* ------------------------------------------------------------------ */ @@ -1092,7 +1034,7 @@ export default function PortalInvestidorApp({ const selected = initialOpportunity ? toOpportunity(initialOpportunity) : null; - const [requestCount, setRequestCount] = useState(0); + const { registerSubmittedInterest } = useTempoUi(); const [heroQuery, setHeroQuery] = useState(''); const [filters, setFilters] = useState({ query: initialQuery, @@ -1137,7 +1079,6 @@ export default function PortalInvestidorApp({ return (
    -
    {view === 'home' && ( @@ -1376,11 +1317,10 @@ export default function PortalInvestidorApp({ key={selected?.reference ?? 'general'} preselected={selected} countries={countries} - onSubmitted={() => setRequestCount((c) => c + 1)} + onSubmitted={registerSubmittedInterest} /> )}
    -