""" Domain 注册中心 提供统一的 domain 组件注册和查询接口。 各模块(Collection/DataSource/Strategy)按需获取。 使用方式: 1. 在 domain/__init__.py 中注册所有组件 2. 各模块按需查询 示例: # 注册 from ..common.registry import DomainRegistry from .contract import ContractSyncNode, ContractJsonlHandler DomainRegistry.register( node_type="contract", schema=ContractResponse, node_class=ContractSyncNode, jsonl_handler_class=ContractJsonlHandler ) # Collection 查询 SyncNode 类 node_class = DomainRegistry.get_node_class("contract") # DataSource 查询 Handler handler_class = DomainRegistry.get_jsonl_handler("contract") """ from typing import Dict, Type, Optional, Any from dataclasses import dataclass, field from pydantic import BaseModel @dataclass class DomainRegistration: """ 单个 domain 的注册信息 包含: - node_class: SyncNode 子类(用于 Collection 恢复) - strategy_class: Strategy 子类(用于 SyncSystem 初始化) - handlers: 各种 Handler(用于 DataSource 初始化) """ node_type: str schema: Type[BaseModel] node_class: Type[Any] # Type[SyncNode[T]],避免循环导入 strategy_class: Optional[Type[Any]] = None # 可选,部分 domain 可能只读 jsonl_handler_class: Optional[Type[Any]] = None api_handler_class: Optional[Type[Any]] = None db_handler_class: Optional[Type[Any]] = None metadata: Dict[str, Any] = field(default_factory=dict) # 额外元数据 class DomainRegistry: """ Domain 注册中心 职责分离: - Collection: 只关心 SyncNode 类(恢复类型) - DataSource: 只关心 Handler 类(执行层) - Strategy: 只关心 Strategy 类(业务逻辑) 每个 domain 只注册一次,各模块按需获取。 """ _registry: Dict[str, DomainRegistration] = {} @classmethod def register( cls, node_type: str, schema: Type[BaseModel], node_class: Type[Any], strategy_class: Optional[Type[Any]] = None, jsonl_handler_class: Optional[Type[Any]] = None, api_handler_class: Optional[Type[Any]] = None, db_handler_class: Optional[Type[Any]] = None, **metadata ) -> None: """ 注册一个 domain Args: node_type: 节点类型(如 "contract") schema: Pydantic Schema 类 node_class: SyncNode 子类 strategy_class: Strategy 子类(可选) jsonl_handler_class: JSONL Handler 类(可选) api_handler_class: API Handler 类(可选) db_handler_class: DB Handler 类(可选) **metadata: 额外的元数据 Raises: ValueError: 如果 node_type 已注册 """ if node_type in cls._registry: raise ValueError(f"Domain '{node_type}' already registered") cls._registry[node_type] = DomainRegistration( node_type=node_type, schema=schema, node_class=node_class, strategy_class=strategy_class, jsonl_handler_class=jsonl_handler_class, api_handler_class=api_handler_class, db_handler_class=db_handler_class, metadata=metadata ) @classmethod def get_node_class(cls, node_type: str) -> Type[Any]: """ 获取 SyncNode 类(用于 Collection 恢复) Args: node_type: 节点类型 Returns: SyncNode 子类 Raises: ValueError: 如果 node_type 未注册 """ reg = cls._registry.get(node_type) if not reg: raise ValueError(f"Unknown node_type: '{node_type}'. Available: {list(cls._registry.keys())}") return reg.node_class @classmethod def get_strategy_class(cls, node_type: str) -> Optional[Type[Any]]: """ 获取 Strategy 类(用于 SyncSystem) Args: node_type: 节点类型 Returns: Strategy 类,如果未注册则返回 None """ reg = cls._registry.get(node_type) if not reg: raise ValueError(f"Unknown node_type: '{node_type}'") return reg.strategy_class @classmethod def get_jsonl_handler(cls, node_type: str) -> Optional[Type[Any]]: """ 获取 JSONL Handler 类(用于 DataSource) Args: node_type: 节点类型 Returns: Handler 类,如果未注册则返回 None """ reg = cls._registry.get(node_type) if not reg: raise ValueError(f"Unknown node_type: '{node_type}'") return reg.jsonl_handler_class @classmethod def get_api_handler(cls, node_type: str) -> Optional[Type[Any]]: """获取 API Handler 类""" reg = cls._registry.get(node_type) if not reg: raise ValueError(f"Unknown node_type: '{node_type}'") return reg.api_handler_class @classmethod def get_db_handler(cls, node_type: str) -> Optional[Type[Any]]: """获取 DB Handler 类""" reg = cls._registry.get(node_type) if not reg: raise ValueError(f"Unknown node_type: '{node_type}'") return reg.db_handler_class @classmethod def get_schema(cls, node_type: str) -> Type[BaseModel]: """获取 Schema 类""" reg = cls._registry.get(node_type) if not reg: raise ValueError(f"Unknown node_type: '{node_type}'") return reg.schema @classmethod def get_registration(cls, node_type: str) -> DomainRegistration: """获取完整的注册信息""" reg = cls._registry.get(node_type) if not reg: raise ValueError(f"Unknown node_type: '{node_type}'") return reg @classmethod def is_registered(cls, node_type: str) -> bool: """检查 node_type 是否已注册""" return node_type in cls._registry @classmethod def list_registered(cls) -> list[str]: """列出所有已注册的 node_type""" return list(cls._registry.keys()) @classmethod def get_registered_types(cls) -> list[str]: """列出所有已注册的 node_type(list_registered 的别名)""" return cls.list_registered() @classmethod def clear(cls) -> None: """清空注册表(仅用于测试)""" cls._registry.clear() @classmethod def print_registry(cls) -> None: """打印所有注册的 domain 信息(用于调试)""" if not cls._registry: print("⚠️ DomainRegistry is empty - no domains registered") return print(f"\n{'='*80}") print(f"📋 DomainRegistry - {len(cls._registry)} domain(s) registered") print(f"{'='*80}\n") for node_type, reg in sorted(cls._registry.items()): print(f"🔹 {node_type}") print(f" Schema: {reg.schema.__name__}") print(f" Node Class: {reg.node_class.__name__}") print(f" Strategy Class: {reg.strategy_class.__name__ if reg.strategy_class else '❌ None'}") print(f" JSONL Handler: {reg.jsonl_handler_class.__name__ if reg.jsonl_handler_class else '❌ None'}") print(f" API Handler: {reg.api_handler_class.__name__ if reg.api_handler_class else '❌ None'}") print(f" DB Handler: {reg.db_handler_class.__name__ if reg.db_handler_class else '❌ None'}") if reg.metadata: print(f" Metadata: {reg.metadata}") print() print(f"{'='*80}\n") @classmethod def get_summary(cls) -> Dict[str, Dict[str, bool]]: """ 获取注册摘要(用于自动化检查) Returns: 字典,key 为 node_type,value 为各组件的注册状态 Example: { "contract": { "has_node": True, "has_strategy": True, "has_jsonl_handler": True, "has_api_handler": True, "has_db_handler": False }, ... } """ summary = {} for node_type, reg in cls._registry.items(): summary[node_type] = { "has_node": reg.node_class is not None, "has_strategy": reg.strategy_class is not None, "has_jsonl_handler": reg.jsonl_handler_class is not None, "has_api_handler": reg.api_handler_class is not None, "has_db_handler": reg.db_handler_class is not None, } return summary