"""Preserve sealed C110 sources; prepare logout/history correction in a new QA source copy.""" from pathlib import Path from datetime import datetime,timezone import json,shutil,subprocess ROOT=Path(__file__).resolve().parent.parent PRIVATE=ROOT/'storage/app/private/investmoz-v2/portal-audit' meta=json.loads((PRIVATE/'country-https-latest.json').read_text());previous=Path(meta['source']) source=PRIVATE/('country-https-source-'+datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S'));source.mkdir() for directory in ['app','config','routes','resources','database','bootstrap','tests','tools']: shutil.copytree(previous/directory,source/directory) 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']: shutil.copyfile(previous/name,source/name) for directory in ['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 ['vendor','node_modules']: subprocess.run(['powershell','-NoProfile','-Command',f"New-Item -ItemType Junction -Path '{source/name}' -Target '{ROOT/name}' | Out-Null"],check=True) proof=previous/'storage/app/private/investmoz-v2/opportunity-resources-backup-proof.json' shutil.copyfile(proof,source/'storage/app/private/investmoz-v2/opportunity-resources-backup-proof.json') file=source/'app/Providers/AppServiceProvider.php';text=file.read_text(encoding='utf-8') anchor=' $this->configureDefaults();' patch=''' // Fortify calls this response AFTER invalidating/regenerating the server session. // Clear the client's encryption key too, so Back must reauthorize private pages. $this->app->bind(\\Laravel\\Fortify\\Contracts\\LogoutResponse::class, function () { return new class extends \\Laravel\\Fortify\\Http\\Responses\\LogoutResponse { public function toResponse($request) { \\Inertia\\Inertia::clearHistory(); return parent::toResponse($request); } }; });''' assert text.count(anchor)==1;text=text.replace(anchor,anchor+patch);file.write_text(text,encoding='utf-8') meta['previous_source']=str(previous);meta['source']=str(source);meta['C112']='Prepared: Fortify LogoutResponse clears Inertia history after session invalidation' (PRIVATE/'country-https-latest.json').write_text(json.dumps(meta,indent=2),encoding='utf-8') original=(ROOT/'tools/portal-country-production-stage.py').read_text(encoding='utf-8') original=original.replace("ROOT = Path(__file__).resolve().parent.parent", "ROOT = Path(__file__).resolve().parent.parent\nLIVE = Path('C:/laragon/www/portal-investidor')") original=original.replace("OUT = ROOT / 'outputs/investmoz-country02-candidate-20261011'", "OUT = LIVE / 'outputs/investmoz-country02-https-20261011'") original=original.replace("PRIVATE = ROOT / 'storage/app/private/investmoz-v2/portal-audit'", "PRIVATE = LIVE / 'storage/app/private/investmoz-v2/portal-audit'") original=original.replace("ROOT / 'public/build'", "LIVE / 'public/build'") original=original.replace("'vite.config.ts']:","'vite.config.ts', 'qa-autoload.php']:") original=original.replace("$loader = require __DIR__.'/vendor/autoload.php';", "$loader = require __DIR__.'/qa-autoload.php';") original=original.replace('country-production-stage-latest.json','country-https-production-stage-latest.json') builder=source/'tools/portal-country-https-build.py';builder.write_text(original,encoding='utf-8') backup=(source/'tools/portal-country-c110-backup.php').read_text(encoding='utf-8').replace('country-c110-backup-latest.json','country-https-backup-latest.json').replace('country-c110-production-stage-latest.json','country-https-production-stage-latest.json') (source/'tools/portal-country-https-backup.php').write_text(backup,encoding='utf-8') router=source/'tools/portal-country-https-qa.php';text=router.read_text(encoding='utf-8').replace('country-production-stage-latest.json','country-https-production-stage-latest.json');router.write_text(text,encoding='utf-8') print(json.dumps({'source':str(source),'application_changes':['AppServiceProvider.php logout response binding'],'sealed_C110_sources_preserved':True,'active_changes':0})) subprocess.run(['C:/Users/macbook/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe','-X','utf8',str(builder)],check=True)