6.3 KiB
Ponte de compatibilidade — 29/09/2026
Actualização: reexecução dos anexos D/E, com migration 005 aplicada, dry-run, saída estrita de reconciliação e testes de privilégios numa conta isolada não-superuser. As limitações de activação abaixo mantêm-se.
Estado da entrega
Incremento aplicado e testado localmente. O anexo D ainda não está integralmente concluído. public continua como autoridade de leitura e escrita dos formulários. Não há escrita dupla, migração de negócios, publicação nem activação de leitura canónica.
Inventário confirmado
public.users.id e public.sectors.id são bigint; public.existing_businesses.id, mne.parties.id e mne.existing_businesses.id são UUID. O formulário privado não possui campo sectorial. A associação territorial de mne.locations continua a usar os identificadores inteiros de investmoz, sem nova taxonomia.
004_mne_compatibility.sql cria seis tabelas: identity_links, sector_links, business_links, compatibility_checkpoints, compatibility_rejections e compatibility_controls. Todas as novas FK têm cobertura por índices completos das constraints UNIQUE. O script verifica pré-condições, usa bloqueio consultivo, recusa tabelas de ponte com definição divergente e pode ser reaplicado. Não altera os ficheiros 001–003.
A coluna UUID mne.parties.user_id é mantida para reversibilidade, mas a nova constraint exige NULL. Contas autenticadas passam a ser resolvidas exclusivamente através de identity_links. A migration recusa dados antigos nesse campo em vez de tentar converter bigint em UUID. Pessoas podem existir sem conta; IdentityResolver só devolve uma ligação activa, vigente, a uma pessoa não arquivada. O resolver não autentica nem atribui permissões.
Aplicação e backfill
BusinessRepository, LegacyBusinessRepository e CompatibleBusinessRepository estão ligados aos pontos de consulta dos controladores e dos quatro serviços privados. Políticas, bloqueios de escrita, versões e payloads HTTP existentes são preservados. Criação e gravação continuam nos modelos legados.
MneBusinessRepository é, por enquanto, um adaptador apenas para comparação de cinco campos: código, modalidade, estado, classificação e versão. Não implementa ainda a hidratação completa de um negócio nem substitui a autorização legada. SectorResolver v1 devolve UUIDs estáveis de ligação à taxonomia existente; não copia nomes ou cria sectores canónicos concorrentes.
php artisan mne:backfill-compatibility --batch=100
php artisan mne:reconcile-compatibility
Usar um PHP com extensão pgsql. O backfill faz transacção por lote, bloqueio consultivo, IDs determinísticos, checksums e checkpoint do último lote não vazio. Cada nova execução percorre novamente a origem, para detectar também alterações anteriores ao checkpoint. Dados modificados invalidam a reconciliação. Vínculos sem destino canónico ficam pendentes, com código, causa e responsável data-steward na fila de excepções. A resolução não é aceite automaticamente. O backfill não cria pessoas ou negócios canónicos.
Resultado local: 1 vínculo de identidade pendente, 12 vínculos sectoriais activos, 0 negócios, nenhuma chave em falta nem checksum divergente na execução. Há uma excepção de identidade não resolvida. A inexistência de negócios não conta como validação de uma migração real.
Comparação sombra e reversão operacional
A comparação só é agendada após autorização de consulta da ficha. Requer INVESTMOZ_MNE_COMPATIBILITY_SHADOW=true e o controlo shadow em compatibility_controls activado com referência de evidência e percentagem. Ambos estão desligados na instalação local. O consumidor é php artisan queue:work database --queue=mne-shadow; filas síncronas são recusadas. O evento contém apenas resultado e latência, sem payload, identificador ou mensagem de excepção. Desligar o controlo interrompe novos agendamentos; trabalhos já enfileirados continuam somente de leitura.
Comparação parcial igual não abre o gate de leitura canónica. canonical_read está reservado, sem adaptador de resposta completo habilitado. Alterar a flag não transfere leitura ou escrita. Não se apresentam métricas de fallback canónico como se essa capacidade já existisse.
O DOWN 004 recusa qualquer vínculo, checkpoint, rejeição, controlo activo ou pessoa dependente. Esta é a situação local após backfill: para reverter a estrutura, é necessário arquivar/reconciliar primeiro essas dependências. Para continuar a operar pelo legado não é necessário executar DOWN. O script não remove dados de negócios nem históricos.
Evidência
- Backup/restauro verificado de 204 tabelas antes de 004:
storage/app/private/mne-integrity-backup-20260929-191334/. - Aplicação:
storage/app/private/mne-compatibility-20260929-191400/; contagens de 91 tabelas anteriores preservadas; schema mne passa de 70 para 76 tabelas. tools/test-mne-compatibility.php: 001–004 em base isolada, repetição, DOWN/reaplicação, backfill repetido, negócio sintético, acesso proprietário/terceiro, unicidade, FK, identidade revogada, sector desconhecido/alterado e recusa de estrutura divergente. Transacção integralmente revertida.- Suite completa: 178 testes / 1820 verificações aprovados antes do teste adicional de isolamento da sombra. Esse teste adicional passou com 5 verificações.
- PHPStan aprovado. Contrato OpenAPI privado preservado. Sem alterações de interface; navegador não validado neste incremento.
Gates ainda não satisfeitos
- Correspondência canónica da identidade pendente e resolução formal das excepções.
- Campo/relação sectorial nos negócios e reconciliação real de proprietários, estados e conteúdo completo.
- Adaptador de leitura canónica completo, comparação integral, rollout e fallback testados.
- Separação owner/migrator/runtime e testes de privilégios: a ligação local actual é superuser. Os triggers existem, mas esta conta pode desactivá-los. Nenhuma garantia de privilégio mínimo é declarada.
- Concorrência com duas sessões, jornadas de navegador nos dois modos, notificações/SLA e deduplicação ponta a ponta.
Permanecem bloqueadas a transferência de escrita, a publicação e a produção. Não foi criado commit Git.