Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ee427bad4 | ||
|
|
669cb8979b | ||
|
|
9fda6d6e12 |
@@ -71,7 +71,6 @@ class PortalServicesController extends Controller
|
||||
$props = ['section' => $page, 'filters' => $filters, 'countries' => app(CountryCatalogue::class)->all()];
|
||||
if ($page === 'sectors') {
|
||||
$props['sectors'] = \App\Services\SectorOrganization::catalog();
|
||||
$props['sectorDetails'] = $props['sectors']->map(fn (Sector $sector) => app(\App\Services\SectorInvestment::class)->page($sector))->values();
|
||||
}
|
||||
if (in_array($page, ['documents', 'legislation'], true)) {
|
||||
$query = $this->resources();
|
||||
|
||||
@@ -1403,3 +1403,27 @@ O relatório comum tinha um conflito de imports. Foram conservados ambos e as ch
|
||||
Retomar na sessão local com SSH autenticado, usando a autorização já registada: medir espaço/inodes na partição efectiva, comparar com compilação e backup, conferir main e revisão activa, criar e ensaiar backup fresco, instalar L8 e conferir apenas o seu delta. Depois repetir as guardas necessárias para a candidata conjunta e conferir o delta proactivo preservando L8. Manter a versão activa até a nova estar pronta. Excluir fixtures QA dos inputs de instalação; não executar seeders/importações de amostras, não publicar pilotos privados nem usar o pacote QA como cópia da base activa. SGF TEMPO separado.
|
||||
|
||||
Recibo de preparação: `docs/investmoz/unification/sequential-delivery-preparation-20261027.json`. Provas e instrução de passagem: `outputs/sequential-delivery-20261027/`. Os recibos de execução e as duas revisões servidas serão registados apenas depois de execução real na sessão autenticada; este recibo não os substitui.
|
||||
|
||||
|
||||
## 27/10/2026 — correcção delimitada da navegação dos sectores
|
||||
|
||||
Reprodução local autorizada da intenção de `88b39b527859bd420f2e223a7afea89bea38de54`, indisponível no origin/outro ambiente. Base exacta `9fda6d6e12832a3cf25e7314f1f895dd430238c5`; novo ramo `codex/sector-navigation-fix-local-20261027`. Não se afirma identidade binária com o pacote externo. QA concluída; instalação ainda pendente nesta revisão documental.
|
||||
|
||||
**Causa e alteração:** o índice `/sectores` carregava `sectorDetails` para todos os sectores e apresentava as páginas completas abaixo dos cartões; os cartões passavam a âncoras locais. Removidos esse carregamento e a apresentação agregada. Os cartões usam `sector.url`, preservando as páginas individuais, a especialização Fintech e os caminhos históricos existentes. O índice mantém descrições curtas, contagens e acesso aos sectores, sem repetir guias e oportunidades de todos eles.
|
||||
|
||||
**Preservação:** página individual, `SectorContent`, `SectorEntry`, `SectorInvestment`, `SectorOrganization`, filtros, dados mestres, originais e continuidade para o mesmo dossier não foram alterados. PEC `7fdb6b42` continua no seu ramo QA; não é integrado nesta correcção. L8 instalado e percurso proactivo de `9fda6d6e` preservados. Songo/Gurué privados; sem fixtures QA no activo, publicação, importações, migrations ou alterações de permissões.
|
||||
|
||||
**Delta demonstrado:** actualizados os dois testes afectados de `SectorCatalogueContentTest` e acrescentado um caso de isolamento/regresso/recarregamento:3 testes/319 asserções, base isolada `proactive_investment_20261027_test`, loopback55441, transacções com rollback; sem `migrate:fresh`. Wayfinder `--with-form`, TypeScript e build QA aprovados. Navegador real:10 cartões, acesso separado a Agronegócio e Turismo, oportunidades próprias, filtro Agronegócio mantido no catálogo, recarregamento da página individual e regresso ao índice sem repetição. Entrada Turismo para o dossier conserva o contexto sectorial na ligação e encaminha o visitante para a autenticação existente; não se repetiu a prova completa de gravação do dossier já aceite. A amostra QA não tem guias editoriais carregados; a preservação dos guias assenta na comparação dos consumidores/fontes, e será conferida no destino sem republicar conteúdo. A captura de imagem do browser devolveu «0 width»; árvore de acessibilidade e testes guardados, sem alegação de captura visual inexistente.
|
||||
|
||||
Requisitos existentes actualizados apenas neste delta: `MASTER-471012ab-0007` e `MASTER-9dee08d0-0017`; não se encerra automaticamente o âmbito mais amplo dessas linhas. Recibo QA: `docs/investmoz/unification/sector-navigation-qa-20261027.json`. Provas locais: `outputs/sector-navigation-fix-20261027/`. Entrega autorizada seguirá o processo Git existente, com capacidade, backup/restauro fresco, comparação de fonte/dados/schema/configuração/permissões e revisão efectivamente servida.
|
||||
|
||||
|
||||
## 27/10/2026 — navegação dos sectores instalada e conferida
|
||||
|
||||
**Disponível no portal em `669cb8979b0c372659fc2ad3876aebc919d5df19`**, sobre `9fda6d6e`. Reproduzida localmente a correcção solicitada, com novo identificador; `88b39b5` não foi importado e deixa de ser condição de transferência/instalação. O índice mostra10cartões sem os detalhes completos de todos os sectores; cada cartão usa a URL própria. Páginas individuais, guias, especialização Fintech, filtro e continuidade do dossier preservados. Comparação pública antes/depois:os mesmos10cartões e as mesmas3páginas de Agronegócio/Turismo/Fintech, cada uma com1guia e respectivas oportunidades; só o índice perdeu `sectorDetails`, conforme pedido. Navegador no portal confirmou o índice servido sem repetição.
|
||||
|
||||
QA dirigida:3testes/319asserções, transacções com rollback em loopback55441;Wayfinder/tipos/build aprovados. Instalador existente preservado e controlos automáticos aprovados:PostgreSQL1/3106,Unit59/317,frontend1080pass/0fail,TypeScript ebuild31,42s. Integração Git normal,sem force;release anterior mantida até compilação e verificações prontas,seguida de troca atómica e conferência da revisão/manifest servidos. Delta de aplicação limitado a2ficheiros;1000ficheiros de fonte/recursos/documentos conferidos com o Git. Apenas2registos previstos da matriz actualizados,demais registos semanticamente intactos.
|
||||
|
||||
Capacidade antes:88,3GiB e23,76milhões de inodes livres;novamente conferida após backup. Backup fresco `/var/backups/investmoz-sector-navigation-20261027/backup`,dumpSHA256`9b2437017495fe449cfe0c869da62870bd0fc4bddde596660a37392b8dbdaaba`;restauro das174tabelas com contagens/checksums idênticos,em contentor sem rede,porta55441.369ficheiros persistentes/configuração verificados;172tabelas de negócio intactas depois da instalação;cache/sessões operacionais reconciliados por identidade/expiração/pedidos públicos. Schema,papéis,grants epermissões iguais. Sem migrations,importações ou publicação de pilotos;storageQA fica separado da release servida. Songo/Gurué privados;L8 e percurso proactivo anteriores preservados. PEC`7fdb6b42` continua emQA separado e não foi instalado nesta passagem. Avaliação real da equipa continua dependente do retorno dos participantes.
|
||||
|
||||
Recibo consolidado: `docs/investmoz/unification/sector-navigation-delivery-20261027.json`. Cópia remota: `/var/backups/investmoz-sector-navigation-20261027/installed-receipt.json`,SHA256`cd95142b7f85e40a0f86e0f7d3dca513e7bc208c89aa91b8e3ad213191d8465f`. Provas locais: `outputs/sector-navigation-delivery-20261027/`. Os registos anteriores de QA/transferência são históricos;esta correcção já não está pendente de instalação. Não se declara concluído o âmbito global dos requisitos sectoriais ou do simulador.
|
||||
|
||||
@@ -0,0 +1,759 @@
|
||||
{
|
||||
"date": "2026-10-27",
|
||||
"status": "installed_and_verified",
|
||||
"served_commit": "669cb8979b0c372659fc2ad3876aebc919d5df19",
|
||||
"previous_commit": "9fda6d6e12832a3cf25e7314f1f895dd430238c5",
|
||||
"remote_backup": "/var/backups/investmoz-sector-navigation-20261027/backup",
|
||||
"remote_receipt": "/var/backups/investmoz-sector-navigation-20261027/installed-receipt.json",
|
||||
"runtime_delta": [
|
||||
{
|
||||
"file": "app/Http/Controllers/PortalServicesController.php",
|
||||
"before_sha256": "512cc1e2a45a62f4164076a77c5b005a507c6f2150c4fbf7f834193b6357e6f8",
|
||||
"after_sha256": "9bf672f584e5012ec5d8b71828c83ea40d6c116619a41f985396d4531d733cdf"
|
||||
},
|
||||
{
|
||||
"file": "resources/js/pages/portal/services.tsx",
|
||||
"before_sha256": "434790ec829e8f6cb012f88da3871746593051eb7fd6034b6e7977eb2bef4e73",
|
||||
"after_sha256": "9621eaec71bbb87157dbe41841ba1c098e2b5603a72bbaa80adf3bceaa14b61c"
|
||||
}
|
||||
],
|
||||
"source_files_verified": 1000,
|
||||
"qa": {
|
||||
"tests": 3,
|
||||
"assertions": 319,
|
||||
"database": "proactive_investment_20261027_test",
|
||||
"port": 55441,
|
||||
"rollback": true,
|
||||
"routes_types_build": "passed",
|
||||
"browser": "10 unique cards;Agronegocio/Turismo isolated;sector filter,back,reload,guest dossier entry preserved",
|
||||
"screenshot": "unavailable (zero width);AX proof retained"
|
||||
},
|
||||
"installer": {
|
||||
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
|
||||
"installed": {
|
||||
"status": "installed",
|
||||
"commit": "669cb8979b0c372659fc2ad3876aebc919d5df19",
|
||||
"release": "/var/www/investmoz-homologacao/releases/669cb8979b0c372659fc2ad3876aebc919d5df19-6a2f00c6",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/9fda6d6e12832a3cf25e7314f1f895dd430238c5-88fc859c",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0
|
||||
},
|
||||
"latest_report": {
|
||||
"status": "installed",
|
||||
"commit": "669cb8979b0c372659fc2ad3876aebc919d5df19",
|
||||
"release": "/var/www/investmoz-homologacao/releases/669cb8979b0c372659fc2ad3876aebc919d5df19-6a2f00c6",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/9fda6d6e12832a3cf25e7314f1f895dd430238c5-88fc859c",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0,
|
||||
"requested_commits": [
|
||||
"669cb8979b0c372659fc2ad3876aebc919d5df19"
|
||||
],
|
||||
"finished_at": "2026-10-27T11:53:24.879567+00:00"
|
||||
},
|
||||
"log_file": "1793101792543556387.log",
|
||||
"summaries": [
|
||||
"OK (1 test, 3106 assertions)",
|
||||
"built in 31.42s",
|
||||
"OK (59 tests, 317 assertions)",
|
||||
"# tests 1080",
|
||||
"# pass 1080",
|
||||
"# fail 0"
|
||||
],
|
||||
"log_bytes": 306104
|
||||
},
|
||||
"backup": {
|
||||
"stage": "/var/backups/investmoz-sector-navigation-20261027/backup",
|
||||
"created_at": "2026-10-27T11:44:59Z",
|
||||
"target": {
|
||||
"database": "teste_investidor",
|
||||
"port": 5432
|
||||
},
|
||||
"tables": 174,
|
||||
"files_verified": 369,
|
||||
"dump_sha256": "9b2437017495fe449cfe0c869da62870bd0fc4bddde596660a37392b8dbdaaba",
|
||||
"files_sha256": "bf268753549312be793605de294105ac6836ff96a16ab740b1a2c929a15a523a",
|
||||
"restore_verified": false
|
||||
},
|
||||
"restore": {
|
||||
"restore_verified": true,
|
||||
"tables_verified": 174,
|
||||
"container_network": "none",
|
||||
"database": "sector_navigation_restore_20261027",
|
||||
"port": 55441,
|
||||
"source_dump_sha256": "9b2437017495fe449cfe0c869da62870bd0fc4bddde596660a37392b8dbdaaba",
|
||||
"active_database_writes": 0
|
||||
},
|
||||
"capacity_after_backup": {
|
||||
"at": "2026-10-27T11:48:33.493720+00:00",
|
||||
"baseline": "9fda6d6e12832a3cf25e7314f1f895dd430238c5",
|
||||
"capacity_after_backup_satisfied": true,
|
||||
"volumes": [
|
||||
{
|
||||
"path": "/var/www/investmoz-homologacao/releases",
|
||||
"free_bytes": 94615425024,
|
||||
"free_inodes": 23762622
|
||||
},
|
||||
{
|
||||
"path": "/var/lib/investmoz-deploy",
|
||||
"free_bytes": 94615425024,
|
||||
"free_inodes": 23762622
|
||||
},
|
||||
{
|
||||
"path": "/var/backups",
|
||||
"free_bytes": 94615425024,
|
||||
"free_inodes": 23762622
|
||||
},
|
||||
{
|
||||
"path": "/tmp",
|
||||
"free_bytes": 94615425024,
|
||||
"free_inodes": 23762622
|
||||
},
|
||||
{
|
||||
"path": "/var/lib/docker",
|
||||
"free_bytes": 94615425024,
|
||||
"free_inodes": 23762622
|
||||
}
|
||||
],
|
||||
"backup_age_seconds": 214.493685,
|
||||
"backup_dump_sha256": "9b2437017495fe449cfe0c869da62870bd0fc4bddde596660a37392b8dbdaaba",
|
||||
"restore_verified": true,
|
||||
"tables_verified": 174,
|
||||
"files_verified": 369,
|
||||
"backup_paths": {
|
||||
"dump": "/var/backups/investmoz-sector-navigation-20261027/backup/database.dump",
|
||||
"files": "/var/backups/investmoz-sector-navigation-20261027/backup/files-before.tar.gz"
|
||||
},
|
||||
"active_writes": 0
|
||||
},
|
||||
"schema_permissions": {
|
||||
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
|
||||
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
|
||||
"filesystem_permissions": {
|
||||
".env": {
|
||||
"mode": 416,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"storage": {
|
||||
"mode": 1533,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"storage/app": {
|
||||
"mode": 1533,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"bootstrap/cache": {
|
||||
"mode": 1528,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
}
|
||||
},
|
||||
"comparison_identity": "postgres;catalogue read only;no passwords collected",
|
||||
"unchanged": true
|
||||
},
|
||||
"preservation": {
|
||||
"checked_at": "2026-10-27T11:55:17.440349+00:00",
|
||||
"installed": "669cb8979b0c372659fc2ad3876aebc919d5df19",
|
||||
"business_tables_unchanged": 172,
|
||||
"total_tables": 174,
|
||||
"operational_tables_to_reconcile": {
|
||||
"cache": {
|
||||
"before": {
|
||||
"rows": 108,
|
||||
"checksum": "0d9184e9b1f30ace1b1da4990b284ed9"
|
||||
},
|
||||
"after": {
|
||||
"rows": 108,
|
||||
"checksum": "6cf70f4b3bfc3a57f18b68080f939a19"
|
||||
}
|
||||
},
|
||||
"sessions": {
|
||||
"before": {
|
||||
"rows": 21,
|
||||
"checksum": "a5144e0ab915427ad1a8dddb70d8beee"
|
||||
},
|
||||
"after": {
|
||||
"rows": 41,
|
||||
"checksum": "261778bcf00473e4d1792749cc5ec6d0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"persistent_files_unchanged": 369,
|
||||
"original_configuration_preserved": true,
|
||||
"synthetic_QA_storage_not_served": true,
|
||||
"QA_storage_saved_outside_active": "/var/lib/investmoz-deploy/qa-runtime/669cb8979b0c372659fc2ad3876aebc919d5df19-6a2f00c6",
|
||||
"fixture_or_content_imports": 0,
|
||||
"migrations": 0,
|
||||
"comparison_identity": "postgres;UTC;consistent before snapshot and after read-only transaction",
|
||||
"active_database_writes": 0
|
||||
},
|
||||
"operational_delta": {
|
||||
"status": "operational_delta_reconciled",
|
||||
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
|
||||
"cache": "queue:restart;requestthrottle;identical home-sector cached value with refreshed expiry(HomeController remember10min);no deletedcache",
|
||||
"sessions": "anonymous sessions from delivery user-agent or exactUA/time correlated with nginx public request;deleted sessions individually expired beyond configured lifetime,normal database session garbage collection(config/session lottery2/100)",
|
||||
"delta": {
|
||||
"cache": {
|
||||
"before_rows": 108,
|
||||
"after_rows": 108,
|
||||
"changes": [
|
||||
{
|
||||
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
|
||||
"kind": "updated",
|
||||
"fields": [
|
||||
"value",
|
||||
"expiration"
|
||||
],
|
||||
"key_pattern": "investemoz-cache-illuminate:queue:restart",
|
||||
"is_queue_restart_key": true,
|
||||
"expiration_unchanged": false,
|
||||
"throttle_timer_pair": false,
|
||||
"same_value_home_cache_expiry_refresh": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"sessions": {
|
||||
"before_rows": 21,
|
||||
"after_rows": 41,
|
||||
"changes": [
|
||||
{
|
||||
"key_sha256": "2ad1cb241771733ecdcd4d01332669674850e8c69e092604b4deb80014596094",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "17b9f88494ab475782d0a1a069bd6c3c6154489201d1335fbae9af15530a7231",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "fba4cdd75dd31dbc9d9b38ae207cc10c91cf889ecdbe8e7996059f7d5c94a0ae",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "c2ac41f80cf479eb3c8f024b6140d7c65bb75407f8d92a89102b2424e9c78b81",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "438d48be29b8f94cadc4c0731034c86c65cbf457a422949e3ff8a3af82694313",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "64b01593f650d8ab56f143f5e7dd32647277e9be7ace1a77dba9578c6b5b7501",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": false,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "3bb40945f442a7f0f13c7471b2ede4fad92bb615c5716e5f8cbae29b8cb690f4",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "cad0a1de3861c0491bd01e7f133074335041313d64a0aa4692cf70fa607ba81c",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "a88c70aba8ba526065925b98c73e3a05cab4051d9b298e565bd562080eb19bf1",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "d0c392ca36450e9123f8d5472757d86954f41168448fb512ad1fdda6d7c6dd8b",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "96464d3abc3cbd84145b5d265e1d647b762c4e89afdc8cbccd5f3778940ca7d1",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "cfbc6ad7b813e14d9fb2b805daece5ab8c1ea2bfb42c548be709972b692eee3d",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "3caf5a87cdae5355a8066aa5a2773c3252608403c0b8dc66bbbc657c8029bae8",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "294f5cb374a33087114fbb2e71d8815b366ff4e52057ca8ec381d3998786d4fc",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "2f342bbe74c8109df6d30a2c1d293b36572c4953b80d9ccb18d7c8924642f4d7",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "1e430e81b8fc7238b6cc37d5ef16c8482f1475c15b490fc2a8512a7ec15d1136",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "8c7e4a6a4af2a4e0106a24dc4d6e434baefdb8d0bca551bc8377c34cee667ba5",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "9c23bed34e3ee88810369ce7daef74863f692d5ab0360a4f3ae46cd7f60fac2d",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "810ed909001d96275b1c7f2d3f5fd1843afdc2054c134a7d0e8474a9261d6f85",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "7e025b942486695c1749702b5ca355089121e35d744dcd03220aa7b1f5b4cb08",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"business_tables_to_confirm_separately": 172,
|
||||
"active_data_writes_by_comparison": 0,
|
||||
"restore_network": "none"
|
||||
},
|
||||
"public_delta": {
|
||||
"cards": 10,
|
||||
"index_details_before": true,
|
||||
"index_details_after": false,
|
||||
"sector_pages_unchanged": [
|
||||
"agronegocio",
|
||||
"turismo",
|
||||
"mercado-financeiro/fintech"
|
||||
],
|
||||
"guide_count_per_selected_sector": {
|
||||
"agronegocio": 1,
|
||||
"turismo": 1,
|
||||
"mercado-financeiro/fintech": 1
|
||||
},
|
||||
"filter": "agronegocio",
|
||||
"manifest_sha256": "e8f9e3d19077576db83e80adf3f34a93ca676553ac1f6c69c3f4e715a4bde76a",
|
||||
"manifest_verified": true,
|
||||
"private_writes": 0
|
||||
},
|
||||
"main_delivery": "normal fast-forward Git push;existing webhook/installer;old release preserved until ready",
|
||||
"private_pilots": "No Songo/Gurue publication;no QA data import",
|
||||
"pec": "7fdb6b42 remains separate QA branch, not installed in this delivery",
|
||||
"external_commit": "88b39b5 intent reproduced locally by explicit user instruction;no binary-equivalence claim",
|
||||
"artifacts": [
|
||||
{
|
||||
"file": "after.json",
|
||||
"bytes": 235088,
|
||||
"sha256": "2cbdd93fa921c8d2b1d05e5b7c9cdb896f7ebbda8839abe9d52f4f3728d1826e"
|
||||
},
|
||||
{
|
||||
"file": "backup.py",
|
||||
"bytes": 5452,
|
||||
"sha256": "3d4d549387b3b811f51c47e8da79f75e33d9814fd8ee93a116c7254c62d426ae"
|
||||
},
|
||||
{
|
||||
"file": "backup.txt",
|
||||
"bytes": 822,
|
||||
"sha256": "504f147468d9ffdd9cb773fa7eb7c0e1963f0b14047fbdd208659a78332f29d6"
|
||||
},
|
||||
{
|
||||
"file": "before.json",
|
||||
"bytes": 235089,
|
||||
"sha256": "ae5dd2e81c21bb71d01435e397ddf6d831a7527c5e8e7699ef86ef6f5200056a"
|
||||
},
|
||||
{
|
||||
"file": "capacity-after.py",
|
||||
"bytes": 1610,
|
||||
"sha256": "5fc773a1f74a3f6028c2d190c452c8d58f8b4a2f56afc508c61002d4eb892371"
|
||||
},
|
||||
{
|
||||
"file": "capacity-after.txt",
|
||||
"bytes": 1994,
|
||||
"sha256": "dffb2f7bc0f8a4d46dd76022d3952513b4f029545524b7e2d81e97cebebd9f09"
|
||||
},
|
||||
{
|
||||
"file": "index-served.txt",
|
||||
"bytes": 6663,
|
||||
"sha256": "bea4d0bbb39366a90a6b2c2fd16d14d0bd31bed93595145f1afe2740d59b99a0"
|
||||
},
|
||||
{
|
||||
"file": "inspect.txt",
|
||||
"bytes": 61498,
|
||||
"sha256": "6e66ce6aaeeb67723daa65d3659660aadb14760d365db21dc3a36a8b3cef2d3f"
|
||||
},
|
||||
{
|
||||
"file": "integrated.json",
|
||||
"bytes": 251,
|
||||
"sha256": "5f58ca5aad02394c5d0f8932ce9c3d09c915c16d2299ec76ddd06445f9c3b5e2"
|
||||
},
|
||||
{
|
||||
"file": "matrix-preservation.json",
|
||||
"bytes": 142,
|
||||
"sha256": "3f9eba3a66126091ade7bde897f6ed5be1428ddcb62b610a537ec638007ba2fe"
|
||||
},
|
||||
{
|
||||
"file": "operational-delta.txt",
|
||||
"bytes": 7899,
|
||||
"sha256": "56d9ac3eb9be3069164303d615fc484dedc3c1912a4e422bd340529419cb9c82"
|
||||
},
|
||||
{
|
||||
"file": "pipeline-current.py",
|
||||
"bytes": 21198,
|
||||
"sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604"
|
||||
},
|
||||
{
|
||||
"file": "preflight.py",
|
||||
"bytes": 2337,
|
||||
"sha256": "73484c8e8e811f68799200b87c7f2b58b91b09502afbd64b8f9b3116ab59bbf2"
|
||||
},
|
||||
{
|
||||
"file": "preflight.txt",
|
||||
"bytes": 4446,
|
||||
"sha256": "16d116ab7c673aa836fb5afae74369077b0103028d7972e1cb34bbb0bf9f8afd"
|
||||
},
|
||||
{
|
||||
"file": "preparation.json",
|
||||
"bytes": 245104,
|
||||
"sha256": "bbad8749a58c20e89f40064eee47b53969f85c4e478bcfd65eb73e0666684773"
|
||||
},
|
||||
{
|
||||
"file": "preservation.txt",
|
||||
"bytes": 945,
|
||||
"sha256": "95ed7c2338244ca751fb01e2a92ca5a4e408e23947bc394322970c2bf5eab860"
|
||||
},
|
||||
{
|
||||
"file": "preserve-data.py",
|
||||
"bytes": 2288,
|
||||
"sha256": "9f0c3097467fe171508e741fa1e360df7747aab15f2feb1465adaf38520e69c3"
|
||||
},
|
||||
{
|
||||
"file": "public-after.json",
|
||||
"bytes": 42854,
|
||||
"sha256": "cee7364e130234ca27fea14ad271c0b13d9de68fbecf0910ac4014fec07c498c"
|
||||
},
|
||||
{
|
||||
"file": "public-before.json",
|
||||
"bytes": 42784,
|
||||
"sha256": "cfe084efbf1bf43b3624e4a1b4834857c6673dc32f614fe6a8e57f47882c8b11"
|
||||
},
|
||||
{
|
||||
"file": "public-details-after-diagnostic.json",
|
||||
"bytes": 34496,
|
||||
"sha256": "173fc6ceb4429e4c53a481606efedb3c6738f224d761f43a75dc18cae4b6a1e8"
|
||||
},
|
||||
{
|
||||
"file": "reconcile-operational-delta.py",
|
||||
"bytes": 5338,
|
||||
"sha256": "295501048b897c8506ced3943013058f8bd2c904e8a48b083ecd173759c41cf3"
|
||||
},
|
||||
{
|
||||
"file": "restore.py",
|
||||
"bytes": 2819,
|
||||
"sha256": "4bd143dd278701e08d1878d4011b096d1fb22ecadd995b5b433349d9e4cd36cc"
|
||||
},
|
||||
{
|
||||
"file": "restore.txt",
|
||||
"bytes": 554,
|
||||
"sha256": "2b31f1844444604094dfbaed3e17a62a6e3c8dcac178052632b62780efd063c6"
|
||||
},
|
||||
{
|
||||
"file": "schema-after.txt",
|
||||
"bytes": 526,
|
||||
"sha256": "d5855a7a0a16c1762cce140750c3b8c984e9ea61817bdf02e684cc9ae1c01592"
|
||||
},
|
||||
{
|
||||
"file": "schema-before.txt",
|
||||
"bytes": 1016,
|
||||
"sha256": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7"
|
||||
},
|
||||
{
|
||||
"file": "schema-permissions-after.py",
|
||||
"bytes": 1864,
|
||||
"sha256": "52ddfc9d1a235518e95dedc653eb303866477d52a8b712da75d331cea7ab714f"
|
||||
},
|
||||
{
|
||||
"file": "schema-permissions-before.py",
|
||||
"bytes": 1707,
|
||||
"sha256": "2723b6a4e099f3af2efd333f3f9d8c6937e6cf2255b8448f5f27bc74455af319"
|
||||
},
|
||||
{
|
||||
"file": "source-after.txt",
|
||||
"bytes": 160,
|
||||
"sha256": "e88624cd7f7e72c2dad88fabac95c2dfe6ca9c140d40aecfed238fd46e2a0997"
|
||||
},
|
||||
{
|
||||
"file": "source-before.txt",
|
||||
"bytes": 324,
|
||||
"sha256": "d0211ba30920fd270b5bc3873455067b20cb0078f35991410f26356b70350e2b"
|
||||
},
|
||||
{
|
||||
"file": "source-check.py",
|
||||
"bytes": 669,
|
||||
"sha256": "2ea95b35eb8c2eb950216ab77e2a3127b2400372e5034179953edae058b0eb84"
|
||||
},
|
||||
{
|
||||
"file": "ssh-session.py",
|
||||
"bytes": 3050,
|
||||
"sha256": "51c402acdfb594d8146610a224f03b17369b6641511235a616c84c7e5d688f18"
|
||||
},
|
||||
{
|
||||
"file": "status-a1.txt",
|
||||
"bytes": 1994,
|
||||
"sha256": "1d78e2bf83b402b2108dff42b029fe95753399dfcd3e880263d0cdb2c77f4b85"
|
||||
},
|
||||
{
|
||||
"file": "status-a2.txt",
|
||||
"bytes": 2058,
|
||||
"sha256": "0307b19f4fd764350cac2c839968011516c7c7aa7bb5d80317816a70bc5cd16f"
|
||||
},
|
||||
{
|
||||
"file": "status-a3.txt",
|
||||
"bytes": 2162,
|
||||
"sha256": "ebdec6a635347bcec45d45b3ab182b7a10a22d816cef57709b156e4d2a1e4da7"
|
||||
},
|
||||
{
|
||||
"file": "status-a4.txt",
|
||||
"bytes": 2162,
|
||||
"sha256": "ebdec6a635347bcec45d45b3ab182b7a10a22d816cef57709b156e4d2a1e4da7"
|
||||
},
|
||||
{
|
||||
"file": "status-a5.txt",
|
||||
"bytes": 2244,
|
||||
"sha256": "f6f22631054fa0920a3c897db7bc6e3a00bce5420e4893f08125bd103dc5fb8f"
|
||||
},
|
||||
{
|
||||
"file": "verify-public.py",
|
||||
"bytes": 2470,
|
||||
"sha256": "733a94aa83698de4a5f1f1a79c9d3dbdce8d80c69787b549864f7916810777b4"
|
||||
}
|
||||
],
|
||||
"remote_receipt_sha256": "cd95142b7f85e40a0f86e0f7d3dca513e7bc208c89aa91b8e3ad213191d8465f"
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"date": "2026-10-27",
|
||||
"status": "QA passed; not yet installed",
|
||||
"source_intention": "88b39b527859bd420f2e223a7afea89bea38de54",
|
||||
"reproduced_locally": true,
|
||||
"byte_equivalence_to_external_commit": false,
|
||||
"baseline": "9fda6d6e12832a3cf25e7314f1f895dd430238c5",
|
||||
"branch": "codex/sector-navigation-fix-local-20261027",
|
||||
"runtime_delta": [
|
||||
"app/Http/Controllers/PortalServicesController.php",
|
||||
"resources/js/pages/portal/services.tsx"
|
||||
],
|
||||
"tests": {
|
||||
"feature_tests": 3,
|
||||
"assertions": 319,
|
||||
"database": "proactive_investment_20261027_test",
|
||||
"port": 55441,
|
||||
"rollback": true,
|
||||
"routes": "passed",
|
||||
"typescript": "passed",
|
||||
"build": "passed"
|
||||
},
|
||||
"browser": {
|
||||
"index_cards": 10,
|
||||
"separate_sectors": [
|
||||
"agronegocio",
|
||||
"turismo"
|
||||
],
|
||||
"opportunities_isolated": true,
|
||||
"filter": "agronegocio",
|
||||
"back": true,
|
||||
"reload": true,
|
||||
"fintech_url_preserved": true,
|
||||
"dossier_entry": "sector:3; existing guest authentication, no new dossier created",
|
||||
"screenshots": "capture unavailable: zero width; AX proof retained",
|
||||
"editorial_guides": "not loaded in QA sample; consumers unchanged, destination to check"
|
||||
},
|
||||
"protected_files": [
|
||||
{
|
||||
"file": "resources/js/components/sector-content.tsx",
|
||||
"sha256_LF": "4ee55554f8a88ba7db1ac0dc74259d4e66603979c3873f9ec897437830b8e0ae",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "resources/js/components/sector-entry.tsx",
|
||||
"sha256_LF": "96672c709b70f840d105c664a92d49a17acb66cd852d43dadaa8f3fef8b3e845",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "resources/js/components/public-sector-cards.tsx",
|
||||
"sha256_LF": "858ba6235ef8b46461d416b3264436e4df2c9555b8e6d8c3644dbd8c55463484",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "app/Services/SectorInvestment.php",
|
||||
"sha256_LF": "0b8fbc6e3d03ede627e95332703e4749a53d86708bdc0f9579e958caf30e4d17",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "app/Services/SectorOrganization.php",
|
||||
"sha256_LF": "f0e54fe6acfe746c6758387f43610232cb51371b0404bcefaf466d8b704f3ae3",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "app/Http/Controllers/PublicPortalController.php",
|
||||
"sha256_LF": "cb6abd75533660a52e18148cc5f1ab706d2e08f9c94334510541e6b0e003b461",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "resources/js/lib/project-dossier.ts",
|
||||
"sha256_LF": "d59f3fa4dcb3fade1f967564c972e30932aa095a4e5dd4ba0be8b4e07492ef0a",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "resources/js/lib/irpc-annual-settlement.ts",
|
||||
"sha256_LF": "8cca5316259e3ebabfa75be9f64143a8664a447ac30b23b882318edfd70a68f1",
|
||||
"unchanged": true
|
||||
},
|
||||
{
|
||||
"file": "routes/web.php",
|
||||
"sha256_LF": "95930c76977d446b74a422acc4b60869ff6bae5d4567c21cc644484c5f09cbda",
|
||||
"unchanged": true
|
||||
}
|
||||
],
|
||||
"pec_branch_not_integrated": "7fdb6b42",
|
||||
"active_writes": 0,
|
||||
"private_pilots_published": false
|
||||
}
|
||||
@@ -6924,3 +6924,27 @@ O relatório comum tinha um conflito de imports. Foram conservados ambos e as ch
|
||||
Retomar na sessão local com SSH autenticado, usando a autorização já registada: medir espaço/inodes na partição efectiva, comparar com compilação e backup, conferir main e revisão activa, criar e ensaiar backup fresco, instalar L8 e conferir apenas o seu delta. Depois repetir as guardas necessárias para a candidata conjunta e conferir o delta proactivo preservando L8. Manter a versão activa até a nova estar pronta. Excluir fixtures QA dos inputs de instalação; não executar seeders/importações de amostras, não publicar pilotos privados nem usar o pacote QA como cópia da base activa. SGF TEMPO separado.
|
||||
|
||||
Recibo de preparação: `docs/investmoz/unification/sequential-delivery-preparation-20261027.json`. Provas e instrução de passagem: `outputs/sequential-delivery-20261027/`. Os recibos de execução e as duas revisões servidas serão registados apenas depois de execução real na sessão autenticada; este recibo não os substitui.
|
||||
|
||||
|
||||
## 27/10/2026 — correcção delimitada da navegação dos sectores
|
||||
|
||||
Reprodução local autorizada da intenção de `88b39b527859bd420f2e223a7afea89bea38de54`, indisponível no origin/outro ambiente. Base exacta `9fda6d6e12832a3cf25e7314f1f895dd430238c5`; novo ramo `codex/sector-navigation-fix-local-20261027`. Não se afirma identidade binária com o pacote externo. QA concluída; instalação ainda pendente nesta revisão documental.
|
||||
|
||||
**Causa e alteração:** o índice `/sectores` carregava `sectorDetails` para todos os sectores e apresentava as páginas completas abaixo dos cartões; os cartões passavam a âncoras locais. Removidos esse carregamento e a apresentação agregada. Os cartões usam `sector.url`, preservando as páginas individuais, a especialização Fintech e os caminhos históricos existentes. O índice mantém descrições curtas, contagens e acesso aos sectores, sem repetir guias e oportunidades de todos eles.
|
||||
|
||||
**Preservação:** página individual, `SectorContent`, `SectorEntry`, `SectorInvestment`, `SectorOrganization`, filtros, dados mestres, originais e continuidade para o mesmo dossier não foram alterados. PEC `7fdb6b42` continua no seu ramo QA; não é integrado nesta correcção. L8 instalado e percurso proactivo de `9fda6d6e` preservados. Songo/Gurué privados; sem fixtures QA no activo, publicação, importações, migrations ou alterações de permissões.
|
||||
|
||||
**Delta demonstrado:** actualizados os dois testes afectados de `SectorCatalogueContentTest` e acrescentado um caso de isolamento/regresso/recarregamento:3 testes/319 asserções, base isolada `proactive_investment_20261027_test`, loopback55441, transacções com rollback; sem `migrate:fresh`. Wayfinder `--with-form`, TypeScript e build QA aprovados. Navegador real:10 cartões, acesso separado a Agronegócio e Turismo, oportunidades próprias, filtro Agronegócio mantido no catálogo, recarregamento da página individual e regresso ao índice sem repetição. Entrada Turismo para o dossier conserva o contexto sectorial na ligação e encaminha o visitante para a autenticação existente; não se repetiu a prova completa de gravação do dossier já aceite. A amostra QA não tem guias editoriais carregados; a preservação dos guias assenta na comparação dos consumidores/fontes, e será conferida no destino sem republicar conteúdo. A captura de imagem do browser devolveu «0 width»; árvore de acessibilidade e testes guardados, sem alegação de captura visual inexistente.
|
||||
|
||||
Requisitos existentes actualizados apenas neste delta: `MASTER-471012ab-0007` e `MASTER-9dee08d0-0017`; não se encerra automaticamente o âmbito mais amplo dessas linhas. Recibo QA: `docs/investmoz/unification/sector-navigation-qa-20261027.json`. Provas locais: `outputs/sector-navigation-fix-20261027/`. Entrega autorizada seguirá o processo Git existente, com capacidade, backup/restauro fresco, comparação de fonte/dados/schema/configuração/permissões e revisão efectivamente servida.
|
||||
|
||||
|
||||
## 27/10/2026 — navegação dos sectores instalada e conferida
|
||||
|
||||
**Disponível no portal em `669cb8979b0c372659fc2ad3876aebc919d5df19`**, sobre `9fda6d6e`. Reproduzida localmente a correcção solicitada, com novo identificador; `88b39b5` não foi importado e deixa de ser condição de transferência/instalação. O índice mostra10cartões sem os detalhes completos de todos os sectores; cada cartão usa a URL própria. Páginas individuais, guias, especialização Fintech, filtro e continuidade do dossier preservados. Comparação pública antes/depois:os mesmos10cartões e as mesmas3páginas de Agronegócio/Turismo/Fintech, cada uma com1guia e respectivas oportunidades; só o índice perdeu `sectorDetails`, conforme pedido. Navegador no portal confirmou o índice servido sem repetição.
|
||||
|
||||
QA dirigida:3testes/319asserções, transacções com rollback em loopback55441;Wayfinder/tipos/build aprovados. Instalador existente preservado e controlos automáticos aprovados:PostgreSQL1/3106,Unit59/317,frontend1080pass/0fail,TypeScript ebuild31,42s. Integração Git normal,sem force;release anterior mantida até compilação e verificações prontas,seguida de troca atómica e conferência da revisão/manifest servidos. Delta de aplicação limitado a2ficheiros;1000ficheiros de fonte/recursos/documentos conferidos com o Git. Apenas2registos previstos da matriz actualizados,demais registos semanticamente intactos.
|
||||
|
||||
Capacidade antes:88,3GiB e23,76milhões de inodes livres;novamente conferida após backup. Backup fresco `/var/backups/investmoz-sector-navigation-20261027/backup`,dumpSHA256`9b2437017495fe449cfe0c869da62870bd0fc4bddde596660a37392b8dbdaaba`;restauro das174tabelas com contagens/checksums idênticos,em contentor sem rede,porta55441.369ficheiros persistentes/configuração verificados;172tabelas de negócio intactas depois da instalação;cache/sessões operacionais reconciliados por identidade/expiração/pedidos públicos. Schema,papéis,grants epermissões iguais. Sem migrations,importações ou publicação de pilotos;storageQA fica separado da release servida. Songo/Gurué privados;L8 e percurso proactivo anteriores preservados. PEC`7fdb6b42` continua emQA separado e não foi instalado nesta passagem. Avaliação real da equipa continua dependente do retorno dos participantes.
|
||||
|
||||
Recibo consolidado: `docs/investmoz/unification/sector-navigation-delivery-20261027.json`. Cópia remota: `/var/backups/investmoz-sector-navigation-20261027/installed-receipt.json`,SHA256`cd95142b7f85e40a0f86e0f7d3dca513e7bc208c89aa91b8e3ad213191d8465f`. Provas locais: `outputs/sector-navigation-delivery-20261027/`. Os registos anteriores de QA/transferência são históricos;esta correcção já não está pendente de instalação. Não se declara concluído o âmbito global dos requisitos sectoriais ou do simulador.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,7 +71,6 @@ type Page<T> = {
|
||||
};
|
||||
type Props = {
|
||||
sectorEntry?: SectorDetailData['sectorEntry'];
|
||||
sectorDetails?: SectorDetailData[];
|
||||
countries?: Country[];
|
||||
section: string;
|
||||
filters?: Record<string, string | string[]>;
|
||||
@@ -518,41 +517,9 @@ export default function Services(p: Props) {
|
||||
description: sector.short_description,
|
||||
opportunitiesCount: sector.opportunities_count,
|
||||
specializations: sector.specializations,
|
||||
url: p.sectorDetails?.length
|
||||
? `#sector-${sector.slug}`
|
||||
: sector.url,
|
||||
url: sector.url,
|
||||
}))}
|
||||
/>
|
||||
{p.sectorDetails?.map((detail) => (
|
||||
<section
|
||||
id={`sector-${detail.sector.slug}`}
|
||||
key={detail.sector.id}
|
||||
aria-labelledby={`sector-heading-${detail.sector.slug}`}
|
||||
className="scroll-mt-24 space-y-5 border-t border-slate-200 pt-6"
|
||||
>
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<h2
|
||||
id={`sector-heading-${detail.sector.slug}`}
|
||||
className="text-2xl font-bold"
|
||||
>
|
||||
{detail.sector.name}
|
||||
</h2>
|
||||
<Link
|
||||
href={`/sectores/${detail.sector.slug}`}
|
||||
className="inline-flex min-h-11 items-center text-sm font-semibold underline"
|
||||
>
|
||||
Abrir página do sector
|
||||
</Link>
|
||||
</div>
|
||||
<SectorContent {...detail} headingLevel={3} />
|
||||
<a
|
||||
href="#sectores-indice"
|
||||
className="inline-flex min-h-11 items-center text-sm font-semibold underline"
|
||||
>
|
||||
Voltar à lista de sectores
|
||||
</a>
|
||||
</section>
|
||||
))}
|
||||
{!p.sectors?.length && (
|
||||
<p>Não existem sectores publicados.</p>
|
||||
)}
|
||||
|
||||
@@ -47,17 +47,22 @@ class SectorCatalogueContentTest extends TestCase
|
||||
$before = [DB::table('desk_cases')->count(), DB::table('opportunities')->count(), DB::table('portal_resources')->count()];
|
||||
|
||||
$props = $this->get('/sectores')->assertOk()->inertiaProps();
|
||||
$this->assertSame(array_column($props['sectors'], 'id'), array_column(array_column($props['sectorDetails'], 'sector'), 'id'));
|
||||
foreach ($props['sectorDetails'] as $detail) {
|
||||
$single = $this->get('/sectores/'.$detail['sector']['slug'])->assertOk()->inertiaProps();
|
||||
$this->assertSame($single['sector'], $detail['sector']);
|
||||
$this->assertSame($single['sectorEntry'], $detail['sectorEntry']);
|
||||
$this->assertSame($single['opportunities'], $detail['opportunities']);
|
||||
$this->assertIsArray($detail['sectorEntry']['articles']);
|
||||
$this->assertIsArray($detail['sectorEntry']['relations']);
|
||||
$this->assertIsArray($detail['sectorEntry']['locations']);
|
||||
$this->assertArrayNotHasKey('sectorDetails', $props);
|
||||
$ids = array_column($props['sectors'], 'id');
|
||||
$this->assertSame($ids, array_values(array_unique($ids)));
|
||||
foreach ($props['sectors'] as $card) {
|
||||
$this->assertSame(\App\Services\SectorOrganization::href($card['slug']), $card['url']);
|
||||
$this->assertStringNotContainsString('#', $card['url']);
|
||||
$single = $this->get($card['url'])->assertOk()->inertiaProps();
|
||||
$this->assertSame('sector', $single['section']);
|
||||
$this->assertSame($card['id'], $single['sector']['id']);
|
||||
$this->assertArrayNotHasKey('sectorDetails', $single);
|
||||
$this->assertArrayNotHasKey('sectors', $single);
|
||||
$this->assertIsArray($single['sectorEntry']['articles']);
|
||||
$this->assertIsArray($single['sectorEntry']['relations']);
|
||||
$this->assertIsArray($single['sectorEntry']['locations']);
|
||||
}
|
||||
$entry = collect($props['sectorDetails'])->firstWhere('sector.id', $withoutGuide->id)['sectorEntry'];
|
||||
$entry = $this->get('/sectores/'.$withoutGuide->slug)->assertOk()->inertiaProps()['sectorEntry'];
|
||||
$this->assertSame([], $entry['articles']);
|
||||
$this->assertSame('/minhas-oportunidades/create?sector_id='.$withoutGuide->id, $entry['register_href']);
|
||||
$this->assertNotNull($entry['start_href']);
|
||||
@@ -80,10 +85,11 @@ class SectorCatalogueContentTest extends TestCase
|
||||
}
|
||||
config(['investor-path.enabled' => false, 'portal.profile_access_enabled' => false]);
|
||||
$props = $this->get('/sectores')->assertOk()->inertiaProps();
|
||||
$ids = array_column(array_column($props['sectorDetails'], 'sector'), 'id');
|
||||
$this->assertArrayNotHasKey('sectorDetails', $props);
|
||||
$ids = array_column($props['sectors'], 'id');
|
||||
$this->assertNotContains($unpublished->id, $ids);
|
||||
$this->assertNotContains($inactive->id, $ids);
|
||||
$detail = collect($props['sectorDetails'])->firstWhere('sector.id', $public->id);
|
||||
$detail = $this->get('/sectores/'.$public->slug)->assertOk()->inertiaProps();
|
||||
$this->assertSame([$slugs['published']], array_column($detail['opportunities'], 'slug'));
|
||||
$this->assertNull($detail['sectorEntry']['start_href']);
|
||||
$this->assertNull($detail['sectorEntry']['register_href']);
|
||||
@@ -92,4 +98,29 @@ class SectorCatalogueContentTest extends TestCase
|
||||
$this->get('/sectores/'.$unpublished->slug)->assertNotFound();
|
||||
$this->get('/sectores/'.$inactive->slug)->assertNotFound();
|
||||
}
|
||||
public function test_selecting_a_sector_keeps_opportunities_scoped_on_reload_and_return(): void
|
||||
{
|
||||
$a = $this->sector();$b = $this->sector();
|
||||
foreach ([$a, $b] as $sector) {
|
||||
$slug = 'qa-isolated-'.Str::lower(Str::random(12));
|
||||
Opportunity::create(['sector_id'=>$sector->id, 'reference'=>$slug, 'title'=>$slug, 'slug'=>$slug,
|
||||
'summary'=>'Synthetic scoped opportunity', 'status'=>'published', 'published_at'=>now()->subDay()]);
|
||||
}
|
||||
$index = $this->get('/sectores')->assertOk()->inertiaProps();
|
||||
foreach ([$a, $b, $a] as $sector) {
|
||||
$url = collect($index['sectors'])->firstWhere('id', $sector->id)['url'];
|
||||
$first = $this->get($url)->assertOk()->inertiaProps();
|
||||
$reload = $this->get($url)->assertOk()->inertiaProps();
|
||||
$this->assertSame($first['sector'], $reload['sector']);
|
||||
$this->assertSame($first['opportunities'], $reload['opportunities']);
|
||||
$this->assertSame($sector->id, $first['sector']['id']);
|
||||
$this->assertSame(Opportunity::where('sector_id',$sector->id)->pluck('slug')->all(), array_column($first['opportunities'],'slug'));
|
||||
$this->assertSame('/investimentos/a-partir-do-setor/'.$sector->slug, $first['sectorEntry']['start_href']);
|
||||
$this->get($first['sectorEntry']['start_href'])->assertRedirect('/login');
|
||||
$returned = $this->get('/sectores')->assertOk()->inertiaProps();
|
||||
$this->assertSame($index['sectors'], $returned['sectors']);
|
||||
$this->assertArrayNotHasKey('sectorDetails', $returned);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"fixture_notice": "Synthetic public projection of accepted API QA consumers;no profiles,real pilots,credentials,dossier or personal data. Test input only;never import into application data.",
|
||||
"consumer_contexts": [
|
||||
{
|
||||
"prefill": {
|
||||
"simulator": {
|
||||
"context_applicability_snapshot": "{\"version\":1,\"consumer_opportunity\":\"opportunity:399\",\"opportunity_choices\":[{\"opportunity\":{\"key\":\"opportunity:399\",\"title\":\"SYNTHETIC QA — Cahora Bassa\",\"version\":2,\"analysis\":{\"proactive\":{\"need\":\"SYNTHETIC QA necessidade por verificar.\",\"basis\":\"Fixture pública sintética; não é evidência de procura local.\",\"group\":\"ideas\",\"stage\":\"Apoio — correspondência real por confirmar\",\"state\":\"hypothesis\",\"notice\":\"A ausência de registo não comprova ausência de oferta. Proximidade não comprova contrato, participação, energia acessível, terra disponível ou benefício fiscal. Necessidade confirmada não comprova viabilidade comercial; hipótese de fornecimento não é encomenda.\",\"version\":1,\"chain_id\":null,\"evidence\":[{\"id\":\"3587d2e4-7428-4cd7-994b-60607b20d7da\",\"scope\":\"Cahora Bassa — contexto piloto\",\"period\":\"Exercício2026 — cenário sintético\",\"source\":\"SYNTHETIC QA exemplar público fictício Cahora Bassa\",\"locator\":\"Fixture QA, linha1\",\"purpose\":\"local\",\"category\":\"infrastructure\",\"coverage\":\"Cobertura fictícia; informação real por confirmar\",\"statement\":\"SYNTHETIC QA: capacidade fictícia em Cahora Bassa; não é diagnóstico económico real.\",\"verified_on\":\"2026-10-27\"}],\"proposal\":\"SYNTHETIC QA solução em preparação.\",\"relations\":[],\"limitations\":\"Sem validação económica, contrato, terra ou energia garantidos.\",\"next_action\":\"Confirmar evidências reais antes de decidir.\",\"evidence_ids\":[\"3587d2e4-7428-4cd7-994b-60607b20d7da\"],\"economic_validation\":false,\"availability_confirmed\":false}}}}]}"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"prefill": {
|
||||
"simulator": {
|
||||
"context_applicability_snapshot": "{\"version\":1,\"consumer_opportunity\":\"opportunity:400\",\"opportunity_choices\":[{\"opportunity\":{\"key\":\"opportunity:400\",\"title\":\"SYNTHETIC QA — Gurué\",\"version\":2,\"analysis\":{\"proactive\":{\"need\":\"SYNTHETIC QA necessidade por verificar.\",\"basis\":\"Fixture pública sintética; não é evidência de procura local.\",\"group\":\"ideas\",\"stage\":\"Apoio — correspondência real por confirmar\",\"state\":\"hypothesis\",\"notice\":\"A ausência de registo não comprova ausência de oferta. Proximidade não comprova contrato, participação, energia acessível, terra disponível ou benefício fiscal. Necessidade confirmada não comprova viabilidade comercial; hipótese de fornecimento não é encomenda.\",\"version\":1,\"chain_id\":null,\"evidence\":[{\"id\":\"1421bb80-78c0-40c9-9de0-f45e18c5a093\",\"scope\":\"Gurué — contexto piloto\",\"period\":\"Exercício2026 — cenário sintético\",\"source\":\"SYNTHETIC QA exemplar público fictício Gurué\",\"locator\":\"Fixture QA, linha1\",\"purpose\":\"local\",\"category\":\"infrastructure\",\"coverage\":\"Cobertura fictícia; informação real por confirmar\",\"statement\":\"SYNTHETIC QA: capacidade fictícia em Gurué; não é diagnóstico económico real.\",\"verified_on\":\"2026-10-27\"}],\"proposal\":\"SYNTHETIC QA solução em preparação.\",\"relations\":[],\"limitations\":\"Sem validação económica, contrato, terra ou energia garantidos.\",\"next_action\":\"Confirmar evidências reais antes de decidir.\",\"evidence_ids\":[\"1421bb80-78c0-40c9-9de0-f45e18c5a093\"],\"economic_validation\":false,\"availability_confirmed\":false}}}}]}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,7 +6,7 @@ test('absent proactivity is a no-op for accepted dossiers',()=>{assert.deepEqual
|
||||
test('each idea retains origin,source,need,limits without summing or inventing economic values',()=>{const choices=[{opportunity:source(1,'A')},{opportunity:source(2,'B')}],d={context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:choices})},r=proactiveInvestmentRows(d);assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,2);assert.match(JSON.stringify(r),/opportunity:1/);assert.match(JSON.stringify(r),/opportunity:2/);assert.match(JSON.stringify(r),/Hipótese analítica/);assert.match(JSON.stringify(r),/não é zero/);assert.equal(d.context_applicability_snapshot,JSON.stringify({version:1,opportunity_choices:choices}));});
|
||||
test('consumer selection only reports its idea even when other source contexts are present',()=>{const choices=[{opportunity:source(1,'A')},{opportunity:source(2,'B')}],r=proactiveInvestmentRows({context_opportunity:'opportunity:2',context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:choices})});assert.doesNotMatch(JSON.stringify(r),/opportunity:1/);assert.match(JSON.stringify(r),/opportunity:2/);});
|
||||
test('explicit consumer snapshot is retained and repeat references do not duplicate report rows',()=>{const a=source(1,'A');let r=proactiveInvestmentRows({context_opportunity_snapshot:JSON.stringify({choice:{opportunity:a}})});assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,1);r=proactiveInvestmentRows({context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:[{opportunity:a},{opportunity:a}]})});assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,1);});
|
||||
test('new API-recovered multi idea snapshot produces an independently scoped report',()=>{const d=JSON.parse(fs.readFileSync('outputs/proactive-investment-20261027/recovered-context.json','utf8'));const r=d.consumer_contexts.flatMap(c=>proactiveInvestmentRows(c.prefill.simulator));assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,2);assert.doesNotMatch(JSON.stringify(r),/PRIVATE-QA-/);fs.writeFileSync('outputs/proactive-investment-20261027/recovered-report-rows.json',JSON.stringify(r,null,2));});
|
||||
test('portable API consumer snapshot produces an independently scoped report',()=>{const d=JSON.parse(fs.readFileSync(new URL('./fixtures/proactive-api-consumers.json',import.meta.url),'utf8'));const before=JSON.stringify(d);const perConsumer=d.consumer_contexts.map(c=>proactiveInvestmentRows(c.prefill.simulator));for(const rows of perConsumer)assert.equal(rows.filter(x=>x[1]==='Origem da análise e ideia').length,1);const r=perConsumer.flat();assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,2);assert.match(JSON.stringify(perConsumer[0]),/opportunity:399/);assert.doesNotMatch(JSON.stringify(perConsumer[0]),/opportunity:400/);assert.match(JSON.stringify(perConsumer[1]),/opportunity:400/);assert.doesNotMatch(JSON.stringify(perConsumer[1]),/opportunity:399/);assert.doesNotMatch(JSON.stringify(r),/PRIVATE-QA-/);assert.equal(JSON.stringify(d),before);});
|
||||
|
||||
test('resources,assumptions and selected relationships are retained in the existing dossier report',()=>{const a=source(7,'A');Object.assign(a.analysis.proactive,{resources:'QA recurso declarado',assumptions:'QA pressuposto explícito',conditions:'QA condição',relations:[{kind:'project',target_id:'QA-reference',label:'QA projecto existente',relationship:'hypothesis',basis:'QA fundamento público'}]});const draft={context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:[{opportunity:a}]})},rows=buildProjectDossierRows(draft);assert.match(JSON.stringify(rows),/QA pressuposto explícito/);assert.match(JSON.stringify(rows),/QA projecto existente/);assert.match(JSON.stringify(rows),/sem contrato, acesso ou participação presumidos/);});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user