5.7 KiB
Dropdowns e associação territorial — aplicados em 29/09/2026
Actualização que substitui as contagens e limites da primeira entrega abaixo: corrigido o uso de códigos como nomes na extracção do Excel. Actualmente há 11 províncias, 148 distritos, 437 postos e 1.324 localidades com designações explícitas. Os filtros públicos e os formulários de criação foram integrados; as seis oportunidades existentes têm associação provincial. Histórico e lacunas restantes em delivery-gaps.md. As secções abaixo conservam a descrição da primeira entrega, anterior a esta correcção.
Onde utilizar
Aceder como gestor a Gestão → Localizações dos investimentos, endereço /management/territory-associations. Escolher tipo e investimento; seleccionar Província → Distrito → Posto administrativo → Localidade e clicar Guardar localização. Pode guardar só até ao nível conhecido, ou limpar a província e guardar para remover a associação.
O mesmo painel está nas fichas de edição de oportunidades, clusters e projectos, e na gestão de zonas (ZEE, ZFI e parques industriais). A página central também permite associar corredores. Numa ficha nova, guardar primeiro o registo para obter o identificador. A associação territorial tem botão e versão próprios, separados do formulário principal.
Campos textuais legados de província/distrito permanecem por compatibilidade; não são a relação geográfica guardada pelo novo painel. Os filtros do catálogo público ainda usam o contrato anterior. Este incremento entrega a associação na gestão, não a migração de todos os filtros públicos.
Dados efectivamente carregados
Fonte: C:/Mac/Home/Documents/eBAU/cartografia_moz.xlsx, SHA-256 964a187ad32ea553b9e112cd159caa90b900050c42b7329594a75bcd798a96ff, indicada pelo utilizador e utilizada ao abrigo das suas instruções de aplicação dos dados. Extraídas apenas as colunas explícitas Provincia/Distrito/Posto_Administrativo/Localidade. O PDF INE com colunas desalinhadas não foi usado para construir estas relações.
Carregadas 1.990 entradas em geo_locations: 1 país, 11 províncias, 150 distritos, 451 postos administrativos e 1.377 localidades. Onze linhas apresentam lacunas: níveis descendentes de uma lacuna não foram inferidos; os níveis anteriores completos puderam ser aproveitados. Identificadores determinísticos deduplicam nome/tipo/pai, preservando localidades homónimas em pais diferentes. Os códigos XLSX-… são internos, não códigos oficiais INE. Não foram geradas coordenadas.
Origem cartografia-workbook, classificação interna. Estas referências são consultáveis por gestores; não se apresentam como territórios publicados pelo workflow institucional. Nenhum investimento real recebeu uma localização inferida automaticamente. Os campos de associação estão disponíveis para seleccionar e guardar o local conhecido.
Artefactos privados: storage/app/private/territory-workbook-candidates.json contém candidatos e linhas sinalizadas. Preparação reproduzível: tools/prepare-territory-workbook.py; carga transaccional: tools/import-territory-workbook.php. Segunda execução criou zero entradas, confirmando idempotência. Os scripts verificam o checksum da fonte e não substituem registos divergentes.
Persistência e endpoints
Migration 2026_09_28_160000_investment_primary_territory aplicada: primary_territory_id com FK restritiva para geo_locations e territory_version em opportunities, projects, economic_clusters, development_corridors e investment_zones. A localização principal mais específica é guardada; os ascendentes são obtidos pelas relações parent_id. As relações múltiplas legadas são preservadas.
- GET
/management/territory-associations: página de gestão. - GET
/management/territory-subjects?kind=clusters&q=…: investimentos paginados, 50/página. - GET
/management/territory-options?type=district&parent_id=…&q=…: opções paginadas, 100/página. - GET
/management/territories/{kind}/{id}: versão e caminho actual. - POST
/management/territories/{kind}/{id}:{ "version": 0, "path": ["UUID-província", "UUID-distrito"] }.
Tipos: opportunities, projects, clusters, corridors, zones. Sessão autenticada, email verificado, permissão manage-portal e CSRF nas escritas. Escrita em zonas mantém requisito MFA. Servidor rejeita níveis fora de ordem, pais incompatíveis, referências apagadas e versões desactualizadas; mantém FK e auditoria da gravação. Opções não expõem classificações confidenciais/restritas. Pesquisa tem debounce e cancelamento de pedidos anteriores. Selecção arquivada preexistente é mostrada sem substituição silenciosa.
Verificação e recuperação
- Backup/restauro verificado antes da aplicação:
storage/app/private/zones-backup-20260929-003609/, 113 tabelas reconciliadas. - Suite completa: 170 testes / 1.722 verificações aprovadas antes das últimas verificações da página central; testes focados depois: 2 testes / 18 verificações aprovadas.
- PHPStan, Pint, TypeScript, lint dos componentes novos e build aprovados.
- Navegador QA com dados sintéticos: cascata completa, gravação e reset dos descendentes aprovados; 390/1.440 px sem overflow, zero erros JavaScript. Script
tools/territory-browser.mjs, conta sintética e papel de gestor configurados exclusivamente no servidor QA durante a execução.
Rollback da migration recusa associações existentes. Com dados, preservar o backup e corrigir progressivamente. Não apagar geo_locations para desfazer a interface: são referências partilhadas. Não houve publicação automática, georreferenciação ou mudança de papéis de utilizadores da aplicação local.