#!/usr/bin/env python3 # -*- coding: utf-8 -*- """pbls 应用唯一入口(PBL Agent OS Phase 0/1)。 设计依据 -------- * projects/pbls/pbls_spec.json —— app / load_order / 端口(唯一事实源在 projects/pbls/env/) * docs/01-design/architecture.md —— 单应用单端口、模块挂载顺序 * docs/01-design/data-model.md —— 36 表 mariadb 方言、tenant_id 强制打头 * projects/pbls/env/test.json —— 端口与 DB 连接(应用仓不另存 env/、不硬编码端口) 规范对齐(web-application-spec 固定模板,QC 第 4 轮 #1/#2/#3/#4/#8 已整改) -------------------------------------------------------------------------- * init() 无参签名,函数体内 `env = ServerEnv()`(ahserver webapp(init) 以无参调用 init) * 平台基座导入路径按规范字面:appbase.init / rbac.init / bricks_for_python(+.init) * 业务模块导入路径按 module-development-spec 标准出口:{module}.init * 入口内不出现任何端口字面量(端口只由 projects/pbls/env/{test,prod}.json 注入) * webapp(init) 置于 __main__ 守卫内,被 import 不触发启动 """ import json import os from ahserver.webapp import webapp from ahserver.serverenv import ServerEnv import bricks_for_python # noqa: F401 registers bui processor from bricks_for_python.init import load_pybricks # registers UiWindow etc. from appbase.init import load_appbase from rbac.init import load_rbac # ---- 引用模块(严格写保护:只读挂载,扩展一律走 pbl_*_ext 薄扩展模块) from world.init import load_world from scene.init import load_scene from entity.init import load_entity from script_engine.init import load_script_engine from scense_runtime.init import load_scense_runtime from scense.init import load_scense # ---- 新建 pbl_* 模块(严格按 pbls_spec.json load_order) from pbl_common.init import load_pbl_common from pbl_appcodes.init import load_pbl_appcodes from pbl_blueprint.init import load_pbl_blueprint from pbl_validation.init import load_pbl_validation from pbl_compiler.init import load_pbl_compiler from pbl_agent_runtime.init import load_pbl_agent_runtime from pbl_evidence.init import load_pbl_evidence from pbl_assessment.init import load_pbl_assessment from pbl_domain_ext.init import load_pbl_domain_ext from pbl_scense_ext.init import load_pbl_scense_ext from pbl_runtime_ext.init import load_pbl_runtime_ext from pbl_kdb_ext.init import load_pbl_kdb_ext CONF_PATH = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "conf", "config.json" ) _MODULE_DBNAME_MAP = None def _load_module_dbname_map(): """从应用 conf/config.json 的 module_dbname 段读取「模块名 → 库名」映射。 库名唯一事实源是 conf/config.json(由 build.sh 依据 projects/pbls/env/*.json 生成), 代码内不写死任何库名。 """ global _MODULE_DBNAME_MAP if _MODULE_DBNAME_MAP is None: with open(CONF_PATH, "r", encoding="utf-8") as fp: cfg = json.load(fp) _MODULE_DBNAME_MAP = cfg.get("module_dbname") or {} return _MODULE_DBNAME_MAP def get_module_dbname(m): """返回模块 m 对应的数据库名(web-application-spec / module-development-spec 要求)。""" mapping = _load_module_dbname_map() if m in mapping: return mapping[m] if "default" in mapping: return mapping["default"] raise RuntimeError( "module_dbname mapping missing for module %r; check %s" % (m, CONF_PATH) ) def password_encode(s): if s is None: return '' from ahserver.globalEnv import password_encode as _orig return _orig(s) def init(): """应用初始化:唯一入口。端口/DB 连接由 projects/pbls/env/{test,prod}.json 注入。""" env = ServerEnv() # ← MUST be before load_rbac env.get_module_dbname = get_module_dbname env.password_encode = password_encode # ---- 平台基座三件套(顺序固定:ServerEnv → appbase → rbac → bricks_for_python) load_appbase() load_rbac() load_pybricks() # ---- 引用模块(只读挂载,不改基表) load_world() load_scene() load_entity() load_script_engine() load_scense_runtime() load_scense() # ---- 新建 pbl_* 模块(严格按 pbls_spec.json load_order) load_pbl_common() # 公共内核:租户上下文/DB 适配/错误码/审计/CRUD 工厂 load_pbl_appcodes() # 枚举编码注入(8 组 74 项,幂等,零表) load_pbl_blueprint() # M1a/M1b 蓝图聚合根 + 7 类子对象 + 版本 + 模板 load_pbl_validation() # M2 校验引擎(14 维 + 5 级质量状态) load_pbl_compiler() # M3a/M3b 确定性编译 + Game Definition load_pbl_agent_runtime() # M4a/M4b Designer/Critic 运行时 + fail-closed 工具裁决 load_pbl_evidence() # M5a/M5b 证据幂等采集 load_pbl_assessment() # M6 Rubric 加权评估与报告 load_pbl_domain_ext() # M8 world/scene/entity 薄扩展(不改基表) load_pbl_scense_ext() # M9 前端覆盖层与页面注册 load_pbl_runtime_ext() # M11a/M11b 单事务事件+状态写入与广播 load_pbl_kdb_ext() # M7 KDB 只读桩与匿名聚合(零写入) return env if __name__ == '__main__': webapp(init)