feat: platform.db 模型与超管引导(WAL/scrypt/幂等bootstrap)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
+17
-4
@@ -18,6 +18,7 @@ from app.engine.models import Base
|
||||
# "先 import app.main 再 import chat_rest"的循环导入次序坑随全局单例一并
|
||||
# 消失(routes 不再反向 import app.main),直接导入即可。
|
||||
from app.main import app
|
||||
from app.platform.db import make_platform_engine
|
||||
from app.platform.registry import TenantRegistry
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -136,9 +137,20 @@ def build_app(seed_dir, data_dir):
|
||||
延迟取 registry),工厂只负责把 Registry 放进 app.state——lifespan 见
|
||||
已挂则沿用(测试注入缝),不再加载仓库 seed。调用方用完必须复位
|
||||
app.state.registry = None(见 app_test_client 的 finally)。
|
||||
|
||||
Phase 2 Task 1 起同时预置 platform_engine(data_dir 下的临时平台库,
|
||||
同一注入缝)——不预置则 lifespan 会在仓库根建出真实 platform.db;
|
||||
schema+bootstrap 由 lifespan 统一跑(幂等),dispose 也在 lifespan
|
||||
finally(与 registry.dispose_all 同处)。
|
||||
"""
|
||||
registry = TenantRegistry.load_from_dir(seed_dir, data_dir=data_dir)
|
||||
app.state.registry = registry
|
||||
# data_dir 可能尚不存在(租户库由 _ensure_ready 按需 mkdir,平台库由
|
||||
# lifespan 立即连接——这里先建目录,否则 sqlite "unable to open database
|
||||
# file")
|
||||
Path(data_dir).mkdir(parents=True, exist_ok=True)
|
||||
app.state.platform_engine = make_platform_engine(
|
||||
Path(data_dir) / "platform.db")
|
||||
return app
|
||||
|
||||
|
||||
@@ -172,10 +184,10 @@ class TenantTestClient(TestClient):
|
||||
|
||||
@contextmanager
|
||||
def app_test_client(app_instance, base_url, cleanup_root):
|
||||
"""TestClient 包装:统一退出纪律——lifespan finally 已 dispose_all
|
||||
(Windows 文件锁),再置空 app.state.registry(关残留窗:不让已 dispose
|
||||
的测试 Registry 被后续无夹具的 lifespan 误用),最后清 tmp 目录
|
||||
(删不掉告警留痕,不静默吞)。"""
|
||||
"""TestClient 包装:统一退出纪律——lifespan finally 已 dispose_all +
|
||||
platform_engine.dispose(Windows 文件锁),再置空 app.state.registry /
|
||||
platform_engine(关残留窗:不让已 dispose 的测试对象被后续无夹具的
|
||||
lifespan 误用),最后清 tmp 目录(删不掉告警留痕,不静默吞)。"""
|
||||
try:
|
||||
with TenantTestClient(
|
||||
app_instance, base_url=base_url,
|
||||
@@ -183,6 +195,7 @@ def app_test_client(app_instance, base_url, cleanup_root):
|
||||
yield c
|
||||
finally:
|
||||
app_instance.state.registry = None
|
||||
app_instance.state.platform_engine = None
|
||||
_rmtree_warn(cleanup_root)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user