127 lines
20 KiB
Python
127 lines
20 KiB
Python
"""Reconcile current QA evidence into existing reports; no database or new matrix."""
|
||
import json
|
||
import xml.etree.ElementTree as ET
|
||
from pathlib import Path
|
||
from datetime import datetime, timezone
|
||
|
||
root = Path(__file__).resolve().parent.parent
|
||
private = root / 'storage/app/private/investmoz-v2/portal-audit'
|
||
docs = root / 'docs/investmoz/v2/auditoria-portal'
|
||
runtime = json.loads((private / 'investor-path-qa-runtime.json').read_text(encoding='utf-8-sig'))
|
||
http = json.loads((private / 'investor-path-http-qa.json').read_text(encoding='utf-8-sig'))
|
||
assert http['target'] == runtime['target'] and http['api_persistence_passed']
|
||
assert not http['integrated_ui_ab_passed'] and http['active_writes'] == 0
|
||
proof_file = private / 'investor-path-evidence.json'
|
||
proof = json.loads(proof_file.read_text(encoding='utf-8-sig'))
|
||
calculation = json.loads((private / 'investor-path-recovered-calculations.json').read_text(encoding='utf-8-sig'))
|
||
assert calculation['passed'] and calculation['target'] == runtime['target'] and not calculation['interface_observed']
|
||
old = private / 'investor-path-evidence-before-continuation.json'
|
||
if not old.exists():
|
||
old.write_text(json.dumps(proof, indent=2), encoding='utf-8')
|
||
proof['previous_full_suite'] = proof.get('previous_full_suite', {**proof['full_suite'], 'code_hash': proof['code_hash'], 'scope': 'Previous full regression; no per-requirement or current UI acceptance'})
|
||
proof.update(runtime)
|
||
selected = []
|
||
for name in ['continuation-consumer-qa.xml', 'continuation-profile-qa.xml', 'continuation-install-qa.xml', 'continuation-business-journey-qa.xml']:
|
||
tree = ET.parse(private / name)
|
||
cases = list(tree.iter('testcase'))
|
||
assert cases and all(not list(case) for case in cases), f'Failure/skip in {name}'
|
||
selected.append({'junit': name, 'tests': len(cases), 'assertions': sum(int(c.get('assertions', 0)) for c in cases), 'result': 'passed',
|
||
'cases': [{'class': c.get('class'), 'method': c.get('name'), 'assertions': int(c.get('assertions', 0))} for c in cases]})
|
||
proof.update({'current_selected_suites': selected, 'real_http_ab_evidence': 'investor-path-http-qa.json',
|
||
'new_authenticated_http_session_recovered': True, 'integrated_ui_ab_passed': False,
|
||
'cartography_current_qa_evidence': 'geometry-consumers-path-qa.json', 'current_frontend_directed_tests': 7,
|
||
'manual_script': 'roteiro-manual-qa-i0-i3.md', 'activation_ready': False,
|
||
'actual_recovered_calculations': 'investor-path-recovered-calculations.json',
|
||
'qa_demonstrated': 'Real authenticated HTTP/new cookie sessions A/B plus API/persistence/profile criteria; UI pending',
|
||
'remaining': ['A/B browser interface and new browser session', 'Visual country/origin/statistics per form',
|
||
'Each selector/map consumer rendering, including C27',
|
||
'Workflow and specialized contracts', 'Visual authenticated cartography import/reversal',
|
||
'Final backup/restore/compatibility renewal after visual demonstration'],
|
||
'browser': {'apps': [], 'browsers': [], 'reset_rechecked': True, 'failed_providers': ['iab', 'chrome', 'edge'],
|
||
'qa_login_http': 200, 'cause': 'No browser provider exposed; connection/registration root cause not established', 'visual_verified': False}})
|
||
proof_file.write_text(json.dumps(proof, ensure_ascii=False, indent=2), encoding='utf-8')
|
||
|
||
|
||
def insert(filename, heading, body):
|
||
file = docs / filename
|
||
text = file.read_text(encoding='utf-8-sig')
|
||
block = heading + '\n\n' + body.strip() + '\n\n'
|
||
start = text.find(heading + '\n')
|
||
if start >= 0:
|
||
end = text.find('\n## ', start + len(heading))
|
||
text = text[:start] + block + (text[end + 1:] if end >= 0 else '')
|
||
else:
|
||
first = text.find('\n')
|
||
text = text[:first + 1] + '\n' + block + text[first + 1:].lstrip('\n')
|
||
file.write_text(text, encoding='utf-8')
|
||
|
||
|
||
insert('relatorio-executivo.md', '## Continuação atual — prova HTTP, cobertura por formulário e interface pendente', '''
|
||
**I0–I3 continuam parciais; nenhuma escrita ativa.** A/B passaram no servidor QA real18097: login → criação/gravação → logout → nova sessão/cookies/login → recuperação → aplicabilidade → ferramenta/entradas congeladas → resultado no dossier → rascunho Balcão → acompanhamento interno. Outra conta403/404; troca de contexto403; gestor não lê draft/resultado financeiro privado. Tarefa de mercado concluída enquanto terra aguarda. QA web{runtime['qa_path_journeys']} instâncias/{runtime['qa_path_steps']} etapas; inclui os dossiers sintéticos preservados e a continuação com MFA quando demonstrada. Não importar fixtures no ativo.
|
||
|
||
País/origem/filtros/estatísticas: provas específicas dos quatro tipos de apoio e três serviços Balcão reforçadas; wizard, fundiário, perfil/empresa/submissão e CRM conservam provas próprias. Complemento continuation-business-journey-qa.xml demonstra interesse em negócio público PT/ZA, recibo/replay, recuperação/filtro/estatística e jornada PT=1/MZ=0, sem inferir país como origem. Ver [cobertura por formulário/consumidor](cobertura-percursos-i0-i3.md), ligada aos IDs da matriz. Apresentação visual continua pendente.
|
||
|
||
C27 preparou a ligação do território principal ao preview na ficha da oportunidade e do filtro aplicado ao mapa da Bolsa; TypeScript/build passaram.361/361 limites reais recuperados READ ONLY na mesma QA A/B; perfis HTTP gestor/público/conta comum ensaiados em província/distrito/posto. Públicos0, internos361; faltam2/39/179 correspondências e polígonos de localidades. **Nenhum mapa ou seletor foi visualmente aceite.**
|
||
|
||
C29: a fixture HTTP inicial tinha listas orçamentais vazias incompatíveis. Corrigida por nova versão, mantendo os resultados congelados anteriores e o erro explícito. A função efetiva do dossier verifica agora os snapshots realmente recuperados: A20unidades/0.00 e B20/70000.00; é cálculo demonstrado, sem observação visual.
|
||
|
||
Browser: inventário vazio antes/depois de reset, IAB/Chrome/Edge indisponíveis; login QA HTTP200. Causa observada é fornecedor não exposto nesta sessão; causa de conexão/registo não determinada. [Roteiro manual executável](roteiro-manual-qa-i0-i3.md) com URLs, contas QA, ações/esperados e negativas preparado. HTML/props/HTTP não substituem essa execução.
|
||
|
||
Matriz única mantém3.354 requisitos/linhas canónicas e5.830 ocorrências;5 concluídos anteriores,3.198 parciais,146 não implementados,1 implementado mas não ativado,4 decisões concretas. **Nenhum novo requisito encerrado.** Evidências complementares por método nos JUnit continuation-consumer/profile/install, sessão real em investor-path-http-qa.json e mapa de cobertura acima. Regressão global384/5215 é anterior a C27; não serve como prova atual de interface. C28 remove número381 fixo no preparador de evidências, sem eliminar guardas/hashes/autenticação.
|
||
|
||
Backup/restauro final não renovado antes da demonstração visual. Fingerprints mudaram; ready=true histórico não vale para a versão atual. Instalação de recursos, extensão do percurso, disponibilização por configuração e importação/divulgação cartográfica são ações separadas, fora da autorização ativa. Workflow e contratos especializados permanecem no backlog; nenhuma jornada educativa nova.
|
||
''')
|
||
insert('backlog.md', '## Próximo lote atual — critérios abertos após as provas HTTP', '''
|
||
1. **P0/P1 AUD-UI-01, DASH-01, SIM-01, DESK-02, GUIDE-01, CRM-01:** executar [roteiro A/B](roteiro-manual-qa-i0-i3.md), criar projetos novos pela interface, recuperar em outra sessão do navegador, alternar sem mistura, ferramenta/resultado, rascunho de apoio e tarefa paralela. Provas HTTP já passaram; navegador continua sem fornecedor. Fecho exige capturas/resultados/rede/persistência por passo.
|
||
2. **P1 AUD-COUNTRY-01–04/06–07 e STATS-01:** ensaiar visualmente cada formulário da [cobertura](cobertura-percursos-i0-i3.md), filtros/URL/tabela e agregados separados. Interesse em negócio público e estatística específica da jornada agora têm provas API/persistência próprias; a apresentação e variações condicionais continuam abertas. Perfil/empresa e residência fiscal/fundos preservam significados próprios.
|
||
3. **P1 AUD-GEO-02/03:** observar cada seletor/mapa, incluindo C27 já preparado; guardar/reabrir campo, limpar descendentes, respeitar acesso e edição.361 disponíveis na QA não são361 públicos nem cobertura visual. Correspondências2/39/179 e localidades permanecem; reutilizar cadastro/originais sem aproximação ou dados inventados. Edição de zonas exige conta QA com MFA; não desativar a permissão.
|
||
4. **P1 AUD-OPS-01:** após demonstração, renovar backup/restauro/hashes/compatibilidade da versão final; repetir somente ensaios pertinentes e gerar provas verdadeiras. Recursos030000 e percurso190000 são instalações distintas; flag habilita navegação separadamente. Mecanismo cartográfico C30 preparado e demonstrado em QA; verificar interface e preparar prova específica da revisão/alvo após backup final. Importador CLI QA não pode ser apontado ao ativo. C28 preparador corrigido para não exigir contagem381 fixa.
|
||
5. **Workflow e contratos especializados:** continuam pendentes; sem novas jornadas educativas enquanto falhas prioritárias abertas. ClamD real e GD/scan das três derivadas de oportunidades têm provas QA atuais; arranque permanente/manutenção/PHP ativo e operações ainda não ensaiadas são pendências específicas, sem bloquear países/preparação.
|
||
|
||
Todas as linhas permanecem na matriz existente; não reabrir aceitação de fontes oficiais nem recriar estados/dados paralelos. Nenhuma instalação ativa autorizada.
|
||
''')
|
||
insert('execucao-percurso-i1-i3.md', '## Continuação atual — sessões reais e evidência por consumidor', '''
|
||
Prova posterior ao lote inicial abaixo: investor-path-http-qa.json executa login/logout e novo cookie jar/login no servidor QA18097, recupera A/B por ID, aplicabilidade, draft próprio, resultado congelado, pedido e tarefa concluída. Outra conta403/draft404 e contexto cruzado403. A mostra necessidade esperada0; B70000; ambas20unidades nas fórmulas. Na QA web existem4instâncias/76etapas, incluindo2fixtures de setup e2HTTP; os38steps dos testes abaixo pertencem a outra base isolada.
|
||
|
||
País/origem/filtros/estatísticas foram reforçados por formulário; interesse em negócio público e jornada têm agora provas específicas. C27 liga consumidores de mapas; build/TypeScript passaram. C28 corrige a contagem fixa no preparador. Ver cobertura-percursos-i0-i3.md e roteiro-manual-qa-i0-i3.md.
|
||
|
||
Interface ainda não observada; I0–I3 permanecem parciais. Provas anteriores de backup e hashes são históricas; renovar depois da demonstração visual. Nenhuma escrita/ativação ativa autorizada; instalação de schema, flag e importação/divulgação cartográfica são atos separados.
|
||
''')
|
||
insert('plano-ativacao.md', '## Sequência atual — após demonstração e sem autorização ativa', f'''
|
||
Plano preparado, **não executado**. A/B HTTP/nova sessão real passaram; interface ainda pendente. Por isso não renovar o backup final como se a demonstração visual estivesse concluída nem considerar pronta a ativação. A revisão atual alterou fingerprints: percurso `{runtime['code_hash']}`; recursos `{runtime['resource_code_hash']}`. Provas anteriores preservadas e insuficientes para esses hashes. `activation_ready=false`.
|
||
|
||
| Ordem | Ação exata futura | Dependência/efeito esperado | Verificação e reversão |
|
||
| --- | --- | --- | --- |
|
||
| 0 | Concluir roteiro QA A/B e consumidores; fixar revisão/assets/hashes | Interface com nova sessão/perfis/resultados; nenhuma mistura. Não usar contagem global como substituto. | Registar cada critério na mesma matriz; se mudar código relevante, repetir respetiva demonstração. |
|
||
| 1 | Renovar dump + ficheiros privados e restaurar numa nova base loopback*_test:55441; ensaiar compatibilidade/reversão sobre essa cópia | Origem ativa apenas READ ONLY; destino QA com guarda. Usar mecanismos de backup existentes, incluindo tools/desk-activation-backup.php; preservar prova antiga antes de substituir. Comparar schema, contagens, hashes por tabela, ficheiros/chave privada, órfãos/relações/RLS.288tabelas/5ficheiros são baseline histórico, não contagem a forçar. | Repetir ensaio vazio e recusa depois de uso; gerar provas para ambos os fingerprints sem fabricar true nem copiar flags visuais de outra versão. Não renovar/aplicar no ativo agora. |
|
||
| 2 | Disponibilizar correções/assets desta revisão, mantendo INVESTOR_PATH_ENABLED=false | Países/origem/filtros/maturidade/C27; sem reclassificar valores legados, sem novo dado por deploy. | Confirmar assets servidos; rollback de código compatível preserva novos payloads/histórico. |
|
||
| 3 | Conta ativa autorizada: GET `/management/opportunity-resources-install`, confirmar prévia atual, depois POST nessa rota **somente se030000 estiver ausente** | `2026_10_09_030000_extend_opportunity_resources`:3tabelas de associação existentes no desenho,1coluna em documents,1função/3triggers,1migration/evento;0recursos/documentos/localizações novos automaticamente. Backup/restauro/compatibilidade/hash/permissões. | Ler ledger/evento/autor/hash e comparar dados/classificações/relações/originais. Não repetir instalação como ensaio. Down só sem recursos/originais cifrados; após uso preservação/exportação antes de recuperação. |
|
||
| 4 | GET `/management/balcao-install`, conferir apenas migration190000 pendente; POST autenticado pela mesma rota |2colunas nas entidades atuais +1definição publicada imutável +ledger/evento.0conversões de journeys antigos,0dossiers/etapas/tarefas criados. `pathQaVerified` exige API e A/B visual dessa revisão. Não repetir migrations básicas do Balcão/Bolsa/gestão já instaladas. | Schema/definição/ledger/evento/hash; instalação não habilita percurso. Down recusa após uso; preservar definição/história/RLS. |
|
||
| 5 | Em ação de configuração/deploy separada, habilitar INVESTOR_PATH_ENABLED e atualizar configuração servida | Só depois de schema instalado e QA visual da versão. Mostra `/investimentos`/painel; instancia19etapas apenas ao criar novo dossier, sem renumerar roteiros. | Confirmar rotas/layout/perfis/recuperação. Reversão imediata: desligar flag preservando dossiers, drafts, resultados, documentos, consentimentos, tarefas e eventos; ferramentas diretas mantidas. |
|
||
| 6 | Prévia/aplicação **cartográfica autenticada**, lote oficial privado, em geo_geometries existentes | C30: GET/POST `/management/territory-geometry-import`, POST `/{{batch}}/reverse`; mecanismo preparado e demonstrado em QA. **Não existe prova ativa válida desta revisão agora**. Depende de prévia/hash/original/scan/dedup/conflitos. Se base continuar0 e todas as correspondências permanecerem inequívocas:361=9+120+232novos;0geo_locations/pontos/perímetros de investimento.2/39/179ficam de fora. | Guardar lote/origem/edição/IDs/autor/eventos; replay0novos. Não apontar portal-audit-geometry-qa.php ao ativo. Reverter acesso/arquivar apenas lote novo sem uso; preservar originais/relações/história. |
|
||
| 7 | Disponibilizar camadas por consumidor/âmbito autorizado, ato separado de importar | Fonte aceite não é divulgação automática; edição2019/atualidade jurídica/administrativo vs implantação explícitos. Limites internos não podem aparecer publicamente para tornar o teste verde. | Conferir cada mapa/selector/perfil. Retirar camada/autorização sem apagar geometria ou histórico. |
|
||
|
||
ClamD é requisito de scan/reabertura/download/publicação dos binários afetados; arranque/assinaturas e cada derivada têm provas próprias. GD/WebP depende do PHP web. Não bloquear metadados, países, estatísticas ou preparação independente por estes itens. Nenhum cálculo fiscal ativado por importação/publicação.
|
||
|
||
Restauro integral ativo continua fora da autorização; antes dele reconciliar todas as escritas posteriores ao backup. A renovação após interface pode envolver leitura ativa/restoreQA, mas nenhuma instalação, importação, publicação ou sobrescrita ativa está autorizada.
|
||
''')
|
||
with (docs / 'casos-reproducao.md').open('a', encoding='utf-8') as f:
|
||
if '## C27 —' not in (docs / 'casos-reproducao.md').read_text(encoding='utf-8'):
|
||
f.write('''\n## C27 — consumidores sem contexto cartográfico\n\nRequisitos AUD-GEO-02/03. Reprodução de código: ficha de oportunidade chama InvestmentMapPanel apenas com opportunity_id; preview procura IDs territoriais exclusivamente nos filtros e recebe vazio. Bolsa desenha pontos e omite consulta de limites do território aplicado. Esperado: contexto administrativo do território conhecido, respeitando classificação, sem mudar resultado económico nem inventar implantação. Observado: chamada ao preview ausente nestes consumidores. Causa identificada: ligação de props/componente incompleta. Corrigido em código QA: territoryId separado a partir do primary_territory_path, e TerritoryGeometryPreview da Bolsa a partir de p.filters. TypeScript/build passam; GET real/serviço QA verificam acessos. Reprodução/renderização no navegador ainda pendentes; não confundir causa de código com prova visual.\n\n## C28 — preparador de prova preso à contagem381\n\nRequisito AUD-OPS-01. Fonte tools/portal-audit-prepare-activation.php exigia tests=passed=381 e emitia381 fixo; a regressão posterior384/5215, apesar de passar, seria rejeitada por esta condição. Esperado: total positivo, todos passados, sem skips, mantendo hash/backup/restauro/compatibilidade/autenticação independentes. Corrigida condição/serialização para usar total efetivo; a contagem continua apenas inventário de regressão, sem provar critérios ou UI. Sintaxe/Pint verificados. Preparador não executado contra ativo nem prova de ativação emitida; demais dependências continuam obrigatórias.\n''')
|
||
if '## C29 —' not in (docs / 'casos-reproducao.md').read_text(encoding='utf-8'):
|
||
f.write('''\n## C29 — fixture HTTP com orçamento incompatível\n\nRequisito AUD-SIM-02; falha na preparação da fixture, não demonstrada como regressão do portal. Reprodução QA: snapshot financeirov1 com incomes=[]/expenses=[], gravar draft e devolver evidência; executar recoverPathResult sobre o snapshot recuperado. Esperado para demonstração:20unidades/gap0(A) ou70000(B). Observado: Entradas incompatíveis. Causa: fixture criada pelo ensaio HTTP não respeitava o contrato de pelo menos uma linha orçamental. Correção no ensaio: novas linhas sintéticas explicitamente identificadas, PUT com ETag/contexto gera draftv2 e novo resultado; originais congeladosv1 preservados. Não relaxada a validação nem atribuído zero ao erro. investor-path-recovered-calculations.json demonstra novos cálculos e recusa dos resultados históricos incompatíveis; HTTP recupera ambos sem sobrescrita. Roteiro visual cria projetos novos e informa o histórico das fixtures de inspeção. Interface permanece pendente.\n''')
|
||
historical = {
|
||
'relatorio-executivo.md': {'## Estado atual — lote I0/I1–I3 executado exclusivamente em QA': '## Histórico do lote inicial I0/I1–I3 — antes da continuação HTTP/C27'},
|
||
'backlog.md': {'## Próximo lote — após execução QA aprovada de I1–I3': '## Histórico do próximo lote então definido — antes da continuação HTTP/C27'},
|
||
'plano-ativacao.md': {'## Ordem final — execução aprovada QA, ativo não autorizado': '## Histórico da ordem anterior — fingerprints substituídos por C27',
|
||
'## Versão atual — separar preparação, instalação e disponibilização': '## Histórico da versão anterior — separar preparação, instalação e disponibilização'},
|
||
'execucao-percurso-i1-i3.md': {'## Lote executado e limites da evidência': '## Histórico do lote inicial — limites da evidência então obtida'},
|
||
}
|
||
for filename, replacements in historical.items():
|
||
file = docs / filename
|
||
content = file.read_text(encoding='utf-8')
|
||
for old_heading, new_heading in replacements.items():
|
||
content = content.replace(old_heading, new_heading)
|
||
file.write_text(content, encoding='utf-8')
|
||
print(json.dumps({'evidence_updated': True, 'requirements_closed': 0, 'active_writes': 0, 'qa_instances': runtime['qa_path_journeys'], 'qa_steps': runtime['qa_path_steps'], 'visual': False}))
|