first commit

This commit is contained in:
strepsiades
2026-03-09 16:31:42 +08:00
commit 4a9c444b10
486 changed files with 52479 additions and 0 deletions
+267
View File
@@ -0,0 +1,267 @@
"""
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_typelist_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_typevalue 为各组件的注册状态
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