# Cartografia GIS — execução incremental **Mapa interactivo:** [implementação, testes e cobertura real](interactive-map.md). Catálogo e fichas usam marcadores, zoom e filtros reactivos. A base contém seis oportunidades públicas e zero coordenadas de local; o critério de georreferenciação integral ainda não está cumprido. **Correcção de 29/09/2026:** a extracção anterior confundiu códigos com nomes. Reparados os nomes a partir de «Designação» e arquivadas 69 referências sem definição inequívoca. Dropdowns públicos e filtros ligados às associações agora disponíveis em `/oportunidades` e `/zonas`. Contagens válidas: 11 províncias, 148 distritos, 437 postos, 1.324 localidades. Ver [omissões, correcções e trabalho restante](../delivery-gaps.md). **29/09/2026 — dropdowns aplicados:** [selecção em cascata e associação aos investimentos](investment-dropdowns.md). Disponível em `/management/territory-associations` e nas fichas de gestão. Excel carregado: 11 províncias, 150 distritos, 451 postos e 1.377 localidades; relações guardadas por UUID. Aceitação do responsável aplicada ao pacote INE: declaração de dados validados e autenticados registada na auditoria local e vinculada aos checksums. Ver [decisão e limites técnicos](ine-import-status.md#aceitação-expressa-do-responsável--aplicada). A carga de territórios continua dependente da resolução das colunas desalinhadas. Novo anexo: [preparação da importação INE, evidências e fases pendentes](ine-import-status.md). Auditoria CSV e extracção para revisão entregues; a carga territorial integral continua por implementar. Actualização: recebido o novo documento do modelo territorial, com autorização integral. Foi implementado o [núcleo do registo territorial e APIs editoriais](territorial-mvp.md), sem duplicar a identidade de geo_locations. O histórico abaixo descreve a auditoria anterior; não representa a cobertura integral do novo MVP. ## Inspecção do Excel indicado pelo utilizador - SHA-256: `964a187ad32ea553b9e112cd159caa90b900050c42b7329594a75bcd798a96ff`; tamanho 879.583 bytes. - Uma folha `Sheet1`, intervalo `A1:H20408`, 20.408 linhas presentes, incluindo cabeçalho; 20.407 linhas subsequentes. - Cabeçalhos: `ID`, `Provincia`, `Distrito`, `Posto_Administrativo`, `Localidade`, `Bairro_Urbano`, `Aldeia_Quarteirao`, `Designacao`. - Sem coluna de coordenadas/WKT/GeoJSON nos cabeçalhos. Não gerar coordenadas nem presumir que `ID` seja código oficial. - Auditoria: 20.408 linhas pendentes; nenhum duplicado de linha inteira detectado. Isto não prova unicidade de localidades ou chaves. - Proprietário, versão documental, classificação e CRS não comprovados. Para uso exclusivamente alfanumérico, a aplicabilidade do CRS deve ser decidida no mapeamento; não atribuir EPSG:4326 a nomes de locais. - Manifesto de inspecção e relatório por linha/campo: `storage/app/private/gis-audit-20260928/`. Autorização de inspecção: indicação explícita do utilizador. Não foi fabricado proprietário ou mandato de publicação. - PHPStan aprovado após implementação; 4 testes unitários/13 verificações aprovadas. O auditor não abre ligação à base de dados. Actualizado em 28/09/2026. Branch: `feature/gis-phase-0`. O dono do produto autorizou a progressão automática por todas as fases nesta sessão, depois de fornecer o prompt GIS. Esta autorização substitui a espera entre fases; não constitui validação institucional de uma fonte, mandato de uma entidade ou autorização de divulgação de uma geometria. ## Estado por fase | Fase | Estado e recomendação | Evidência / condição | | ------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 0 — inventário | Parcial; Go condicionado para artefactos preparatórios | Código, índices, mapas e controlos inventariados abaixo. Excel localizado e inspeccionado após indicação do utilizador; documento original A.31 ainda não localizado. | | 1 — modelo e regras | Proposta de reconciliação; Go condicionado | Reutilizar o cadastro existente, sem uma segunda base GIS. Reconciliar a proposta com A.31 antes de fechar o modelo. | | 2 — serviços e importação | Auditor de XLSX implementado; restante pendente | Auditor local sem ligação à BD, com checksum, autorização de inspecção, limites e quarentena. Não é importador. | | 3 — mapas e CRM | Base preexistente parcial; No-Go para declarar conformidade GIS | Catálogo e zonas têm mapas/listas; autorização geral, precisão e origem completa mapa→CRM ainda incompletas. | | 4 — piloto e UAT | Testes sintéticos do auditor aprovados; No-Go para piloto real | Excel inspeccionado; faltam proveniência, classificação, mapeamento e amostras oficiais. | | 5 — staging/produção | No-Go | Sem UAT, carga, matriz de mandatos, fontes e ensaio operacional do módulo completo. Nenhum deploy realizado. | Não foram executadas migrations, importações, alterações de dados ou publicação de mapas nesta entrega GIS. O avanço técnico independente foi executado; as operações dependentes de fontes ausentes continuam pendentes, sem presumir os respectivos valores. ## Diagnóstico e evidências existentes - `database/migrations/2026_09_24_003000_investmoz_geography.php`: `geo_locations` e `geo_geometries`, UUID, classificação, versão, soft delete e hierarquia. Tipos de localização limitados a país, província, distrito, município e local. Geometrias 2D/4326, tipos controlados, ST_IsValid, não vazias e limites globais. - `2026_09_24_004000_investmoz_projects.php`: `project_locations` já suporta vários projectos/locais e papéis. Faltam validade e controlo de publicação da relação conforme novo prompt. - `2026_09_24_012000_investmoz_indexes.php`: GiST, chaves de origem, código/tipo de localização e unicidade de geometria por local/tipo activo. A última regra precisa de reconciliação para permitir versões e representações internas/públicas distintas. - `InvestmentCatalogue::map`: apenas oportunidades publicadas, localização/geometria públicas e não apagadas, pontos e limite 1000. **Lacuna de segurança RF-GEO-005/006:** classificação pública não comprova autorização institucional vigente; não existe nível de precisão aplicável neste caminho. Não carregar dados geográficos reais neste caminho até resolver a lacuna. Não foi demonstrada exposição de dados reais nesta execução. - `InvestmentZoneGeometryController`: GeoJSON, validação PostGIS, revisão independente por utilizador designado, suspensão, fonte vigente quando associada, bbox e limite 100. A simplificação geométrica não substitui generalização por confidencialidade. Não reutilizar esta autorização como autorização geral de localizações. - `config/investment-zones.php`, `RequireZoneMfa` e rotas de zonas: perfis configuráveis de revisão GIS/publicação, gestor verificado e MFA. O cadastro não prova mandato institucional. Não se enumeraram emails, credenciais ou outros dados pessoais. - `resources/js/pages/investment/catalogue.tsx` e `zone-map.tsx`: lista/mapa e alternativa textual; falta experiência GIS transversal, comparação territorial e mapa interno completo. - CRM: `investment_submission_zones` preserva zona/versão/intenção. Não preserva ainda a totalidade localização/camada/campanha/corredor/cluster exigida para conversão pelo mapa. - APIs existentes: `/api/v1/investment/map` e `/api/v2/investment/zone-map`; não equivalem aos novos contratos `/api/v1/geo/*` e `/api/v1/maps/*`. Pesquisaram-se nomes de ficheiros DOCX/XLSX/PDF no repositório (incluindo ignorados, excluindo dependências, `.git` e backups privados) e na pasta de anexos fornecida pelo utilizador. Na pesquisa inicial não se localizaram o documento original nem o Excel; posteriormente o utilizador indicou a localização do Excel, que foi inspeccionado. Documentação derivada menciona A.31; essas menções não substituem a secção original. Não se pesquisou indiscriminadamente o disco pessoal nem o servidor da outra máquina. ## Rastreabilidade e plano técnico Os identificadores TECH abaixo são **provisórios locais**, não transcrição da A.31. Não se criou uma segunda sequência RF-GIS. | RF-GEO | TECH provisório | Modelo / serviço previsto | API / evento previsto | Frontend e teste necessário | Estado | | ------ | -------------------- | --------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------- | --------------------------------- | | 001 | TECH-GEO-CAD | Adaptar geo_locations, proveniência, validade, revisão imutável | locations GET/POST/PATCH; location.revised | Cadastro; códigos duplicados, ciclos e concorrência | Base parcial | | 002 | TECH-GEO-REL | Adaptar project_locations, papel, período, natureza | Relações explicitadas no contrato de localização | Vários projectos sem duplicar geometria | Base parcial | | 003 | TECH-GEO-MULTI | Localização principal por período; secundárias | Ficha do projecto/localizações | Projecto multiterritorial; unicidade principal | Parcial | | 004 | TECH-GEO-VALID | Geometria versionada, CRS original, método de transformação | geometries; validate; geometry.validated | Painel; SRID ausente, inválida, vazia e territorialmente divergente | PostGIS/zonas parcial | | 005 | TECH-GEO-AUTH | geo_authorizations, documento, entidade e validade | authorize-publication; authorization.revoked | Painel de autorização; expiração/revogação em todos os caminhos | Geral em falta | | 006 | TECH-GEO-PRECISION | Representação autorizada separada da geometria interna | Serviço comum a mapas, pesquisa, exportação e cache | Não reconstrução por bbox, raio, exportação ou respostas combinadas | Em falta | | 007 | TECH-GEO-INSTITUTION | map_validation_requests, protocolo, anexos, decisões | validation.requested/decided | Painel interno; contestação impede publicação | Em falta | | 008 | TECH-GEO-SUSPEND | Suspensão transaccional e tarefa de revalidação | suspend; map.suspended | Revogação imediata; cache e links históricos | Zonas parcial | | 009 | TECH-GEO-SEARCH | GiST, filtros aplicados à representação autorizada | maps/search, projects, corridors, clusters, nearby | Lista sincronizada; limites, paginação, teclado e carga | Parcial | | 010 | TECH-GEO-IMPORT | Batch, checksum, manifesto, relatório por linha, idempotência | import-jobs, errors, reconcile; import.reconciled | Upload privado; ZIP/XML hostil, duplicados e reconciliação | Auditor preparatório implementado | ## Modelo, contratos e autorização propostos — Fase 1 Adaptar as três tabelas existentes; acrescentar camadas, autorizações, pedidos de validação, revisões e batches apenas depois de comparar A.31. Não atribuir código territorial pelo nome nem fundir localidades por semelhança textual. Preservar sistema de referência original; ausência coloca em quarentena. Nunca calcular ponto aproximado ou centroide como autorização implícita de divulgação. Uma política comum de publicação deverá exigir local e geometria validados, ausência de contestação, autorização/documento vigentes, versão correspondente e representação permitida. Pesquisa espacial pública deve operar sobre essa representação, não sobre a exacta restrita. Cache tem de invalidar em revisão, suspensão, revogação e expiração. Logs não devem conter coordenadas, conteúdo dos anexos ou dados privados de pontos focais. APIs de gestão propostas: autenticação, gestor verificado, MFA, papel específico configurado, CSRF, limites de payload, correlation_id gerado, erro normalizado e comparação de versão. APIs públicas precisam de política de leitura pública explícita; o prompt pede autenticação em todos os endpoints e também mapa público. Registar esta divergência para resolução na especificação, sem inventar um token público com privilégios. Eventos devem transportar identificadores/versões, não geometria restrita, através da outbox existente. Conversão pelo mapa deverá guardar referências verificadas no servidor e consentimento específico, nunca confiar num contexto arbitrário enviado pelo navegador. Pedido de reunião significa pedido de contacto até existir agenda integrada; não confirmar reunião automaticamente. ## Auditor XLSX — reprodução Ficheiros criados: `app/Services/CartographyWorkbookAudit.php`, `tools/cartography-audit.php`, `tests/Unit/CartographyWorkbookAuditTest.php`, este documento e `source-manifest.example.json`. Definir `INVESTMOZ_CARTOGRAPHY_FILE` e `INVESTMOZ_CARTOGRAPHY_MANIFEST` para ficheiros autorizados locais, fora do directório público; executar `php tools/cartography-audit.php`. O caminho não está codificado no projecto. O manifesto exige checksum SHA-256 exacto e evidência de autorização **de inspecção**, distinta de publicação. Proprietário, versão, recepção, classificação e CRS ausentes ficam explicitamente pendentes. O relatório deve ser guardado em armazenamento privado, pois os nomes de folhas também podem ser sensíveis. Limites: 20 MB comprimidos, 50 MB declarados descomprimidos, 1000 entradas ZIP e 50000 linhas presentes. Leitura XML sem entidades/DTD nem acesso à rede. Fórmulas não são executadas; referências externas não são resolvidas. Relatório contém folha/linha/campo, duplicados exactos e anomalias, sem valores das células. Todas as linhas ficam pendentes ou duplicadas; o auditor não certifica validade territorial. Células omitidas não são reconstruídas; datas, unidades, separador decimal, cabeçalhos e chaves ainda exigem mapeamento autorizado. CRS declarado não é prova do CRS real. Teste: `php vendor/bin/phpunit tests/Unit/CartographyWorkbookAuditTest.php --do-not-cache-result`. Resultado observado: **4 testes, 13 verificações aprovadas**, sem Laravel/BD, apenas XLSX sintético temporário. Cobertura: checksum divergente, autorização ausente, entidade XML externa, duplicados, fórmula, confidencialidade do relatório e quarentena por CRS ausente. Executado também sobre o Excel indicado, conforme resultado abaixo; não é certificação de qualidade do corpus nem de GIS completo. ## Migrations, rollback e decisões pendentes Nenhuma migration criada ou executada nesta entrega. Futuras migrations devem ser aditivas, testadas em BD isolada e precedidas de backup/restauro e reconciliação no destino. Não usar DROP EXTENSION nem CASCADE destrutivo. Rollback de tabelas com evidência ou histórico deve recusar perda de dados; preferir suspensão e correcção progressiva. Reversão desta entrega: retirar apenas os três ficheiros novos de código/teste do auditor e os seus documentos, depois de confirmar ausência de alterações posteriores. Não reverter o trabalho anterior do portal. A branch foi criada sobre `main`, mantendo as alterações de interface já em curso. Pendências humanas concretas: localização e versão da A.31; Excel e seu manifesto; proprietário e autorização de uso; CRS e mapeamento de colunas; entidades e mandatos de validação; níveis de divulgação; resolução da autenticação do mapa público. Estas pendências são de informação e validação institucional, não um novo pedido de autorização para desenvolver. Risco residual principal: endpoints preexistentes não estão certificados para as regras transversais do novo GIS. Produção e dados reais permanecem No-Go até fechar a política comum e os ensaios RF-GEO-005/006. A implementação integral solicitada ainda não está concluída.