from __future__ import annotations from typing import Any from yuxi.utils.logging_config import logger LEGACY_CONFIG_KEYS = ("wx_corp_id", "wx_corp_secret", "wx_agent_id", "wx_app_id", "wx_app_secret") MIGRATION_MAP = { "wx_corp_id": "corp_id", "wx_corp_secret": "corp_secret", "wx_agent_id": "agent_id", "wx_app_id": "app_id", "wx_app_secret": "app_secret", } class WeChatLifecycleAdapter: def __init__(self): self._migration_from: str | None = None self._migration_log: list[dict[str, Any]] = [] def detect_legacy_config(self, config: dict[str, Any]) -> list[str]: found: list[str] = [] for key in LEGACY_CONFIG_KEYS: if key in config: found.append(key) if found: logger.info(f"[WeChat/Lifecycle] Legacy config keys detected: {found}") return found def migrate_config(self, config: dict[str, Any]) -> dict[str, Any]: legacy_keys = self.detect_legacy_config(config) if not legacy_keys: return config migrated_config = dict(config) for legacy_key, new_key in MIGRATION_MAP.items(): if legacy_key in migrated_config: if new_key not in migrated_config: migrated_config[new_key] = migrated_config.pop(legacy_key) self._migration_log.append( { "from_key": legacy_key, "to_key": new_key, "action": "migrated", } ) else: migrated_config.pop(legacy_key) self._migration_log.append( { "from_key": legacy_key, "to_key": new_key, "action": "skipped (target exists)", } ) self._migration_from = "v1" logger.info(f"[WeChat/Lifecycle] Migrated {len(self._migration_log)} key(s) from v1 config") return migrated_config def detect_state_migration(self, config: dict[str, Any]) -> dict[str, Any]: issues: list[str] = [] if not config.get("corp_id") and config.get("corp_secret"): issues.append("corp_secret exists without corp_id — possible incomplete migration") if not config.get("app_id") and config.get("app_secret"): issues.append("app_secret exists without app_id — possible incomplete migration") if config.get("agent_id") and not config.get("corp_id"): issues.append("agent_id exists without corp_id — possible incomplete migration") mode_count = sum( [ all(config.get(k) for k in ("corp_id", "corp_secret", "agent_id")), all(config.get(k) for k in ("app_id", "app_secret")), bool(config.get("bridge_url")), ] ) if mode_count > 1: issues.append(f"Multiple modes configured ({mode_count}) — verify intentionally") return { "migration_source": self._migration_from, "legacy_keys_found": bool(self.detect_legacy_config(config)), "issues": issues, "migration_log": list(self._migration_log), } def get_migration_report(self) -> dict[str, Any]: return { "source_version": self._migration_from, "total_migrations": len(self._migration_log), "details": list(self._migration_log), }