Files
Investidor-V2/docs/investmoz/education/migration-proposal.md
T
nala 250ac35fd1
tests / ci (push) Canceled after 0s
first commit
2026-09-28 10:01:09 +02:00

60 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Proposta de migração Education
> Actualização: o repositório já contém a migration de recepção interna `2026_09_26_100000_education_intake.php`, ensaiada numa base temporária nesta revisão. Ver [relatório actual](implementation-status.md). O inventário abaixo é histórico e não comprova o esquema nem as contagens da base actual da aplicação.
Estado: **Proposta — Pendente de validação**. Este ficheiro não é uma migration executável. Não criar SQL activo para B02/B03 antes da decisão de modelo/identidade e autorização. Diagnóstico local read-only em 26/09/2026: as seis tabelas da migration Education existem e têm zero registos. Isso não prova ausência de fontes externas.
## Inventário e mapeamento
| Origem confirmada | Destino lógico | Transformação proposta | Rejeição/quarentena |
| ------------------------------------------------ | ------------------------------ | --------------------------------------------------------------------------- | ---------------------------------------------------- |
| skills.code/name | Skill canónica | Preservar UUID/código; sinónimos e versão em extensão | Código ambíguo, taxonomia desconhecida |
| occupations.code/name | Occupation | Preservar UUID; relacionar Skills por versão | Equivalência de nível sem prova |
| training_needs.quantity | Registo legado de necessidade | Manter o valor e a semântica original; só ligar a LabourDemand após revisão | Nunca assumir que quantity significa trabalhadores |
| training_needs.project_id/occupation_id/skill_id | Relações contextuais | Manter FKs; verificar consistência da cadeia | Órfão, projecto eliminado, fonte ausente |
| training_providers.organization_id/name/status | Provider canónico | Conservar candidate/approved/inactive | Nenhuma conversão approved → acreditada |
| courses.provider_id/code/title/status | Curso canónico | Manter UUID e vínculo; separar revisão curricular | Nenhuma conversão published → certificado |
| education_opportunities.course_id/datas/capacity | Oferta calendarizada existente | Preservar contrato actual | Não reutilizar como projecto de construção de centro |
| Documentos/fontes externos não inventariados | Área de recepção proposta | Fonte, proprietário, autorização, checksum, versão, unidade e data | Sem autorização não importar |
## Vagas técnicas propostas
| Vaga | Conteúdo lógico aditivo | Pré-condição | Reconciliação | Reversão |
| ---- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| M0 | Snapshot do catálogo, colunas, FKs, índices, triggers, consumidores e permissões | Inventário aprovado; backup base/documentos/configuração verificado | Contagens, hashes por conteúdo normalizado e manifesto | Nenhuma escrita |
| M1 | Extensões de fonte, validade e versão de taxonomia; relações ocupação–competência e curso–competência | Taxonomia/Shared confirmados | 100% UUID preservados, zero órfãos; decisão de unicidade | Desactivar leitores novos; conservar histórico |
| M2 | LabourDemand e relações contextuais, sem renomear training_needs | B02/B03 resolvidos | Quantidades/unidades/períodos iguais à fonte aprovada; rejeições explicadas | Parar escritores novos; não dropar dados |
| M3 | Capacidade por período/pool e snapshots SkillGap | Regras e fonte de disponibilidade aprovadas | Contagem de pools/alocações; zero dupla contagem | Reverter exposição e workers; snapshots preservados |
| M4 | Identidade de investimento educativo e vínculo a Opportunity | Decisão formal B02 | Cada oportunidade tem promotor, lacuna/versão e fonte; sem duplicação comercial | Despublicar e suspender encaminhamento |
| M5 | Projecções de leitura, contratos e eventos | Idempotência e mandatos testados | Reconciliar outbox/inbox e consumidor; zero estados oficiais promovidos | Feature flag desligada; drenar ou reter fila conforme plano |
Nomes físicos novos, índices, rotas e policies são propostas, não factos confirmados. Antes de converter para Laravel migrations: revisar catálogo real completo e tipos, validar envelope, constraints e impacto nas queries/consumidores. Não acrescentar estado oficial a enum editorial. Preferir extensões opcionais inicialmente; backfill separado e validado antes de NOT NULL. A idempotência da criação estrutural usa o ledger de migrations; não esconder divergência com IF NOT EXISTS indiscriminado.
## Pseudocódigo do importador, não executável
```text
exigir fonte autorizada + versão do mapeamento aprovada + feature flag de ensaio
para cada lote:
verificar checksum, unidades, datas, direitos e chaves externas
normalizar apenas segundo taxonomia aprovada
rejeitar ambíguos para quarentena com motivo e referência, sem PII em logs
numa transacção:
procurar por sistema_origem + id_externo + versão
se versão igual e checksum igual: no-op
se versão igual e conteúdo diferente: conflito, não sobrescrever
se versão menor: rejeitar regressão
se versão maior: preservar snapshot e aplicar decisão de precedência
nunca copiar acreditação/certificação como confirmada sem decisão externa verificada
escrever auditoria e recibo do lote
emitir relatório de aceites/rejeitados/conflitos e totais por unidade/período
aprovar reconciliação antes de activar leitores públicos
```
## Ensaio, backup e aceitação
Usar ambiente PostgreSQL/PostGIS isolado, primeiro dados sintéticos e depois cópia anonimizada autorizada. Zero dados pessoais reais em fixtures. Comparar antes/depois: contagens, somas por unidade e moeda, chaves, hashes normalizados, versões, relações, geometrias válidas, classificações e estados. Relatório inclui rejeições; não forçar sucesso descartando linhas silenciosamente.
Backup consistente com manifestos de base/documentos/configuração; cifrado, acesso restrito, restauro verificado em ambiente separado. Critérios propostos: zero perda não autorizada, zero órfãos, zero duplicados de chaves, zero estados oficiais promovidos, totais reconciliados para cada lote aceite; divergências pendentes impedem activação do lote. Responsáveis e limites financeiros de reconciliação permanecem por aprovação.
Rollback de aplicação começa pela flag, exposição e produtores/consumidores; não remove tabelas. Restauro físico só em incidente aprovado e depois de avaliar escritas posteriores ao backup. Eventos já entregues requerem compensação/reconciliação, não fingir que restaurar a base os desenvia. Remoções futuras exigem inventário, período de transição, aprovação e restauro ensaiado, numa entrega distinta.