15 KiB
Formulário por etapas — entrega local, 29/09/2026
Disponível em /investidor/negocios: criar rascunho e abrir a ficha. O prompt A–C completo ainda não está entregue. Este incremento implementa a preparação privada por etapas, autosave, retoma, sector e confirmação. Não implementa ainda publicação, uploads seguros, manifestações MNE ou operação integral.
- Diagnóstico tecnológico: Laravel 13.30.1, PHP de validação 8.5.11, React 19.2.8, TypeScript 5.9.3, Inertia, Vite Plus, Leaflet e PostgreSQL 17.11/PostGIS. Mantidos componentes e autenticação por sessão/email verificado. Filas database/Redis e disco S3 são configuráveis; conectividade Redis/S3/ClamAV e CRM não ensaiada neste incremento. Sem novas dependências.
- Pressupostos: formulário autenticado, classificação reservada e
public.existing_businessescomo autoridade. Identidade e titularidade são declarações pendentes. Referências documentais não são uploads, mandatos validados ou autorizações de transmissão. O preenchimento permite rascunhos incompletos; a submissão aplica validações adicionais. Clientes anteriores sem wizard_version conservam o contrato legado; converter todos os clientes exige uma migração de contrato posterior. - Mapa A–C: ver matriz abaixo. Não há equivalência entre oito etapas visíveis e implementação de todos os requisitos dessas etapas.
- Plano por fase: responsável técnico da implementação: Codex. Incremento A1 executado: schema/validação, FK sectorial, wizard e testes. A2 pendente: localização normalizada/cartografia, contexto económico, anexos/scanner, consentimentos separados e acessibilidade integral. B pendente: manifestação MNE ligada a anúncio publicado, perfil e CRM idempotente. C pendente: aprovações, tarefas, SLA, alertas e dashboard. Dependências e gates mantidos em
implementation-status.md; autorizações de desenvolvimento existentes preservadas. - Modelo PostgreSQL: coluna nullable bigint
existing_businesses.sector_id, FK RESTRICT para a taxonomia existente e índice B-tree completo. Dados declarativos privados ficam no payload cifrado já existente; activos/direitos continuam nas entidades tipadas existentes. Não foram criadas pessoas, sectores ou negócios no schema mne. Localização deste formulário é ainda descritiva, não georreferenciada. - Migration/modelos:
2026_09_29_200000_existing_business_form_sector.phpaplicada localmente. DOWN remove a coluna somente se não houver associações sectoriais. Modelo ExistingBusiness existente preservado;BusinessFormSchemacentraliza campos, rótulos PT/EN e validação. Snapshot/auditoria cifrados existentes conservados. - API: mesmos nove endpoints privados
/api/v1/existing-business.sector_idé adicional no draft;confirmation_codeexigido na submissão de wizard_version=1. GET da ficha fornece formSchema e sectores activos. Erros 403/409/422 e ausência de publicação preservados. OpenAPI actualizado para 1.2.0; schema exportável portools/export-business-form-schema.php. - Permissões: proprietário verificado cria/edita rascunho ou pedido de informação; revisor designado, independente e com MFA consulta submissões. Terceiros recusados. Revisores recebem os novos campos apenas após a policy de consulta. Autosave usa as mesmas autorizações e versões da gravação manual.
- Estados: rascunho → submetido; revisão/pedido de informação/retirada existentes. Confirmação explícita por código e consentimento de análise interna no servidor. Repetir submissão com versão anterior dá 409 sem duplicar histórico; ainda não há comprovativo idempotente por chave de pedido. As duas aprovações e os demais estados de A–C continuam pendentes.
- Serviços/eventos/Jobs: reutilizados ExistingBusinessDrafts, ExistingBusinessIntake, objectos, snapshots e ponte legada. Nenhum Job externo, tarefa de triagem, notificação ou envio CRM novo. O consentimento actual é de revisão interna; não é o catálogo completo de consentimentos versionados do anexo.
- React:
business-wizard.tsxoferece oito etapas, progresso, PT/EN nos controlos principais, autosave após três segundos, retoma no servidor, resumo e confirmação. Navegação/fecho avisam sobre alterações não gravadas; conflitos não substituem silenciosamente dados. Representante revela campos de mandato. Activos/direitos reutilizam BusinessObjects; estes componentes existentes ainda não estão integralmente traduzidos. Criação/consulta administrativa por representação de terceiros permanece pendente. - Código por ficheiro: novos
app/Services/BusinessFormSchema.php, migration sectorial,resources/js/pages/investment/business-wizard.tsx,tests/Feature/ExistingBusinessWizardTest.php, exportador de schema e ferramentas de navegador. Alterados controlador, Drafts, Intake, business.tsx, businesses.tsx, business-types.ts e gerador OpenAPI. Código completo nesses ficheiros; sem ficheiros removidos nem commit Git. - Testes: suite completa executada: 180 testes / 1845 verificações. Depois do controlo adicional por modalidade e do teste de rollback, suite específica do wizard: 2 testes / 30 verificações aprovados. Cobertura inclui cifragem, terceiro recusado, retoma, sector, dados inválidos, conflito de versão, mandato, activo obrigatório, confirmação, submissão duplicada e rollback. Navegador: autosave/recarga, resumo em 390/1440 px e submissão, sem excepções JS. Isto não é uma auditoria WCAG completa.
- Comandos: abaixo. Não foi necessário instalar pacotes Composer/npm. Backend requer PHP com pgsql. Migration local aplicada após backup/restauro, usando
--pathespecífico. Os scripts de navegador e fixtures só usam QA em 55441/18027, nunca a base local operacional. - Resultados: PHPStan, Pint, TypeScript, lint do wizard e build aprovados. Backup com restauro de 210 tabelas:
storage/app/private/mne-integrity-backup-20260929-200103/. Evidência do navegador:wizard-browser-validation.json. Auditoria de dependências e ensaios de serviços externos não executados neste incremento. - Riscos residuais: restantes campos e relações A; identidade normalizada; coordenadas/geometria; CRM MNE; scanner/upload; redis em operação; consentimentos separados; comprovativo/notificações; SLA; aprovações/publicação; tradução integral; testes de acessibilidade, carga e serviços externos. A conta de BD local ainda é superuser. Nenhuma alegação de prontidão para produção.
- Go/No-Go: Go para testar preparação privada local; No-Go para entrega integral A–C ou Go-Live. Os fluxos incompletos não foram expostos como funcionais.
| Requisito | Implementação actual | Estado |
|---|---|---|
| A: proponente/representação | Campos cifrados, mandato condicional, declaração e validação | Parcial; sem verificação de identidade/documentos |
| A: modalidade/sector/valor | Taxonomia existente, FK, limites, moeda e natureza na submissão | Parcial; faltam intervalos e estruturas completas |
| A: localização/contexto | Descrição privada | Geografia estruturada e ligações pendentes |
| A: activos/direitos | Editor tipado existente; objecto aplicável exigido por modalidade | Parcial |
| A: fontes/documentos | Referências declaradas | Upload/scanner pendentes |
| A: rascunho/retoma/resumo | Autosave, versão, oito etapas, confirmação no servidor | Testado |
| B: interesse/CRM | Serviço geral existente preservado | Integração MNE pendente |
| C: revisão | Revisão privada e histórico existentes | Tarefas/SLA/dupla aprovação pendentes |
php artisan migrate --path=database/migrations/2026_09_29_200000_existing_business_form_sector.php
php tools/export-business-form-schema.php
node tools/existing-business-openapi.mjs
php vendor/bin/phpunit --filter ExistingBusinessWizard --do-not-cache-result
npm.cmd run types:check
npm.cmd run build
Em ambiente QA isolado (APP_ENV=testing, base portal_services_test, porta 55441): php tools/business-wizard-browser-seed.php, seguido de node tools/business-wizard-browser.mjs, com servidor QA 18027 e navegador CDP 9224. As fixtures sintéticas ficam apenas nessa base de teste.
Revisão da especificação do formulário de oportunidades — 02/10/2026
- O cadastro continua em sessão autenticada em
/investidor/negocios, com classificação reservada. Não é uma submissão pública anónima e não publica automaticamente. - O wizard
wizard_version=2apresenta os sete tipos pedidos, recolhe proponente/representação e fonte, mostra dados de negócio por tipo, disponibilidade, estado de valor e três confirmações separadas. Rascunho/retoma permanecem no armazenamento cifrado já existente. O contrato legado v1 continua com validação própria; não se reescrevem rascunhos históricos. - A nova migration aditiva
2026_10_02_160000_extend_existing_business_opportunity_types.phpestende o CHECK de modalidades sem editar migration anterior. Recusa migrar se não localizar exactamente uma constraint da modalidade. A reversão recusa remover os valores quando existirem registos que os usam. Migration não executada nesta continuação. - Localização específica/múltipla usa dropdowns territoriais em cascata da referência pública existente e valida a hierarquia na submissão. Os IDs ficam no payload cifrado; ainda não criam relação espacial canónica para a oportunidade, não há marcador de mapa nem múltiplas localizações estruturadas. Subsector/actividade é texto pesquisável por designação, sem código obrigatório.
- Recursos tipados aceitam estado (disponível, contratado, previsto ou por confirmar) e data da fonte. Referências documentais continuam referências, não upload. Anexos classificados, scanner, classificação individual de conteúdo público/interno/confidencial, parque/cluster/corredor/ZEE/ZFI e projecto âncora continuam pendentes.
- Proponente existente pode ser declarado por nome, mas não há selector de CRM/cadastro sem duplicação. A escolha de contacto empresarial aprovado é uma preferência declarada; não é autorização automática de publicação. A projecção pública mantém contactos pessoais fora da allowlist.
- Não foi implementado pedido pós-publicação para suspensão/encerramento, alerta periódico de disponibilidade, nem fluxo MNE completo de consulta e resposta. Alterações materiais continuam limitadas a draft/pedido de informação e precisam de nova submissão/revisão.
docs/investmoz/existing-business/form-schema.jsonedocs/investmoz/existing-business/openapi.jsonforam regenerados pelos exportadores existentes.npm.cmd run types:check,php -lnos seis ficheiros PHP alterados egit diff --checkpassaram. Não executei testes PHPUnit nem a migration.- Gate proposto: parcial, apenas teste privado após aplicar e validar a migration num banco isolado. Sem uploads/revisão de anexos e consentimentos de divulgação por item, não avançar para publicação de oportunidades reais.
Verificação do formulário recebido — 03/10/2026
-
A proposta foi comparada com o wizard v2. Já existem as oito etapas, sete tipos de oportunidade, campos por modalidade, declaração de proponente/representação, contacto por email ou telefone, hierarquia territorial dependente, resumo editável e submissão reservada para revisão. O marketplace público usa uma allowlist e não recebe contactos pessoais nem o payload cifrado.
-
Corrigida a submissão com
valid_untilvencido em payloads semwizard_version: o prazo continua opcional, mas qualquer prazo fornecido passa a ser validado como não vencido. A versão 1 continua a exigir prazo conforme o contrato legado; as versões seguintes aceitam prazo omitido. -
Permanecem por implementar: selector de proponente/cadastro sem duplicação; múltiplas localizações estruturadas, coordenadas e precisão no mapa; relações económicas; upload com antivírus e classificação individual de anexos; selecção granular dos campos publicáveis; e fluxo para actualizar disponibilidade, suspender/encerrar e confirmar disponibilidade periodicamente. Referências documentais continuam a não ser anexos validados.
-
Evidência executada nesta verificação:
php -l app/Services/ExistingBusinessIntake.php,php vendor/bin/pint --test app/Services/ExistingBusinessIntake.phpe o teste dirigidoExistingBusinessIntakeTest::test_arbitrary_states_and_incomplete_or_expired_submission_are_rejectedpassaram (1 teste, 5 asserções) no PostgreSQL isolado em 55441. O cluster de QA foi parado e a porta confirmou-se fechada; não usei a base da aplicação. Restantes testes do wizard permanecem por executar nesta verificação. -
Pesquisa de sector: o campo do passo 3 agora filtra a taxonomia activa por designação, sem perder a selecção actual do rascunho. Esta melhoria não altera a API nem o armazenamento. Continuam pendentes o proponente associado a cadastro existente sem duplicação, localizações múltiplas/georreferenciadas, relações económicas estruturadas, anexos com scanner e consentimento individual de divulgação, e ciclo de vida pós-publicação.
Localizações administrativas múltiplas — 2026-10-03
- O rascunho privado agora admite 2–20 percursos administrativos, guardados em
payload.locations_jsondentro do payload já cifrado. O cliente limpa selecções descendentes ao mudar um nível; o servidor valida UUID, hierarquia na referência pública, mínimo/máximo e percursos repetidos ou sobrepostos. Não são recolhidas nem inventadas coordenadas. - A resposta de leitura/gravação resolve os nomes dos percursos exclusivamente a partir da referência territorial pública. O resumo mostra os nomes depois de guardar.
wizard_version=2consta do contrato OpenAPI; a rota legada conserva validação própria. - Ficheiros desta tranche:
BusinessFormSchema.php,InvestmentGeography.php,ExistingBusinessController.php,business-locations.ts,business-wizard.tsx,business-types.ts,existing-business-openapi.mjs,ExistingBusinessWizardTest.phpebusiness-locations.test.mjs. - Evidência: PHP 8.5.11 e PostgreSQL 17 descartável na porta 55441, migrations aplicadas apenas na base temporária;
ExistingBusinessWizardTest3/3, 49 assertions; testes frontend da localização 3/3; TypeScript, Pint dirigido, PHP lint egit diff --checkpassaram. O listener preexistente em 5432 não foi utilizado. Cluster parado; os ficheiros de dados QA permanecem no directório temporário%TEMP%\investmoz-stage-multilocporque a limpeza automática foi bloqueada pelo executor. - Sem migration nem alteração de esquema persistente. Rollback: reverter os trechos acima e remover os dois testes/helpers novos; não há dados existentes a migrar. Permanecem pendentes mapa/coordenadas, relação territorial canónica e associação a parques/zonas; esta entrega não autoriza publicação de oportunidade.