Files
Investidor-V2/tools/portal-audit-c37-close-prepare.py
T
nala 20971d523f
tests / ci (push) Canceled after 0s
oportunidades 6
2026-10-10 21:17:46 +02:00

83 lines
7.3 KiB
Python
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.
"""Record the responsible user's scoped C37 acceptance, without repeating tests."""
import csv
import hashlib
import json
from datetime import datetime, timedelta, timezone
from pathlib import Path
csv.field_size_limit(16000000)
ROOT = Path(__file__).resolve().parent.parent
DOC = ROOT / 'docs/investmoz/v2/auditoria-portal'
PRIVATE = ROOT / 'storage/app/private/investmoz-v2/portal-audit'
OUT = PRIVATE / 'c37-manual-close-20261010'
OUT.mkdir(exist_ok=True)
stamp = datetime.now(timezone.utc)
references = ['c37-qa18-chromium-20261010.json', 'investor-ab-chromium-20261010.json',
'portal-logout-chromium-20261010.json', 'logout-finalize-20261010/manual-qa18-logout.json']
proofs = []
for name in references:
data = (PRIVATE / name).read_bytes()
proof = json.loads(data)
if name.endswith('manual-qa18-logout.json'):
assert proof['button_and_logout_confirmed_by_user'] and not proof['session_authenticated_after_logout']
else:
assert proof['result'] == 'passed' and proof['active_writes'] == 0
proofs.append({'file': name, 'sha256': hashlib.sha256(data).hexdigest()})
evidence = {'recorded_at_utc': stamp.isoformat(), 'case': 'C37', 'state': 'closed_scoped_qa18_authentication',
'manual_confirmation': 'Registar a confirmação manual e encerrar C37 no âmbito da autenticação QA18, ligando-a às provas anteriores de logout e recuperação. Não repetir os ensaios já concluídos.',
'accepted_by': 'Responsável, mensagem desta conversa em 10/10/2026', 'actor_id': 18,
'scope': 'Login, MFA, redirecionamento, sessão autenticada, atualização, logout e recuperação/nova sessão QA18',
'references': proofs, 'tests_repeated': False, 'active_writes': 0,
'does_not_close': ['A/B acceptance', 'entire audit', 'mobile and full accessibility', 'other profiles', 'active activation']}
(OUT / 'acceptance.json').write_text(json.dumps(evidence, ensure_ascii=False, indent=2), encoding='utf-8')
tag = '[C37 fechado QA18 10/10/2026] '
text = ('Confirmação manual expressa do responsável: C37 encerrado exclusivamente no âmbito da autenticação QA18. '
'Liga login/MFA/redirecionamento/sessão/F5/nova sessão à prova Chromium QA18 anterior, '
'ao logout manual18 com invalidação de sessão e à recuperação previamente demonstrada; sem repetir ensaios. '
'Aceitação sanitizada e hashes: c37-manual-close-20261010/acceptance.json. C85 permanece corrigido QA. '
'Não encerra A/B, auditoria integral, outros perfis ou ativação ativa.')
ids = {'AUD-UI-01', 'AUD-GUIDE-01', 'AUD-DASH-01', 'AUD-PROFILE-24', 'AUD-PROFILE-25'}
files = []
for filename in ['matriz-requisitos.csv', 'backlog-priorizado.csv']:
source = DOC / filename
rows = list(csv.reader(source.open(encoding='utf-8-sig', newline='')))
h = rows[0]
patches = []
for index, row in enumerate(rows[1:], 1):
old = dict(zip(h, row))
if old['ID'] not in ids:
continue
if filename.startswith('matriz'):
values = {'Evidência funcional': old['Evidência funcional'] + ' | ' + tag + text,
'Lacuna': tag + 'C37 não é mais pendência de autenticação QA18; permanecem os demais critérios do requisito. Histórico abaixo preservado e superado apenas neste âmbito. | ' + old['Lacuna'],
'Interface': old['Interface'] + ' | ' + tag + 'Aceitação manual QA18 encerrada, ligada a logout e recuperação anteriores.',
'Recuperação': old['Recuperação'] + ' | ' + tag + 'Recuperação/nova sessão aceite pelo responsável; provas anteriores preservadas, não repetidas.',
'Consolidação': old['Consolidação'] + ' | ' + tag + 'Fecho por caso e âmbito; estado global parcial e referências/versões preservados.'}
variants = json.loads(old['Critérios e versões por origem (JSON)'])
for variant in variants:
variant['aceitacao_c37_qa18_20261010'] = {'case': 'C37', 'estado': 'encerrado no âmbito da autenticação QA18',
'fonte': 'Confirmação manual expressa do responsável', 'prova': 'c37-manual-close-20261010/acceptance.json',
'registado_em': stamp.isoformat(), 'ensaios_repetidos': False, 'ativacao': False}
values['Critérios e versões por origem (JSON)'] = json.dumps(variants, ensure_ascii=False, separators=(',', ':'))
else:
values = {'Pendência': tag + 'C37 autenticação QA18 encerrado; não agendar repetição. Demais pendências e histórico: ' + old['Pendência'],
'Aceitação': old['Aceitação'] + ' | ' + tag + text}
patches.append({'row': index, 'values': values})
assert len(rows) == 3394 and len(patches) == len(ids)
files.append({'filename': filename, 'input_sha256': hashlib.sha256(source.read_bytes()).hexdigest(), 'rows': rows,
'patches': patches, 'allowed_columns': sorted({field for patch in patches for field in patch['values']}), 'append': []})
(OUT / 'csv-edits.json').write_text(json.dumps({'files': files}, ensure_ascii=False), encoding='utf-8')
section = f'''## C37 encerrado — autenticação QA18 — {stamp.astimezone(timezone(timedelta(hours=2))).isoformat()}
**Confirmação manual expressa do responsável registada. C37 está encerrado exclusivamente no âmbito da autenticação QA18.** Login → MFA → redirecionamento → sessão autenticada → atualização → logout → nova sessão/recuperação estão ligados às provas anteriores, sem repetir ensaios nem alterar conta, chave ou MFA. O logout manual de 20:17:15 foi confirmado pelo responsável e pelo rastreio: POST302→/, autenticação e estado persistido vazios.
Aceitação e hashes dos recibos: `c37-manual-close-20261010/acceptance.json`. Referências: `c37-qa18-chromium-20261010.json`, `logout-finalize-20261010/manual-qa18-logout.json`, `portal-logout-chromium-20261010.json` e recuperação do dossier em `investor-ab-chromium-20261010.json`. A prova QA21 do botão é complementar; a conta18 tem a sua própria confirmação. Horário local UTC+02; datas técnicas dos recibos conservadas em UTC.
O fecho **não encerra A/B, auditoria integral, móvel/acessibilidade integral, outros perfis ou ativação ativa**. Os cinco requisitos relacionados continuam parciais pelos seus outros critérios; contagens preservadas: 3393 requisitos/3393 linhas/6845 ocorrências. Menções históricas abaixo a C37/autenticação18 pendente são superadas somente por este fecho. C85 permanece corrigido em QA. Próximo trabalho independente: gravação/recuperação territorial e consistência país–hierarquia por consumidor, países/origem/estatísticas, documentos e workflow, preservando decisões próprias de perfis modulares/SLA.
'''
for name in ['relatorio-executivo.md', 'backlog.md', 'casos-reproducao.md', 'plano-ativacao.md']:
file = DOC / name
old = file.read_text(encoding='utf-8-sig')
file.write_text('<!-- c37-manual-close-20261010:begin -->\n' + section + '\n<!-- c37-manual-close-20261010:end -->\n\n' + old, encoding='utf-8')
print(json.dumps({'case': 'C37', 'state': 'closed_scoped_qa18_authentication', 'requirements_touched': len(ids), 'tests_repeated': False, 'active_writes': 0}))