From 14ad2f60c5465a15e30aa1c0a9e9047103c17c20 Mon Sep 17 00:00:00 2001 From: Paulo Massingue Date: Mon, 19 Oct 2026 13:07:16 +0200 Subject: [PATCH 1/4] header:navbar e footer --- .gitattributes | 3 + README.md | 14 +- .../Commands/CheckDevelopmentEnvironment.php | 51 ++ .../EditorialArticleController.php | 5 + app/Support/IsolatedQaDatabase.php | 23 + bootstrap/app.php | 6 +- bootstrap/storage.php | 17 + composer.json | 1 + ...00_add_investment_zone_editorial_draft.php | 2 +- ...dd_investment_zone_operational_details.php | 2 +- ...create_investor_navigation_preferences.php | 2 +- ...18_160000_add_portal_editorial_content.php | 2 +- deploy/local/README.md | 86 ++++ deploy/local/VERIFICACAO-20261019.md | 62 +++ deploy/local/compose.yaml | 21 + deploy/local/start.ps1 | 13 + .../v2/auditoria-portal/matriz-requisitos.csv | 4 +- public/images/logo/logo-vermelho.png | Bin 0 -> 25390 bytes resources/css/app.css | 289 ++++++++++++ resources/js/components/app-logo.tsx | 23 +- .../js/components/portal-grouped-menu.tsx | 434 ++++++++---------- resources/js/components/tempo-brand.tsx | 288 ++++++++++++ resources/js/components/tempo-footer.tsx | 136 ++++++ .../js/components/tempo-header-tools.tsx | 141 ++++++ resources/js/layouts/portal-navigation.tsx | 135 +++--- resources/js/lib/portal-navigation.ts | 2 +- resources/js/pages/PortalInvestidor.tsx | 66 +-- resources/js/pages/portal/services.tsx | 10 - routes/web.php | 2 +- tests/Feature/DevelopmentEnvironmentTest.php | 35 ++ tests/Unit/EconomicReferenceManifestTest.php | 20 + tests/Unit/RuntimeStorageTest.php | 47 ++ tools/local-dev-smoke.cjs | 51 ++ tools/local-qa-bootstrap.php | 48 ++ 34 files changed, 1631 insertions(+), 410 deletions(-) create mode 100644 app/Console/Commands/CheckDevelopmentEnvironment.php create mode 100644 app/Support/IsolatedQaDatabase.php create mode 100644 bootstrap/storage.php create mode 100644 deploy/local/README.md create mode 100644 deploy/local/VERIFICACAO-20261019.md create mode 100644 deploy/local/compose.yaml create mode 100644 deploy/local/start.ps1 create mode 100644 public/images/logo/logo-vermelho.png create mode 100644 resources/js/components/tempo-brand.tsx create mode 100644 resources/js/components/tempo-footer.tsx create mode 100644 resources/js/components/tempo-header-tools.tsx create mode 100644 tests/Feature/DevelopmentEnvironmentTest.php create mode 100644 tests/Unit/EconomicReferenceManifestTest.php create mode 100644 tests/Unit/RuntimeStorageTest.php create mode 100644 tools/local-dev-smoke.cjs create mode 100644 tools/local-qa-bootstrap.php 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 0000000000000000000000000000000000000000..16f4870758469671af8f5cceee89bd9a7dd79813 GIT binary patch literal 25390 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 literal 0 HcmV?d00001 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} /> )}
    -