7d16ae6318
- app/main.py: lifespan registry 装配按 env TENANT_SOURCE 切换(db|file, 默认 db)——db 走 TenantRegistry(DbTenantSource(platform_engine)) + schema 就绪后 async load_all;file 回退旧 load_from_dir。空 platform.db 冷启动不炸:显式预检 tenants 表(非捕 ValueError——坏数据同样抛 ValueError,一揽子吞会把数据损坏静默成空平台),空表保持空注册表 (域名全 404 直到 bootstrap 导入),清扫循环对空 runtimes() 安全。 非法值在创建任何 engine 前显性炸。conftest 预置缝优先于 env 装配, 既有 558 测试零改动全绿。 - scripts/bootstrap_platform.py: init(schema+超管,env/.env 凭据,空表 才建)+ 出厂档案幂等导入(已存在 slug 跳过;FileTenantSource.read_tenant 同构快照 → Tenant+sites+domains+版本1,版本走 write_config_version 单一 路径;域名 _normalize_host 归一)。不建租户管理员——导入是存量迁移 形态,租户管理员按需走后台创建向导补。CLI 照 extract_config.py 的 argparse 风格(--db/--profiles/--seed)。 - tests/test_bootstrap_script.py: 幂等两遍零变化(行数/版本数逐项断言)、 超管 env 凭据、未知档案显性炸、bootstrap→DbTenantSource→registry 两租户 resolve 冒烟(jc 蓝/17 条/ai-kefu-jc,auto 橙/13 条/ai-kefu,es 覆盖层)、 TENANT_SOURCE 三态装配(db 空/库冷启动、file 回退、非法值炸)。 Co-Authored-By: Claude Code <noreply@anthropic.com>