Files
nala 1106509116
tests / ci (push) Canceled after 0s
vrsao 2
2026-10-08 14:02:01 +02:00

14 KiB

Dados, migração e operação da unificação

Modelo e dicionário da extensão

O esquema executável está em database/migrations/2026_09_27_140000_investment_unification.php e 2026_09_27_150000_investor_workspace.php. Todas as relações têm chaves externas com eliminação restringida. Identificadores territoriais são UUID; oportunidades e utilizadores conservam os seus identificadores numéricos.

Tabela Chave / relação Conteúdo e regra
investment_reference_options id; único (group,code) Rótulo, actividade, ordem, obrigatoriedade de especificação. Códigos estáveis; desactivar não elimina referências históricas.
opportunity_profiles PK/FK opportunity_id Educação, modelo de negócio, requisitos, riscos, data-alvo, fonte, versão. Texto destinado à ficha pública após publicação. Não colocar aqui notas privadas.
opportunity_clusters PK (opportunity_id,cluster_id) Uma oportunidade pode pertencer a vários clusters.
opportunity_corridors PK (opportunity_id,corridor_id) Vários corredores por oportunidade.
opportunity_projects PK (opportunity_id,project_id) Vários projectos âncora por oportunidade.
opportunity_locations PK (opportunity_id,geo_location_id) Ligações às localizações existentes. Geometrias continuam em geo_geometries, PostGIS SRID 4326.
opportunity_facets PK (opportunity_id,option_id) Subsector, parceria, impacto, educação, infraestrutura, competências e necessidades configuráveis.
investment_submissions UUID; dono user_id; recibo único interest_request_id payload encriptado, versão, estado draft/submitted. No máximo um destino: oportunidade ou dossier; interesse geral admite nenhum. Submissão exige recibo e rascunho não o admite.
investment_specific_needs submission_id; opções FK Categoria, tipo, quantidade decimal não negativa, unidade, prioridade, prazo. Descrição, localização e demais detalhes são encriptados.
investment_submission_attachments UUID; submissão/documento FK Ficheiro privado em documents; nome, tipo, tamanho e checksum canónicos.
investment_submission_events submission_id, actor, versão Criação, gravação, anexo e submissão. Guarda actos e versões; não é um arquivo de cópias integrais dos rascunhos.
opportunity_favourites PK (user_id,opportunity_id) Favoritos privados, sem duplicações. Retirada de publicação oculta-os.
investment_accounts PK/FK user_id Perfil de investimento encriptado e versionado; complementa nome/email da conta.
investment_company_declarations UUID; dono user_id Dados empresariais declarados, encriptados e versionados; até vinte por utilizador. Não altera organizations ou memberships, nem comprova representação.
investment_messages UUID; submissão/actor; chave única (submission_id,actor_id,client_key) Conversa encriptada depois da submissão. Repetição com mesmo texto devolve ID; reutilização da chave com outro texto é conflito.
investment_notifications UUID; utilizador/submissão; evento único por destinatário Confirmação, estado e mensagem, conteúdo encriptado, data de leitura. Notificações internas, sem envio de email nesta extensão.
investment_submission_revisions único (submission_id,version) Snapshot encriptado do formulário, necessidades e IDs dos anexos em cada nova versão. Consulta por titular/gestor, sem restauro automático.

Relações principais: users → investment_submissions → investment_specific_needs; investment_submissions → investment_submission_attachments → documents; investment_submissions → interest_requests → outbox_events → CRM; opportunities ↔ clusters/corridors/projects/locations através dos quatro pivots. Dossiers continuam ligados às entidades territoriais originais, sem serem copiados para opportunities.

O payload admite nome, email, telefone, país, organização, função, experiência, capacidade declarada, perfil, sector, objectivo, participação, parceria, montante/moeda, horizonte, localização, referências territoriais, especificação de Outro e consentimento. Campos desconhecidos são recusados. As necessidades admitem descrição, localização, observações, qualificação, especialidade, experiência, certificações, disponibilidade, instituição, modalidade/duração de formação e estado declarado. Os dados quantitativos não são indicadores territoriais verificados.

Regras de visibilidade e segurança

  • A pesquisa exige oportunidade publicada, data de publicação atingida e ausência de eliminação lógica. Relações territoriais públicas exigem dossier publicado; localizações e geometrias exigem classificação pública.
  • O mapa devolve apenas pontos publicados; não estima coordenadas nem consulta serviços externos. A lista textual contém os mesmos locais.
  • Editar contexto devolve a oportunidade a rascunho. A versão recebida tem de coincidir sob bloqueio transaccional; conflito devolve 409.
  • Só o titular altera a sua manifestação. Gestores autorizados podem lê-la para atendimento. Outro investidor recebe 404. Após submissão, alterações são recusadas e repetir o envio devolve o mesmo protocolo.
  • A submissão, o recibo e o evento de integração são gravados atomicamente pelo serviço existente InterestSubmission. Nenhum envio externo SuiteCRM é activado por esta extensão.
  • Anexos PDF/TXT: até 10 MiB cada, dez por manifestação. Armazenamento privado; acesso revalida dono/gestor, estado, directório e SHA-256. Os anexos não integram o catálogo público.
  • payload e detalhes usam encriptação Laravel. Preservar APP_KEY com o backup e restringir o acesso; trocar a chave sem plano torna estes campos ilegíveis.
  • Auditoria guarda actor, identificador, acto e versão, sem copiar perguntas, contactos ou texto privado. A retenção e eliminação de dados pessoais ainda exigem uma política operacional implementada.
  • As revisões integrais privadas ficam separadas da auditoria. Quem deixa de ser gestor perde acesso a pedidos e notificações de terceiros. Mensagens só são permitidas em manifestações submetidas e não alteram a versão do formulário.
  • APIs privadas usam sessão web, email verificado, CSRF e limites de pedidos. Registo público não atribui gestão. Papéis técnico/validador/promotor separados ainda não foram introduzidos nesta extensão.

Migração local executada em 27/09/2026

  1. Backup privado storage/app/private/unification-backup-20260927-134405/database.dump e manifesto SHA-256.
  2. Restauro numa base isolada unification_restore_20260927134405_test, PostgreSQL de QA na porta 55441; comparação de contagens das 76 tabelas existentes antes de migrar.
  3. Aplicação exclusiva da migration 2026_09_27_140000_investment_unification e de InvestmentReferenceSeeder. São doze tabelas adicionais. O seed usa insertOrIgnore: não substitui opções editadas.
  4. Não se executou DatabaseSeeder, não se importaram exemplos remotos e não se criaram oportunidades, empresas ou coordenadas fictícias na base local.

Segunda extensão: migration 2026_09_27_150000_investor_workspace, após backup/restauro verificado de 88 tabelas em storage/app/private/workspace-backup-20260927-184429/. Resultado: 93 tabelas; as cinco novas ficaram vazias. Reconciliação após a segunda migration: apenas migrations mudou (33 → 34); contagens das restantes 87 tabelas preservadas. O seed de instalação local passou também a incluir as opções de investimento; não foi reexecutado globalmente na base operacional.

O backup integral anterior, C:\laragon\backups\portal-investidor-20260927-101224, tem instruções em RESTAURO.md. Representa uma versão anterior à extensão das sete áreas públicas; não misturar silenciosamente esse código com a base nova.

Aplicação noutro ambiente

Reconciliar primeiro código, migrations aplicadas e conteúdo da outra máquina. Gerar backup integral de código, base, ficheiros privados e chave, e ensaiar restauro isolado. Preservar IDs/origens remotos numa tabela de correspondência antes de qualquer importação; comparar contagens, unicidade, FKs, checksums e conteúdo por categoria. Exemplos demonstrativos ficam excluídos do catálogo real. A comparação pública não prova equivalência das bases.

Com o código compatível e o backup conferido:

php artisan migrate --path=database/migrations/2026_09_27_140000_investment_unification.php --force
php artisan db:seed --class=InvestmentReferenceSeeder --force
php artisan migrate --path=database/migrations/2026_09_27_150000_investor_workspace.php --force
npm run build
php artisan optimize:clear

Executar os testes apenas com APP_ENV=testing e base isolada terminada em _test. Nunca usar migrate:fresh na base operacional.

Reversão e monitorização

O down() recusa remover tabelas com dados, incluindo as opções semeadas. Para reverter código, conservar as tabelas aditivas e retirar os novos acessos. Para restaurar a base integral, suspender escritas e trabalhadores, guardar primeiro os dados recebidos depois do backup, restaurar numa base nova e reconciliar antes de mudar a ligação. Não substituir a base activa durante a verificação. O ensaio desta entrega prova restauro do dump anterior; não prova reversão de produção com tráfego concorrente.

Monitorizar erros HTTP 5xx, conflitos 409, recusas 403/404, limites 429, fila/outbox pendente e falhas de entrega, integridade dos anexos, espaço em disco, backups e latência de pesquisa/submissão. Não colocar nomes, emails, conteúdo de anexos ou formulários em métricas. Medir p50/p95/p99 no destino antes de definir SLA; medições locais de poucos registos não são ensaio de carga.

Go / No-Go

Item Situação
Autorização dos requisitos Expressamente concedida pelo proprietário; não requer nova aprovação genérica.
Extensão local e opções Aplicadas após backup/restauro.
QA automatizado e navegador Evidências em validation.md; conferir limitações de cada ensaio.
Conteúdo e geografia Publica-se apenas o existente autorizado; completar dados com fontes reais.
Consolidação da outra máquina Adiada pelo proprietário para fase futura; fora do âmbito da execução local actual.
WCAG 2.2 AA Verificações parciais; falta auditoria completa com tecnologia assistiva.
Área pessoal, empresas declaradas, mensagens e notificações Implementadas e testadas localmente; sem atribuição automática de representação empresarial.
Perfis especializados e cadastro territorial completo Cobertura parcial; ver matriz de rastreabilidade.
SuiteCRM real, carga, recuperação no destino Não ensaiados nesta entrega.
Formação e produção Plano preparado; sessões e entrada em produção não executadas.

Resultado: disponível para utilização e avaliação local. A conclusão integral do prompt e a prontidão de produção não estão demonstradas pelos testes desta extensão.