from pathlib import Path import hashlib import json import shutil source, production = Path('C:/kefu/wechat_rpa'), Path('C:/wechat_rpa') artifact = Path(__file__).parent mapping = {'review_assistant_contacts.py': 'before-contacts', 'review_assistant.py': 'before-notification'} for name, before in mapping.items(): assert (production / name).read_bytes() == (artifact / before / name).read_bytes(), name files = [*mapping, 'test_review_assistant_contacts.py', 'test_review_assistant_ui.py', 'test_review_assistant_contact_order.py', 'test_review_assistant_picker_layout.py', 'tests/test_review_assistant.py', 'tests/test_review_customer_notifications.py'] manifest = {} for name in files: path = production / name backup = artifact / 'before-production' / name if path.exists(): backup.parent.mkdir(parents=True, exist_ok=True) assert not backup.exists(), backup shutil.copy2(path, backup) path.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(source / name, path) manifest[name] = hashlib.sha256(path.read_bytes()).hexdigest() version = production / 'app_version.py' backup = artifact / 'before-production/app_version.py' assert not backup.exists() shutil.copy2(version, backup) text = version.read_text(encoding='utf-8-sig') assert text.count('APP_VERSION = "1.4.25"') == 1 version.write_text(text.replace('APP_VERSION = "1.4.25"', 'APP_VERSION = "1.4.26"'), encoding='utf-8', newline='\n') manifest['app_version.py'] = hashlib.sha256(version.read_bytes()).hexdigest() for name in ('wechat_gui_qt.py', 'assets/ui/console-app.js'): manifest[name] = hashlib.sha256((production / name).read_bytes()).hexdigest() (artifact / 'production-sync.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding='utf-8') plan_root = Path('C:/kefu/deploy/my-customers-20260918') plan = json.loads((plan_root / 'customers-release-plan.template.json').read_text(encoding='utf-8-sig')) plan.update(finalized=True, windowsTestModules=['test_review_assistant_contacts', 'test_review_assistant_ui', 'test_review_assistant_contact_order', 'test_review_assistant_picker_layout'], notes='User explicitly authorized selecting one medical assistant from My Customers. Local release only; no configuration changes, installation, real sends or cloud deployment. Notification pytest frozen tests run separately.') (plan_root / 'customers-release-plan.json').write_text(json.dumps(plan, ensure_ascii=False, indent=2), encoding='utf-8') print('Synced scoped client code/tests, production version 1.4.26. No running processes or user settings changed.')