"""Prepare isolated stabilization sources; never replace active sources/configuration.""" from pathlib import Path from datetime import datetime, timezone import hashlib, json, shutil, subprocess ROOT = Path(__file__).resolve().parent.parent PRIVATE = ROOT / 'storage/app/private/investmoz-v2/portal-audit' read = lambda p: json.loads(Path(p).read_text(encoding='utf-8-sig')) sha = lambda p: hashlib.sha256(Path(p).read_bytes()).hexdigest() stamp = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S') SOURCE = PRIVATE / ('portal-stability-source-' + stamp) BASE = Path(read(PRIVATE / 'country-https-latest.json')['source']) baseline = {} for directory in ['app', 'config', 'routes', 'resources', 'database', 'bootstrap', 'tests']: for p in (BASE / directory).rglob('*'): if not p.is_file() or 'cache' in p.relative_to(BASE / directory).parts: continue rel = p.relative_to(BASE) target = SOURCE / rel target.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(p, target) baseline[rel.as_posix()] = sha(p) for name in ['artisan', 'composer.json', 'composer.lock', 'package.json', 'package-lock.json', 'tsconfig.json', 'vite.config.ts', 'phpunit.xml', 'phpstan.neon', 'qa-autoload.php', '.env.testing']: if (BASE / name).is_file(): shutil.copy2(BASE / name, SOURCE / name) baseline[name] = sha(BASE / name) for directory in ['bootstrap/cache', 'public', 'storage/framework/views', 'storage/framework/cache', 'storage/framework/sessions', 'storage/logs', 'storage/app/private/investmoz-v2/portal-audit']: (SOURCE / directory).mkdir(parents=True, exist_ok=True) for name in ['packages.php', 'services.php']: if (BASE / 'bootstrap/cache' / name).is_file(): shutil.copy2(BASE / 'bootstrap/cache' / name, SOURCE / 'bootstrap/cache' / name) for name in ['vendor', 'node_modules']: subprocess.run(['powershell', '-NoProfile', '-Command', f"New-Item -ItemType Junction -Path '{SOURCE / name}' -Target '{ROOT / name}' | Out-Null"], check=True) # One cryptographically secure UUID mechanism for the 25 remaining calls. It does not # change any business payload, idempotency scope, source identifier or existing UUID. helper = SOURCE / 'resources/js/lib/operation-key.ts' helper.write_text('''/** UUID v4 for operation identifiers; retries keep the caller's existing key. */ export function createOperationKey(): string { const secureRandom = globalThis.crypto; if (typeof secureRandom?.randomUUID === 'function') return secureRandom.randomUUID(); if (typeof secureRandom?.getRandomValues !== 'function') { throw new Error('O navegador não disponibiliza geração criptográfica segura. Reabra o portal no endereço HTTPS configurado.'); } const bytes = secureRandom.getRandomValues(new Uint8Array(16)); bytes[6] = (bytes[6] & 0x0f) | 0x40; bytes[8] = (bytes[8] & 0x3f) | 0x80; const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join(''); return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`; } ''', encoding='utf-8') calls = [] for file in (SOURCE / 'resources/js').rglob('*.tsx'): text = file.read_text(encoding='utf-8-sig') count = text.count('crypto.randomUUID()') if not count: continue text = text.replace('globalThis.crypto.randomUUID()', 'createOperationKey()').replace('crypto.randomUUID()', 'createOperationKey()') text = "import { createOperationKey } from '@/lib/operation-key';\n" + text file.write_text(text, encoding='utf-8') calls.append({'file': file.relative_to(SOURCE).as_posix(), 'occurrences': count}) assert sum(item['occurrences'] for item in calls) == 25 assert len(calls) == 14 # Installing and bootstrapping are different operations. Repeating either attempt # retains its UUID through validation/network errors instead of allocating per click. profile = SOURCE / 'resources/js/pages/profiles/installation.tsx' text = profile.read_text(encoding='utf-8') anchor = " const [message, setMessage] = useState('');" assert text.count(anchor) == 1 text = text.replace(anchor, anchor + "\n const [installationKey] = useState(createOperationKey);\n const [bootstrapKey] = useState(createOperationKey);") assert text.count('idempotency_key: createOperationKey(),') == 1 text = text.replace('idempotency_key: createOperationKey(),', 'idempotency_key: bootstrap ? bootstrapKey : installationKey,') profile.write_text(text, encoding='utf-8') changed = {item['file']: {'before': baseline[item['file']], 'after': sha(SOURCE / item['file'])} for item in calls} changed['resources/js/lib/operation-key.ts'] = {'before': None, 'after': sha(helper)} plan = {'at': datetime.now(timezone.utc).isoformat(), 'source': str(SOURCE), 'baseline_candidate': str(BASE), 'baseline_sources': baseline, 'changed_files': changed, 'uuid_consumers': calls, 'approved_delivery_preserved': '13644ed74a48', 'approved_code_preserved': '162daff6ce08', 'activation_suspended': True, 'active_sources_modified': False, 'active_database_writes': 0} (PRIVATE / 'portal-stability-latest.json').write_text(json.dumps(plan, ensure_ascii=False, indent=2), encoding='utf-8') print(json.dumps({'result': 'QA sources prepared', 'source': str(SOURCE), 'uuid_calls': 25, 'components': 14, 'changed_files': len(changed), 'active_sources_modified': False, 'active_database_writes': 0}))