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.
payloade detalhes usam encriptação Laravel. PreservarAPP_KEYcom 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
- Backup privado
storage/app/private/unification-backup-20260927-134405/database.dumpe manifesto SHA-256. - 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. - Aplicação exclusiva da migration
2026_09_27_140000_investment_unificatione deInvestmentReferenceSeeder. São doze tabelas adicionais. O seed usainsertOrIgnore: não substitui opções editadas. - 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.